CGJU
查工具网
2026年5月28日 · 阅读时长 6 分钟

FLV.js 简介

FLV.js 是由 Bilibili(B站)开源的一个纯 JavaScript 实现的 FLV 播放器,可以在不使用 Flash 插件的情况下,在支持 MSE(Media Source Extensions)的现代浏览器中播放 FLV 视频流。它的出现解决了 Flash 淘汰后网页端 FLV 直播播放的难题。

在 Flash 时代,RTMP/FLV 是直播的主流方案。但随着 Flash 被各大浏览器淘汰,网页端直播面临转型。FLV.js 的出现让基于 HTTP-FLV 的直播方案得以延续,配合 CDN 的 HTTP 分发,可以实现低延迟、高并发的直播体验。

FLV.js 的核心特性

  • 纯 JavaScript 实现:无需任何插件,纯浏览器端运行
  • 低延迟:HTTP-FLV 方案延迟可低至 1-3 秒
  • 高性能:使用 Web Worker 解析数据,不阻塞主线程
  • 兼容性好:支持所有支持 MSE 的现代浏览器
  • 功能丰富:支持直播、点播、直播录制、实时流切换等
  • 开源免费:基于 MIT 协议开源,可自由使用

B站开源背景

FLV.js 项目诞生于 Bilibili 前端团队,最初是为了解决 B 站直播业务的播放器问题。2016 年,随着 Flash 的衰落,B 站需要一个纯网页端的直播播放方案,于是发起了这个项目。

FLV.js 于 2016 年正式开源,迅速成为前端直播领域的标杆项目,被大量直播平台和视频网站采用。它的成功推动了 HTTP-FLV 直播方案的普及,也催生了更多基于 MSE 的播放器项目。

工作原理

FLV.js 的核心工作原理是:通过 HTTP 请求获取 FLV 流数据,在浏览器端用 JavaScript 解析 FLV 封装格式,然后将音视频数据通过 MSE API 喂给浏览器原生的 video 标签进行解码和播放。

整体架构

  1. IO 层:负责数据传输,支持 Fetch API、XHR、WebSocket 等方式
  2. 解析层:在 Web Worker 中解析 FLV 数据,提取音视频帧
  3. 缓冲层:管理视频缓冲区,确保播放流畅
  4. 控制层:处理播放、暂停、跳转等控制逻辑
  5. MSE 层:将解析后的数据喂给 Media Source Extensions

FLV 解析流程

FLV.js 对 FLV 文件的解析过程如下:

  • 读取 FLV Header,确认文件类型和是否包含音视频
  • 解析 Script Tag,获取视频元数据(分辨率、码率等)
  • 解析 Video Tag,提取 H.264 视频数据
  • 解析 Audio Tag,提取 AAC/MP3 音频数据
  • 将音视频数据封装成 FMP4 格式,通过 MSE 播放

flv.js 与 mpegts.js 的区别

很多人会混淆 flv.js 和 mpegts.js,其实它们是同一个作者开发的两个不同项目:

特性 flv.js mpegts.js
开发者 Bilibili 原 flv.js 作者个人
支持格式 FLV FLV、MPEG-TS
更新状态 较慢 活跃
功能 基础功能 更多新特性
推荐场景 只需要FLV播放 需要更多格式和功能

基础使用代码示例

下面通过一个完整的示例,演示如何在网页中使用 FLV.js 播放 FLV 视频流。

引入 FLV.js

最简单的方式是通过 CDN 引入:

<script src="https://cdn.jsdelivr.net/npm/flv.js@latest/dist/flv.min.js"></script>

也可以通过 npm 安装:

npm install flv.js --save

HTML 结构

在页面中添加一个 video 元素:

<video id="videoElement" controls autoplay muted playsinline></video>

JavaScript 初始化

使用 FLV.js 创建播放器实例并加载视频流:

if (flvjs.isSupported()) {
    const videoElement = document.getElementById('videoElement');
    const flvPlayer = flvjs.createPlayer({
        type: 'flv',
        url: 'https://example.com/live/stream.flv',
        isLive: true
    });
    flvPlayer.attachMediaElement(videoElement);
    flvPlayer.load();
    flvPlayer.play();
}

配置参数说明

  • type:媒体类型,'flv' 或 'mp4'
  • url:视频流地址
  • isLive:是否为直播流
  • cors:是否启用 CORS 跨域
  • withCredentials:是否携带 Cookie
  • hasAudio:是否包含音频
  • hasVideo:是否包含视频

低延迟优化

直播场景下,延迟是一个非常重要的指标。FLV.js 提供了多种配置选项来优化延迟。

关键配置项

const flvPlayer = flvjs.createPlayer({
    type: 'flv',
    url: 'https://example.com/live/stream.flv',
    isLive: true
}, {
    enableWorker: true,
    enableStashBuffer: false,
    stashInitialSize: 128,
    liveBufferLatencyChasing: true,
    liveBufferLatencyMaxLatency: 1.5,
    liveBufferLatencyMinRemain: 0.5,
    autoCleanupSourceBuffer: true
});

低延迟配置说明

  • enableWorker: true:启用 Web Worker,避免解析阻塞主线程
  • enableStashBuffer: false:禁用缓存缓冲区,减少延迟
  • stashInitialSize: 128:初始缓存大小(KB),设置较小值
  • liveBufferLatencyChasing: true:启用直播延迟追赶
  • liveBufferLatencyMaxLatency: 1.5:最大延迟 1.5 秒,超过则加速
  • liveBufferLatencyMinRemain: 0.5:最小缓冲 0.5 秒
  • autoCleanupSourceBuffer: true:自动清理缓冲区,避免内存增长

