of+mdat 组成的,它们已经包含了足够的 metadata 信息与数据, 可以直接 seek 到这个位置开始播放。也就是说 fMP4 是一个流式的封装格式,这样更适合在网络中进行流式传输,而不需要依赖文件头的metadata。
Apple在WWDC 2016 大会上宣布会在 iOS 10、tvOS、macO S的 HLS 中支持 fMP4,可见fMP4 的前景非常的好。
值得一提的是,fMP4、CMAF、ISOBMFF 其实都是类似的东西。
MSE java script API
从高层次上看,MSE 提供了
- 一套 java script API 来构建 media streams
- 一个拼接和缓存模型
- 识别一些 byte 流类型
- WebM
- ISO Base Media File Format
- MPEG-2 Transport Streams
MSE 内部结构
MSE 本身的设计是不依赖任务特定的编解码和容器格式的,但是不同的浏览器支持程度是不一样的。
可以通过传递一个 MIME 类型的字符串到静态方法:
> MediaSource.isTypeSupported来检查。比如 ▽
MediaSource.isTypeSupported('audio/mp3'); // false
MediaSource.isTypeSupported('video/mp4'); // true
MediaSource.isTypeSupported('video/mp4; codecs="avc1.4D4028, mp4a.40.2"'); // true
获取 Codec MIME string 的方法可以通过在线的 [mp4info](http://nickdesaulniers.github.io/mp4info),或者使用命令行 mp4info test.mp4 | grep Codecs,可以得到类似如下结果 ▽
> mp4info fmp4.mp4| grep Codec
Codecs String: mp4a.40.2
Codecs String: avc1.42E01E
当前,H.264 + AAC 的 MP4 容器在所有的浏览器都支持。
普通的 MP4 文件是不能和 MSE 一起使用的, 需要将 MP4 进行 fragment 化。
检查一个 MP4 是否已经 fragment 的方法 ▽
> mp4dump test.mp4 | grep "\[m"
如果是non-fragment会显示如下信息 ▽
> mp4dump nfmp4.mp4 | grep "\[m"
[mdat] size=8+50873
[moov] size=8+7804
[mvhd] size=12+96
[mdia] size=8+3335
[mdhd] size=12+20
[minf] size=8+3250
[mdia] size=8+3975
[mdhd] size=12+20
[minf] size=8+3890
[mp4a] size=8+82
[meta] size=12+78
如果已经 fragment,会显示如下的类似信息 ▽
> mp4dump fmp4.mp4 | grep "\[m" | head -n 30
[moov] size=8+1871
[mvhd] size=12+96
[mdia] size=8+312
[mdhd] size=12+20
[minf] size=8+219
[mp4a] size=8+67
[mdia] size=8+371
[mdhd] size=12+20
[minf] size=8+278
[mdia] size=8+248
[mdhd] size=12+20
[minf] size=8+156
[mdia] size=8+248
[mdhd] size=12+20
[minf] size=8+156
[mvex] size=8+144
[mehd] size=12+4
[moof] size=8+600
[mfhd] size=12+4
[mdat] size=8+138679
[moof] size=8+536
[mfhd] size=12+4
[mdat] size=8+24490
[moof] size=8+592
[mfhd] size=12+4
[mdat] size=8+14444
[moof] size=8+312
[mfhd] size=12+4
[mdat] size=8+1840
[moof] size=8+600
把一个 non-fragment MP4 转换成 fragment MP4。
可以使用 FFmpeg 的 -movflags 来转换。
对于原始文件为非 MP4 文件 ▽
> ffmpeg -i trailer_1080p.mov -c:v copy -c:a copy -movflags frag_keyframe+empty_moov bunny_fragmented.mp4
对于原始文件已经是 MP4 文件 ▽
> ffmpeg -i non_fragmented.mp4 -movflags frag_keyframe+empty_moov fragmented.mp4
或者使用 mp4fragment ▽
> mp4fragment input.mp4 output.mp4
DEMO TIME
最后阶段,展示两个demo,分别是 MSE Vod Demo、MSE Live Demo
MSE Vod Demo
展示利用 MSE 和 WebSocket 实现一个点播服务
后端读取一个 fMP4 文件,通过 WebSocket 发送给 MSE,进行播放
展示利用 MSE 和 WebSocket 实现一个直播服务
后端代理一条 HTTP-FLV 直播流,通过 WebSocket 发送给 MSE,进行播放
前端 MSE 部分做了很多工作, 包括将 flv 实时转封装成了 fMP4,这里引用了 videojs-flow 的实现
Refs
WebSocket
- rfc6455
- HTTP Upgrade
- WebSocket API
- MDN WebSocket
- videojs-flow
MSE
- W3C
- MDN MSE
- HTML5 Codec MIME
又拍直播云是基于又拍云内容分发网络为直播应用提供超低延迟、高码率、高并发的整套从推流端到播放端的一站式解决方案。包括实时转码,实时录制,分发加速,水印,截图,秒级禁播,延时直播等功能。直播源站支持自主源站或又拍云源,为支持用户在不同终端播放,支持 RTMP、HLS、HTTP-flv 播放输出。
详情了解:https://www.upyun.com/products/live
推荐阅读:
无连麦,不直播,都在说的直播利器连麦互动到底是啥?
技术干货|移动直播六大关键技术详解
又拍直播云SDK,自带美颜、滤镜、消噪、人声增益等功能
又拍直播云功能处理篇:转码、录制、视频水印、视频截图
又拍直播云功能基础篇:推流和拉流、多协议输出、多访问方式、回源端口自定义
又拍直播云功能高级篇:防盗链、秒级禁播、自动鉴黄、API接口