Post

视频工作基础入门

因 VFR 视频引发的问题进行了音视频方面的肤浅研究和学习

视频工作基础入门

最近倒腾了一阵子 Final Cut Pro,遇到了不少视频编码和封装上面的问题,简单学习和了解相关知识后记录成文。

分辨率、码率和帧率

分辨率

分辨率指的是水平方向和垂直方向的像素数量。数字电视和互联网主流标准下的分辨率大多是 16:9 比例,从 360p 到现在的 4k 乃至 8k,其实都是遵循 16:9 比例的一系列分辨率的简称。

分辨率水平×竖直名称
720p1280×720高清(HD)
1080p1920×1080全高清(FHD)
4k3840×2160超高清(UHD)

除此之外还有一些比例不同的分辨率,比如老式电视的 4:3,电影行业比 16:9 更宽,短视频的 9:16。

为了更好的剪辑效果,录制视频的时候会选择略大于输出视频的分辨率,比如录制 4k 视频,然后剪辑后输出为 1080p,这样给编辑预留了不少空间,也能尽可能降低缩放带来的画质损失。

码率

通俗来讲,码率(bitrate)就是视频每一秒画面包含的信息总量,使用单位 bps (bit per second) 表示。决定码率大小的是分辨率和视频的编码格式,也就是画面信息的压缩算法。不同编码格式的压缩效率也有所差别,所以对相同分辨率来说,码率越大不一定等于画质越好。

码率控制(bitrate control)也是录制视频时的一个重要参数,最常见的是固定码率(CBR)和动态码率(VBR)。固定码率很好理解,就是视频画面始终保持一个恒定的码率,优点是视频体积很好预测,在推流中可以保持传输压力平稳,但是缺点是可能导致空间浪费,而且遇到复杂画面时可能因为码率不够而导致画质降低。动态码率则会根据画面内容智能调整当前码率,效率比较高,同等体积下画质要优于固定码率。此外还有平均码率(ABR)和恒定质量因子(CRF),前者指定了一个码率的平均数,后者类似 VBR,也会根据画面复杂度动态分配码率,来保持恒定的感知画质,但是视频文件的大小相较 VBR 更难预估。

帧率

帧率值得就是一秒钟有几张画面,帧率越高,视频中的动作看起来越连贯、越顺滑。电影一般采用 24fps,网络视频一般采用 30fps 或者 60fps,取决于视频对动作感的追求力度。

帧率也可以像码率一样动态变化,也就是动态帧率(VFR)。动态帧率也是为了平衡视频流畅度和体积而设计的。但是 VFR 视频对剪辑软件可能不是很友好。最近我把 Steam 录制的游戏视频放到 Final Cut Pro 中预览和编辑的时候,视频总是有明显的卡顿,音画也偶尔不同步,查询资料后才知道 Steam 录制视频采用了 VFR,基于时间线的剪辑软件很难处理。

编码格式

前面介绍码率的时候已经提到,影响码率的重要因素是编码格式。如今常见的编码格式是 H.264 和 ProRes,前者是目前最普及的视频压缩格式,是业界标准的分发格式之一,优点是体积小、画质优秀、兼容性好。ProRes 的设计则和 H.264 完全相反,它旨在保留细节并降低 CPU 运算负载,使其成为了最适合剪辑的编码格式之一,同时它的画质非常优秀,不过缺点是体积非常大。Final Cut Pro 非常推荐使用 ProRes 格式的素材进行剪辑,但是我觉得这对硬盘容量的考验确实有点儿太大了。

封装格式

封装格式通常也被称为“视频格式”或“容器”,作用是将视频、音频、字幕等多个文件打包成一个独立的文件。比较常见的封装格式有兼容性最强的 mp4,Apple 设计的 mov 和开源的 mkv。所以 mp4 根本不是视频压缩格式,它只是负责把视频、音频等多媒体文件打包在一起。

不同的封装格式之间可以互相转换,相当于换了一个“打包盒”。当然,转换的过程中也可以执行一些重编码工作,比如给视频换一个编码格式,这些具体在后面介绍 FFmpeg 的时候会提及。

视频格式转换

处理视频文件的时候经常会涉及到不同编码格式和封装格式之间的转换,例如发布视频时会进行编码导出,剪辑前可能进行重编码,也可能是单纯的封装格式替换。取决于不同的工作流,进行剪辑时需求的格式可能也各不相同。

