ffmpeg:rtsp=>hls流;
nginx 托管hls流服务;
vlc测试hls流服务;
参考了很多相关文档和资料,由于比较乱就不在一一引用介绍了,下面的是实操OK的例子;
- 1)ffmpeg (ffmpeg-4.4.1-full_build),要用full版本,否则会缺某些插件;
rtsp地址
rtsp://admin:admin123@192.168.30.168:554
用ffmpeg把rtsp流转hls流
ffmpeg -rtsp_transport tcp -r 25 -i rtsp://admin:admin123@192.168.30.168:554 -fflags flush_packets -max_delay 1 -segment_time 5 -an -flags -global_header -hls_time 1 -hls_list_size 3 -hls_wrap 4 -vcodec copy -y "D:\hls\dh.m3u8"
r
- 1.1)经测试ffmpeg 6.0最新版如下命令可用
ffmpeg.exe -fflags nobuffer ^
-loglevel debug ^
-rtsp_transport tcp ^
-i rtsp://admin:admin123@192.168.30.22:554 ^
-vsync 0 ^
-copyts ^
-vcodec copy ^
-movflags frag_keyframe+empty_moov ^
-an ^
-hls_flags delete_segments+append_list ^
-f hls ^
-hls_time 1 ^
-hls_list_size 3 ^
-hls_segment_type mpegts ^
"D:\hls\dh.m3u8"
如上参数参考(refs:Convert RTSP to HLS using FFmpeg | Mike Polinowski),原文为5.0版本;
依然有10秒左右延时;
其他参考
FFMPEG:Convert RTSP live stream to HLS
官方参数解释
(FFmpeg Formats Documentation)
- 2)nginx 1.24.0版
配置如下
worker_processes 1;
events {
worker_connections 1024;
}
http {
server{
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm test.html;
}
#监控视频点播服务
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
add_header Cache-Control no-cache;
#存放hls切片的路径
alias 'D:/hls';
autoindex off;
expires 1h;
}
}
}
- 3)vlc 播放网络流
http://127.0.0.1:1935/hls/dh.m3u8
以上为ffmpege转rtsp流为hls流,并在web页面显示的步骤,基本OK,但延时较大,约10秒;
以下为nginx种的test.html页面代码,测试web播放功能;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
html, body {
margin: 0;
padding: 0;
height: 98%;
overflow: hidden;
}
#video {
width: 95%;
height: 95%;
background: black;
}
</style>
</head>
<body>
<video id="video" muted controls autoplay playsinline></video>
<script src="https://cdn.jsdelivr.net/npm/hls.js@1.4.10/dist/hls.min.js"></script>
<script>
const create = () => {
const video = document.getElementById('video');
// always prefer hls.js over native HLS.
// this is because some Android versions support native HLS
// but don't support fMP4s.
if (Hls.isSupported()) {
const hls = new Hls({
maxLiveSyncPlaybackRate: 1.5,
});
hls.on(Hls.Events.ERROR, (evt, data) => {
if (data.fatal) {
hls.destroy();
setTimeout(create, 2000);
}
});
hls.loadSource('http://localhost/hls/dh.m3u8');
hls.attachMedia(video);
video.play();
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
// since it's not possible to detect timeout errors in iOS,
// wait for the playlist to be available before starting the stream
fetch('http://localhost/hls/dh.m3u8')
.then(() => {
video.src = 'http://localhost/hls/dh.m3u8';
video.play();
});
}
};
window.addEventListener('DOMContentLoaded', create);
</script>
</body>
</html>
===========
下面尝试转为webrtc,看是否能减少延时。
4)用ffmpeg转发rtsp流到mediamtx服务;(csdn下载)
ffmpeg -rtsp_transport tcp -i rtsp://admin:admin123@192.168.30.22:554 -vcodec copy -f rtsp rtsp://127.0.0.1:8554/mystream
vlc播放测试,地址即为
rtsp://localhost:8554/mystream
//----------分割线---------一些问题------------------
- 昨日在家,也是如此搭配,却没有成功;
- 1)发现ffmpeg必须用full版本,否则会缺失;
家中版本(ffmpeg version 2023-08-17-git-9ae4863cc5-full_build-www.gyan.dev Copyright (c) 2000-2023 the FFmpeg developers built with gcc 12.2.0 (Rev10, Built by MSYS2 project))
公司版本 ffmpeg 4.4.1;
新版的参数可能不一样,而参考的文档大都是旧版参数,所以新版不成功;
- 2)ffmpeg 转换时会出现-10054错误,自动断开,后把tcp改成udp,才算可以;
怀疑ffmpeg的参数不一致,在家测试的版本参考的有个优化是减少延时;当前虽然OK,但延时较大(约有12秒);
- 3)nginx配置后始终无法下载m3u8文件,虽然就在那个文件下;
误以为是nginx缺少hls模块导致,现在看来不是这样,nginx的配置就有问题;
当时在/hls节点用的是 root 'D:\hls',可能是错误的,用alias更合理。