一次用ffmpeg實現(xiàn)圖片+音頻合成視頻的開發(fā)

一、需求

用戶針對一個PPT的每一頁圖片,進行語音錄制黄虱,輸出多段音頻文件,將用戶每段音頻和對應(yīng)的PPT圖片拼接起來下梢,最后輸出成一整段MP4視頻,作為教學(xué)視頻播放

二塞蹭、方案選擇

針對需求孽江,最開始提出了幾個主要的方案

方案 優(yōu)點 缺點
方案一:直播推流錄制 使用現(xiàn)成直播方案,上手成本小 業(yè)務(wù)邏輯要和直播業(yè)務(wù)切割隔離番电,重新弄一套岗屏,不合適,而且感覺殺雞用牛刀
方案二:客戶端處理圖片漱办、音頻合成这刷,視頻拼接等多媒體操作 1、后端業(yè)務(wù)簡單;
2娩井、大多數(shù)視頻處理類APP都是如此,方案成熟
1咐刨、前端要新嵌入七牛多媒體處理SDK昙衅,對包穩(wěn)定性有影響
2、APP處理視頻而涉,可能比較耗費手機性能,如果APP受眾用戶是中老年用戶联予,可能手機性能扛不住
方案三:服務(wù)端統(tǒng)一處理圖片啼县、音頻合成沸久,視頻拼接等多媒體操作 1卷胯、客戶端無需再嵌入SDK
2诵竭、對用戶手機性能的要求降到最低
服務(wù)端交互邏輯變復(fù)雜卵慰,并且要處理耗時的多媒體合成任務(wù)

最終定了方案三,原因是該功能的受眾是老年用戶鲤嫡,手機性能可能很差暖眼,耗時的操作交給服務(wù)端來比較合適

三、方案執(zhí)行

3.1 初版方案

查詢了一下栋豫,對應(yīng)圖片+音頻合成視頻,這樣的音畫合成的操作嫩絮,七牛并沒有提供API~
所以只能服務(wù)端采用萬能的多媒體處理工具:ffmpeg 了摔踱,整體方案如下


ppt錄制ffmpeg處理方案流程.png

可以看到上述方案蛹批,有兩個關(guān)鍵操作:

關(guān)鍵操作 描述 如何觸發(fā)
音畫合成 圖片+音頻合成視頻 客戶端接口觸發(fā),用戶每錄一段語音猪勇,則服務(wù)端立馬調(diào)異步任務(wù)進行音畫合成
視頻mp4拼接 不同的視頻片段拼接成一整段視頻 客戶端接口觸發(fā)泣刹,用戶點擊預(yù)覽或提交審核寡键,服務(wù)端檢查所有語音片段是否音畫合成完畢西轩,條件符合則進行視頻mp4拼接

注意马僻,七牛提供了視頻mp4拼接的接口韭邓,但是經(jīng)過實踐诗力,用ffmpeg進行本地視頻mp4拼接沒有任何問題袜茧,并且速度很快俺夕,所以這里所有操作都用 本地 ffmpeg 來進行

ffmpeg 不具體介紹映九,詳情可自行g(shù)oogle:

官網(wǎng):https://ffmpeg.org/

參數(shù)詳解:https://zhuanlan.zhihu.com/p/31674583

具體ffmpeg的命令執(zhí)行操作捌议,第一版的執(zhí)行如下:

關(guān)鍵操作 描述 ffmpeg操作和參考
音畫合成 圖片+音頻合成視頻 ffmpeg -i 1976.aac -i mulan.jpg -acodec aac -strict -2 -vcodec libx264 -ar 22050 -ab 128k -ac 2 -pix_fmt yuvj420p -y conf_liutao_test1.mp4
參考來源:https://blog.51cto.com/cjxkaka/1569109
視頻mp4拼接 不同的視頻片段拼接成一整段視頻 如下
$ cat mylist.txt
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'

$ ffmpeg -f concat 
-i mylist.txt 
-c copy output

不同的視頻片段拼接成一整段視頻
參考來源:我是Stack Overflow鏈接
參考上面 Stack Overflow回答中”Jack Miller“ 的回答

