ffmpeg 永远不会完成编码,而是在达到 -vframes 限制后开始无限期地丢弃帧

ffmpeg 永远不会完成编码,而是在达到 -vframes 限制后开始无限期地丢弃帧

我正在尝试将 VR 180° 视频的 5 个视角(摄像机指向前方、指向上方、指向左侧等)拼接在一起,这需要拍摄 5 个视频文件、应用蒙版并将它们叠加在一起。我还想在结果中添加可选音频。

为了实现这一点,我有以下 Python 函数:

def combine_five_parts(front_fp, top_fp, bottom_fp, left_fp, right_fp, output_fp, audio_fp=None):
    """
    Combine the five angles of a VR180 video into one.
    This function relies on the presence of the ``masks`` directory containing .png files
    in the same directory as this file.
    """
    ffmpeg_args = [
        'ffmpeg',
        # Input videos
        '-i', front_fp, '-i', top_fp, '-i', bottom_fp, '-i', left_fp, '-i', right_fp,
        # Start of filtergraph
        '-filter_complex',
        # Extract the alpha channel from mask inputs
        'movie=masks/vr180mask_front.png[FrontMaskIn];'
        '[FrontMaskIn][0]scale2ref[FrontMaskScaled][Front];'
        '[FrontMaskScaled]format=pix_fmts=yuva444p,alphaextract[FrontMask];'
        
        'movie=masks/vr180mask_t_small.png[TopMaskIn];'
        '[TopMaskIn][1]scale2ref[TopMaskScaled][Top];'
        '[TopMaskScaled]format=pix_fmts=yuva444p,alphaextract[TopMask];'
        
        'movie=masks/vr180mask_b_small.png[BottomMaskIn];'
        '[BottomMaskIn][2]scale2ref[BottomMaskScaled][Bottom]'
        ';[BottomMaskScaled]format=pix_fmts=yuva444p,alphaextract[BottomMask];'
        
        'movie=masks/vr180mask_left.png[LeftMaskIn];'
        '[LeftMaskIn][3]scale2ref[LeftMaskScaled][Left];'
        '[LeftMaskScaled]format=pix_fmts=yuva444p,alphaextract[LeftMask];'
        # Merge gray masks with input videos
        '[Front][FrontMask]alphamerge[FrontOut];'
        '[Top][TopMask]alphamerge[TopOut];'
        '[Bottom][BottomMask]alphamerge[BottomOut];'
        '[Left][LeftMask]alphamerge[LeftOut];'
        ## Overlay all 5 parts in order
        '[4][LeftOut]overlay=shortest=1[RL];'
        '[RL][BottomOut]overlay=shortest=1[RLB];'
        '[RLB][TopOut]overlay=shortest=1[RLBT];'
        '[RLBT][FrontOut]overlay=shortest=1[out]',
        # Output parameters
        '-map', '[out]:v',
        output_fp
    ]
    if audio_fp:
        ffmpeg_args.insert(-3, '-i')
        ffmpeg_args.insert(-3, audio_fp)
        ffmpeg_args.insert(-3, '-map')
        ffmpeg_args.insert(-3, '5:a')
        ffmpeg_args.insert(-1, '-vframes')
        ffmpeg_args.insert(-1, '500')
        ffmpeg_args.insert(-1, '-aframes')
        ffmpeg_args.insert(-1, '500')
    p = subprocess.run(ffmpeg_args)

如果audio_fp没有指定,即后面的参数if audio_fp:没有添加到命令中,则一切都按预期工作:我得到了一个完整长度的视频,并且该过程按时完成。此外,如果-vframes 500添加了参数但没有添加音频,一切也按预期工作 - 输出视频长度为 500 帧。

如果audio_fp指定,当 ffmpeg 达到第 500 帧时,drop=状态行末尾的值开始无限增加,而 frame=保持在 500。除非我按 Ctrl+C,否则 ffmpeg 进程不会退出。正如预期的那样,生成的视频文件格式错误且无法使用。

如果我包含音频但不包含任何帧或时间限制(即输出与最长输入一样长),则一切都正常。

我尝试过仅使用-vframes、同时使用-vframes-aframes、改用-frames以及添加-vsync 2-vsync 0,但这些都没有改变这种行为。

以下是该命令的输出:

ffmpeg version n5.0.1 Copyright (c) 2000-2022 the FFmpeg developers
built with gcc 12.1.0 (GCC)
configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-amf --enable-avisynth --enable-cuda-llvm --enable-lto --enable-fontconfig --enable-gmp --enable-gnutls --enable-gpl --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libdav1d --enable-libdrm --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libiec61883 --enable-libjack --enable-libmfx --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librav1e --enable-librsvg --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxcb --enable-libxml2 --enable-libxvid --enable-libzimg --enable-nvdec --enable-nvenc --enable-shared --enable-version3
libavutil      57. 17.100 / 57. 17.100
libavcodec     59. 18.100 / 59. 18.100
libavformat    59. 16.100 / 59. 16.100
libavdevice    59.  4.100 / 59.  4.100
libavfilter     8. 24.100 /  8. 24.100
libswscale      6.  4.100 /  6.  4.100
libswresample   4.  3.100 /  4.  3.100
libpostproc    56.  3.100 / 56.  3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/mnt/other/BigOutput/vr30_ALL_FRONT.mp4':
Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.16.100
Duration: 00:01:59.37, start: 0.000000, bitrate: 7332 kb/s
Stream #0:0[0x1](und): Video: h264 (High 4:2:2) (avc1 / 0x31637661), yuvj422p(pc, progressive), 4320x2160, 7326 kb/s, 60 fps, 60 tbr, 5000k tbn (default)
    Metadata:
    handler_name    : VideoHandler
    vendor_id       : [0][0][0][0]
