繁体   English   中英

使用 ffmpeg 修剪 HEVC 视频:正确的持续时间,但 output 文件大小太大

[英]Using ffmpeg to trim HEVC video: correct duration, but output file size too large

我有一个数字化的 8mm 16fps HEVC.mp4,我试图在 MacOS 终端上使用ffmpeg (5.1.2) 将其拆分成剪辑。 output 文件修剪到正确的持续时间,但文件大小太大。

ffmpeg -ss 05:09 -i input.mp4 -t 02:19 -an -sn -dn -c copy output.mp4

input.mp4 :持续时间为 11:56,文件大小为 8.24 GB(比特率 674251 kbits/s)。
output.mp4 :持续时间为 02:19,文件大小为 5.15 GB(太大)。

5.15 GB 是我期望在input.mp4的 674251 Kbits/s 下持续时间为 05:09 + 02:19 的剪辑的文件大小:
(05:09+02:19) * 674251 kbits/sec = 5.16 GB

我尝试了各种-ss start_pos-t duration值,结果相似。 output 文件的duration时间是正确的,但出乎意料的是 ( start_pos + duration )* 文件大小的比特率。

我已经查阅了这篇关于使用ffmpeg修剪的ShotStack.io文章和关于从文件中剪切小部分的ffmpeg wiki部分。 两者都没有具体说明生成的文件大小将被修剪以匹配剪辑的持续时间,但我认为这很有用。

附录
我的输入文件在 t=0.000 秒时只有一个关键帧。 可能是我所有问题的根源。

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的不寻常之处在于它在 t=0.000s 处只有一个关键帧,所有其他都是 B 帧(已通过ffprobe验证)。

ffmpeg命令是正确的,output 是只有一个关键帧的结果。 使用-c copy coder 时,所有修剪/拼接/剪切都必须在先前的关键帧处进行,对于此输入文件,它仅在 t=0 时。

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 :

Frame type:    Ibbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb???
Keyframe:      ^
Trim Points:                        |-----------------|
Time:          ^-start_pos          0                 ^duration

start_pos回到前一个关键帧(在此文件中是第一帧)的所有帧都必须包含在output.mp4中。

output.mp4的解码从开头(关键帧)开始,但直到 t=0 时才显示帧。 在大文件中,这可能会在显示视频之前产生明显的延迟。

我不确定在start_pos+duration之后需要多少额外的帧,但有些是因为剪辑的末尾有B帧,可以在 i 方向(向后和向前)引用多个帧B

las,我对这个问题的不满意解决方案是对input.mp4进行无损重新编码(添加更多关键帧),修剪我想要的剪辑,然后存档输出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM