flv.js全面解析(代码片段)

爱是与世界平行 爱是与世界平行     2022-12-01     181

关键词:

Flv.js全面解析

(推荐使用Typora查看!)

相关内容参考地址:

Flv.js 是 HTML5 Flash 视频(FLV)播放器,纯原生 JavaScript 开发,没有用到 Flash。由 bilibili 网站开源。
Github地址:https://github.com/Bilibili/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秒,浏览器不支持。

Flv.js概览

一个实现了在 HTML5 视频中播放 FLV 格式视频的 JavaScript 库。它的工作原理是将 FLV 文件流转码复用成 ISO BMFF(MP4 碎片)片段,然后通过 Media Source Extensions 将 MP4 片段喂进浏览器。

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

flash性能问题是长期以来被全世界人所诟病的,尤其是明年起chrome彻底抛弃flash,越来越多有直播需求的人产生焦虑。这就加速了html5播放器的发展,也使得人们对html5非插件式的播放器更加渴望。而flv.js就是这么一款可以利用html5的video标签将http-flv直播流实时播放的一个js版的播放器。

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

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

HTML5 原生仅支持播放 mp4/webm 格式,flv.js 实现了在 HTML5 上播放 FLV 格式视频。

flv.js在获取到FLV格式的音视频数据后将 FLV 文件流转码复用成 ISO BMFF(MP4 碎片)片段,再通过Media Source Extensions API 传递给原生HTML5 Video标签进行播放。

flv.js 是使用 ECMAScript 6 编写的,然后通过 Babel Compiler 编译成 ECMAScript 5,使用 Browserify 打包。

Flv.js结构图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qzxCCfbB-1602205776596)(F:/lovebetterworld/流媒体/flv/flv.png)]

flv.js 中的demux就是一套 FLV 媒体数据格式的解析器。

架构图

功能

  • FLV 容器,具有 H.264 + AAC 编解码器播放功能
  • 多部分分段视频播放
  • HTTP FLV 低延迟实时流播放
  • FLV 通过 WebSocket 实时流播放
  • 兼容 Chrome, FireFox, Safari 10, IE11 和 Edge
  • 十分低开销,并且通过你的浏览器进行硬件加速

API文档相关

flvjs.isSupported()
// 查看当前浏览器是否支持flv.js,返回类型为布尔值

flvjs.createPlayer(mediaDataSource: MediaDataSource, config?: Config)

/* 创建一个Player实例,它接收一个MediaDataSource(必选), 一个Config(可选),如:
var flvPlayer = flvjs.createPlayer(
   type: 'flv',
   url: 'http://example.com/flv/video.flv'
); */

MediaDataSource的字段列表如下,

这里说下最后一个segments字段(其余字段都很简单),它接收一个数组,类型为MediaSegment,MediaSegment的字段列表如下,

如果segments字段存在,transmuxer将把此MediaDataSource视为多片段源。在多片段模式下,将忽略MediaDataSource结构中的duration filesize url字段。
什么个意思呢,用白话说就是如果指定了segments字段那么之前指定的duration filesize url字段就不再生效了,将标志这是一个多片段合成一个的视频,进度条的总时长就等于各片段相加的和,所以每个片段的duration filesize一定要指定准确。

Config

flvjs.getFeatureList()

// 返回一些功能特性列表,比如是否支持FLV直播流、H264 MP4 视频文件等等,如下

Flv.js兼容性

理论上只要是支持Media Source Extensions和ECMAScript 5的浏览器都是兼容flv.js的,浏览器对MSE的兼容情况如下图,从图中可以看出,flv.js的兼容性还是非常不错的。 需要指出的是iPhone版的Safari是不支持MSE的,所以在iPhone上只有hls是最理想的选择,而庆幸的是PC版和android版的浏览器大多都是支持MSE的,也就是说可以利用http-flv直播实现延时较低的效果。

如果你对兼容性要求非常高的话,HLS会是非常好的选择,而并非所有浏览器版本都支持HLS播放,但是你可以利用另外一个JS播放器项目(video.js)实现全平台的hls直播。

各个浏览器对HLS的支持情况:

所以,你可以将flv.js和video.js配合使用,针对不同平台实现最优的方案。

