[英]Using ffmpeg to trim HEVC video: correct duration, but output file size too large
I have a digitized 8mm 16fps HEVC.mp4 that I'm trying to split into clips using ffmpeg
(5.1.2) on MacOS terminal.我有一个数字化的 8mm 16fps HEVC.mp4,我试图在 MacOS 终端上使用ffmpeg
(5.1.2) 将其拆分成剪辑。 The output file trims to the correct duration but the filesize is too large. output 文件修剪到正确的持续时间,但文件大小太大。
ffmpeg -ss 05:09 -i input.mp4 -t 02:19 -an -sn -dn -c copy output.mp4
input.mp4
: 11:56 in duration and 8.24 GB in filesize (bitrate 674251 kbits/s). input.mp4
:持续时间为 11:56,文件大小为 8.24 GB(比特率 674251 kbits/s)。
output.mp4
: 02:19 in duration and 5.15 GB in filesize (too large). output.mp4
:持续时间为 02:19,文件大小为 5.15 GB(太大)。
5.15 GB is the filesize I'd expect for a clip that is 05:09 + 02:19 in duration at input.mp4
's 674251 Kbits/s: 5.15 GB 是我期望在input.mp4
的 674251 Kbits/s 下持续时间为 05:09 + 02:19 的剪辑的文件大小:
(05:09+02:19) * 674251 kbits/sec = 5.16 GB (05:09+02:19) * 674251 kbits/sec = 5.16 GB
I've tried various -ss start_pos
and -t duration
values with similar results.我尝试了各种-ss start_pos
和-t duration
值,结果相似。 The output file is correctly duration
in time and unexpectedly ( start_pos
+ duration
)*bitrate in filesize. output 文件的duration
时间是正确的,但出乎意料的是 ( start_pos
+ duration
)* 文件大小的比特率。
I've consulted this ShotStack.io article on trimming with ffmpeg
and this ffmpeg wiki section on cutting small sections from files.我已经查阅了这篇关于使用ffmpeg
修剪的ShotStack.io文章和关于从文件中剪切小部分的ffmpeg wiki部分。 Neither specifically states that the resulting file size will be trimmed to match the duration of the clip, but I'd think that'd be useful.两者都没有具体说明生成的文件大小将被修剪以匹配剪辑的持续时间,但我认为这很有用。
Addendum :附录:
My input file has only one keyframe at t=0.000s.我的输入文件在 t=0.000 秒时只有一个关键帧。 Likely the root of all my problems.可能是我所有问题的根源。
ffmpeg stdout : ffmpeg 标准输出:
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x14ff04760] Using non-standard frame rate 16384/1024
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2mp41
creation_time : 2021-07-24T11:23:44.000000Z
encoder : Lavf58.45.100
Duration: 00:11:56.13, start: 0.000000, bitrate: 92041 kb/s
Stream #0:0[0x1](und): Video: hevc (Main) (hvc1 / 0x31637668), yuv420p(tv, bt709/bt709/unknown, progressive), 5120x3840 [SAR 1:1 DAR 4:3], 91715 kb/s, 16 fps, 16 tbr, 16384 tbn (default)
Metadata:
creation_time : 2021-07-24T11:23:44.000000Z
handler_name : VideoHandler
vendor_id : [0][0][0][0]
timecode : 17:15:11:05
Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, mono, fltp, 159 kb/s (default)
Metadata:
creation_time : 2021-07-24T11:23:44.000000Z
handler_name : SoundHandler
vendor_id : [0][0][0][0]
Stream #0:2[0x3](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, mono, fltp, 159 kb/s (default)
Metadata:
creation_time : 2021-07-24T11:23:44.000000Z
handler_name : SoundHandler
vendor_id : [0][0][0][0]
Stream #0:3[0x4](eng): Data: none (tmcd / 0x64636D74)
Metadata:
creation_time : 2021-07-24T11:23:44.000000Z
handler_name : TimeCodeHandler
timecode : 17:15:11:05
File 'output.mp4' already exists. Overwrite? [y/N] y
[mp4 @ 0x14ff08660] Using non-standard frame rate 16/1
Last message repeated 1 times
Output #0, mp4, to 'output.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2mp41
encoder : Lavf59.27.100
Stream #0:0(und): Video: hevc (Main) (hvc1 / 0x31637668), yuv420p(tv, bt709/bt709/unknown, progressive), 5120x3840 [SAR 1:1 DAR 4:3], q=2-31, 91715 kb/s, 16 fps, 16 tbr, 16384 tbn (default)
Metadata:
creation_time : 2021-07-24T11:23:44.000000Z
handler_name : VideoHandler
vendor_id : [0][0][0][0]
timecode : 17:15:11:05
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
frame= 4290 fps=0.0 q=-1.0 Lsize= 2988507kB time=00:02:18.93 bitrate=176207.6kbits/s speed= 189x
video:2988420kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.002924%
ffprobe output.mp4
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x130804080] Using non-standard frame rate 16384/1024
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'output.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2mp41
encoder : Lavf59.27.100
Duration: 00:02:19.31, start: 0.000000, bitrate: 175732 kb/s
Stream #0:0[0x1](und): Video: hevc (Main) (hvc1 / 0x31637668), yuv420p(tv, bt709/bt709/unknown, progressive), 5120x3840 [SAR 1:1 DAR 4:3], 91304 kb/s, 16 fps, 16 tbr, 16384 tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
timecode : 17:15:11:05
Stream #0:1[0x2](eng): Data: none (tmcd / 0x64636D74)
Metadata:
handler_name : VideoHandler
timecode : 17:15:11:05
Unsupported codec with id 0 for input stream 1
input.mp4
is unusual in that it only has one keyframe at t=0.000s, all others are B-frames (verified with ffprobe
). input.mp4
的不寻常之处在于它在 t=0.000s 处只有一个关键帧,所有其他都是 B 帧(已通过ffprobe
验证)。
The ffmpeg
command is correct and the output is a result of there only being one keyframe. ffmpeg
命令是正确的,output 是只有一个关键帧的结果。 When using the -c copy
coder, all trims/ splices/cuts have to be made at the prior keyframe, which for this input file is only at t=0.使用-c copy
coder 时,所有修剪/拼接/剪切都必须在先前的关键帧处进行,对于此输入文件,它仅在 t=0 时。
input.mp4
and desired trim clip: input.mp4
和所需的修剪剪辑:
Frame type: Ibbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...
Keyframe: ^
Trim Points: |-----------------|
Time: 0 ^start_pos ^start_pos+duration
ffmpeg -ss start_pos -i input.mp4 -t duration -c copy output.mp4
output.mp4
: output.mp4
:
Frame type: Ibbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb???
Keyframe: ^
Trim Points: |-----------------|
Time: ^-start_pos 0 ^duration
All frames from start_pos
back to the prior keyframe (which in this file is the first frame) have to be included in output.mp4
.从start_pos
回到前一个关键帧(在此文件中是第一帧)的所有帧都必须包含在output.mp4
中。
Decoding of output.mp4
starts at the beginning (the keyframe) but frames are not displayed until t=0. output.mp4
的解码从开头(关键帧)开始,但直到 t=0 时才显示帧。 In a large file, that could incur significant delay before displaying video.在大文件中,这可能会在显示视频之前产生明显的延迟。
I'm not sure how many extra frames are needed after start_pos+duration
, but some will be because the end of the clip has B
-frames that can reference several frames B
i-directionally (backwards and forwards).我不确定在start_pos+duration
之后需要多少额外的帧,但有些是因为剪辑的末尾有B
帧,可以在 i 方向(向后和向前)引用多个帧B
。
Alas, my unsatisfying solution for this problem is to lossless re-encode the input.mp4
(adding in more keyframes), trim out my desired clips, and archive the outputs. las,我对这个问题的不满意解决方案是对input.mp4
进行无损重新编码(添加更多关键帧),修剪我想要的剪辑,然后存档输出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.