重新编码 vlc 创建的 mpeg2 .ts 文件生成 20 秒文件;又名:带有隐藏流的多流文件

Re-encoding vlc-created mpeg2 .ts file results in 20 second file; AKA: multi-stream file with hidden streams

我正在用 vlc 关闭 v4l2 录制一些东西(以防万一),我刚刚选择了第一个有效的格式,即使用 TS 容器的 mpeg2。文件导致 .ts 扩展名,由 vlc 自动选择。当我试图将视频文件放入我的视频编辑器时,它说视频有 19,884 小时长,而它应该是大约 6 分钟(大小约为 80mb)。当我尝试在 xine 中播放它时,它正确显示了持续时间(vlc 没有),当我使用 ffprobe:

[mpegts @ 0x9b2c0a0] max_analyze_duration 5000000 reached at 5000000
Input #0, mpegts, from 'loopbacktestcap.ts':   Duration: N/A, start:
17978.139456, bitrate: N/A   Program 1 
     Stream #0:0[0x44](): Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p, 640x480 [SAR 1:1 DAR 4:3], 104857 kb/s, 30 fps, 30
tbr, 90k tbn, 60 tbc
     Stream #0:1[0x46](): Video: mpeg2video ([2][0][0][0] / 0x0002), 90k tbn

特别注意这一行:

   Duration: N/A, start: 17978.139456, bitrate: N/A   Program 1 

我查了一下,好像没有持续时间和容器有关。但是我尝试了一些重新编码的方法(我尝试了 -vcodec copy、mpeg2、libx264...),我所能得到的只是 1.1mb - 1.8mb 的 20 秒文件。

那么我怎样才能重新编码这个文件,使持续时间出现,我得到完整的 6 分钟,而不仅仅是前 20 秒?

在我们的视频处理基础架构中支持传输流 (ts) 视频文件时,我遇到了类似的挑战。我使用 ffmpegts 转换为 mp4 具有两次编码的文件。

完整的命令:

第 1 轮:

ffmpeg -i camera.ts -filter:v scale=-1:480,setsar=1/1 -pix_fmt yuv420p -threads 0 -r 25/1 -force_fps -c:v libx264 -profile:v baseline -preset slow -x264opts level=3.0:ref=1 -b:v 1000k -maxrate 1000k -bufsize 2000k -s hd480 -c:a libfaac -ar 16000 -ac 2 -ab 128000 -pass 1 -movflags faststart -y video.mp4

第 2 轮:

ffmpeg -i camera.ts -filter:v scale=-1:480,setsar=1/1 -pix_fmt yuv420p -threads 0 -r 25/1 -force_fps -c:v libx264 -profile:v baseline -preset slow -x264opts level=3.0:ref=1 -b:v 1000k -maxrate 1000k -bufsize 2000k -s hd480 -c:a libfaac -ar 16000 -ac 2 -ab 128000 -pass 2 -movflags faststart -y video.mp4 >>& ffmpeg.log

我将视频缩小到 hd480 (852x480) 使用 libx264 基线级别 3 比特率相对较低的视频流以及使用 libfaac 的音频重新编码并移动 moov原子到文件的开头以实现 Web 兼容性 (-movflags faststart)

有关标志的所有详细信息,请参阅 FFMpeg documentation

请注意,我刚刚找到了适用于我们设置的命令:处理来自 IP 摄像机的传输流记录。您可能需要根据您的需要专门调整分辨率和比特率。希望这能为您指明正确的方向。

当我发现这个 link 时达到了第一个里程碑:Map - ffmpeg -- Example #8 这促使我尝试:

ffmpeg -probesize 90M -analyzeduration 90M -i my_mpeg2_file.ts

产生以下结果:

[mpegts @ 0x9980f40] max_analyze_duration 90000000 reached at 90000000
Input #0, mpegts, from 'loopbacktestcap.ts':
  Duration: 00:16:00.96, start: 17978.139456, bitrate: 695 kb/s
  Program 1 
    Stream #0:0[0x44](): Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p, 640x480 [SAR 1:1 DAR 4:3], 104857 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc
    Stream #0:1[0x45](): Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p, 640x480 [SAR 1:1 DAR 4:3], 104857 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc
    Stream #0:2[0x46](): Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p, 640x480 [SAR 1:1 DAR 4:3], 104857 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc

请注意,它现在为我提供了正确的持续时间以及额外的流和有关第二个(技术上是第三个)的更多信息。那么我 运行:

ffmpeg -probesize 90M -analyzeduration 90M -i my_mpeg2_file.ts  -map 0 -c copy map0.mp4

现在生成了一个 79451050 字节的文件 map0.mp4,其中 my_mpeg2_file.ts 是 83499636。我试着玩这在 vlc 中,它显示持续时间为 9:12,但是如果我慢跑播放位置,则会打开另外两个 vlc windows 并且 vlc 开始执行 st运行ge;视频显示区域挂起,但播放位置指示器继续前进。这可能只是一个有问题的 vlc,但我被困在了这一点上。如果有人看到我在这里遗漏的任何内容,请告诉我。

xine 但是无法播放新文件(它播放原始文件并显示它有 6 分钟长——实际上,持续时间计数器在我播放文件时变得有点疯狂并不断变化,所以我不知道)。

所以,我尝试的下一个命令是:

ffmpeg -probesize 90M -analyzeduration 90M -i my_mpeg2_file.ts  -map 0 -c libx264 map0x264.mp4

尝试播放生成的文件(43652975 字节,出于好奇)在 vlc 中导致了相同的 st运行ge 行为,现在我可以看到它正在打开一个新的 window对于每个流,并在其各自的 window 中播放流时 "turn",冻结另一个 windows 的其他显示区域。尝试关闭它们会停止所有播放并关闭两个额外的 windows。我猜将所有 3 个流保存在同一个文件中是无稽之谈。

成功!

下一次尝试是:

ffmpeg -probesize 90M -analyzeduration 90M -i my_mpeg2_file.ts  -map 0:0 -c copy map0_0.ts
ffmpeg -probesize 90M -analyzeduration 90M -i my_mpeg2_file.ts  -map 0:1 -c copy map0_1.ts
ffmpeg -probesize 90M -analyzeduration 90M -i my_mpeg2_file.ts  -map 0:2 -c copy map0_2.ts

这导致文件大小:

 4912 map0_0.ts
 5372 map0_1.ts
74728 map0_2.ts

map0_0.ts是20秒长,map0_1.ts是静止图像1:12长, 而 map0_2.ts 是 9:12。正是我想要的!我的视频编辑器可以毫无问题地接受它们。已解决!