急速裁剪视频(不重新编码)

开始接触 ffmpeg 就是在裁剪视频长度的时候。Premier、格式工厂、Windows 照片自带的裁剪等软件都需要对视频进行重新编码。而 ffmpeg 则可以通过设置参数 -c copy,在创建视频的时候不重新编码,这样的好处是裁剪的过程基本就是文件复制的过程,CPU 不再成为性能瓶颈,SSD 上速度是真滴快。

1
ffmpeg -i input.mp4 -ss 00:01:00 -t 01:00:00 -c copy output.mp4

-i 参数指定输入文件,-ss 指定开始裁剪的时间,-t 指定裁剪总长度,-c 指定编码格式。

改变码率和分辨率

  • 限制码率:使用参数 -b 2M 将视频平均码率限制在 2Mbps。
  • 修改视频分辨率:使用参数 -vf scale=640:480,或省略一个参数 -vf scale=-1:480,程序将自动按比例缩放。
1
ffmpeg -i input.mp4 -b 2M -vf scale=-1:720 output.mp4

需要注意的是,过低的码率会导致画质变低,甚至出现花屏。

使用 CUDA 加速重新编码软件

查看可使用的硬件加速:

1
2
3
4
5
6
7
8
> ffmpeg -hwaccels
:: 略过一堆输出
Hardware acceleration methods:
cuda
dxva2
qsv
d3d11va
vulkan

这里由于使用的是 N 卡,于是确定使用 cuda

确定编码格式和对应的编码器,带了 nv 的基本就是 NVIDIA 的编码/解码器:

1
2
3
4
5
6
7
8
> ffmpeg -codecs | find "nv"
:: 略过一堆输出
D.V.L. dsicinvideo Delphine Software International CIN video
DEV.LS h264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (decoders: h264 h264_qsv h264_cuvid ) (encoders: libx264 libx264rgb h264_amf h264_nvenc h264_qsv nvenc nvenc_h264 )
DEV.L. hevc H.265 / HEVC (High Efficiency Video Coding) (decoders: hevc hevc_qsv hevc_cuvid ) (encoders: libx265 nvenc_hevc hevc_amf hevc_nvenc hevc_qsv )
D.V.L. idcin id Quake II CIN video (decoders: idcinvideo )
D.VIL. wnv1 Winnov WNV1
D.AIL. twinvq VQF TwinVQ

我们使用 H.265(HEVC) 格式编码,用 CUDA 加速编码过程。于是选择使用 hevc_nvenc 作为编码器。

最后写命令:

1
ffmpeg -hwaccel cuda -i input.mp4 -c:v hevc_nvenc output.mp4

其中 -c 参数放在 -i 后,表示修改编码格式(在 -i 前则是解码格式);-c:v 是修改视频编码格式。

如果提示 Nvidia 驱动版本太低,需要更新驱动。

下载 m3u8

m3u8 是一种流媒体格式,常用于在线观看、直播等。如腾讯课堂的回看就是以这个格式提供的。

网上有不少 m3u8 下载器,我一直使用的是 nilaoda/M3U8-Downloader。我也知道它用到了 ffmpeg,不过一直以为它只是做了视频合并。

今天使用某 APP 时,刚开始没有找到现成的将加密 m3u8 转为 mp4 的轮子,于是自己想按照博客 手写一个 shell 脚本实现。但看到最后,没想到 ffmpeg 还能一行(从网络或从本地)下载 m3u8 并转为单文件!nb!

下面给出三个版本的用法(一般采用第一个就行,最快):

1
2
3
4
5
6
7
8
# 不重新编码
ffmpeg -allowed_extensions ALL -i "URL" -c:v copy output.mp4

# 使用默认编码进行编码(应该是 h264 吧)
ffmpeg -allowed_extensions ALL -i "URL" output.mp4

# 使用 CUDA 编码为 h265
ffmpeg -allowed_extensions ALL -hwaccel cuda -i "URL" -c:v hevc_nvenc output.mp4
  • -allowed_extensions ALL:m3u8 可能涉及到加密,需要读取 .key 秘钥文件;而 ffmpeg 默认不让读取媒体格式以外的格式,所以需要加这个参数允许读取所有格式;
  • "URL":替换为本地路径或 HTTP URL 均可。也可以用 wgetcurl 将 URL 中的 m3u8 源文件下载下来,再运行 ffmpeg
  • output.mp4:输出文件,没什么好说的。