使用以下方式将 H264/TS 转换为 RAW/AVI
ffmpeg -i in.ts -vcodec rawvideo -pix_fmt yuv420p out.avi
我发现输出的 AVI 文件的帧数比预期的要少。这可能是由于 TS 中的 PTS 错误造成的,但如果我使用该-vcodec copy
选项先将其转换为 MP4,则在执行 MP4 到 RAW/AVI 转换时不会丢失帧。
有没有办法可以忽略 PTS 直接从 TS 转换?
原始 H264/TS 信息:
$ ffmpeg -i input.ts
ffmpeg version N-53782-g2976e2a Copyright (c) 2000-2013 the FFmpeg developers
built on Jun 3 2013 03:49:16 with gcc 4.7.3 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libblu
ray --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-l
ibopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-lib
vpx --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib
libavutil 52. 34.100 / 52. 34.100
libavcodec 55. 14.100 / 55. 14.100
libavformat 55. 8.102 / 55. 8.102
libavdevice 55. 2.100 / 55. 2.100
libavfilter 3. 74.101 / 3. 74.101
libswscale 2. 3.100 / 2. 3.100
libswresample 0. 17.102 / 0. 17.102
libpostproc 52. 3.100 / 52. 3.100
[mpegts @ 000000000248b440] max_analyze_duration 5000000 reached at 5000000 microseconds
Input #0, mpegts, from 'input.ts':
Duration: 00:00:00.04, start: 1.400000, bitrate: N/A
Program 1
Metadata:
service_name : Service01
service_provider: FFmpeg
Stream #0:0[0x100]: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p, 320x240, 24 fps, 24 tbr, 90k tbn, 48 tbc
FFMPEG 报告持续时间为 4 秒,速度为 24fps,但使用 TS 分析器我发现了 9598 帧,并且我看到了 PTS/DTS 错误。
如果我们直接转换为 AVI:
$ ffmpeg -i input.ts -vcodec rawvideo -pix_fmt yuv420p output.avi
ffmpeg version N-53782-g2976e2a Copyright (c) 2000-2013 the FFmpeg developers
built on Jun 3 2013 03:49:16 with gcc 4.7.3 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libblu
ray --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-l
ibopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-lib
vpx --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib
libavutil 52. 34.100 / 52. 34.100
libavcodec 55. 14.100 / 55. 14.100
libavformat 55. 8.102 / 55. 8.102
libavdevice 55. 2.100 / 55. 2.100
libavfilter 3. 74.101 / 3. 74.101
libswscale 2. 3.100 / 2. 3.100
libswresample 0. 17.102 / 0. 17.102
libpostproc 52. 3.100 / 52. 3.100
[mpegts @ 00000000025dbc80] max_analyze_duration 5000000 reached at 5000000 microseconds
Input #0, mpegts, from 'input.ts':
Duration: 00:00:00.04, start: 1.400000, bitrate: N/A
Program 1
Metadata:
service_name : Service01
service_provider: FFmpeg
Stream #0:0[0x100]: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p, 320x240, 24 fps, 24 tbr, 90k tbn, 48 tbc
Output #0, avi, to 'output.avi':
Metadata:
ISFT : Lavf55.8.102
Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 320x240, q=2-31, 200 kb/s, 24 tbn, 24 tbc
Stream mapping:
Stream #0:0 -> #0:0 (h264 -> rawvideo)
Press [q] to stop, [?] for help
frame= 3393 fps=1521 q=0.0 Lsize= 381798kB time=00:02:21.37 bitrate=22123.3kbits/s dup=0 drop=6207
video:381712kB audio:0kB subtitle:0 global headers:0kB muxing overhead 0.022287%
输出显示frame= 3393
现在我先将其转换为 MP4 ( -vcode copy
) 然后再转换为 AVI
$ ffmpeg -i input.ts -vcodec copy output.mp4
ffmpeg version N-53782-g2976e2a Copyright (c) 2000-2013 the FFmpeg developers
built on Jun 3 2013 03:49:16 with gcc 4.7.3 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libblu
ray --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-l
ibopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-lib
vpx --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib
libavutil 52. 34.100 / 52. 34.100
libavcodec 55. 14.100 / 55. 14.100
libavformat 55. 8.102 / 55. 8.102
libavdevice 55. 2.100 / 55. 2.100
libavfilter 3. 74.101 / 3. 74.101
libswscale 2. 3.100 / 2. 3.100
libswresample 0. 17.102 / 0. 17.102
libpostproc 52. 3.100 / 52. 3.100
[mpegts @ 000000000248bb40] max_analyze_duration 5000000 reached at 5000000 microseconds
Input #0, mpegts, from 'input.ts':
Duration: 00:00:00.04, start: 1.400000, bitrate: N/A
Program 1
Metadata:
service_name : Service01
service_provider: FFmpeg
Stream #0:0[0x100]: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p, 320x240, 24 fps, 24 tbr, 90k tbn, 48 tbc
Output #0, mp4, to 'output.mp4':
Metadata:
encoder : Lavf55.8.102
Stream #0:0: Video: h264 ([33][0][0][0] / 0x0021), yuv420p, 320x240, q=2-31, 24 fps, 90k tbn, 90k tbc
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
frame= 9600 fps=0.0 q=-1.0 Lsize= 105953kB time=00:06:39.95 bitrate=2170.1kbits/s
video:105838kB audio:0kB subtitle:0 global headers:0kB muxing overhead 0.108838%
我们看到了frame= 9600
复制到 MP4 中并且 MP4 转换为 AVI 时具有正确数量的转码帧。我搜索了使用原始 TS 文件的命令以防止跳帧,因为使用中间转换作为 MP4 会消耗存储和时间!
$ ffmpeg -i output.mp4 -vcodec rawvideo -pix_fmt yuv420p output.avi
ffmpeg version N-53782-g2976e2a Copyright (c) 2000-2013 the FFmpeg developers
built on Jun 3 2013 03:49:16 with gcc 4.7.3 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libblu
ray --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-l
ibopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-lib
vpx --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib
libavutil 52. 34.100 / 52. 34.100
libavcodec 55. 14.100 / 55. 14.100
libavformat 55. 8.102 / 55. 8.102
libavdevice 55. 2.100 / 55. 2.100
libavfilter 3. 74.101 / 3. 74.101
libswscale 2. 3.100 / 2. 3.100
libswresample 0. 17.102 / 0. 17.102
libpostproc 52. 3.100 / 52. 3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'output.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf55.8.102
Duration: 00:06:40.00, start: 0.000000, bitrate: 2169 kb/s
Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 320x240, 2167 kb/s, 24 fps, 24 tbr, 90k tbn, 48 tbc
Metadata:
handler_name : VideoHandler
File 'output.avi' already exists. Overwrite ? [y/N] y
Output #0, avi, to 'output.avi':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
ISFT : Lavf55.8.102
Stream #0:0(und): Video: rawvideo (I420 / 0x30323449), yuv420p, 320x240, q=2-31, 200 kb/s, 24 tbn, 24 tbc
Metadata:
handler_name : VideoHandler
Stream mapping:
Stream #0:0 -> #0:0 (h264 -> rawvideo)
Press [q] to stop, [?] for help
frame= 9600 fps=4491 q=0.0 Lsize= 1080301kB time=00:06:40.00 bitrate=22124.6kbits/s
video:1080000kB audio:0kB subtitle:0 global headers:0kB muxing overhead 0.027894%