如何让FFmpeg适配仅视频、仅音频或音视频并存的RTSP流并转封装为HLS
如何让FFmpeg适配仅视频、仅音频或音视频并存的RTSP流并转封装为HLS
嘿,这个问题我之前帮不少人解决过,FFmpeg其实自带了针对这种场景的灵活配置,不用复杂的脚本就能搞定!
你之前的命令之所以会报错,是因为你明确指定了-c:v copy和-c:a copy,这相当于要求FFmpeg必须找到视频和音频流来复制,但如果输入流缺少其中一种,FFmpeg就会因为找不到对应流而终止。
解决思路很简单:用带条件的流映射参数,告诉FFmpeg“如果某类流存在就处理,不存在就跳过”,具体有两种方案可选:
方案一:精准控制仅处理视频和音频流(推荐)
这种方式只映射输入中存在的视频/音频流,完全贴合你的需求,修改后的命令如下:
ffmpeg \ -hide_banner \ -nostats \ -i "rtsps://....." \ -map 0:v? -c:v copy \ -map 0:a? -c:a copy \ -hls_init_time 2 \ -hls_time 2 \ -hls_list_size 100 \ -strftime 1 \ -hls_allow_cache 1 \ -hls_segment_type fmp4 \ -hls_segment_filename "$MTX_PATH-%Y%m%d%H%M%S.mp4" \ -hls_flags 'append_list+discont_start+delete_segments+omit_endlist' \ "$MTX_PATH.m3u8"
关键变化是这两行:
-map 0:v?:0代表第一个输入流(也就是你的RTSP流),v代表视频流,?表示如果该流存在就映射,不存在则忽略-map 0:a?:同理,仅映射存在的音频流
这样不管输入是仅视频、仅音频还是两者都有,FFmpeg都会自动适配,不会再因为找不到流而报错。
方案二:自动复制所有存在的流(简洁版)
如果你不介意复制输入中可能存在的其他流(比如字幕流),可以用更简洁的写法,直接映射所有存在的流并复制:
ffmpeg \ -hide_banner \ -nostats \ -i "rtsps://....." \ -map 0 -c copy \ -hls_init_time 2 \ -hls_time 2 \ -hls_list_size 100 \ -strftime 1 \ -hls_allow_cache 1 \ -hls_segment_type fmp4 \ -hls_segment_filename "$MTX_PATH-%Y%m%d%H%M%S.mp4" \ -hls_flags 'append_list+discont_start+delete_segments+omit_endlist' \ "$MTX_PATH.m3u8"
这里-map 0会映射第一个输入的所有流,-c copy则对所有映射的流进行直接复制,同样能自动适配不同的输入流组合。
两种方案都能完美解决你的问题,选哪种取决于你是否需要过滤非音视频流~
备注:内容来源于stack exchange,提问作者KamilCuk
相关产品推荐
相关产品推荐