3.2 遇到的問題和優(yōu)化

問題1. 音畫合成的視頻荞雏,在有些瀏覽器中無法拖動進度條

咨詢了人森導(dǎo)師手哥悦陋,他給我介紹了一個工具:mediainfo,該工具可以查看視頻詳情筑辨,如音軌(Audio)和畫面(Video)的時長俺驶,通過該工具可以看到通過第一版操作音畫合成的視頻,畫面時長只有40ms棍辕,然而音軌時長卻有7s暮现,這里存在嚴(yán)重的不同步还绘,因此在有些瀏覽器(safari)中并不能正常拖動進度條播放:


quiz_audioD_videoD.png

問題1的解決辦法

參考:Combine one image + one audio file to make one video using FFmpeg

中"community wiki"的回答,使用如下ffmpeg命令可以正常生成Video_Duration和Audio_Duration接近的視頻

ffmpeg -loop 1 -i xuanwu.jpg 
-i 1.aac 
-c:v libx264 -tune stillimage 
-c:a aac -b:a 192k -pix_fmt yuvj420p 
-shortest liutao_test_2.mp4

問題2:將不同的音畫合成后的視頻片段拼接起來后生成的 最終課程錄制視頻栖袋,會有音畫不同步的問題

現(xiàn)象是明明是第一個PPT的錄音拍顷,畫面已經(jīng)翻到PPT第二頁了,錄音還在播放第一頁PPT尾段的錄制語音

原因:通過 mediainfo 查看最后生成的 最終拼接視頻塘幅,發(fā)現(xiàn)還是存在 Video_Duration和Audio_Duration 不一致的問題

應(yīng)該是第一步音畫合成的視頻片段本身就有 Video_Duration和Audio_Duration 不完全一致昔案,將他們拼接起來后,是音軌和畫面軌道分別拼接电媳,最后兩條軸出現(xiàn)了不一致的問題爱沟。

因此,我們需要在第一步音畫合成的時候做處理匆背,讓 Video_Duration和Audio_Duration 保持嚴(yán)格一致或盡量接近

問題2的解決辦法

在音畫合成后呼伸,多一步操作,對合成的視頻片段钝尸,進行人為剪裁~讓視頻的 Video_Duration和Audio_Duration 保持一致:

ffmpeg -i input.mp4 
-ss 00:00:00 
-t 00:00:11.72 
-acodec aac -vcodec h264 
-strict -2 cut_output.mp4

如此生成的視頻 Video_Duration和Audio_Duration 不會有太大差距括享。

問題3:安卓端的播放器,播放合成的課程視頻珍促,依然無法拖動視頻的進度條

和安卓端同學(xué)溝通后铃辖,定位問題是視頻缺少關(guān)鍵幀,需要為視頻加入關(guān)鍵幀

問題3的解決辦法

參考:https://codeday.me/bug/20180927/259812.html

在音畫合成截斷猪叙,就針對視頻插入關(guān)鍵幀娇斩,關(guān)鍵命令:

ffmpeg -x264-params keyint=1:scenecut=0

上面的keyint=1表示每隔1幀插入設(shè)置一個關(guān)鍵幀

問題4:音畫合成的速度特別慢,音畫合成生成的文件也特別的大

首先觀察現(xiàn)象穴翩,發(fā)現(xiàn) 圖片大小為 212k犬第,音頻 .aac 文件大小為 132k,生成的視頻文件居然會是540k

懷疑是幀率問題芒帕,google了一下歉嗓,ffmpeg指令如果不人為設(shè)定幀率,默認(rèn)幀率為25背蟆,而我們音畫合成的視頻就是一張圖片鉴分,并不需要太高的幀率,這個地方應(yīng)該可以優(yōu)化下

問題4的解決辦法

參考:https://zhuanlan.zhihu.com/p/31674583

經(jīng)過人為設(shè)置幀率為1带膀,生成文件大小優(yōu)化為356k

人為設(shè)置幀率為1的關(guān)鍵指令如下:

ffmpeg -r 1

同時志珍,寫了個小腳本,做了下實驗驗證垛叨,人為設(shè)置幀率伦糯,也大大降低了處理速度:

實驗:對比使用 -r 2 設(shè)置幀率(fps) 來對靜態(tài)圖的mp4處理速度和大小進行優(yōu)化
第一組:幀率使用默認(rèn)值為25的處理:
Array
(
    [command] => ffmpeg -loop 1 -i mulan.jpg -i 1_min.aac -c:v libx264 -c:a aac -b:a 64k -pix_fmt yuvj420p -shortest liutao_test_1min_64k.mp4
    [spend] => 46401.793956757ms
)
第二組:幀率認(rèn)為設(shè)定為2的處理(使用 命令參數(shù) -r 2 認(rèn)為指定幀率為2):
Array
(
    [command] => ffmpeg -loop 1 -i mulan.jpg -i 1_min.aac -r 2 -c:v libx264 -c:a aac -b:a 64k -pix_fmt yuvj420p -shortest liutao_test_1min_64k_r2.mp4
    [spend] => 21741.201877594ms
)
生成文件大小的對比
[med@qa liutao]$ du -ak liutao_test_1min_64k.mp4 liutao_test_1min_64k_r2.mp4
1404    liutao_test_1min_64k.mp4
548 liutao_test_1min_64k_r2.mp4

從上面的實驗看起來,針對1分鐘的音頻,人為設(shè)置幀率為2使得處理耗時降低了至少50%舔株,生成文件大小降低了近60%

問題5:音畫合成后的視頻莺琳,截斷后又丟失了關(guān)鍵幀

音畫合成后的視頻,是帶有關(guān)鍵幀信息的载慈,為何截斷后又丟失了關(guān)鍵幀惭等?

經(jīng)過仔細(xì)對比,發(fā)現(xiàn)音畫合成和截斷的命令办铡,有著細(xì)微差距

1,音畫合成:
ffmpeg -loop 1 
-i mulan.jpg 
-i 2191.aac 
-r 1 
-c:v libx264 -x264-params keyint=1:scenecut=0 
-c:a aac 
-b:a 32k -pix_fmt yuvj420p  
-shortest 
liutao_test_2191_mulan_r1_key1.mp4
2辞做,截斷:
ffmpeg -i output1.mp4 
-ss 00:00:00 
-t 00:00:06.80 
-acodec aac 
-vcodec h264 
-strict -2 output1_cut.mp4

仔細(xì)觀察上面兩個命令,經(jīng)過google寡具,發(fā)現(xiàn) 【-c:a】和【-acodec】是一個意思秤茅,表示音頻編碼方式,【-c:v】和【-vcodec】是一個意思童叠,表示視頻編碼方式

這里兩個指令的 視頻編碼方式框喳,一個指定的使用 libx264,一個使用h264, 懷疑是這里的不一致導(dǎo)致關(guān)鍵幀丟失

經(jīng)過試驗厦坛,發(fā)現(xiàn)猜測正確五垮。

問題5的解決辦法:

將音畫合成和視頻截斷的音頻解碼方式統(tǒng)一為 libx264,就能保證截斷后視頻的關(guān)鍵幀不丟失:

1,音畫合成:
ffmpeg -loop 1 
-i mulan.jpg 
-i 2191.aac 
-r 1 
-c:v libx264 -x264-params keyint=1:scenecut=0 
-c:a aac 
-b:a 32k -pix_fmt yuvj420p  
-shortest 
liutao_test_2191_mulan_r1_key1.mp4
2,截斷:
ffmpeg -i output1.mp4 
-ss 00:00:00 
-t 00:00:06.80 
-acodec aac 
-vcodec libx264 -x264-params keyint=1:scenecut=0 
-strict -2 output1_cut.mp4

3.3 最終的視頻處理命令

三個步驟:

  1. 音畫合成杜秸,圖片+音頻合成視頻
ffmpeg -loop 1 
-i mulan.jpg 
-i 2191.aac 
-r 1 
-c:v libx264 -x264-params keyint=1:scenecut=0 
-c:a aac 
-b:a 32k 
-pix_fmt yuvj420p  
-shortest liutao_test_2191_mulan_r1_key1.mp4