最方便的格式转换工具当属开源的 FFmpeg。FFmpeg 几乎汇集了当下所有的音视频格式,播放、重编码、格式转换都不在话下。完整学习使用 FFmpeg 需要一些音视频领域的基础知识,我对此了解并不深入,所以只能罗列一些简单的用法作为参考。

FFmpeg 最基础的用法是进行音视频的读取和转换:

1
ffmpeg -i <input> <output>

-i <input> 指出了输入文件,FFmpeg 会读取输入文件,识别音视频文件的元数据并打印,然后将其转换输出为目标文件。在不加其他参数的情况下,FFmpeg 总是会进行重编码,并且会根据 <ouput> 文件的后缀名来决定默认的重编码格式。例如,对于 mp4 后缀名,FFmpeg 会采用第三方编码库 libx264 生成 H.264 格式的视频,音频则使用自带的 ACC 编码组件进行重编码。执行命令时会看到这样的输出:

1
2
3
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))

这表示原视频有两个轨道:第一个轨道是 H.264 格式的视频,使用 FFmpeg 内置的 H.264 解码器解码后,又使用 libx264 编码为了 H.264 格式的视频,输出到了目标文件的第一个轨道中;第二个轨道是 ACC 格式的音频,FFmpeg 也对其进行了解码和重编码。

FFmpeg 提供了非常多的选项用来控制编解码流程。比较常用的是使用 -c / -codec 选项指定编码器。

  • -c:指定所有。
  • -c:v:指定所有视频。
  • -c:a:138:指定第 138 个音频。

例如,使用 -c copy 指定 FFmpeg 不要进行编解码,只是将音视频流原封不动地封装进目标文件;-c:v libx264 指定使用 libx264 进行视频轨道的重编码。

使用 libx264 编码视频的时候,还可以使用 -crf 指定目标视频的 CRF 质量因子,默认是 23(画质和体积比较平衡)。CRF 越低,画质越好,体积也越大,18 基本是视觉上无损,大于 28 可能会导致画质偏低。

下面列举一些常用命令,以及命令行解释。

将 MKV 格式无损转换为 MOV/MP4 格式

Final Cut Pro 不支持 MKV 格式的素材,因此需要将 MKV 文件进行无损的重新封装。

1
ffmpeg -i intput.mkv -map 0 -c copy output.mp4
  • -map 0:将首个输入文件中的所有流都映射到目标文件。如果不指定,FFmpeg 只会在输入文件中选取一个视频和一个音频轨道,如果有多个音轨的话会导致素材不完整。
  • -c copy:不要编解码,直接封装。

提取视频中的所有音频轨道

1
ffmpeg -i video.mp4 -vn -c:a copy music.m4a
  • -vn:忽略所有视频轨道。
  • -c:a copy:指定所有音频轨道为直接拷贝。

MP4 视频中的音频一般是 AAC 格式,一般不能直接拷贝到 MP3 文件中。要想生成 MP3 文件,可以额外指定编码器:

1
ffmpeg -i video.mp4 -vn -c:a libmp3lame -q:a 2 music.mp3

-q:a 指定音频质量(quality of audio),取值为 0 到 9,0 是极致质量但是文件偏大,2 是比较标准和平衡的质量。指定 -q:a 的时候,音频码率控制使用的是 VBR,也可以使用 -b:a 指定固定码率,比如 -b:a 320k

Final Cut Pro 实践

Final Cut Pro 对 MOV 封装格式支持比较好,也鼓励用户使用 MOV 格式导出。Final Cut Pro 支持给原片创建“optimized or proxy media”。将视频转化为 optimized media 实质上就是用 ProRes 422 格式进行重编码,这能大大优化剪辑体验,但是 optimized media 会大量占据存储空间。Proxy media 和 optimized media 类似,都是为剪辑设计的,但是占用存储空间较小。

Final Cut Pro 对动态帧率(VFR)视频支持不够好,这类视频在 Final Cut Pro 中会出现音画不同步、音轨卡顿等异常现象,导出成片后也会有问题。录制视频时最好不要开启 VFR,但是 Steam 录制游戏画面没办法关闭这个功能,所以只能转用 OBS 了。OBS 默认的输出格式是 MKV,无法直接导入到 Final Cut Pro 中,因此要使用 FFmpeg 进行格式转换,这里就需要使用 -c copy -map 0 选项来进行无损封装,并保留所有轨道。


我了解到并值得一提的知识和应用场景就是这些。后面在使用 Final Cut Pro 的时候遇到新鲜知识的时候再来更新博客 ☺️。

参考文献

This post is licensed under CC BY 4.0 by the author.