使用flv.js做直播 · Issue #3 · gwuhaolin/blog · GitHub

标签: | 发表时间:2019-05-10 10:19 | 作者:
出处:https://github.com

为什么要在这个时候探索flv.js做直播呢?原因在于各大浏览器厂商已经默认禁用Flash,之前常见的Flash直播方案需要用户同意使用Flash后才可以正常使用直播功能,这样的用户体验很致命。

在介绍flv.js之前先介绍下常见的直播协议以及给出我对它们的延迟与性能所做的测试得出的数据。
如果你看的很吃力可以先了解下音视频技术的一些 基础概念

常见直播协议

  • RTMP: 底层基于 TCP,在浏览器端依赖Flash。
  • HTTP-FLV: 基于 HTTP流式IO传输FLV,依赖浏览器支持播放FLV。
  • WebSocket-FLV: 基于 WebSocket传输FLV,依赖浏览器支持播放FLV。 WebSocket建立在 HTTP之上,建立 WebSocket连接前还要先建立 HTTP连接。
  • HLS: Http Live Streaming,苹果提出基于 HTTP的流媒体传输协议。 HTML5可以直接打开播放。
  • RTP: 基于 UDP,延迟1秒,浏览器不支持。

常见直播协议延迟与性能数据 以下数据只做对比参考

传输协议 播放器 延迟 内存 CPU
RTMP Flash 1s 430M 11%
HTTP-FLV Video 1s 310M 4.4%
HLS Video 20s 205M 3%

在支持浏览器的协议里,延迟排序是:
RTMP = HTTP-FLV = WebSocket-FLV < HLS
而性能排序恰好相反:
RTMP > HTTP-FLV = WebSocket-FLV > HLS
也就是说延迟小的性能不好。

可以看出在浏览器里做直播,使用HTTP-FLV协议是不错的,性能优于RTMP+Flash,延迟可以做到和RTMP+Flash一样甚至更好。

flv.js 简介

flv.js是来自Bilibli的开源项目。它解析FLV文件喂给原生HTML5 Video标签播放音视频数据,使浏览器在不借助Flash的情况下播放FLV成为可能。

flv.js 优势

  • 由于浏览器对原生Video标签采用了硬件加速,性能很好,支持高清。
  • 同时支持录播和直播
  • 去掉对Flash的依赖

flv.js 限制

  • FLV里所包含的视频编码必须是 H.264,音频编码必须是 AACMP3, IE11和Edge浏览器不支持MP3音频编码,所以FLV里采用的编码最好是H.264+AAC,这个让音视频服务兼容不是问题。
  • 对于录播,依赖 原生HTML5 Video标签Media Source ExtensionsAPI
  • 对于直播,依赖录播所需要的播放技术,同时依赖 HTTP FLV或者 WebSocket中的一种协议来传输FLV。其中 HTTP FLV需通过流式IO去拉取数据,支持流式IO的有 fetch或者 stream
  • flv.min.js文件大小 164Kb,gzip后 35.5Kb,flash播放器gzip后差不多也是这么大。
  • 由于依赖 Media Source Extensions,目前所有iOS和Android4.4.4以下里的浏览器都不支持,也就是说目前对于移动端flv.js基本是不能用的。

flv.js依赖的浏览器特性兼容列表

flv.js 原理

flv.js只做了一件事,在获取到FLV格式的音视频数据后通过原生的JS去解码FLV数据,再通过 Media Source ExtensionsAPI 喂给原生HTML5 Video标签。(HTML5 原生仅支持播放 mp4/webm 格式,不支持 FLV)

flv.js 为什么要绕一圈,从服务器获取FLV再解码转换后再喂给Video标签呢?原因如下:

  1. 兼容目前的直播方案:目前大多数直播方案的音视频服务都是采用FLV容器格式传输音视频数据。
  2. FLV容器格式相比于MP4格式更加简单,解析起来更快更方便。

flv.js兼容方案

由于目前flv.js兼容性还不是很好,要用在产品中必要要兼顾到不支持flv.js的浏览器。兼容方案如下:

PC端

  1. 优先使用 HTTP-FLV,因为它延迟小,性能也不差1080P都很流畅。
  2. 不支持 flv.js 就使用 Flash播放器播 RTMP 流。Flash兼容性很好,但是性能差默认被很多浏览器禁用。
  3. 不想用Flash兼容也可以用HLS,但是PC端只有Safari支持HLS

