0、为什么要转视频流
我这边遇到的两个问题,一个是多个客户端同时访问rtsp视频流时,会导致断帧或者丢包(也就是图像残缺),所以考虑发布一个本地局域网的流媒体服务器供大家取流。另外一个原因就是前端播放rtsp和rtmp都比较麻烦,网上说要用vlc插件,而且chrome超过41版本的还用不了。这么苛刻的条件我实在接受不了。而hls就轻松多了,基于http协议,而且只需下载一些js组件包就可以播放了。所以,我做了下述的3个工作。
1、ffmpeg解决视频流转换问题
参考:https://medium.com/androvideo/convert-rtsp-to-hls-using-ffmpeg-2fe2cdf3a0de
一个命令
$ nohup ffmpeg -i [视频流地址] -fflags flush_packets -max_delay 1 -an -flags -global_header -hls_time 10 -hls_list_size 3 -hls_wrap 10 -vcodec copy -y [切片存储地址/index.m3u8] &
或者
ffmpeg -fflags nobuffer \
-rtsp_transport tcp \
-i rtsp://your_rtsp_address \
-vsync 0 \
-copyts \
-vcodec copy \
-movflags frag_keyframe+empty_moov \
-an \
-hls_flags delete_segments+append_list \
-f segment \
-segment_list_flags live \
-segment_time 1 \
-segment_list_size 3 \
-segment_format mpegts \
-segment_list /tmp/stream/index.m3u8 \
-segment_list_type m3u8 \
-segment_list_entry_prefix ./ \
/tmp/stream/%d.ts
ffmpeg在处理音视频流上是专业的,对于视频流的接入、解码、编码、视频流转换都是一句命令解决的问题。
2、nginx发布本地视频流
就是让其它人可以接入你发布的视频流。其实也挺简单的,hls流本质上就是文件,首先是一个叫m3u8的文件,其次是分块的视频文件,ts格式。m3u8会不断更新,它是一个索引文件,它会告诉客户端,最新的分块视频文件是哪个。这种机制不可避免的就是延迟。假如一个分块视频文件是20s,那么可以预见的最小延迟是20s(因为你必须等最新的分块视频文件生成好了之后才能够访问它),最大的延迟是40s(自行脑补其中逻辑)。严谨点说,这边所说的延迟不包括网络的延迟和rtsp原始流的延迟。
发布本地视频流很简单,就是nginx的基础运用,只要保证客户端能够访问到你的m3u8文件就可以了。
参考我的配置,server节点是在http节点内的。关于nginx的配置还真的要花点时间琢磨,要不然这么易用的家伙都能折腾上半天。(我就是)
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-type,Authorization';
location / {
root /tmp/stream;
index index.html index.htm;
}
}
3、前端展示
前端的展示就要用到video.js 和 video_contrib.js了。具体的请百度“前端如何播放hls视频流”。
4、shit words
加班结束写总结,还是挺惬意的。不过有些细节还真的就懒得写了,毕竟窗外下着雨,我又是穷逼程序员,只有小电驴,而且我住的地方离公司20公里,意味着我要在雨中驰骋1小时。skr,还好我会rap,没错!一路rap到家!
软中华
软玉溪
头发越短越牛皮
抢地盘
夹毛居
再大的场合都不得虚
...《重庆魂——gai》