隨著自媒體興起黎炉,許多人會(huì)自拍視頻或者找視頻素材裁剪膜钓,配上背景音樂或解說嗽交,加上各種特效邊框,處理后再生成新的視頻文件颂斜,發(fā)布到各大平臺(tái)夫壁。生成的原始視頻文件都很大,我們需要轉(zhuǎn)換格式或者壓縮大小沃疮,便于上傳或者在其他如手機(jī)等設(shè)備上分享盒让。
FFmpeg 介紹
FFmpeg是一款開源免費(fèi)的多媒體視頻處理工具,功能包括視頻采集功能司蔬、視頻格式轉(zhuǎn)換糯彬、視頻抓圖、給視頻加水印等葱她。它提供了錄制、轉(zhuǎn)換以及流化音視頻的完整解決方案似扔。
FFmpeg項(xiàng)目在開源界的影響力也是數(shù)一數(shù)二的吨些。幾乎你所見到的視頻轉(zhuǎn)換軟件或播放器中用到的功能或編碼/解碼都基于FFmpeg。它采用LGPL或GPL許可證炒辉,曾今國內(nèi)某些知名播放器使用FFmpeg源碼未聲明豪墅,被FFmpeg釘在歷史的恥辱柱上。
FFmpeg 安裝
FFmpeg提供源碼黔寇,可自行編譯偶器。幾乎所有發(fā)行版Linux倉庫中已有FFmpeg,可以直接安裝缝裤。
# debian/ubuntu
apt install ffmpeg
# redhat/centos/fedora'
yum install ffmpeg
或
dnf install ffmpeg
FFmpeg官方也提供二進(jìn)制包:ffmpeg.org/download.html
推薦使用FFmpeg官方static二進(jìn)制包屏轰,無需額外動(dòng)態(tài)庫,僅一個(gè)可執(zhí)行文件官網(wǎng)下載后的FFmpeg解壓后有三個(gè)可執(zhí)行文件:ffmpeg憋飞、ffprobe霎苗、ffplay。
FFmpeg 使用
官網(wǎng)下載后的FFmpeg解壓后有三個(gè)可執(zhí)行文件:
ffmpeg:音視頻文件處理轉(zhuǎn)換
ffprobe:讀取視頻文件信息
ffplay:一個(gè)簡易的播放器
ffmpeg命令:
ffmpeg -i video.wma ./video.mp4
把 video.wma 視頻文件轉(zhuǎn)換成 mp4 格式榛做。ffmpeg mp4 格式默認(rèn)使用h264編碼
ffmpeg -i video.wma -c:v libx265 video.mp4
把 video.wma 視頻文件轉(zhuǎn)換成 h265 編碼的 mp4 格式唁盏。
h265比h264編碼有更高的壓縮率,在低碼率下生成的文件更小检眯。
也就是說厘擂,相同質(zhì)量下的h265編碼比h264更清晰。相同大小的視頻文件锰瘸,h265編碼比h264編碼的視頻文件體積更小刽严。但是當(dāng)視頻碼率到達(dá)一定大小時(shí),兩者清晰度區(qū)別不大避凝。
h264比h265有更好的兼容性港庄,有些手機(jī)默認(rèn)不支持h265編碼的視頻文件倔既,需要借助軟件解碼。
視頻轉(zhuǎn)換鹏氧,h265編碼比h264編碼用時(shí)會(huì)更長渤涌,更消耗CPU資源。
ffmpeg -i video.mp4 -s 1280x720 video2.mp4
將視頻壓縮到1280x720分辨率把还。
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秒,因?yàn)橐纛l視頻編碼指定參數(shù)值copy吊履,不會(huì)影響視頻質(zhì)量安皱。
使用ss參數(shù)一定要在-i之前,如果寫在-i之后艇炎,ffmpeg會(huì)理解為起始點(diǎn)是作用于輸出文件酌伊。
ffmpeg -i video.mp4 -metadata:s:v rotate="90" -c:v copy -c:a copy out.mp4
不改變視頻和音頻的質(zhì)量將視頻翻轉(zhuǎn)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 參數(shù)一樣蔗草,指定視頻編碼,如:libx264疆柔,libx265
acodec 與 c:a 參數(shù)一樣咒精,指定音頻編碼,如:aac旷档,mp4狠轻,flac
FFmpeg還有很多其他用法,比如調(diào)整碼率彬犯,幀數(shù)等向楼。使用 ffmpeg --help 可以看到全部參數(shù)說明。
GPU加速
FFmpeg默認(rèn)使用CPU編碼谐区。執(zhí)行ffmpeg命令時(shí)湖蜕,資源管理器可以看到CPU使用率升高。
如果使用GPU運(yùn)算宋列,轉(zhuǎn)換速度能成倍提高昭抒,特別是轉(zhuǎn)換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編碼,運(yùn)行以上ffmpeg命令熙含,可以看到GPU占用率升高罚缕。
使用GPU加速視頻轉(zhuǎn)換速度快了很多,我僅使用核顯速度也比CPU轉(zhuǎn)碼也能快數(shù)倍怎静。
ffprobe命令
ffprobe ./video.mp4
查看視頻文件信息邮弹。
從輸出信息可以看到該視頻文件是使用h264編碼,分辨率1280x720蚓聘,視頻平均碼率921kbps腌乡,24幀。視頻的音頻使用aac編碼夜牡,采樣率44100Hz与纽,碼率128kpbs。
ffprobe -v error -show_streams -print_format json ./video.mp4
使用json格式輸出視頻信息塘装。
ffplay命令
ffplay ./video.mp4
播放視頻文件急迂。這時(shí)會(huì)彈出一個(gè)播放器。
ffplay命令還有很多控制參數(shù)氢哮。不過我覺得用處不大,畢竟圖形化播放器更好用型檀,功能也更強(qiáng)大冗尤。
開發(fā)集成
使用FFmpeg命令,我們可以用程序或腳本完成視頻自動(dòng)轉(zhuǎn)換胀溺。也可以讓我們開發(fā)的系統(tǒng)擁有視頻轉(zhuǎn)碼裂七,或讀取視頻信息的功能。以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調(diào)用外部命令使用 Runtime.getRuntime().exec(command) 仓坞。
在使用調(diào)用ffmpeg命令時(shí)背零,必須要讀取執(zhí)行命令輸出流中的內(nèi)容,程序才不會(huì)阻塞无埃。否則緩沖讀滿后徙瓶,進(jìn)程會(huì)卡住。
視頻轉(zhuǎn)換會(huì)非常耗時(shí)嫉称,取決于硬件性能侦镇。在實(shí)際應(yīng)用中,我們也可以開啟線程去處理织阅。
FFmpeg還提供C調(diào)用壳繁,公共庫集成。以上方法并不是最優(yōu)解決方案,僅提供一種參考闹炉。
除非注明蒿赢,否則均為"攻城獅·正"原創(chuàng)文章,請(qǐng)注明出處渣触。