移动端

  1. 优先使用 HTTP-FLV,因为它延迟小,支持HTTP-FLV的设备性能运行 flv.js 足够了。
  2. 不支持 flv.js 就使用 HLS,但是 HLS延迟非常大。
  3. HLS 也不支持就没法直播了,因为移动端都不支持Flash。

flv.js实战

说了这么多介绍与原理,接下来教大家如何用flv.js搭建一个完整的直播系统。
我已经搭建好了 一个demo可以供大家体验。

搭建音视频服务

主播推流到音视频服务,音视频服务再转发给所有连接的客户端。为了让你快速搭建服务推荐我用go语言实现的 livego,因为它可以运行在任何操作系统上,对Golang感兴趣?请看 Golang 中文学习资料汇总

  1. 下载livego,注意选对你的操作系统和位数。
  2. 解压,执行 livego,服务就启动好了。它会启动RTMP(1935端口)服务用于主播推流,以及HTTP-FLV(7001端口)服务用于播放。

实现播放页

在react体系里使用react flv.js 组件 reflv快速实现。
先安装 npm i reflv,再写代码:

importReact, {PureComponent}from'react';importReflvfrom'reflv';exportclassHttpFlvextendsPureComponent{render() {return(<Reflv
        url={`http://localhost:7001/live/test.flv`}
        type="flv"isLive
        cors/>)
  }
}

让以上代码在浏览器里运行。这是你还看不到直播,是因为还没有主播推流。

  • 你可以使用 OBS来推流,注意要配置好OBS:

screen shot 2017-06-07 at 5 41 32 pm

  • 也可以使用 ffmpeg来推流,推流命令 ffmpeg -f avfoundation -i "0" -vcodec h264 -acodec aac -f flv rtmp://localhost/live/test

flv.js延迟优化

按照上面的教程运行起来的直播延迟大概有3秒,经过优化可以到1秒。在教你怎么优化前先要介绍下直播运行流程:

  1. 主播端在采集到一段时间的音视频原数据后,因为音视频原数据庞大需要先压缩数据:

    • 通过H264视频编码压缩数据数据
    • 通过PCM音频编码压缩音频AAC数据
  2. 压缩完后再通过FLV容器格式封装压缩后的数据,封装成一个FLV TAG

  3. 再把FLV TAG通过RTMP协议推流到音视频服务器,音视频服务器再从RTMP协议里解析出FLV TAG。

  4. 音视频服务器再通过HTTP协议通过和浏览器建立的长链接流式把FLV TAG传给浏览器。

  5. flv.js 获取FLV TAG后解析出压缩后的音视频数据喂给Video播放。

