FFmpeg编码MP4时JPG输入导致失败,PNG输入正常的问题求助
FFmpeg编码MP4时JPG输入导致失败,PNG输入正常的问题求助
我现在遇到一个奇怪的FFmpeg编码问题,折腾了好几个小时才摸清楚规律——当输入流里包含JPG文件时,编码会出现异常,但把这个JPG转成PNG后就能顺利完成编码。我更倾向于是自己的命令用法有误,而不是FFmpeg的bug,所以来求助大家帮忙排查问题。
问题现象
故障分两种表现形式,看起来本质应该是同一个问题:
- 第一种情况:FFmpeg会正常编码到JPG文件对应的时间点,之后就一直重复之前的最后一帧,直到我手动终止进程。生成的视频播放到该节点前都完全正常,之后就是无限重复的画面。
- 第二种情况:FFmpeg启动后只写入1帧就停止输出新帧,但进程还在运行,统计信息里的编码速度会持续下降,比如显示:
frame= 0 fps=0.0 q=0.0 size= 0kB time=00:00:00.01 bitrate= 36.0kbits/s speed=7.63e-06x
环境与前置说明
- FFmpeg是2023年6月3日用media-autobuild_suite编译的最新版本,用这个版本已经成功编码过几千个视频了。
- 除了把JPG转成PNG这一步,其他所有文件、命令参数完全一致。转格式用的命令是:
ffmpeg -i 611.jpg -update 1 611.png
核心命令与输入结构
我的命令总长超过22000字符,没法完全贴出,这里放关键部分(换行是为了可读性):
ffmpeg -hide_banner -loglevel level+error -stats -y -an -i images\progress_bar.mp4 -stream_loop -1 -framerate 60 -t 2000ms -i images\bg\611.png # 这里换成611.jpg就出问题,会只写1帧 -stream_loop -1 -framerate 60 -t 2000ms -i images\box_level.png -an -f concat -i 1.ffconcat -an -f concat -i 2.ffconcat # 中间省略4个类似的concat输入 -an -f concat -i 7.ffconcat # 下面是18个带itsoffset的静态图片输入,都是PNG -itsoffset 27000ms -stream_loop -1 -framerate 60 -t 5100ms -i images\supporter\4237.png -itsoffset 61100ms -stream_loop -1 -framerate 60 -t 5100ms -i images\supporter\6787.png # 省略16个同类输入 -itsoffset 640800ms -stream_loop -1 -framerate 60 -t 5100ms -i images\supporter\3699.png -itsoffset 674900ms -stream_loop -1 -framerate 60 -t 5100ms -i images\supporter\2144.png -an -itsoffset 180000ms -i images\engage\like_1.mp4 # 最后几个静态图片输入,其中images\avatars\7_bg.png如果换成JPG,会导致编码到那部分卡住 -stream_loop -1 -framerate 60 -t 8500ms -i images\bg_plain\LevelsEvent.png -stream_loop -1 -framerate 60 -t 8500ms -i images\avatars\avatar_frame.png -stream_loop -1 -framerate 60 -t 8500ms -i images\avatars\7.png -stream_loop -1 -framerate 60 -t 8500ms -i images\avatars\7_bg.png -stream_loop -1 -framerate 60 -t 6000ms -i images\bg\Microworld_v.png -stream_loop -1 -t 727567ms -i Music\27min.aac -filter_complex_script 0.filter_complex -r 60 -g 30 -crf 17 -fpre FFpresets\youtube.ffpreset -profile:v high -x264opts bframes=2:colormatrix=bt709 -pix_fmt yuv420p -preset slow -map 36:a -codec:a copy -map "[3_CONCATENATED_36]" -threads 0 "publish\output file.mp4"
FFconcat文件示例
每个ffconcat文件包含6-16个片段,比如6.ffconcat的前2条内容:
ffconcat version 1.0 file '6.mp4' inpoint 00:00:00.017 outpoint 00:00:06.517 duration 00:00:06.500 file '6.mp4' inpoint 00:00:13.350 outpoint 00:00:27.050 duration 00:00:13.700
Filter_complex核心逻辑(简化版)
原脚本有11000多字符,这里保留关键流程:
# 背景与过渡层处理 [1]scale=1080:1920:flags=lanczos,setdar=9/16[TRANSITION_BG]; [TRANSITION_BG][2]overlay=x=0-overlay_w/2+540:y=0-overlay_h/2+640[TRANSITION_BOX]; [TRANSITION_BOX]split=7[TRANSITION_BOX_1][TRANSITION_BOX_2][TRANSITION_BOX_3][TRANSITION_BOX_4][TRANSITION_BOX_5][TRANSITION_BOX_6][TRANSITION_BOX_7]; # 为每个过渡层添加文字与淡入 [TRANSITION_BOX_1]drawtext=fontcolor=0xffffff:text='Level 1':fontsize=116:fontfile=/full/path/fonts/font_file.ttf:x=540-(text_w/2):y=640-(text_h/2)[LEVEL_1]; [LEVEL_1]fade=in:0:30[INTRO_1]; # 处理concat输入的视频,添加裁剪与叠加 [3]crop=out_w=1080:out_h=1920[1_MIDDLE]; [3]crop=out_w=1080:out_h=190+60:x=0:y=120-60[1_TOP]; [1_MIDDLE][1_TOP]overlay=x=0-overlay_w/2+0+overlay_w/2:y=0-overlay_h/2+0+overlay_h/2[1_MIDDLE_1_TOP]; [3]crop=out_w=1080:out_h=210+40:x=0:y=in_h-210-80[1_BOTTOM]; [1_MIDDLE_1_TOP][1_BOTTOM]overlay=x=0-overlay_w/2+0+overlay_w/2:y=0-overlay_h/2+main_h-overlay_h+overlay_h/2[1_VIDEO_OVERLAYS]; [1_VIDEO_OVERLAYS]fade=in:start_time=0:duration=0.5,setdar=9/16[VIDEO_BASE_1]; # 重复上述逻辑处理剩下的6组concat输入,生成INTRO_2到INTRO_7、VIDEO_BASE_2到VIDEO_BASE_7 # 拼接所有过渡与视频层 [INTRO_1][VIDEO_BASE_1][INTRO_2][VIDEO_BASE_2][INTRO_3][VIDEO_BASE_3][INTRO_4][VIDEO_BASE_4][INTRO_5][VIDEO_BASE_5][INTRO_6][VIDEO_BASE_6][INTRO_7][VIDEO_BASE_7]concat=n=14:v=1:a=0[14_CONCATENATED_10]; # 叠加18个支持者头像(带淡入淡出与时间控制) [10]fade=type=in:alpha=1:start_time=27000ms:duration=500ms,fade=type=out:alpha=1:start_time=31600ms:duration=500ms[FADE_10]; [14_CONCATENATED_10][FADE_10]overlay=x=0-overlay_w/2+463:y=0-overlay_h/2+1775:enable='between(t,27000/1000,32100/1000)'[SUPPORTER_10]; # 省略18个同类叠加步骤,直到SUPPORTER_29 # 叠加点赞视频 [30]colorkey=color=0x00d800:similarity=0.3,scale=1024:576:flags=lanczos[LIKE_30]; [SUPPORTER_29][LIKE_30]overlay=x=0-overlay_w/2+540:y=0-overlay_h/2+-140+overlay_h/2:enable='between(t,180000/1000,184000/1000)'[THUMB_30]; # 处理结尾的奖励画面与结束屏幕 [31]crop=out_w=1080:out_h=1920,setdar=9/16[AWARD_BG]; [AWARD_BG][32]overlay=x=0-overlay_w/2+540:y=0-overlay_h/2+376[AWARD_FRAME]; [AWARD_FRAME][33]overlay=x=0-overlay_w/2+540:y=0-overlay_h/2+376[AWARD_AVATAR]; [34]pad=w=1080:h=1080:color=0x4d5e6e:x=(out_w-in_w)/2:y=(out_h-in_h)/2[POSTCARD]; [AWARD_AVATAR][POSTCARD]overlay=x=0-overlay_w/2+540:y=0-overlay_h/2+1290[AWARD_POSTCARD]; [AWARD_POSTCARD]fade=type=in:start_time=0:duration=0.5[AWARD]; [35]scale=1080:1920:flags=lanczos,fade=type=in:start_time=0:duration=0.5:color=black[ENDSCREEN]; [ENDSCREEN]drawtext=fontcolor=0x265b7d:textfile=/full/path/text_UTF-8.txt:fontsize=64:fontfile=/full/path/fonts/different_font_file.ttf:box=1:boxcolor=0xf9f9f9:boxborderw=32:x=540-(text_w/2):y=520-(text_h/2):enable='between(t,1500/1000,6000/1000)',setdar=9/16[QTY_VIDEOS]; # 拼接最终的视频序列 [THUMB_30][AWARD][QTY_VIDEOS]concat=n=3:v=1:a=0[3_CONCATENATED_36];
预设文件(youtube.ffpreset)
这个预设已经用了3000+次,不过有个疑问:预设里写了bf=2,命令行又加了-x264opts bframes=2,不知道会不会重复或者冲突?
vcodec=libx264 movflags=faststart field_order=progressive bf=2 flags=cgop coder=1 colorspace=bt709 color_trc=bt709 color_primaries=bt709
日志信息
成功编码(用PNG)的警告日志
主要是concat的DTS乱序和swscaler的转换警告,看起来和concat输入的视频片段有关:
[aac @ 0000024c57dea940] [warning] Estimating duration from bitrate, this may be inaccurate [swscaler @ 0000024c6d3c0040] [swscaler @ 0000024c6d3d5040] [warning] No accelerated colorspace conversion found from yuv420p to argb. # 重复14次同类swscaler警告 [concat @ 0000024c57038cc0] [warning] DTS 86097 < 174117 out of order # 重复3次同类DTS警告 [out_0_1 @ 0000024c6997bc00] [warning] 100 buffers queued in out_0_1, something may be wrong. # 还有多组concat的DTS乱序警告,对应7个concat输入
失败编码(用JPG)的警告日志
因为只写了1帧,日志更短,多了几个deprecated pixel format used的警告:
[aac @ 000001c64988c580] [warning] Estimating duration from bitrate, this may be inaccurate [swscaler @ 000001c65b2c5f00] [warning] deprecated pixel format used, make sure you did set range correctly [swscaler @ 000001c65d9f7040] [swscaler @ 000001c65da04000] [warning] No accelerated colorspace conversion found from yuv420p to argb. # 重复多组swscaler转换警告 [swscaler @ 000001c65e50ddc0] [warning] deprecated pixel format used, make sure you did set range correctly # 重复3次同类像素格式警告
FFmpeg编译配置
libavutil 58. 12.100 / 58. 12.100 libavcodec 60. 16.100 / 60. 16.100 libavformat 60. 5.100 / 60. 5.100 libavdevice 60. 2.100 / 60. 2.100 libavfilter 9. 8.101 / 9. 8.101 libswscale 7. 3.100 / 7. 3.100 libswresample 4. 11.100 / 4. 11.100 libpostproc 57. 2.100 / 57. 2.100 configuration: --pkg-config=pkgconf --cc='ccache gcc' --cxx='ccache g++' --ld='ccache g++' --extra-cxxflags=-fpermissive --extra-cflags=-Wno-int-conversion --disable-autodetect --enable-d3d11va --enable-dxva2 --enable-iconv --enable-lzma --enable-zlib --enable-sdl2 --enable-ffnvcodec --enable-nvdec --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libdav1d --enable-libaom --disable-debug --enable-libfdk-aac --enable-fontconfig --enable-libass --enable-libfreetype --enable-libmysofa --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libsoxr --enable-libwebp --enable-gpl --enable-libtesseract --enable-openal --enable-libopenh264 --enable-openssl --extra-libs=-liconv --enable-version3 --enable-nonfree --extra-cflags=-DAL_LIBTYPE_STATIC --extra-cflags='-IC:/mabs/local64/include' --extra-cflags='-IC:/mabs/local64/include/AL'
备注:内容来源于stack exchange,提问作者hunterhogan
相关产品推荐
相关产品推荐

