利用ffmpeg在服務器端合成視頻

jopen 12年前發布 | 234K 次閱讀 多媒體處理 FFmpeg

最近在做一個手機app的后端,這個手機app有安卓和ios兩個版本主要面向的是國外用戶。app名字就不透露了,國內外加起來有幾十萬的下載量。這個手機app有一項功能是需要將app錄制的聲音加上幾幅圖片合成視頻,然后上傳到非死book網站上分享給好友觀看。本來這個功能是不需要后端介入的,因為手機上可以自己生成視頻并且搞定上傳就可以了。但由于: 1 android手機需要引入第三方的開源庫ffmpeg,導致手機app的安裝包大小會增大好幾M。 2. 在手機上保存生成視頻的資源文件圖片也會增加一定安裝包的大小。 3. android手機的配置五花八門,在一些配置較低的機型上完成合成視頻的工作非常吃力,效率很低。 基于這些考慮,就把這項工作移到后端來做。

說到多媒體的處理,我一般都用ffmpeg這個開源庫。這個庫有兩個特點。第一是功能很多,第二是支持的多媒體格式很全。這里需要感謝ffmpeg的開源軟件工作者的辛勤工作和無私奉獻。創造了這么好的開源工具給我使用,為我的工作提供了便利。可以從下面的網址了解這個庫:

ffmpeg開源庫的網址: http://ffmpeg.org/

ffmpeg下載網址:http://ffmpeg.org/download.html#releases

ffmpeg文檔網址:http://ffmpeg.org/ffmpeg.html

ffmpeg faq:http://ffmpeg.org/faq.html


初學者可以從這個faq開始學習,因為這個faq講的東西非常具體又詳細。它介紹了ffmpeg的一些基本術語和簡單用法。比如對于多段視頻的合并這個功能,faq里的講解很仔細易懂。它講解了視頻合并分成幾種形式: 一種是多段視頻一段播放完之后再播放一段,這種叫concat。 第二種是將兩個視頻在同一個窗口里播放,類似畫中畫的效果。這種方式叫做overlay。 對于不同的方式都解釋了如何實現。


下面開始解釋我的工作。

首先,我的需求是要將一段音頻和幾張圖片合成一段視頻。這幾張圖片需要采用輪播的方式進行循環的播放。

因此工作的第一步,我要知道這段音頻的播放時間有多長,然后我才能計算出圖片需要循環播放多少次。

用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



 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!