最近在作一個手機app的後端,這個手機app有安卓和ios兩個版本主要面向的是國外用戶。app名字就不透露了,國內外加起來有幾十萬的下載量。這個手機app有一項功能是須要將app錄製的聲音加上幾幅圖片合成視頻,而後上傳到facebook網站上分享給好友觀看。原本這個功能是不須要後端介入的,由於手機上能夠本身生成視頻而且搞定上傳就能夠了。但因爲: 1 android手機須要引入第三方的開源庫ffmpeg,致使手機app的安裝包大小會增大好幾M。 2. 在手機上保存生成視頻的資源文件圖片也會增長必定安裝包的大小。 3. android手機的配置五花八門,在一些配置較低的機型上完成合成視頻的工做很是吃力,效率很低。 基於這些考慮,就把這項工做移到後端來作。 html
說到多媒體的處理,我通常都用ffmpeg這個開源庫。這個庫有兩個特色。第一是功能不少,第二是支持的多媒體格式很全。這裏須要感謝ffmpeg的開源軟件工做者的辛勤工做和無私奉獻。創造了這麼好的開源工具給我使用,爲個人工做提供了便利。能夠從下面的網址瞭解這個庫: android
ffmpeg開源庫的網址: http://ffmpeg.org/ ios
ffmpeg下載網址:http://ffmpeg.org/download.html#releases
git
ffmpeg文檔網址:http://ffmpeg.org/ffmpeg.html shell
ffmpeg faq:http://ffmpeg.org/faq.html
後端
初學者能夠從這個faq開始學習,由於這個faq講的東西很是具體又詳細。它介紹了ffmpeg的一些基本術語和簡單用法。好比對於多段視頻的合併這個功能,faq裏的講解很仔細易懂。它講解了視頻合併分紅幾種形式: 一種是多段視頻一段播放完以後再播放一段,這種叫concat。 第二種是將兩個視頻在同一個窗口裏播放,相似畫中畫的效果。這種方式叫作overlay。 對於不一樣的方式都解釋瞭如何實現。 app
下面開始解釋個人工做。 iphone
首先,個人需求是要將一段音頻和幾張圖片合成一段視頻。這幾張圖片須要採用輪播的方式進行循環的播放。 工具
所以工做的第一步,我要知道這段音頻的播放時間有多長,而後我才能計算出圖片須要循環播放多少次。 post
用ffmpeg能夠計算音頻的播放長度,方法很簡單直接運行ffmpeg -i 文件名
$ ffmpeg -i robot.mp3 ffmpeg version 0.11.1.git Copyright (c) 2000-2012 the FFmpeg developers built on Aug 10 2012 19:49:22 with gcc 4.1.2 (GCC) 20070115 (prerelease) (SUSE Linux) configuration: --disable-yasm --enable-libmp3lame --enable-libfaac --enable-libx264 --enable-gpl --enable-nonfree --enable-shared libavutil 51. 66.101 / 51. 66.101 libavcodec 54. 49.100 / 54. 49.100 libavformat 54. 22.101 / 54. 22.101 libavdevice 54. 2.100 / 54. 2.100 libavfilter 3. 5.102 / 3. 5.102 libswscale 2. 1.101 / 2. 1.101 libswresample 0. 15.100 / 0. 15.100 libpostproc 52. 0.100 / 52. 0.100 [mp3 @ 0x80744f0] max_analyze_duration 5000000 reached at 5015510 Input #0, mp3, from 'robot.mp3': Metadata: major_brand : M4A minor_version : 0 compatible_brands: M4A mp42isom encoder : Lavf54.22.101 Duration: 00:00:11.78, start: 0.000000, bitrate: 128 kb/s Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16, 128 kb/s
輸出的結果的Duration就是robot.mp3的播放長度,格式爲 xx:xx:xx:xx, 單位是 「小時:分鐘:秒:百分之一秒」。 經過加權想加便可獲得播放的長度。上文中例子的音頻長度爲11.78s。
工做的第二步是須要計算出整段視頻一共有多少幀。計算方法是:
總幀數 = duration * fps 。
duration是第一步獲得的音頻長度,fps是視頻每秒的幀數。
工做第三步將全部的圖片文件拷貝到一個臨時目錄裏,並經過循環的複製圖片製做出視頻的每一幀圖片。例如圖片的素材是image0.jpg image1.jpg image2.jpg, 須要拷貝到一個臨時文件夾,並臨時生成
image0000.jpg image0001.jpg image0002.jpg image0003.jpg image0004.jpg image0005.jpg 等等。
工做第四步就是要合成視頻了。能夠經過ffmpeg對圖片和音頻文件進行合併。進行合併的方法爲:
ffmpeg -threads2 -y -r 10 -i /tmpdir/image%04d.jpg -i audio.mp3 -absf aac_adtstoasc output.mp4
參數的解釋含義:
-threads 2 以兩個線程進行運行, 加快處理的速度。
-y 對輸出文件進行覆蓋
-r 10 fps設置爲10幀/秒
-i /tmpdir/image%04d.jpg 輸入圖片文件,圖片文件保存爲 image0001.jpg image0002.jpg ....
-i audio.mp3 輸入的音頻文件
-absf aac_adtstoasc 將結果的音頻格式轉爲faac格式時須要這個選項。將音頻格式轉爲faac是由於在iphone上某些音頻格式的視頻沒法播放,例如mp3. 但faac格式的音頻的視頻在iphone上能夠播放。-absf 的意思是設置一個bitstream filter進行某些轉換。能夠用ffmpeg -bsfs 查看全部支持的bitstream filter。 bitstream filter和 aac_adtstoasc的具體含義我也說不上。可是若是不用這個選項又會致使轉換失敗。
能夠從這個連接下載一個合成的視頻的例子:https://dl.dropbox.com/u/35106490/rap.mp4