随着自媒体的兴起,很多人会拍自拍视频或者找视频素材剪辑,配上背景音乐或者解说词,加上各种特效边框,然后经过处理生成新的视频文件,发布到各大平台。生成的原始视频文件都非常大,我们需要转换格式或压缩大小,以便于在手机等其他设备上上传或共享。
FFmpeg 介绍
FFmpeg是一个开源免费的多媒体视频处理工具。其功能包括视频捕获、视频格式转换、视频捕获、视频水印等。它为音频和视频的录制、转换和流式传输提供了完整的解决方案。
FFmpeg项目在开源领域有着最好的影响力之一。您看到的视频转换软件或播放器中使用的几乎所有功能或编码/解码都基于FFmpeg。它采用的是LGPL或者GPL许可证,国内一些知名玩家使用的FFmpeg源代码还没有申报,被FFmpeg钉在了历史的耻辱柱上。
FFmpeg 安装
FFmpeg提供源代码,可以自己编译。FFmpeg已经存在于几乎所有的发行版Linux仓库中,可以直接安装。
# debian/ubuntu
apt安装ffmpeg
# redhat/centos/fedora '
yum安装ffmpeg
或者
dnf安装ffmpeg
FFmpeg官方还提供二进制包:ffmpeg.org/download.html.
建议使用FFmpeg的官方静态二进制包,无需额外的动态库。官网只有一个可执行文件。ffmpeg解压缩后,有三个可执行文件:FFmpeg、ffprobe和ffplay。
FFmpeg 使用
官网下载的FFmpeg解压后有三个可执行文件:
音频和视频文件处理转换
读取视频文件信息
一个简单的玩家
ffmpeg命令:
ffmpeg -i video.wma ./video.mp4
将video.wma视频文件转换为mp4格式。ffmpeg mp4格式默认使用h264编码。
ffmpeg -i video.wma -c:v libx265 video.mp4
将video.wma视频文件转换为h265编码的mp4格式。
H265编码比h264编码有更高的压缩比,低比特率生成的文件更小。
也就是说,同样质量的h265编码比h264更清晰。对于相同大小的视频文件,h265编码的视频文件比h264编码的小。然而,当视频比特率达到一定大小时,它们之间的清晰度几乎没有差异。
H264比h265具有更好的兼容性。有些手机默认不支持h265编码的视频文件,需要软件解码。
视频转换,h265编码比h264编码耗时更长,消耗更多的CPU资源。
ffmpeg -i video.mp4 -s 1280720 video2.mp4
将视频压缩至1280720分辨率。
ffmpeg -i video.mp4 -ss 00:00:10 -i video.mp4 -t 00:00:30 -c:v copy -c:a copy cut.mp4
不要更改视频和音频的编码,剪切视频,10秒后保留视频30秒,因为音视频编码指定了参数值拷贝,不会影响视频质量。
ss参数必须在-i之前使用,如果写在-I之后,ffmpeg就会明白,出发点是作用于输出文件。
ffmpeg -i video.mp4 -metadata:s:v rotate=”90 -c:v copy -c:a copy out.mp4
将视频翻转90度,而不改变视频和音频的质量。将横屏改为竖屏。
ffmpeg -f x11grab -r 30 -i :0.0 -f alsa -i hw:0,0 -acodec aac -vcodec libx264 out.mkv
使用FFmpeg视频录制,这个命令在Linux上有效。每秒30帧,音频格式使用aac,视频格式使用h264,输出mkv格式。
Vcodec与c:v参数一样,指定视频编码,如libx264和libx265。
Acodec与c:a参数一样,指定音频编码,如aac、mp4和flac。
FFmpeg还有很多其他用途,比如调整码率和帧数。使用ffmpeg -help查看所有参数描述。
GPU加速
FFmpeg默认使用CPU编码。当执行ffmpeg命令时,资源管理器可以看到CPU利用率提高了。
gncenter" alt="视频捕捉软件哪个好(视频字幕提取工具使用)" src="/uploads/allimg/211111/2001125E6-0.png">如果使用GPU运算,转换速度能成倍提高,特别是转换h265编码视频。
查看ffmpeg支持视频编码格式:
ffmpeg -codecs
找到 hevc ,也就是h265编码:
- hevc_qsv:intel核显
- hevc_nvenc:nvidia显卡
- hevc_amf:amd显卡
如果使用h264编码,使用 h264_qsv / h264_nvenc 。
ffmpeg -i ./video.mp4 -c:v hevc_qsv ./out.mp4
使用GPU编码,运行以上ffmpeg命令,可以看到GPU占用率升高。
使用GPU加速视频转换速度快了很多,我仅使用核显速度也比CPU转码也能快数倍。
ffprobe命令
ffprobe ./video.mp4
查看视频文件信息。
从输出信息可以看到该视频文件是使用h264编码,分辨率1280×720,视频平均码率921kbps,24帧。视频的音频使用aac编码,采样率44100Hz,码率128kpbs。
ffprobe -v error -show_streams -print_format json ./video.mp4
使用json格式输出视频信息。
ffplay命令
ffplay ./video.mp4
播放视频文件。这时会弹出一个播放器。
ffplay命令还有很多控制参数。不过我觉得用处不大,毕竟图形化播放器更好用,功能也更强大。
开发集成
使用FFmpeg命令,我们可以用程序或脚本完成视频自动转换。也可以让我们开发的系统拥有视频转码,或读取视频信息的功能。以Java示例:
public static int doWaitFor(Process process) {
InputStream in = null;
InputStream err = null;
int exitValue = -1; // returned to caller when p is finished
try {
in = process.getInputStream();
err = process.getErrorStream();
boolean finished = false; // Set to true when p is finished
while (!finished) {
try {
while (in.available() > 0) {
// Print the output of our system call
Character c = new Character((char) in.read());
System.out.print(c);
}
while (err.available() > 0) {
// Print the output of our system call
Character c = new Character((char) err.read());
System.out.print(c);
}
// Ask the process for its exitValue. If the process
// is not finished, an IllegalThreadStateException
// is thrown. If it is finished, we fall through and
// the variable finished is set to true.
exitValue = process.exitValue();
finished = true;
} catch (IllegalThreadStateException e) {
// Process is not finished yet;
// Sleep a little to save on CPU cycles
Thread.currentThread().sleep(500);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (err != null) {
try {
err.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return exitValue;
}
Java调用外部命令使用 Runtime.getRuntime().exec(command) 。
在使用调用ffmpeg命令时,必须要读取执行命令输出流中的内容,程序才不会阻塞。否则缓冲读满后,进程会卡住。
视频转换会非常耗时,取决于硬件性能。在实际应用中,我们也可以开启线程去处理。
FFmpeg还提供C调用,公共库集成。以上方法并不是最优解决方案,仅提供一种参考。
下一篇:如何写好创业课_大学生创业意向