其他优化建议

  • 使用 HTTP/1.1 长连接:减少握手开销
  • 合理设置 GOP 长度:推流端设置 1-2 秒 GOP
  • 使用 MPEG-TS over WebSocket:WebSocket 延迟更低
  • CDN 优化:选择支持低延迟直播的 CDN
  • 编码参数优化:使用 baseline profile,降低编码延迟

事件监听

FLV.js 提供了丰富的事件系统,可以监听各种状态变化。

常用事件

flvPlayer.on(flvjs.Events.ERROR, function(errorType, errorDetail, errorInfo) {
    console.log('错误:', errorType, errorDetail, errorInfo);
});

flvPlayer.on(flvjs.Events.LOADING_COMPLETE, function() {
    console.log('加载完成');
});

flvPlayer.on(flvjs.Events.RECOVERED_EARLY_EOF, function() {
    console.log('从意外结束中恢复');
});

flvPlayer.on(flvjs.Events.MEDIA_INFO, function(mediaInfo) {
    console.log('媒体信息:', mediaInfo);
});

flvPlayer.on(flvjs.Events.STATISTICS_INFO, function(statInfo) {
    console.log('统计信息:', statInfo);
});

事件类型说明

  • ERROR:发生错误时触发
  • LOADING_COMPLETE:数据加载完成时触发(VOD)
  • RECOVERED_EARLY_EOF:直播流意外断开后重新连接
  • MEDIA_INFO:获取到媒体元数据信息
  • STATISTICS_INFO:播放统计信息(每秒更新)
  • BUFFER_EMPTY:缓冲区为空,可能卡顿
  • BUFFER_FULL:缓冲区已满

错误处理

完善的错误处理是生产环境必备的功能。FLV.js 的错误分为不同类型,需要针对性处理。

错误类型

  • NETWORK_ERROR:网络错误,如连接失败、超时等
  • MEDIA_ERROR:媒体错误,如解码失败、格式不支持等
  • OTHER_ERROR:其他错误

完整错误处理示例

flvPlayer.on(flvjs.Events.ERROR, function(errorType, errorDetail, errorInfo) {
    console.error('播放器错误:', errorType, errorDetail);

    if (errorType === flvjs.ErrorTypes.NETWORK_ERROR) {
        if (errorDetail === flvjs.ErrorDetails.NETWORK_STATUS_CODE_INVALID) {
            console.log('HTTP状态码错误,可能链接失效');
        } else if (errorDetail === flvjs.ErrorDetails.NETWORK_TIMEOUT) {
            console.log('网络超时,尝试重连...');
            retryPlay();
        }
    } else if (errorType === flvjs.ErrorTypes.MEDIA_ERROR) {
        console.log('媒体错误,尝试恢复...');
        flvPlayer.recoverMediaError();
    }
});

function retryPlay() {
    flvPlayer.unload();
    flvPlayer.load();
    flvPlayer.play();
}

自动重连机制

对于直播场景,网络波动导致断流是常见问题,建议实现自动重连机制:

let retryCount = 0;
const maxRetry = 5;

flvPlayer.on(flvjs.Events.ERROR, function(errorType) {
    if (errorType === flvjs.ErrorTypes.NETWORK_ERROR && retryCount < maxRetry) {
        retryCount++;
        setTimeout(function() {
            flvPlayer.unload();
            flvPlayer.load();
            flvPlayer.play();
        }, 2000 * retryCount);
    }
});

flvPlayer.on(flvjs.Events.RECOVERED_EARLY_EOF, function() {
    retryCount = 0;
});

最佳实践

1. 浏览器兼容性检测

在初始化前先检测浏览器是否支持,不支持时给出友好提示:

if (flvjs.isSupported()) {
    initPlayer();
} else {
    alert('您的浏览器不支持FLV播放,请使用Chrome、Firefox或Edge浏览器');
}

2. 正确的销毁时机

页面卸载或切换视频时,务必销毁播放器释放资源:

window.addEventListener('beforeunload', function() {
    if (flvPlayer) {
        flvPlayer.pause();
        flvPlayer.unload();
        flvPlayer.detachMediaElement();
        flvPlayer.destroy();
        flvPlayer = null;
    }
});

3. 处理 CORS 跨域

确保视频服务器配置了正确的 CORS 头,否则 FLV.js 无法加载。需要的响应头包括:

  • Access-Control-Allow-Origin: *(或指定域名)
  • Access-Control-Allow-Methods: GET, POST, OPTIONS
  • Access-Control-Expose-Headers: Content-Length

4. 直播暂停后的处理

直播流暂停后再播放,会从暂停的位置继续,导致延迟累积。建议暂停后再播放时跳转到最新位置:

videoElement.addEventListener('play', function() {
    if (flvPlayer && flvPlayer.config.isLive) {
        const livePosition = videoElement.buffered.end(0) - 1;
        if (videoElement.currentTime < livePosition - 3) {
            videoElement.currentTime = livePosition;
        }
    }
});

总结

FLV.js 是一个优秀的开源 FLV 播放器,为网页端直播提供了高性能、低延迟的解决方案。它的纯 JavaScript 实现无需任何插件,配合 HTTP-FLV 协议,可以达到接近 Flash 时代的低延迟体验。

对于想要快速体验 FLV 播放的用户,可以直接使用我们的 FLV/RTMP 在线播放器,粘贴直播地址即可在浏览器中观看,无需编写任何代码。

相关推荐

更多精彩文章和实用工具

想播放FLV直播流?

使用我们的免费FLV在线播放器,粘贴地址即可播放,支持截图、录制、低延迟模式

立即体验 ➡