FFmpeg拆分大文件

时间:2016-02-01 14:33:08

标签: video encoding ffmpeg

我需要快速将大型视频文件拆分成多个部分,而不会出现错误的文件。基本的想法是,我有一个2GB的视频文件,我想改为多种格式。我已经读过一些编码器在编码到不同格式时无法使用超过1个核心。所以我有想法将大文件(非常快)拆分成4/8块,具体取决于我在各个服务器上可用的核心数。将每个片段重新编码为新格式,并使用它们按顺序显示视频。

所以

testfile.mp4

成为

  1. testfile_piece_1.mp4
  2. testfile_piece_2.mp4
  3. testfile_piece_3.mp4
  4. testfile_piece_4.mp4
  5. 然后可以单独转换它们。

    解决方案不应该是特定于格式的。但是我发现了mp4文件的问题。

    我已经尝试过以下命令,它运行得非常好,但是创建的文件有错误。

    ffmpeg -i testfile.mp4 -ss 00:00:00 -t 00:20:00 -c copy testfile_piece_1.mp4
    

    当我在VLC上播放testfile_piece_1.mp4时,它运行正常。将拆分文件转换为不同的高度和宽度mp4文件时出现问题。我会得到类似“moov atom not found”的错误

    我尝试添加-movflags faststart没有运气

    然后我遇到了这个库https://code.google.com/archive/p/moovrelocator/修复了moov问题,但是我会得到一个关于aac的错误“在为输出流#0.0打开编码器时出错 - 可能是不正确的参数,如bit_rate,rate,宽度或高度“

    分割文件的另一种方法是无用的,但涉及重新编码文件。对于较小的文件大小而言并不是太糟糕,但2GB文件可能需要数天才能完成。

    有没有办法快速拆分largr文件而不会生成有错误的文件?我一直在努力工作几天没有运气。

    评论的控制台输出 - FFmpeg splitting large files

    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/usr/share/nginx/html/uploads/testfile01.mp4':
      Metadata:
        major_brand     : isom
        minor_version   : 512
        compatible_brands: isomiso2avc1mp41
        encoder         : Lavf56.36.100
      Duration: 00:05:02.08, start: 302.120000, bitrate: 3254 kb/s
        Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709)                                  , 1920x1080 [SAR 1:1 DAR 16:9], 3252 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (de                                  fault)
        Metadata:
          handler_name    : VideoHandler
    [libx264 @ 0x165ffc0] width not divisible by 2 (853x480)
    Output #0, mp4, to '/usr/share/nginx/html/uploads/testfile01_480.mp4':
      Metadata:
        major_brand     : isom
        minor_version   : 512
        compatible_brands: isomiso2avc1mp41
        encoder         : Lavf56.36.100
        Stream #0:0(und): Video: h264, none, q=2-31, 128 kb/s, SAR 2560:2559 DAR 0:0                                  , 25 fps (default)
        Metadata:
          handler_name    : VideoHandler
          encoder         : Lavc56.41.100 libx264
    Stream mapping:
      Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
    Error while opening encoder for output stream #0:0 - maybe incorrect parameters                                   such as bit_rate, rate, width or height
    

    控制台输出2

    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/usr/share/nginx/html/uploads/testfile.mp4':
      Metadata:
        major_brand     : dash
        minor_version   : 0
        compatible_brands: iso6avc1mp41
        creation_time   : 2016-01-24 04:26:37
      Duration: 01:15:58.08, start: 0.000000, bitrate: 3163 kb/s
        Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 3161 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc (default)
        Metadata:
          creation_time   : 2016-01-24 04:26:37
          handler_name    : VideoHandler
    [segment @ 0x1197060] Codec for stream 0 does not use global headers but container format requires global headers
    [mp4 @ 0x11512a0] Codec for stream 0 does not use global headers but container format requires global headers
    Output #0, segment, to '/usr/share/nginx/html/uploads/testfile%02d.mp4':
      Metadata:
        major_brand     : dash
        minor_version   : 0
        compatible_brands: iso6avc1mp41
        encoder         : Lavf56.36.100
        Stream #0:0(und): Video: h264 (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 3161 kb/s, 25 fps, 25 tbr, 12800 tbn, 25 tbc (default)
        Metadata:
          creation_time   : 2016-01-24 04:26:37
          handler_name    : VideoHandler
    Stream mapping:
      Stream #0:0 -> #0:0 (copy)
    Press [q] to stop, [?] for help
    [mp4 @ 0x11512a0] Codec for stream 0 does not use global headers but container format requires global headers
    [mp4 @ 0x11512a0] Codec for stream 0 does not use global headers but container format requires global headers
    [mp4 @ 0x11512a0] Codec for stream 0 does not use global headers but container format requires global headers
    [mp4 @ 0x11512a0] Codec for stream 0 does not use global headers but container format requires global headers
    [mp4 @ 0x11512a0] Codec for stream 0 does not use global headers but container format requires global headers
    [mp4 @ 0x11512a0] Codec for stream 0 does not use global headers but container format requires global headers
    [mp4 @ 0x11512a0] Codec for stream 0 does not use global headers but container format requires global headers
    [mp4 @ 0x11512a0] Codec for stream 0 does not use global headers but container format requires global headers
    [mp4 @ 0x11512a0] Codec for stream 0 does not use global headers but container format requires global headers
    [mp4 @ 0x11512a0] Codec for stream 0 does not use global headers but container format requires global headers
    [mp4 @ 0x11512a0] Codec for stream 0 does not use global headers but container format requires global headers
    [mp4 @ 0x11512a0] Codec for stream 0 does not use global headers but container format requires global headers
    [mp4 @ 0x11512a0] Codec for stream 0 does not use global headers but container format requires global headers
    [mp4 @ 0x11512a0] Codec for stream 0 does not use global headers but container format requires global headers
    [mp4 @ 0x11512a0] Codec for stream 0 does not use global headers but container format requires global headers
    

1 个答案:

答案 0 :(得分:10)

使用分段多路复用器将输入分成若干段:

ffmpeg -i testfile.mp4 -c copy -f segment -segment_time 1200 testfile_piece_%02d.mp4

这将在关键帧处分割源,因此段可能不会精确地为1200秒。并且时间戳不会重置,因此某些玩家将无法播放第二段和后一段。如果需要可播放性,请插入-reset_timestamps 1

在并行编码之后,您可以先创建一个文本文件seg.txt来拼接生成的片段

file 'encoded_testfile_piece_00.mp4'
file 'encoded_testfile_piece_01.mp4'
file 'encoded_testfile_piece_02.mp4'
file 'encoded_testfile_piece_03.mp4'

然后运行

ffmpeg -f concat -i seg.txt -c copy -fflags +genpts encoded_full.mp4