将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>