flv.js 实战:本地调试到线上部署

举报
周杰伦本人 发表于 2025/07/30 13:54:40 2025/07/30
【摘要】 flv.js 实战:本地调试到线上部署 一、技术选型:为什么用 HTTP-FLV浏览器原生不支持 RTMP,Flash 已淘汰。HLS 延迟高(3-6 秒),HTTP-FLV 可做到 1 秒以内。flv.js 通过 MSE 把 FLV 转封装成 ISO BMFF(MP4 片段),浏览器可直接播放。 二、本地调试:5 分钟搭环境 2.1 启动 RTMP → HTTP-FLV 服务# 拉镜像d...

flv.js 实战:本地调试到线上部署

一、技术选型:为什么用 HTTP-FLV

  1. 浏览器原生不支持 RTMP,Flash 已淘汰。

  2. HLS 延迟高(3-6 秒),HTTP-FLV 可做到 1 秒以内。

  3. flv.js 通过 MSE 把 FLV 转封装成 ISO BMFF(MP4 片段),浏览器可直接播放。

二、本地调试:5 分钟搭环境

2.1 启动 RTMP → HTTP-FLV 服务

# 拉镜像
docker pull alfg/nginx-rtmp

# 运行
docker run -d --name live \
  -p 1935:1935 -p 8080:8080 \
  alfg/nginx-rtmp

2.2 推流

ffmpeg -re -i big_buck_bunny.mp4 \
  -c:v libx264 -preset veryfast -g 30 \
  -c:a aac -f flv rtmp://localhost/live/stream

检查点

  • 浏览器访问 http://localhost:8080/live/stream.flv 返回 200。

  • curl -I 能看到 Content-Type: video/x-flv

三、最小可运行页面

<!doctype html>
<meta charset="utf-8">
<title>flv.js demo</title>
<video id="video" controls width="640" height="360"></video>
<script src="https://cdn.jsdelivr.net/npm/flv.js@1.6.2/dist/flv.min.js"></script>
<script>
  const v = document.getElementById('video');
  if (flvjs.isSupported()) {
    const player = flvjs.createPlayer({
      type: 'flv',
      isLive: true,
      url: 'http://localhost:8080/live/stream.flv'
    });
    player.attachMediaElement(v);
    player.load();
    player.play();
  }
</script>

打开页面即可播放。

createPlayer 返回一个播放器实例,内部会:

  1. 去拉 .flv 文件(或流)。

  2. 解析 FLV tag → 转封装成 MP4 片段 → 喂给 <video> 的 MSE SourceBuffer。

player.attachMediaElement(v);把播放器实例和 <video> 标签“绑”在一起。后续 player.play() 实际上是驱动 <video> 播放。

player.load();建立 XHR(或 fetch)连接,开始下载 .flv。这一步是异步的,不会阻塞页面。

player.play();在拿到首帧数据后立即播放。

四、生产级配置

4.1 低延时参数

const player = flvjs.createPlayer({
  type: 'flv',
  isLive: true,
  url: 'https://cdn.example.com/live/stream.flv'
}, {
  enableStashBuffer: false,   // 关闭缓存
  stashInitialSize: 128 * 1024,
  autoCleanupSourceBuffer: true
});

4.2 断线重连

player.on(flvjs.Events.ERROR, (e, m) => {
  console.warn('flv error', m);
  setTimeout(() => {
    player.unload();
    player.load();
    player.play();
  }, 1000);
});

4.3 自定义 UI(播放/暂停按钮)

<button id="btn">播放</button>
<script>
  const btn = document.getElementById('btn');
  let playing = false;
  btn.onclick = () => {
    if (playing) {
      player.pause();
      btn.textContent = '播放';
    } else {
      player.play();
      btn.textContent = '暂停';
    }
    playing = !playing;
  };
</script>

4.4 HTTPS 环境

  • CDN 必须支持 HTTPS-FLV。

  • 页面与流地址协议必须一致(HTTPS 页面不能拉 HTTP-FLV)。

五、监控与灰度

5.1 性能埋点

player.on('statistics_info', (e, info) => {
  // info.speed 当前网速 kbps
  // info.currentSegmentIndex 已播片段序号
  report({
    event: 'flv_speed',
    speed: info.speed,
    ts: Date.now()
  });
});

5.2 灰度策略

  • 通过 URL 参数 ?v=1 控制新旧播放器。

  • 旧播放器降级到 HLS。

六、常见错误对照表

现象 原因 解决
formatError 流地址 404 确认 nginx-rtmp 已生成 .flv
画面黑屏 CORS 未配置 CDN 加 Access-Control-Allow-Origin: *
声音延迟 时间戳不连续 FFmpeg 加 -use_wallclock_as_timestamps 1
卡顿 GOP 太大 -g 30 或更低

七、一句话总结

Docker 起服务 → FFmpeg 推流 → flv.js 播放,本地联调 5 分钟完成;上线时把 URL 换成 HTTPS-FLV 即可。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。