直播服务器搭建

关于直播服务器搭建的流程,我在以前的博客里写了很多,感兴趣的可以参考分布式直播系统(二)【搭建单点rtmp\\http-flv\\hls流媒体服务器】

当然也可以使用我的一键部署脚本安装:
https://github.com/im-pingo/pingos

# 快速安装
git clone https://github.com/im-pingo/pingos.git

cd pingos

./release.sh -i

# 启动服务
cd /usr/local/pingos/
./sbin/nginx
12345678910

推流

ffmpeg推流

ffmpeg -re -i 文件.mp4 -vcodec copy -acodec copy -f flv rtmp://ip地址/live/01
1

OBS推流

Open Broadcaster Software(简称OBS)是一款直播流媒体内容制作软件。同时程序和其源代码都是免费的。

支持 OS X、Windows、Linux操作系统。适用于多种直播场景。满足大部分直播行为的操作需求(发布桌面、发布摄像头、麦克风、扬声器等等)。

flv.js搭建过程

下载链接

为了方便使用,我已经将flv.js编译打包好了,直接下载解压到你的网站目录引用即可。

  1. 可以使用百度云盘下载
    链接: https://pan.baidu.com/s/1ihTo15nsgfLqXKa0vyFt-w
    提取码: gd55
  2. 也可以从github下载
git clone https://github.com/im-pingo/h5player.git
1

将h5player复制到你的网站目录,h5player/flv目录下有个index.html文件,这里是js播放器接口的调用示例,你可以直接利用这个页面演示。

flv.js Demo演示

Demo地址:http://player.pingos.io/flv

我已经搭建了一个完整的演示界面,你可以快速体验一把。

  1. 输入http-flv的直播地址
  2. 点击load按钮即可播放。

播放器主要参数

参数描述
enableStashBuffer是否开启播放器端缓存
stashInitialSize播放器端缓存
isLive是否为直播流
hasAudio是否播放声音
hasVideo是否播放画面

源码分析

  • createPlayer 接收两个参数:媒体资源 mediaDataSource 和配置 optionalConfig,根据媒体类型( type 属性)创建一个播放器

  • isSupported 实际上是 Features.supportMSEH264Playback()

  • getFeatureList 实际上是 Features.getFeatureList()

flv.js-flvjs 对象入口

它做了以下几件事:

  1. 激活了 polyfill

  2. 组合播放器实例以及相关方法:FlvPlayer 和 NativePlayer,createPlayer、isSupported、getFeatureList。这里个人建议使用 Object.assign 完成组合
    2.1 createPlayer 接收两个参数:媒体资源 mediaDataSource 和配置 optionalConfig,根据媒体类型( type 属性)创建一个播放器
    2.2 isSupported 实际上是 Features.supportMSEH264Playback()
    2.3 getFeatureList 实际上是 Features.getFeatureList()

  3. 关联相关事件和错误、调试工具

  4. 挂载到window对象导出

polyfill.js-Polyfill类-es6的polyfill

  1. 引入了 Object.setPrototypeOf、Object.assign、promise 的 polyfill,包装在 install 函数里
  2. 这一块完全可以交给 polyfill 库或者从 MDN 引,不是 flv.js 的重点

features.js-Features 类-MSE 特征检测

重点文件,可以知道浏览器目前支持 MSE 的哪些功能

supportMSEH264Playback 判断全局上是否有 MediaSource 这个对象,并且需要支持 video/mp4; codecs="avc1.42E01E,mp4a.40.2"这种类型。

  • flv.js 是将 flv 格式转换成 “avc1.42E01E,mp4a.40.2” 格式了。
  • MDN 的 MediaSource 示例也给我们展示了如何通过 MediaSource 的方法和事件加载一个 mp4 文件。

supportNetworkStreamIO 通过创建一个 IOController 来判断加载器是否支持流。 (只能是 fetch-stream-loader 类型或 xhr-moz-chunked-loader 类型)。

supportNativeMediaPlayback 通过创建一个 video 元素,利用它的 canPlayType 方法判断是否支持某种 mime 的数据

