云端FFmpeg子进程无法自行终止问题求助(GCC 4.8.5编译版本)
FFmpeg子进程阻塞问题处理方案
问题描述
本地使用FFmpeg 5.1.2(Apple clang 14.0.0编译)执行视频转帧命令时,子进程可正常退出;但云端环境中,使用gcc 4.8.5 (Red Hat 4.8.5-44)编译的FFmpeg 3.4.11执行相同命令,子进程会阻塞在subprocess.communicate(),无法自行终止,必须依赖定时器强制杀死。需优化实现云端FFmpeg子进程自动正常退出。
本地正常执行情况
执行代码
cmd = f'ffmpeg -nostdin -vsync 0 -i {sec_replace(video_path)} -r {marked_paras.get_divide_frame_fps()}' \ f'-q:v 2 -f image2 {crop_info} {sec_replace(default_frames_dir)}%08d.png' logger.info(cmd) p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) command.utp_command("ps aux | grep ffmpeg") timer = Timer(60, p.kill) try: timer.start() stdout, stderr = p.communicate() finally: timer.cancel() command.utp_command("ffmpeg --version") logger.info("stdout: {}".format(stdout)) logger.info("stderr: {}".format(stderr))
本地输出日志
ffmpeg version 5.1.2 Copyright (c) 2000-2022 the FFmpeg developers built with Apple clang version 14.0.0 stdout: b"ffmpeg version 5.1.2 Copyright (c) 2000-2022 the FFmpeg developers\n built with Apple clang version 14.0.0 (clang-1400.0.29.102)\n configuration: --prefix=/usr/local/Cellar/ffmpeg/5.1.2 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox\n libavutil 57. 28.100 / 57. 28.100\n libavcodec 59. 37.100 / 59. 37.100\n libavformat 59. 27.100 / 59. 27.100\n libavdevice 59. 7.100 / 59. 7.100\n libavfilter =-0.0 size=N/A time=00:00:07.56 bitrate=N/A speed=0.71x \r[image2 @ 0x7fd891906080] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 231 >= 231\nframe= 281 fps= 25 q=-0.0 size=N/A time=00:00:07.90 bitrate=N/A speed=0.708x \rframe= 291 fps= 25 q=-0.0 size=N/A time=00:00:08.23 bitrate=N/A speed=0.706x \r[image2 @ 0x7fd891906080] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 247 >= 247\nframe= 300 fps= 25 q=-0.0 size=N/A time=00:00:08.50 bitrate=N/A speed=0.698x \r[image2 @ 0x7fd891906080] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 261 >= 261\nframe= 312 fps= 25 q=-0.0 size=N/A time=00:00:08.86 bitrate=N/A speed=0.699x \r[image2 @ 0x7fd891906080] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 276 >= 276\nframe= 325 fps= 25 q=-0.0 size=N/A time=00:00:09.26 bitrate=N/A speed=0.702x \rframe= 335 fps= 24 q=-0.0 size=N/A time=00:00:09.60 bitrate=N/A speed= 0.7x \r[image2 @ 0x7fd891906080] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 290 >= 290\n[image2 @ 0x7fd891906080] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 305 >= 305\nframe= 344 fps= 24 q=-0.0 Lsize=N/A time=00:00:10.23 bitrate=N/A speed=0.708x \nvideo:1096936kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown\n"
云端异常执行情况
云端输出日志
stdout: b"ffmpeg version 3.4.11 Copyright (c) 2000-2022 the FFmpeg developers\n built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-44)\n configuration: --prefix=/usr --bindir=/usr/bin --datadir=/usr/share/ffmpeg --docdir=/usr/share/doc/ffmpeg --incdir=/usr/include/ffmpeg --libdir=/usr/lib64 --mandir=/usr/share/man --arch=x86_64 --optflags='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic' --extra-ldflags='-Wl,-z,relro ' --extra-cflags=' ' --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libvo-amrwbenc --enable-version3 --enable-bzlib --disable-crystalhd --enable-fontconfig --enable-gcrypt --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libcdio --enable-libdrm --enable-indev=jack --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libmp3lame --enable-nvenc --enable-openal --enable-opencl --enable-opengl --enable-libopenjpeg --enable-libopus --disable-encoder=libopus --enable-libpulse --enable-librsvg --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libvorbis --enable-libv4l2 --enable-libvidstab --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzvbi --enable-avfilter --enable-avresample --enable-libmodplug --enable-postproc --enable-pthreads --disable-static --enable-shared --enable-gpl --disable-debug --disable-stripping --shlibdir=/usr/lib64 --enable-libmfx --enable-runtime-cpudetect\n libavutil 55. 78.100 / 55. 78.100\n libavcodec 57.107.100 / 57.107.100\n libavformat 57. 83.100 / 57. 83.100\n libavdevice 57. 10.100 / 57. 10.100\n libavfilter 6.107.100 / 6.107.100\n libavresample 3. 7. 0 / 3. 7. 0\n libswscale 4. 8.100 / 4. 8.100\n libswresample 2. 9.100 / 2. 9.100\n libpostproc 54. 7.100 / 54. 7.100\nInput #0, matroska,webm, from 'case.videoquality.recommend_video_quality_performance_case.recommend_video_quality_test/record_video/com.tencent.mtt/1667903766/test.mkv':\n Metadata:\n COMMENT : Recorded by scrcpy 1.24\n ENCODER : Lavf57.83.100\n Duration: N/A, start: 0.000000, bitrate: N/A\n Stream #0:0: Video: h264 (Constrained Baseline), yuv420p(progressive), 1080x2240, 1k fps, 59.94 tbr, 1k tbn, 2k tbc (default)\nUsing -vsync 0 and -r can produce invalid output files\nStream mapping:\n Stream #0:0 -> #0:0 (h264 (native) -> png (native))\nPress [q] to stop, [?] for help\nOutput #0, image2, to 'case.videoquality.recommend_video_quality_performance_case.recommend_video_quality_test/record_video/com.tencent.mtt/1667903766/frames_end/%08d.png':\n Metadata:\n COMMENT : Recorded by scrcpy 1.24\n encoder : Lavf57.83.100\n Stream #0:0: Video: png, rgb24, 1080x2240, q=2-31, 200 kb/s, 30 fps, 30 tbn, 30 tbc (default)\n Metadata:\n encoder : Lavc57.107.100 png\nframe= 6 fps=0.0 q=-0.0 size=N/A time=00:00:00.06 bitrate=N/A speed=0.109x \r[image2size=N/A time=00:00:17.06 bitrate=N/A speed=0.296x \r[image2 @ 0x1a3e900] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 512 >= 512\n[image2 @ 0x1a3e900] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 514 >= 514\nframe= 703 fps= 12 q=-0.0 size=N/A time=00:00:17.20 bitrate=N/A speed=0.295x \r[image2 @ 0x1a3e900] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 516 >= 516\n[image2 @ 0x1a3e900] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 517 >= 517\n[image2 @ 0x1a3e900] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 518 >= 518\nframe= 711 fps= 12 q=-0.0 size=N/A time=00:00:17.36 bitrate=N/A speed=0.295x \r[image2 @ 0x1a3e900] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 520 >= 520\n[image2 @ 0x1a3e900] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 521 >= 521\n[image2 @ 0x1a3e900] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 522 >= 522\nframe= 717 fps= 12 q=-0.0 size=N/A time=00:00:17.46 bitrate=N/A speed=0.293x \r[image2 @ 0x1a3e900] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 524 >= 524\n"
解决方案建议
调整FFmpeg命令参数
- 移除
-vsync 0,替换为-vsync 1或-vsync passthrough:旧版本FFmpeg在-vsync 0与-r组合时会提示可能生成无效文件,且容易因DTS异常卡住 - 添加
-fflags +igndts:忽略输入流中无效的非单调递增DTS,避免FFmpeg陷入死循环 - 明确指定输出帧数或时长:比如用
-vframes <目标帧数>或-t <时长>,因为输入MKV无明确时长(日志中Duration: N/A),旧版本FFmpeg会持续等待输入 - 增加
-y参数:自动覆盖输出文件,避免潜在的交互阻塞
优化Python子进程调用
- 改用列表形式传参,禁用
shell=True:减少shell解析带来的异常,示例:cmd = [ 'ffmpeg', '-nostdin', '-vsync', '1', '-fflags', '+igndts', '-i', sec_replace(video_path), '-r', str(marked_paras.get_divide_frame_fps()), '-q:v', '2', '-f', 'image2', crop_info, sec_replace(default_frames_dir) + '%08d.png', '-y' ] p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - 使用
communicate()的超时参数:替代定时器,Python 3.3+支持,超时后直接终止进程:try: stdout, stderr = p.communicate(timeout=60) except subprocess.TimeoutExpired: p.kill() stdout, stderr = p.communicate() - 主动关闭stdin:执行
p.stdin.close(),避免FFmpeg等待标准输入
内容的提问来源于stack exchange,提问作者haizhohuang
相关产品推荐
相关产品推荐