該指令人為設(shè)置合成幀率為1放仗,降低處理耗時和生成文件大小,
人為設(shè)置關(guān)鍵幀間隔為每間隔1幀設(shè)置一個,解決安卓RN播放無法拉動進度條的問題

  1. 對音畫合成后的視頻片段進行截斷
ffmpeg 
-ss 00:00:00 
-t 00:00:20.096 
-accurate_seek 
-i liutao_test_pre_2191.mp4 
-acodec aac 
-vcodec libx264 -x264-params keyint=1:scenecut=0 
-strict -2 
liutao_test_final_2191.mp4

參考:我是CSDN博客鏈接
截斷是為了保證音軌長度和畫面軌道長度
盡量保持一致撬碟,杜絕拼接后的音畫不同步問題

  1. 視頻mp4拼接,不同的視頻片段拼接成一整段視頻
$ cat mylist.txt
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'

$ ffmpeg -f concat 
-i mylist.txt 
-c copy output

參考來源:我是Stack Overflow鏈接
參考上面 Stack Overflow回答中”Jack Miller“ 的回答

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末诞挨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子呢蛤,更是在濱河造成了極大的恐慌惶傻,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件顾稀,死亡現(xiàn)場離奇詭異达罗,居然都是意外死亡坝撑,警方通過查閱死者的電腦和手機静秆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來巡李,“玉大人抚笔,你說我怎么就攤上這事∏壤梗” “怎么了殊橙?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我膨蛮,道長叠纹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任敞葛,我火速辦了婚禮誉察,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘惹谐。我一直安慰自己持偏,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布氨肌。 她就那樣靜靜地躺著鸿秆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪怎囚。 梳的紋絲不亂的頭發(fā)上卿叽,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音恳守,去河邊找鬼附帽。 笑死,一個胖子當(dāng)著我的面吹牛井誉,可吹牛的內(nèi)容都是我干的蕉扮。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼颗圣,長吁一口氣:“原來是場噩夢啊……” “哼喳钟!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起在岂,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤奔则,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蔽午,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體易茬,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年及老,在試婚紗的時候發(fā)現(xiàn)自己被綠了抽莱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡骄恶,死狀恐怖食铐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情僧鲁,我是刑警寧澤虐呻,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布象泵,位于F島的核電站,受9級特大地震影響斟叼,放射性物質(zhì)發(fā)生泄漏偶惠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一朗涩、第九天 我趴在偏房一處隱蔽的房頂上張望洲鸠。 院中可真熱鬧,春花似錦馋缅、人聲如沸扒腕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瘾腰。三九已至,卻和暖如春覆履,著一層夾襖步出監(jiān)牢的瞬間蹋盆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工硝全, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留栖雾,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓伟众,卻偏偏與公主長得像析藕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子凳厢,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 教程一:視頻截圖(Tutorial 01: Making Screencaps) 首先我們需要了解視頻文件的一些基...
    90后的思維閱讀 4,695評論 0 3
  • 最近學(xué)習(xí)播放器的一些東西账胧,所以接觸了ffmpeg,看源碼的過程中,就想了解一下ffplay是怎么處理音視頻同步的先紫,...
    smm987閱讀 4,411評論 0 5
  • ### YUV顏色空間 視頻是由一幀一幀的數(shù)據(jù)連接而成治泥,而一幀視頻數(shù)據(jù)其實就是一張圖片。 yuv是一種圖片儲存格式...
    天使君閱讀 3,282評論 0 4
  • 0 概述 FFmpeg是一套領(lǐng)先的音視頻多媒體處理開源框架遮精,采用LGPL或GPL許可證居夹。它提供了對音視頻的采集、編...
    但行耕者閱讀 6,808評論 0 19
  • 我近期的目標(biāo)是讓兒子快樂學(xué)習(xí)本冲、提高的學(xué)習(xí)熱情和書寫的認(rèn)真准脂,提升學(xué)習(xí)成績,各科成績達(dá)到95分眼俊,為小升初打下堅實的基礎(chǔ)...
    歸韻閱讀 117評論 0 3