Ubuntu下基于Nginx+ffmpeg+video.js的HLS流媒体视频播放方案
将MP4文件直接放在nginx的目录下,也可以用浏览器打开,但是可能直接下载,而不是播放,video.js直接播放MP4文件,对MP4文件格式有要求,一方面必须是H264编码,否则可能没声音,二是要播放器要先下载moov才能开始播放,而录像设备生成的MP4一般moov在mdat之后,这样要等待很长时间,所以需要用ffmpeg等工具将moov移动到最前面。
目前使用的方案是,先用ffmpeg将MP4转为hls,生成m3u8和ts切片文件,再由nginx发布,在浏览器中用video.js播放。
1 nginx配置
只需在nginx的配置文件中http部分增加设置即可,
http {……server {listen 80;server_name 192.168.3.136;……location /hls {types {application/vnd.apple.mpegurl m3u8;video/mp2t ts;}# 指定 HLS 视频文件的根目录alias /opt/video/hls/;# 不缓存add_header Cache-Control no-cache;# 允许跨域请求,如果你的客户端在另一个域上运行的话add_header 'Access-Control-Allow-Origin' '*';add_header 'Access-Control-Allow-Credentials' 'true';}……}……
}
特别注意这里的视频文件目录设置,使用alias时,后面的目录就是视频文件的实际存放路径,且后面必须有”/“,有些资料里将alias换成root,这时后面的路径假设是path1,那么实际视频存放的路径应该是path1/hls,这个hls是location的名字。
2 m3u8文件的生成
如果有ffmpeg,可以用以下命令将MP4文件转换为m3u8:
ffmpeg -i test.mp4 -codec: copy -bsf:v h264_mp4toannexb -map 0 -f segment -segment_list test.m3u8 -segment_time 10 test%03d.ts-i test.mp4指定输入文件。
-
-codec: copy表示不对视频进行重新编码,只是复制原始数据。
-
-bsf:v h264_mp4toannexb是一个比特流过滤器,用于将H264视频从MP4格式转换为MPEG2 TS格式,这是必需的,因为M3U8是基于TS的。
-
-map 0表示选择所有的流(例如,如果你的视频有音频和字幕)。
-
-f segment表示输出应该被分割成多个文件。
-
-segment_list test.m3u8指定输出的播放列表文件。
-
-segment_time 10表示每个TS段的最大长度(以秒为单位)。
-
test%03d.ts是输出TS文件的名称模式。%03d将被替换为三位数的序号。
3 视频播放
按照上面的配置,视频的访问地址是http://you_host_name/hls/test.m3u8,其中you_host_name是nginx中http server server_name项的主机地址,hls是在location项的地址,test.m3u8是生成的视频文件名。
建议使用视频播放器,或者在浏览器中嵌入视频播放插件来播放,在浏览器中直接输入以上地址,可能会导致直接下载而不是播放视频。
可以使用video.js实现视频播放,对于hls流,还需要增加videojs-contrib-hls插件,完整实例代码如下
<html>
<head><link href="https://vjs.zencdn.net/8.23.3/video-js.css" rel="stylesheet" /><!-- If you'd like to support IE8 (for Video.js versions prior to v7) --><!-- <script src="https://vjs.zencdn.net/ie8/1.1.2/videojs-ie8.min.js"></script> -->
</head><body><video id="myVideoPlayer" class="video-js vjs-default-skin" data-setup="{'fluid': true}" controls><source src="http://192.168.3.136/hls/test.m3u8" type="application/x-mpegURL">Your browser does not support HTML5 video.</video>
<script src="https://vjs.zencdn.net/8.23.3/video.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/video.js-contrib-hls@latest/dist/videojs-contrib-hls.min.js"></script>
<script type="text/javascript">var player = videojs('myVideoPlayer');player.hls({overrideNative: true, // 强制使用 HLS,如果可用的话highWaterMark: 524288 // 设置媒体源扩展的 buffer 大小(以字节为单位)});
</script></body>
</html>