由于现代的浏览器不再支持flash,再加上目前来说h5很强大,时下也是非常流行的来使用h5来播放视频,但是:首要面临的一个问题就是用户观看视频的时候是直接完全加载整个视频的(不管你看了多久),从一开始播放就开始加载,并且并不会因为用户暂停而暂停加载, 它是一直持续加载直到加载完全的。
对于绝大多数用户来说,他们不一定会把视频看完,如果是加载一个小视频,那还没有什么大问题,但如果是加载一个大视频的话,这就会浪费的大量的流量,并且加载过程会持续占用带宽,使得用户量多的时候,视频加载就会出现问题。
这种情况如何解决?
一个最直接最简单的解决方案就是“视频切片”,原理就是将视频文件切分成若干个ts文件,当用户看一段加载一段,视频无缝播放用户体验良好,当用户暂停获跳出就不再继续加载,这更大的程度的节省了带宽,是个绝佳的解决方案。
下面我们这个示例主要说的是视频由 .MP4转成ts文件使用到的ffmpeg工具:
讲示例前,确保你已经熟悉原理并了解Nginx+rtmp搭建流媒体服务实现“直播”教程
使用ffmpeg推流工具实现“流媒体之视频切片”功能
ffmpeg切割视频具体的操作步骤如下:
1、ffmpeg安装
sudo gem install ffmpeg
2、将mp4转为完整的ts
ffmpeg -i .\test.mp4 -c copy -bsf h264_mp4toannexb .\video\test.ts
解释:
.\test.mp4 为输入视频源路径
.\video\test.ts 为输出视频源路径
3、将ts切片并生成.m3u8的文件
ffmpeg -i .\video\test.ts -c copy -map 0 -f segment -segment_list playlist.m3u8 -segment_time 5 -segment_list_entry_prefix 'localhost/video' D:\ffmpeg\video\test_%03d.ts
解释:
.\video\test.ts 上一步输出的ts文件路径
-segment_list playlist.m3u8 指定输出m3u8文件路径--指定文件夹必须存在
-segment_time 5 指定秒数为每段ts文件的时长,由于关键帧的因素存在误差
-segment_list_entry_prefix 'localhost/video' 指定在m3u8文件中每个ts片段的网络或者本地绝对路径--可省略
D:\ffmpeg\video\test_%03d.ts 指定存放ts片段路径--指定文件夹必须存在
4、视频切片的播放
采用Video.js来播放视频,使用h5的video标签,将m3u8文件的路径赋值给src属性即可。
注意:生成的ts切片需与播放的m3u8文件需要在同一路径。
html示例代码:
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="300" height="500" id="ad_djx" title="ad">
<param name="movie" value="http://image.finance.china.cn/picupload/2020/0516/47_252733724_20200517093305.swf" />
<param name="quality" value="high" />
<param name="wmode" value="opaque" />
<param name="swfversion" value="6.0.65.0" />
<param name="expressinstall" value="http://image.finance.china.cn/flash/expressInstall.swf" />
<!--[if !IE]><!-->
<video id="myVideo" class="video-js vjs-default-skin" preload="auto" width="300px" height="500px">
<source id="source" src="./video/test2.m3u8" type='application/x-mpegURL'>
</video>
<!--<![endif]-->
</object>
例如:
这样就可以通过 https://10.0.0.11/video/test2.m3u8 访问切片后的视频。
总结:
其实,流媒体之视频切片, 我们无非是换了一种支持“视频切片”的推流工具罢了,其它的所有操作基本上都是一样的。