使用 ffmpeg 创建屏幕录像:如何保持视频和音频同步?

使用 ffmpeg 创建屏幕录像:如何保持视频和音频同步?

我使用 ffmpeg 创建了一些截屏视频。我使用的 PC 具有强大的硬件(Intel Core i7-4930K 六核 3.40GHz 12MB 缓存,32 GB RAM),但不幸的是它运行的是 Windows 7。因为我想在 Linux 上进行截屏视频,所以我在 VMware 中安装了 Kubuntu。我为虚拟机分配了 4 个 CPU 核心和 4 GB RAM。

我使用以下命令录制我的截屏视频:

ffmpeg -f alsa -ac 1 -i pulse -f x11grab -r 30 -s 1920x1080 -i :0.0 -acodec mp3 -vcodec libx264 -preset ultrafast -crf 0 -threads 0 output.mp4

但是视频的运行速度比音频快得多。几分钟后,音频(由麦克风录制)比视频慢几秒钟。我尝试在 Windows 主机上使用 audacity 并行录制音频,来自 audacity 的音频和 VM 中 ffmpeg 捕获的音频似乎同步。只是视频运行得太快了。

这是什么原因?可能与 VMware 有关吗?有什么设置可以调整吗?有没有 ffmpeg 选项可以用于同步?例如,如果我可以强制 ffmpeg 在音频/视频不同步时丢弃或复制帧,这对我来说完全没问题,但据我了解,ffmpeg 的 -vsync 选项手册已经是默认选项了。

我自己编译了 ffmpeg,如下所示Ubuntu 编译指南我使用 ffmpeg 的想法来自这里

编辑:根据要求的 ffmpeg 输出:

$ /home/yankee/bin/ffmpeg -f alsa -ac 1 -i pulse -f x11grab -r 30 -s 1920x1080 -i :0.0 -acodec mp3 -vcodec libx264 -preset ultrafast -crf 0 -threads 0 05-visitor.mp4
ffmpeg version 2.1.git Copyright (c) 2000-2014 the FFmpeg developers
  built on Feb 24 2014 08:38:08 with gcc 4.8 (Ubuntu/Linaro 4.8.1-10ubuntu9)
  configuration: --prefix=/home/yankee/ffmpeg_build --extra-cflags=-I/home/yankee/ffmpeg_build/include --extra-ldflags=-L/home/yankee/ffmpeg_build/lib --bindir=/home/yankee/bin --extra-libs=-ldl --enable-gpl --enable-libass --enable-libfdk-aac --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-x11grab
  libavutil      52. 65.100 / 52. 65.100
  libavcodec     55. 52.102 / 55. 52.102
  libavformat    55. 33.100 / 55. 33.100
  libavdevice    55. 10.100 / 55. 10.100
  libavfilter     4.  1.103 /  4.  1.103
  libswscale      2.  5.101 /  2.  5.101
  libswresample   0. 17.104 /  0. 17.104
  libpostproc    52.  3.100 / 52.  3.100
Guessed Channel Layout for  Input Stream #0.0 : mono
Input #0, alsa, from 'pulse':
  Duration: N/A, start: 1394106509.365291, bitrate: 768 kb/s
    Stream #0:0: Audio: pcm_s16le, 48000 Hz, mono, s16, 768 kb/s
[x11grab @ 0x2551e40] device: :0.0 -> display: :0.0 x: 0 y: 0 width: 1920 height: 1080
[x11grab @ 0x2551e40] shared memory extension found
Input #1, x11grab, from ':0.0':
  Duration: N/A, start: 1394106509.415547, bitrate: 1990656 kb/s
    Stream #1:0: Video: rawvideo (BGR[0] / 0x524742), bgr0, 1920x1080, 1990656 kb/s, 30 tbr, 1000k tbn, 30 tbc
No pixel format specified, yuv444p for H.264 encoding chosen.
Use -pix_fmt yuv420p for compatibility with outdated media players.                                                                                                                                                                                                            
[libx264 @ 0x256db60] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[libx264 @ 0x256db60] profile High 4:4:4 Predictive, level 4.0, 4:4:4 8-bit
[libx264 @ 0x256db60] 64 - core 142 - H.264/MPEG-4 AVC codec - Copyleft 2003-2014 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=0 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=0 chroma_qp_offset=0 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=250 keyint_min=25 scenecut=0 intra_refresh=0 rc=cqp mbtree=0 qp=0
Output #0, mp4, to '05-visitor.mp4':
  Metadata:
    encoder         : Lavf55.33.100
    Stream #0:0: Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv444p, 1920x1080, q=-1--1, 15360 tbn, 30 tbc
    Stream #0:1: Audio: mp3 (libmp3lame) (i[0][0][0] / 0x0069), 48000 Hz, mono, s16p
Stream mapping:
  Stream #1:0 -> #0:0 (rawvideo -> libx264)
  Stream #0:0 -> #0:1 (pcm_s16le -> libmp3lame)
Press [q] to stop, [?] for help
frame=19011 fps= 30 q=-1.0 Lsize=  186418kB time=00:10:34.84 bitrate=2405.5kbits/s    
video:180861kB audio:4960kB subtitle:0 data:0 global headers:0kB muxing overhead 0.321432%
[libx264 @ 0x256db60] frame I:77    Avg QP: 0.00  size:451985
[libx264 @ 0x256db60] frame P:18934 Avg QP: 0.00  size:  7943
[libx264 @ 0x256db60] mb I  I16..4: 100.0%  0.0%  0.0%
[libx264 @ 0x256db60] mb P  I16..4: 59.7%  0.0%  0.0%  P16..4:  0.0%  0.0%  0.0%  0.0%  0.0%    skip:40.3%
[libx264 @ 0x256db60] coded y,u,v intra: 0.2% 0.2% 0.2% inter: 0.0% 0.0% 0.0%
[libx264 @ 0x256db60] i16 v,h,dc,p: 100%  0%  0%  0%
[libx264 @ 0x256db60] kb/s:2338.03

我又尝试了一下,发现如果输出文件已经存在,ffmpeg 会询问我是否要覆盖该文件。在这种情况下,音频流已经包含我说的内容,而覆盖文件的问题仍然存在。然而,在我确认文件覆盖之前,视频不会开始播放,因此音频自然会落后于视频很多。但这很容易处理。只要不覆盖现有文件即可。

我并不真正关心最终采用的格式,只要视频具有某种无损格式并且我可以使用 Adob​​e Premiere 对其进行编辑(它不支持 mkv)。

编辑 2:我离问题更近了一点。当仔细查看生成的视频流时,有时会注意到缺少几帧。可能是因为我此刻打开了一个窗口,导致视频压缩消耗了更多的 CPU(因为许多像素发生了变化)或诸如此类的原因。也许我可以为 ffmpeg 分配一些缓冲区以加快这种时候的处理速度?毕竟我的机器有 32GB 的 RAM,它应该有好处……或者还有其他我可以使用无损编解码器吗?或者……?下次我也会尝试为 ffmpeg 设置更高的 CPU 优先级。

答案1

这在 2019 年对我有用。我尝试了不同的编码器,但当使用不是nativeffmpeg 的编码器时,音频和视频不同步。具体来说,视频落后了。mpeg4并且aacnative

ffmpeg -f alsa -ac 1 -i pulse -f x11grab -r 30 -s 1920x1080  -i :0.0 -acodec aac -vcodec mpeg4 -preset medium -qscale:v 5 rec.mkv

答案2

我收到“[swscaler @ 0xa314080] 警告:数据未对齐!这可能会导致速度损失”,这似乎是问题所在。但是,我还没有解决方案。

相关内容