video - 如何插入帧以补偿捕获期间丢失的帧

标签 video ffmpeg screen-capture frame-rate

我的原始剪辑是 22:47 长。我使用 Ut Video Lossless Codec 以 29.97 fps 和 pcm 16 位无符号音频捕获了 avi 视频。
我正在使用带有 VHScrCap 驱动程序的 Virtualdub 进行捕获。
Virtualdub、mpc 和 potplayer 播放捕获的文件显然太快了,但前 3-4 分钟的音频音调正确,但视频的其余部分音调很高。时长为19:06,比原来的22:47短(由mediainfo确认)
问题的原因似乎是我在捕获大型高清帧时丢失了更多帧。

正则编码

将捕获的剪辑编码为 mp4:

ffmpeg -ss 3.25 -i input.avi -map 0:0 -map 0:1 -threads 0 -c:v libx264 -profile:v main \
-preset:v medium -level 3.1 -x264opts crf=26.0 -aspect 16:9 -t 1112.69 \
-y -f mp4 -vf "crop=1432:808:4:46, hqdn3d=1.5:1.5:6:6, \
scale=1216:684, pad=1280:720:32:18" -c:a ac3 -ac 2 -ar 48000 -b:a 160k \
output.mp4

输出长度为 18:32,帧率仍为 29:97。前 2 分钟的音频音调还可以,而在视频的其余部分中,音调太高了。

试图纠正

我尝试通过以下三个步骤来纠正它:(1) 对减速到 23.976 fps 的视频流进行编码并提取 wav 音频流,(2) 降低音频的速度和音高,以及 (3) 重新混合视频和音频:
(1)
ffmpeg -ss 3.25 -i input.avi -threads 0 \
-c:v libx264 -profile:v main -preset:v medium -level 3.1 -x264opts crf=26.0 \
-aspect 16:9 -t 1390.862 -an -y -f mp4 -r 24000/1001 \
-vf "crop=1432:808:4:46, hqdn3d=1.5:1.5:6:6, scale=1216:684, pad=1280:720:32:18, \
setpts=1.25*PTS" video_out.mp4  \
-t 1112.69 -y -vn -f wav  audio_out.wav

(2) 然后 wav 音频流使用 sox 以较低的音调减慢:
sox --norm audio_out.mp4.wav audio_out-24.wav speed 0.8

(3) 然后将两个流重新混合为:
ffmpeg -i video_out.mp4 -i audio_out-24.wav -map 0:0 -map 1:0 -c:v copy \
-c:a ac3 -ac 2 -af aresample=resampler=soxr -ar 48000 -b:a 160k \
final_output.mp4

这一次,视频时长(23:10)更接近原始视频,整个视频的音高都可以,除了前 2-3 分钟,它(可以预见)太低了。

我有一种感觉,(1)捕获日志和 ffprobe 逐帧提供信息,显示什么是“瞬时”真实帧速率,以及(2)ffmpeg 编码不使用该信息,但大概可以使用通过插入重复或内插帧来纠正帧速率,以恢复正确的帧速率。我怀疑我可以从 (1) 中获取信息,但不知道如何去做 (2)。

如果熟悉此类问题的人能给我一些建议,并为我指明正确的方向,我将不胜感激。

最佳答案

好吧,如果有人感兴趣,这就是我的立场。

我不确定这是否是答案,但这是我现在的答案。我发现尝试纠正和改进拍摄不佳的视频并不是一个好主意。这就是我现在正在尝试做的,以避免在捕获过程中丢失帧并获得高质量的视频。
注意:确定捕获是否良好的一种简单方法是观察插入帧数与捕获的总帧数。 (我用VirtualDub来捕捉,这些数字是实时显示的)。尝试获得零插入帧。

  • 重新启动计算机以消除在您 try catch 时正在运行的那些旧进程。
  • 在 Windows 任务管理器中查找任何不必要的进程,然后将其杀死。
  • 尝试使用您要捕获的帧的大小。这取决于 CPU 的处理能力。我发现我不应该 try catch 1920x1080(我有一个可能高于平均水平的 Intel i7-3770K),但我可以做到 1280x720。
  • 我将捕获帧速率设置为 23.976 fps (NTSC),这比 29.97 fps 更容易。
  • 选择无损且需要尽可能少的处理能力的编码器。我使用 UT Video Codec YUV420 进行视频,没有音频压缩 (PCM)。鉴于此,您需要大量 GB 来存储捕获的视频。一个小时可能需要 20GB。 (我使用使用 ffmpeg 的脚本单独进行压缩,并将 20GB 以上的视频编码为 500 MB 的文件)

  • 鉴于这些预防措施,我可以捕捉这些视频几乎没有丢帧,然后流畅播放。

    进一步研究:我一直想知道用较低的帧速率换取更高的清晰度是否是一个很好的权衡。例如,以 20 fps 而不是 23.976 的速度拍摄,然后想办法在以后以不会吓到眼睛的方式添加帧。 (我认为应该使用 avisynth 的 ConvertFPS() 函数,而不是 ffmpeg)我还没有对这种方法进行任何实验。

    关于video - 如何插入帧以补偿捕获期间丢失的帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33128869/

    相关文章:

    html - 全 Angular vimeo 包装背景

    c - 如何使用 ffmpeg 库从视频中提取灰度图像?

    video - ffmpeg:如何限制视频输出的比特率?

    c# - 如何避免在avisaveoptions中弹出压缩选项框

    javascript - 如何停止嵌入式YouTube视频

    video - omxplayer AVPacket

    php - 如何使用ffmpeg从任何地方传递视频

    javascript - Node 生成子进程在 aws Node 10 lambda 中的 exec 子进程之后不执行命令

    c++ - 获取被遮挡窗口的图像内容

    wpf - 如何防止(禁用)WPF 应用程序的视频捕获