ffmpeg는 인코딩을 완료하지 않고 대신 -vframes 제한에 도달한 후 프레임을 무기한 삭제하기 시작합니다.

ffmpeg는 인코딩을 완료하지 않고 대신 -vframes 제한에 도달한 후 프레임을 무기한 삭제하기 시작합니다.

저는 5개의 비디오 파일을 촬영하고 마스크를 적용한 후 서로 오버레이하는 VR 180° 비디오(카메라가 앞쪽을 향함, 위쪽을 향함, 왼쪽을 향함 등)의 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

관련 정보