Input #1, mov,mp4,m4a,3gp,3g2,mj2, from '/mnt/other/BigOutput/vr30_ALL_TOP.mp4':
Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.16.100
Duration: 00:01:59.37, start: 0.000000, bitrate: 517 kb/s
Stream #1:0[0x1](und): Video: h264 (High 4:2:2) (avc1 / 0x31637661), yuvj422p(pc, progressive), 4320x2160, 511 kb/s, 60 fps, 60 tbr, 5000k tbn (default)
    Metadata:
    handler_name    : VideoHandler
    vendor_id       : [0][0][0][0]
Input #2, mov,mp4,m4a,3gp,3g2,mj2, from '/mnt/other/BigOutput/vr30_ALL_BOTTOM.mp4':
Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.16.100
Duration: 00:01:59.37, start: 0.000000, bitrate: 480 kb/s
Stream #2:0[0x1](und): Video: h264 (High 4:2:2) (avc1 / 0x31637661), yuvj422p(pc, progressive), 4320x2160, 474 kb/s, 60 fps, 60 tbr, 5000k tbn (default)
    Metadata:
    handler_name    : VideoHandler
    vendor_id       : [0][0][0][0]
Input #3, mov,mp4,m4a,3gp,3g2,mj2, from '/mnt/other/BigOutput/vr30_ALL_LEFT.mp4':
Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.16.100
Duration: 00:01:59.37, start: 0.000000, bitrate: 199 kb/s
Stream #3:0[0x1](und): Video: h264 (High 4:2:2) (avc1 / 0x31637661), yuvj422p(pc, progressive), 4320x2160, 193 kb/s, 60 fps, 60 tbr, 5000k tbn (default)
    Metadata:
    handler_name    : VideoHandler
    vendor_id       : [0][0][0][0]
Input #4, mov,mp4,m4a,3gp,3g2,mj2, from '/mnt/other/BigOutput/vr30_ALL_RIGHT.mp4':
Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.16.100
Duration: 00:01:59.37, start: 0.000000, bitrate: 221 kb/s
Stream #4:0[0x1](und): Video: h264 (High 4:2:2) (avc1 / 0x31637661), yuvj422p(pc, progressive), 4320x2160, 215 kb/s, 60 fps, 60 tbr, 5000k tbn (default)
    Metadata:
    handler_name    : VideoHandler
    vendor_id       : [0][0][0][0]
Input #5, mp3, from '/mnt/other/BigOutput/vr30_audio.mp3':
Metadata:
    encoder         : Lavf58.45.100
Duration: 00:02:04.58, start: 0.023021, bitrate: 160 kb/s
Stream #5:0: Audio: mp3, 48000 Hz, stereo, fltp, 160 kb/s
    Metadata:
    encoder         : Lavc58.91
Stream mapping:
Stream #0:0 (h264) -> scale2ref (graph 0)
Stream #1:0 (h264) -> scale2ref (graph 0)
Stream #2:0 (h264) -> scale2ref (graph 0)
Stream #3:0 (h264) -> scale2ref (graph 0)
Stream #4:0 (h264) -> overlay (graph 0)
Stream #5:0 -> #0:0 (mp3 (mp3float) -> aac (native))
overlay:default (graph 0) -> Stream #0:1 (libx264)
Press [q] to stop, [?] for help
[libx264 @ 0x561350484080] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 0x561350484080] profile High, level 6.0, 4:2:0, 8-bit
[libx264 @ 0x561350484080] 264 - core 164 r3081 19856cc - H.264/MPEG-4 AVC codec - Copyleft 2003-2021 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=18 lookahead_threads=3 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to '/mnt/other/BigOutput/vr30.mp4':
Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.16.100
Stream #0:0: Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s
    Metadata:
    encoder         : Lavc59.18.100 aac
Stream #0:1: Video: h264 (avc1 / 0x31637661), yuvj420p(pc, progressive), 4320x2160, q=2-31, 60 fps, 5000k tbn
    Metadata:
    encoder         : Lavc59.18.100 libx264
    Side data:
    cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
[Parsed_movie_0 @ 0x56136132f4c0] EOF timestamp not reliableitrate=N/A speed=   0x    
[Parsed_movie_4 @ 0x561361354200] EOF timestamp not reliable
[Parsed_movie_8 @ 0x561361388840] EOF timestamp not reliable
[Parsed_movie_12 @ 0x5613613bb680] EOF timestamp not reliable
Traceback (most recent call last):  3328kB time=00:00:07.27 bitrate=3747.7kbits/s dup=0 drop=94 speed=0.183x    
File "/mnt/projects/PyAutoMMDVRRender/_test.py", line 9, in <module>
    postprocessing.combine_five_parts(
File "/mnt/projects/PyAutoMMDVRRender/postprocessing.py", line 98, in combine_five_parts
    p = subprocess.run(ffmpeg_args)
File "/usr/lib/python3.10/subprocess.py", line 503, in run
    stdout, stderr = process.communicate(input, timeout=timeout)
File "/usr/lib/python3.10/subprocess.py", line 1144, in communicate
    self.wait()
File "/usr/lib/python3.10/subprocess.py", line 1207, in wait
    return self._wait(timeout=timeout)
File "/usr/lib/python3.10/subprocess.py", line 1941, in _wait
    (pid, sts) = self._try_wait(0)
File "/usr/lib/python3.10/subprocess.py", line 1899, in _try_wait
    (pid, sts) = os.waitpid(self.pid, wait_flags)
KeyboardInterrupt

相关内容