如何分离单AVI文件内按端口区分的3路MPEGTS多队列视频流
MPEG-TS多队列填充流单文件多路视频分离方案
这种GStreamer生成的多队列填充MPEG-TS文件仅识别到1路流,核心原因是文件PMT表未登记全部3路流的PID,或是文件直接拼接了带UDP端口标识的TS传输包,完全可以通过端口/PID过滤的方式分离独立视频流,不需要做帧级处理。
前置准备
先用Wireshark打开目标output.avi文件:
- 如果能看到UDP层会话信息,记录3路视频分别对应的UDP端口号
- 如果看不到UDP层,直接在TS流统计项里记录3路H.264视频对应的PID值
方案1:基于tshark+ffmpeg的端口过滤分离(适合带UDP头的包拼接文件)
- 按端口过滤导出对应流的裸TS负载
将命令中YOUR_PORT替换为你查到的对应路数的端口号执行,3个端口分别执行3次即可得到3路独立TS流:
tshark -r output.avi -Y "udp.port == YOUR_PORT" -T fields -e data | xxd -r -p > stream_x.ts
命令会把对应端口的所有UDP负载(即标准MPEG-TS视频包)提取为独立TS文件。
- 转封装为通用格式
导出的TS文件可以直接用ffmpeg无损转封装为MP4等常用格式,不需要转码:
ffmpeg -i stream_x.ts -c copy stream_x.mp4
如果开头出现花屏,加-ss 1参数跳过开头1秒的非关键帧段即可:
ffmpeg -ss 1 -i stream_x.ts -c copy stream_x.mp4
方案2:基于GStreamer的直接分流(适合PMT表缺失的纯TS文件)
如果文件是纯TS格式、不带UDP传输头,直接用GStreamer的TS解复用器开启全段解析,就能识别到全部3路流,不需要提前拆包:
- 先查询文件内所有流信息
gst-discoverer-1.0 output.avi
命令会列出所有检测到的视频流、对应的PID和编号。
- 按流编号分流导出
比如要导出第0、1、2路视频,分别执行对应管道命令即可,以下是导出第0路为MP4的示例:
gst-launch-1.0 filesrc location=output.avi ! tsdemux name=demux parse-private-sections=1 demux.video_00 ! h264parse ! mp4mux ! filesink location=stream_0.mp4
把video_00替换为对应路数的pad名(比如video_01/video_02),即可导出另外两路。
注意事项
- 所有分离操作全程用流复制,不要加转码参数,不会损失原视频画质
- 不要直接用默认参数的ffmpeg读取文件,ffmpeg默认只解析PMT表登记的流,必然会漏掉未登记的两路
- 导出的TS文件如果时长显示异常,不影响实际播放,转封装为MP4后时长信息会自动修正
内容的提问来源于stack exchange,提问作者nwf1115
相关产品推荐
相关产品推荐