getFeatureList 获取支持的特性列表,分别是:

  • mseFlvPlayback MSE是否支持
  • networkStreamIO 数据流是否支持
  • networkLoaderName 数据加载器名称
  • mseLiveFlvPlayback MSE 流视频是否支持
  • nativeMP4H264Playback 原生 MP4 格式是否支持
  • nativeWebmVP8Playback 原生 Webm VP8 格式是否支持
  • nativeWebmVP9Playback 原生 Webm VP9 格式是否支持

logging-control.js-LoggingControl类-调试控制器

这里涉及到繁琐的参数设置,并且使用 get 和 set 控制了读写过程,不具体介绍每个方法,主要是介绍用途和事件的使用。

  1. 组合了 EventEmitter,采用发布-订阅模式管理调试,getConfig 方法可以获得所有调试选项,applyConfig 方法可以接受一个 config 对象来配置调试选项。
  2. forceGlobalTag 是否开启强制全局标签和 globalTag 全局标签在 set 中使用了 _notifyChange 方法发布变化。
  3. enableAll/enableDebug/enableVerbose/enableInfo/enableWarn/enableError 这六个方法是是否允许特定模式的 console,刚好对应原生的调试 API,同上会在 set 中发布了变化
  4. _notifyChange 关键是利用 emitter 触发一个 change 事件,参数是所有调试配置。
    4.1 这里利用 listenerCount 方法让多个事件只触发一次。
  5. registerListener(listener) 和 removeListener(listener) 是让 emitter 注册或移除事件监听。
    5.1 代码初始化的时候 new 了一个 EventEmitter 注入到 LoggingControl 中。

exception.js

这个文件里有四个类,用来描述代码运行中的三类错误,其中 RuntimeException 是基类。

  1. RuntimeException类-运行时错误,基类,拥有 _message 私有属性和 message、name 两个只读属性,以及一个 toString 方法用来描述完整的错误信息。

  2. IllegalStateException类-无效状态,name 只读属性重写为 ‘IllegalStateException’

  3. InvalidArgumentException类-无效参数,name 只读属性重写为 ‘InvalidArgumentException’

  4. NotImplementedException-未实现功能,name 只读属性重写为 ‘NotImplementedException’

01flv的binary解析(代码片段)

想要看一下这个flv的格式主要因素为rtsp视频服务转换为rtmp服务转换为前端可用的服务 ,然后里面有flv.js的代码,因为之前出现了一些问题 flvjs播放ws服务代理的不存在的rtsp连接,Cannotreadpropertiesofnull(reading‘flushStashedSamples‘)然后... 查看详情

01flv的binary解析(代码片段)

...解了一下flv的格式以及相关约束 然后后面有点时间,可以解析一下flv的文件,以及websocket交互的flv数据流,来用一下 flv格式的官方文档 http://www.adobe.com/devnet/flv/参考文章 FLV格式详解_狗蛋儿l的博客-CSDN博客_flv格式flv解析主要是基... 查看详情

scripterror.全面解析(代码片段)

一些用户向我们反馈,Fundebug的JavaScript监控插件抓到了很多Scripterror.,然后行号和列号都是0...这就很尴尬了。今天,我们来详细地解析一下Scripterror.,后续我们还会深度测试并且提供解决方法。同源策略(Sameoriginpolicy)解释Scripter... 查看详情

linux全面解析讲解(代码片段)

Linux全面解析讲解目录🏳️‍🌈开讲啦!!!!🏳️‍🌈苏州程序大白🏳️‍🌈🌟博主介绍Linux操作系统认知操作系统(OperationSystem简称OS)Linux系统介绍文件系统Linux常用命... 查看详情

全面解析容器编排技术kubernetes(代码片段)

metadata:name:my-serviceselector:app:my-apptype:ClusterIPports:-name:httpport:80targetPort:8080protocol:TCP上面的示例定义了一个ClusterIPService。ClusterIP上端口80的流量将转发到Pod上的8080端口(targetPort配置项)上,携带 app:my-ap 查看详情

全排列算法的全面解析(代码片段)

...#xff0c;说易也易,下面我就来对这个问题进行一个比较全面的解析吧。如 查看详情

android之json全面解析与使用(代码片段)