知道流程后我们就知道从哪入手优化了:

  • 主播端采集时收集了一段时间的音视频原数据,它专业的叫法是 GOP。缩短这个收集时间(也就是减少GOP长度)可以优化延迟,但这样做的坏处是导致视频压缩率不高,传输效率低。
  • 关闭音视频服务器的I桢缓存可以优化延迟,坏处是用户看到直播首屏的时间变大。
  • 减少音视频服务器的buffer可以优化延迟,坏处是音视频服务器处理效率降低。
  • 减少浏览器端flv.js的buffer可以优化延迟,坏处是浏览器端处理效率降低。
  • 浏览器端开启flv.js的Worker,多线程运行flv.js提升解析速度可以优化延迟,这样做的flv.js配置代码是:
{
          enableWorker:true,
          enableStashBuffer:false,
          stashInitialSize:128,//减少首桢显示等待时长}

这里是 优化后的完整代码

阅读原文

相关 [flv js 直播] 推荐:

HTTP-FLV直播初探 - 冒雨ing - 博客园

- -
两个flv.js的扩展版本:. 目前几种视频流的简单对比:. 可通过html5解封包播放(flv.js). 可通过html5解封包播放(hls.js). 如果dash文件列表是mp4webm文件,可直接播放. RTMP(Real Time Messaging Protocol)是基于TCP的,由Adobe公司为Flash播放器和服务器之间音频、视频传输开发的开放协议.

FLV Extract:轻松从FLV文件中分离音频/视频

- 十年恋一人! - 软件志
一、FLV Extract简介: 这款小工具能帮助我们快速地从FLV文件中分离音频/视频,而且官方宣称是无损分离,能将FLV、F4V、PFV以AVI(H.263/FLV1)(VP6/VP6F)(H.264/AVC)视频格式以及MP3,AAC(ADTS标头),WAV(PCM)的音频格式分离输出. 二、FLV Extract安装及简单使用: 1、下载及安装:下载后解压文件到任意文件夹,因为是绿色软件,所以无须安装,直接运行文件夹内的主程序就能启动该软件; 2、从FLV文件中分离音频/视频: 软件操作十分简单,运行软件后,只需要将FLV视频文件拖拽到软件窗口内,对应该文件的视频文件、timecodes文件以及音频文件就会被单独分离出来.

GitHub - winshining/nginx-http-flv-module: Media streaming server based on nginx-rtmp-module. In addtion to the features nginx-rtmp-module supplies, HTTP-FLV, GOP cache and VHOST are supported now.

- -
MUSTbe enclosed by quotation marks, or arguments in url will be discarded (some shells not so smart will interpret "&" as "run in background").. ngx_rtmp_stat_modulemay not get statistics from a specified worker process in multi-processes mode, for HTTP requests are randomly distributed to worker processes.

WebView JS 交互

- - ITeye博客
WebView加jquery做页面会怎么样呢. // 创建WebView对象. // 把programList添加到js的全局对象window中,. // 这样就可以使用window.programList来获取数据. * 定义js回调java函数. // 绑定键盘的向上,向下按钮事件触发相应的js事件.

JS游戏引擎

- 米随随 - HTML5研究小组
If you don’t have anything better to do and want to help fellow redditors interested in JS game dev out, feel free to fork the list and modify it as you like.

來源請求.js

- 红烧鲤鱼 - Blog: timdream
很早以前就想講了,但講了大概又會被戰. 相較於英文維基百科,中文維基百科在社會和歷史條目充滿了 systemic bias. 但是那些主觀論述又不是編輯者有意加進去的,而是某種編輯者存在的社會所給予的暗示(Inception?)與集體共識,而不是原本百科全書應該有的可驗證的事實. 因為是暗示又是共識,所以有自覺的百科編輯者反而是少數;中文維基只好長成現在這個樣子了.

Js删除节点

- - JavaScript - Web前端 - ITeye博客
 方式一:传this参数调用方法:.  方式二:js方法中通过选择器获取节点:. //此处删除的是a节点 }. 方式三:通过jQuery方式获取节点:(尚未测试,有待测试. 此处a标签传this到js中,js通过this(即a节点)取parent(即p节点). (1)p.remove();可直接删除整个p节点.

用nginx搭建基于rtmp或者http的flv、mp4流媒体服务器

- - 开源软件 - ITeye博客
这种方式要下载FLV视频文件到本地播放,一旦FLV视频文件下载完成,就不会消耗服务器的资源和带宽,但是拖动功能没有RTMP/RTMP流媒体方式强大,很多视频网站都是用HTTP方式实现的,如:YouTube,土豆,酷6等. 2、  RTMP/RTMP流媒体方式. 这种方式不用下载FLV视频文件到本地,可以实时的播放flv文件,可以任意拖拽播放进度条,但是比较消耗服务器的资源.

nginx+jwplayer配置flv/MP4点播系统, 视频拖动支持 - 一 水

- - 博客园_首页
下载 nginx 最新版 http://nginx.org/. 安装依赖库, 以ubuntu为例. 编译nginx, 增加flv和MP4的支持.    编译时可以指定安装目录 --prefix=/path/to/install.    然后make install. 测试是否支持seek(拖动, 快进).

JS游戏引擎列表

- sku - 酷壳 - CoolShell.cn
这里有一个网址收集了关于JS游戏引擎开发库的一个列表,转过来. 关于使用JS和HTML5做的一些小游戏,可参见《HTML5 小游戏展示》. Name Latest Release License Type Notes The Render Engine 1.5.3 MIT 跨浏览器; 大规模 API; 开源. 2 gameQuery 0.5.1 CC BY-SA 2.5 和 jQuery 一起使用 gTile 0.0.1 Tile based.