韋斯

韋斯

我正在尝试使用 ffmpeg 重新流式传输。我不在乎它是 mjpeg 还是其他格式,只要它可以在现代浏览器中播放即可。但延迟至关重要,如果延迟小于 5 秒就更好了。

我试图制作 hls 流,然后放弃并尝试 mjpeg。到目前为止,我想出了类似这样的事情:

韋斯

ffmpeg -i input -an -c:v libx264 -crf 21 -preset veryfast -fflags nobuffer -flags low_delay  -f hls -hls_time 6 -hls_list_size 10 -hls_flags delete_segments restreamed.m3u8

(我通过 nginx 将其输出到服务器文件夹,因此我可以测试是否可以在浏览器或 vlc 中播放该流)

主要问题是 m38u 文件总是缺少最后一段:ffmpeg 创建 restreamed0.ts,但没有 m3u8 文件。在给定时间后,(restreamed)0.ts 完成,并启动另一个块 1.ts。此时,m3u8 已创建,但其中只有 0.ts。当 1.ts 完成时,将启动另一个块 2.ts,并将 1.ts 写入 m3u8 文件,依此类推。这显然会导致一个段的长度延迟,这太多了。

我尝试调整-hls_time-hls_list_size参数以及我在谷歌搜索时遇到的其他标志,但没有任何成功。我已经尝试让它工作了两天,到目前为止,我已经完全忘记了哪些根本不起作用,哪些有点起作用(通常 vlc 要么需要很长时间才能开始播放流,要么延迟很大,但我没有成功创建完美的流)。我完全迷路了,我希望得到一些帮助。

图像格式

然后我放弃了,并尝试做 mjpeg 流,但结果相似。我最好的结果是这样的:

 ffmpeg -i input -vcodec mjpeg -f segment -segment_time 10  -segment_list video.m3u8  -max_delay 0    out%d.mjpg

ffmpeg 输出:

Input #0, mpjpeg, from '...':
  Duration: N/A, bitrate: N/A
    Stream #0:0: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 640x480, 25 tbr, 25 tbn, 25 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (mjpeg (native) -> mjpeg (native))
Press [q] to stop, [?] for help
[segment @ 0x1d62900] Opening 'out0.mjpg' for writing
Output #0, segment, to 'out%d.mjpg':
  Metadata:
    encoder         : Lavf58.20.100
    Stream #0:0: Video: mjpeg, yuvj420p(pc), 640x480, q=2-31, 200 kb/s, 25 fps, 25 tbn, 25 tbc
    Metadata:
      encoder         : Lavc58.35.100 mjpeg
    Side data:
      cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
[segment @ 0x1d62900] Opening 'video.m3u8.tmp' for writingte=N/A speed=0.403x
[segment @ 0x1d62900] Opening 'out1.mjpg' for writing
[segment @ 0x1d62900] Opening 'video.m3u8.tmp' for writingte=N/A speed=0.401x    
[segment @ 0x1d62900] Opening 'out2.mjpg' for writing
[segment @ 0x1d62900] Opening 'video.m3u8.tmp' for writingte=N/A speed=0.401x    
[segment @ 0x1d62900] Opening 'out3.mjpg' for writing
[segment @ 0x1d62900] Opening 'video.m3u8.tmp' for writingte=N/A speed=0.401x    

我无法在 vlc 或 bowser(html 视频元素)中加载该 m3u8 文件。(但是,如果我尝试播放其中一个 .mjpg 文件,它会按预期工作(除了播放速度更快,但我认为这是由于源流为 10fps 造成的,我可以稍后处理))。m3u8 文件如下所示:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:10
#EXTINF:10.000000,
out0.mjpg
#EXTINF:10.000000,
out1.mjpg
#EXTINF:10.000000,
out2.mjpg

除了不能在 vlc 中播放外,在浏览器中也无法播放(我尝试了这个问题),总是缺少最后一个片段。

你能告诉我我做错了什么或者给我指明正确的方向吗?

答案1

首先:.m3u8文件预计不会mJPEG以任何可移植的方式工作,因此这是一条死路。

关于 HLS:.m3u8文件总是仅包含已完成的片段,因此刚刚创建的片段永远不会出现在列表中。由于是通过浏览器消费的,因此这是必要的,并且无法规避。

要做的就是缩短最后一段——缩短所有段:尝试

ffmpeg -i input -an -c:v libx264 -crf 21 -preset veryfast -fflags nobuffer -flags low_delay  -f hls -hls_time 1 -hls_list_size 3 -hls_flags delete_segments restreamed.m3u8

-hls_time 1会将所有片段的长度缩短至一秒,因此创建最后一个片段时的延迟最多为一秒。这-hls_list_size 3会将列表缩短为每段一秒的 3 个片段。

答案2

-hls_list_size 0可以的

ffmpeg -i input -an -c:v libx264 -crf 21 -preset veryfast -fflags nobuffer -flags low_delay  -f hls -hls_time 6 -hls_list_size 0 -hls_flags delete_segments restreamed.m3u8

相关内容