Android之JSON全面解析与使用什么是JSONJSON指的是JavaScript对象表示法(JavaScriptObjectNotation)JSON是轻量级的文本数据交换格式JSON独立于语言(单纯的数据格式,不受语言的约束)JSON具有自我描述性,更易理解... 查看详情

非常全面的hashmap解析!(代码片段)

摘要HashMap是Java程序员使用频率最高的用于映射(键值对)处理的数据类型。随着JDK(JavaDevelopmetKit)版本的更新,JDK1.8对HashMap底层的实现进行了优化,例如引入红黑树的数据结构和扩容的优化等。本文结合JDK1.7和JDK1.8的区别,深... 查看详情

《你不知道的js》——this全面解析(代码片段)

默认绑定//全局对象用于默认绑定functionfoo()console.log(this.a)vara=2;foo();//2//严格模式下,不能将全局对象用于默认绑定functionfoo()‘usestrict‘;console.log(this.a)vara=2;foo();//TypeError:thisisundefined//在严格模式下调用foo()则不影响默认绑定func 查看详情

matplotlib基础知识全面解析(代码片段)

图像基本知识:通常情况下,我们可以将一副Matplotlib图像分成三层结构:1.第一层是底层的容器层,主要包括Canvas、Figure、Axes;2.第二层是辅助显示层,主要包括Axis、Spines、Tick、Grid、Legend、Title等,该层可通过set_axis_off()或set_f... 查看详情

21大软件架构特点的全面解析(代码片段)

????????关注后回复 “进群” ,拉你进程序员交流群????????作者丨sergiuoltean策划丨万佳来源丨InfoQ架构头条(ID:ArchFront)众所周知,架构特点多以"ility"结尾(例如scalability、deployability),也... 查看详情

android全面解析handler(代码片段)

前言:由于Handler和Binder是Android开发的俩大利器之一,所以有必要来深入讲解一下Handler,关于Binder可以参考我上一篇博客《IPC机制Binder》,废话不多说,今天我将图文并茂,一节一节解剖Handler,一节一... 查看详情

播放flv格式视频(代码片段)

flv是一种文件极小、加载速度极快的流媒体格式视频,但有一个缺点是在苹果手机不能播放,苹果笔记本可以。一、html内容<videoid="my-player"></video>二、引入flv.js<scriptsrc="https://cdn.bootcdn.net/ajax/libs... 查看详情

全面解析java日期时间api(代码片段)

时区GMT(GreenwichMeanTime):格林尼治时间,格林尼治标准时间的正午是指当太阳横穿格林尼治子午线时(也就是在格林尼治上空最高点时)的时间。UTC(UniversalTimeCoordinated):统一协调时间,其以原子时秒长为基础,在时刻上尽... 查看详情

全面解析fpga的基础知识(代码片段)

1、FPGA的简介(1)FPGA(Field-ProgrammableGateArray),即现场可编程门阵列,它是在PAL、GAL、CPLD等可编程器件的基础上进一步发展出来的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不... 查看详情

mysql&innodb锁机制全面解析(代码片段)

这里写目录标题一、前言二、锁的类型2.1全局锁2.2表级锁2.2.1表锁2.2.2元数据锁(MetaDataLocks)2.2.3自增列锁(AUTO-INCLocks)2.2.4意向锁(IntentionLocks)2.3行级锁2.3.1RecordLocks2.3.2GapLocks2.3.3Next-KeyLo 查看详情

通过vue+flvjs在html5中播放flv格式视频文件—demo及api(代码片段)

...#xff0c;所以直接用video标签播放是行不通的。因此提供两种解析方法嵌入一个swf媒体播放文件,并利用该文件来播放你预设的文件。这里推荐dplayer——http://dplayer.js.org/zh/guide.html#flv(亲测同样好用)利用B站开源的flv.js&... 查看详情

深度解析volatile关键字(保证够全面)❤❤(代码片段)

深度解析volatile关键字volatile名词解释volatile第一次在c++代码里有接触,当时老师只介绍了其用法,原理这些并没有深入了解,如今再一次在java代码里碰见了。就必须得好好的一探究竟!首先volatile是一个特... 查看详情