我正在使用我的NVIDIA显卡做游戏游戏(Dota2)的屏幕录音,GeForce体验硬件记录(NVEC编码器)。这将创建一个可变帧速率输出视频。我的NVIDIA设置是60 fps 15000 kbps。我雇了一个人来制作一个程序,该程序生成给定开始/停止时间点的脚本,可以从视频中提取剪辑,并将它们与交叉淡出合并。参见下面的示例代码。该脚本适用于许多输入记录,但经常失败:音频和视频在许多剪辑中被去同步(通常是音频延迟),约0.5秒。我认为当帧速率在录制过程中下降得更多时,它会失败得更多。他不知道如何解决这个问题,我想知道是否有人能指出脚本中是否有什么可以修复(例如下面的例子)?
处理速度是相当重要的(现在制作一个10分钟的“高亮”视频大约需要7-10分钟)。不幸的是,增加这一数额的解决办法没有太大的兴趣。他的方法是将音频和视频分开处理,最后合并。他已经有了一个程序来制作用于处理不同场景的ffmpeg代码(还添加了覆盖、添加音乐、入门/outro),所以它会更好地对他的代码进行一些简单的修复,而不是对逻辑进行戏剧性的重新设计。但是,如果没有其他方法可以解决这个问题,重新设计逻辑是可以的。使用ffmpeg以外的其他工具也可以,但是应该是自动化的(脚本/cli),并且不会增加太多的处理时间。
在输入视频上运行"mediainfo“程序显示,对于此输入视频,框架下降得非常低:
帧速率模式:可变
帧速率: 60.000 FPS
最低帧率: 3.059 FPS
最大帧率: 63.739 FPS
完整报告在这里:https://pastebin.com/TX061Wih
输入视频可以从dropbox下载(6GB):https://www.dropbox.com/s/ftwdgapazbi62pr/fullgame.mp4?dl=0
这里的脚本示例,当要求从9:57 (41秒长)和15:45 (28秒长)的输入视频中提取两个剪辑时,将它们合并为0.5交叉淡出时间。在本例中可能有一些未使用的选项的代码残余物(覆盖、音乐、入门/outro)。使用上面的输入视频,这将创建音频/视频desync。
6个命令按顺序超出:
ffmpeg.exe -loglevel warning -ss 00:09:57 -i fullgame.mp4 -t 00:00:41 -filter_complex "[0:a]afade=t=out:st=40.5:d=0.5[a1]" -map "[a1]" -y out_temp_00.mp4.wav
ffmpeg.exe -loglevel warning -i fullgame.mp4 -ss 00:09:57 -t 00:00:41 -an -vcodec copy -f mpegts -avoid_negative_ts make_zero -y out_temp_00.mp4.ts
ffmpeg.exe -loglevel warning -ss 00:15:45 -i fullgame.mp4 -t 00:00:28 -filter_complex "[0:a]afade=t=in:st=0:d=0.5[a1]" -map "[a1]" -y out_temp_01.mp4.wav
ffmpeg.exe -loglevel warning -i fullgame.mp4 -ss 00:15:45 -t 00:00:28 -an -vcodec copy -f mpegts -avoid_negative_ts make_zero -y out_temp_01.mp4.ts
ffmpeg.exe -loglevel warning -i out_temp_00.mp4.wav -i out_temp_01.mp4.wav -y -filter_complex "[0:a]adelay=0|0[a0];[1:a]adelay=40500|40500[a1];[a0][a1]amix=inputs=2:dropout_transition=68.5,atrim=duration=68.5[outa0];[outa0]loudnorm[outa]" -map "[outa]" -ar 48000 -acodec aac -strict -2 fullgame_Output.mp4.aac
ffmpeg.exe -loglevel warning -i out_temp_00.mp4.ts -i out_temp_01.mp4.ts -y -i fullgame_Output.mp4.aac -filter_complex "[0:v]trim=start=0.5,setpts=PTS-STARTPTS[0c];[1:v]trim=start=0.5,setpts=PTS-STARTPTS[1c];[0:v]trim=40.5:41,setpts=PTS-STARTPTS[fo];[1:v]trim=0:0.5[fi];[fi]format=pix_fmts=yuva420p,fade=t=in:st=0:d=0.5:alpha=1[z];[fo]format=pix_fmts=yuva420p,fade=t=out:st=0:d=0.5:alpha=1[x];[z]fifo[w];[x]fifo[q];[q][w]overlay[r];[0c][r][1c]concat=n=3[outv]" -map "[outv]" -map 2:a -shortest -acodec copy -vcodec libx264 -preset ultrafast -b 15000k -aspect 1920:1080 fullgame_Output.mp4附注:
我已经在一间聊天室寻求帮助了。一个人说他知道问题出在哪里,但不知道怎么解决(?):
[00:10] <kepstin> oh, wait, you're using -vcodec copy
[00:10] <kepstin> that explains everything.
[00:10] <kepstin> when you're using -vcodec copy, the start time (set with -ss) is rounded to the nearest keyframe
[00:10] <kepstin> it's not exact
[00:11] <kepstin> depending on the keyframe interval, this will result in possibly quite large shifts
[00:11] <kepstin> (also, your commands are applying audio filters on commands with -an, which is confusing/contradictory)
[00:12] <birdboy88> so the problem is that the audio temporary clips are not being extracted from the same excat timepoints?
[00:13] <kepstin> birdboy88: yeah, your audio is being re-encoded to wav so it's being cut sample-accurate, but the video's not being precisely cut.
[00:16] <birdboy88> kepstin: so I need to use slow seek (?) to extract video accurately? Or somehow extract audio only where there are video keyframes?
[00:17] <kepstin> birdboy88: i don't know how to extract audio starting at video keyframes with ffmpeg cli. You're already doing slow seek, which doesn't help (you should move the -ss option to before the -i option to speed it up)
[00:17] <kepstin> if you want accurate video cutting when saving to a file, you have to re-encode the video
[00:18] <kepstin> (doing this in a single ffmpeg command means you don't have to save to a file, so you can avoid the issue)
[00:18] * kepstin is off for a bit now编辑:所有工作都是用最新的ffmpeg版本完成的。
我没能让Gyan的代码起作用。它总是丢失一些音频(音频为40.5或27.5,因此只使用一个音频)。这是唯一适合我的(更改为adelay=40500|40500和amix=inputs=2a0;a0loudnorm):
ffmpeg -i fullgame.mp4 -filter_complex "[0]split=2[vpre][vpost];
[0]asplit=2[apre][apost];
[vpre]trim=start='00:09:57':duration='00:00:41',setpts=PTS-STARTPTS[vpre-t];
[apre]atrim=start='00:09:57':duration='00:00:41',asetpts=PTS-STARTPTS,afade=t=out:st=40.5:d=0.5[apre-t];
[vpost]trim=start='00:15:45':duration='00:00:28',setpts=PTS-STARTPTS,format=yuva420p,fade=t=in:st=0:d=0.5:alpha=1,setpts=PTS+40.5/TB[vpost-t];
[apost]atrim=start='00:15:45':duration='00:00:28',asetpts=PTS-STARTPTS,afade=t=in:st=0:d=0.5,adelay=40500|40500[apost-t];
[vpre-t][vpost-t]overlay[v];
[apre-t][apost-t]amix=inputs=2[a0];[a0]loudnorm[a]" -map "[v]" -map "[a]" -y -c:v libx264 -preset ultrafast -b:v 15000k -aspect 1920:1080 -c:a aac fullgame_Output.mp4然后,我尝试使用类似的设置,但使用了3个剪辑,但在一台机器上我得到了错误:“错误而过滤:不能分配内存”。而我的16 GB内存机的处理速度是0.02x!有办法避免这种情况吗?这是我尝试过的代码:
ffmpeg -i fullgame.mp4 -filter_complex "[0]split=3[vpre][vpost][v3];
[0]asplit=3[apre][apost][a3];
[vpre]trim=start=357:duration=41,setpts=PTS-STARTPTS[vpre-t];
[apre]atrim=start=357:duration=41,asetpts=PTS-STARTPTS,afade=t=out:st=40.5:d=0.5[apre-t];
[vpost]trim=start=795:duration=28,setpts=PTS-STARTPTS,format=yuva420p,fade=t=in:st=0:d=0.5:alpha=1,fade=t=out:st=40.5:d=0.5:alpha=1,setpts=PTS+40.5/TB[vpost-t];
[apost]atrim=start=795:duration=28,asetpts=PTS-STARTPTS,afade=t=in:st=0:d=0.5,afade=t=out:st=27.5:d=0.5,adelay=40500|40500[apost-t];
[v3]trim=start=95:duration=30,setpts=PTS-STARTPTS,format=yuva420p,fade=t=in:st=0:d=0.5,setpts=PTS+41+28-0.5/TB[v3-t];
[a3]atrim=start=95:duration=30,asetpts=PTS-STARTPTS,afade=t=in:st=0:d=0.5,adelay=68500|68500[a3-t];
[vpre-t][vpost-t]overlay[v1];
[v1][v3-t]overlay[v];
[apre-t][apost-t][a3-t]amix=inputs=3[a0];
[a0]loudnorm[a]" -map "[v]" -map "[a]" -y -c:v libx264 -preset ultrafast -b:v 15000k -aspect 1920:1080 -c:a aac fullgame_Output.mp4发布于 2018-12-22 06:21:02
只要用一个命令就行了。
除了关键帧查找问题(这是正确的)之外,您的当前序列在最后一个命令中有一个错误。您有[0:v]trim=start=0.5...[0c],它缩短了最初的0.5秒,并将导致它自己的desync。因为这是第一个剪辑,所以应该是[0:v]trim=0:40.5。
完整的单个命令应该是
ffmpeg -i fullgame.mp4 -filter_complex
"[0]split=2[vpre][vpost];[0]asplit=2[apre][apost];
[vpre]trim=start='00:09:57':duration='00:00:41',setpts=PTS-STARTPTS[vpre-t];
[apre]atrim=start='00:09:57':duration='00:00:41',asetpts=PTS-STARTPTS,afade=t=out:st=40.5:d=0.5[apre-t];
[vpost]trim=start='00:15:45':duration='00:00:28',setpts=PTS-STARTPTS,format=yuva420p,fade=t=in:st=0:d=0.5:alpha=1,setpts=PTS+40.5/TB[vpost-t];
[apost]atrim=start='00:15:45':duration='00:00:28',asetpts=PTS-STARTPTS,afade=t=in:st=0:d=0.5[apost-t];
[vpre-t][vpost-t]overlay[v];
[apre-t][apost-t]acrossfade=d=0.5,loudnorm,aresample=48000[a]"
-map "[v]" -map "[a]" -c:v libx264 -preset ultrafast -b:v 15000k -aspect 1920:1080 -c:a aac fullgame_Output.mp4您的原始序列有用于音频AAC编码的-strict -2。这是自2015年12月以来不需要的。如果您的ffmpeg没有抛出一个错误,那么您有一个非常旧的ffmpeg版本。先升级。
我没有用您的文件测试上面的内容,因为过滤完整的高清60 fps视频需要花费16分钟的时间,但是我测试了下面的更快的命令,它可以很好地处理最新的git版本的ffmpeg:
ffmpeg -ss 00:09:57 -t 00:00:41 -i fullgame.mp4 -ss 00:15:45 -t 00:00:28 -i fullgame.mp4 -filter_complex
"[0]afade=t=out:st=40.5:d=0.5[apre-t];
[1]format=yuva420p,fade=t=in:st=0:d=0.5:alpha=1,setpts=PTS+40.5/TB[vpost-t];
[1]afade=t=in:st=0:d=0.5[apost-t];
[0][vpost-t]overlay[v];
[apre-t][apost-t]acrossfade=d=0.5,loudnorm,aresample=48000:ocl=stereo[a]"
-map "[v]" -map "[a]" -c:v libx264 -preset ultrafast -b:v 15000k -aspect 1920:1080 -c:a aac fullgame_Output.mp4https://stackoverflow.com/questions/53890488
复制相似问题