前言
最近在公司做一些視訊處理的task,遇到了一個需求,是把MP4視訊裡的音訊提取成AAC格式。
當時的第一感覺就是很簡單,直接使用ffmpeg -i source.mp4 -vn -acodec copy sound.aac
就好。
但是發現這樣是有問題的,其最終AAC的duration
和MP4的duration
完全不一樣。如圖:
網上的方法也都試了,但是都無法解決這個問題。
分析 / 解決
後來經過測試,發現不同的位元率(bit rate),最終的生成的AAC Duration是不一樣的。
但是我怎麼知道這個位元率的值是多少呢?所以我從頭縷了一下。
首先MP4的視訊檔案我們是從Webm格式轉過來的,而Webm視訊我們又是基於MediaRecorder來的。
我又重新看了一下MediaRecorder API
,發現其中有這樣的屬性:
audioBitsPerSecond
: 指定音訊的位元率
OK找到了,改了程式碼,對MediaRecorder
介面增了audioBitsPerSecond
屬性,值設定了128000
,也就是128K
然後使用下面的命令轉化下,看看結果:
ffmpeg -i source.mp4 -vn -acodec aac -b:a 128k -y sound.aac
複製程式碼
發現情況並沒有得到改善...
後來想了一下,會不會是因為雖然使用了恆定位元率,但是還是會有一定的浮動,於是我把128k
改為200k
嘗試下:
不僅沒解決,反而又增加了duration
在接近放棄的時候,rurico提供了一個思路,讓我嘗試下libfdk_aac
編碼器。於是經過重新編譯FFmpeg來安裝libfdk_aac
編碼器(FFmpeg安裝額外編碼器需要重新編譯)。
成功了...
靜態編譯FFmpeg / 自動化
但是這只是在MAC上成功,我需要讓其在Ubuntu
上跑起來,但是一想到,在Ubuntu Docker
上編譯整個FFmpeg
就頭皮發麻。(我花了4個小時的時間去嘗試在Ubuntu上編譯帶有libfdk_aac的FFmpeg,最終失敗告終。)
下班回家後吃完飯後,又在網上重新查了下ubuntu build ffmpeg
,發現了靜態編譯
的字樣。茅塞頓開
於是在網上搜了下有沒有現成的靜態編譯好的FFmpeg,發現有是有,但是因為libfdk_aac的LICENSE規定,普遍都沒有把libfdk_aac編譯進去。
於是在github上找到一個開源的FFmpeg靜態編譯專案:ffmpeg-static
經過測試發現沒問題,但是因為在國內,每次下載、安裝、編譯都很慢,於是想到gitlab有免費的runner
可以使用。於是在gitlab建了一個專案,用於自動編譯。
只需要在專案里加上.gitlab-ci.yml
就好:
image: ubuntu:18.04
stages:
- build
build-ubuntu:
stage: build
script:
- apt-get update
- apt-get install -yq bzip2 xz-utils perl tar wget git bc
- apt-get install -yq autoconf automake build-essential cmake curl frei0r-plugins-dev gawk libfontconfig-dev libfreetype6-dev libopencore-amrnb-dev libopencore-amrwb-dev libsdl2-dev libspeex-dev libtheora-dev libtool libva-dev libvdpau-dev libvo-amrwbenc-dev libvorbis-dev libwebp-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev libxvidcore-dev lsb-release pkg-config texi2html yasm
- git clone https://github.com/BlackHole1/ffmpeg-static
- cd ffmpeg-static
- chmod 777 *
- ./build-ubuntu.sh -B
artifacts:
name: build
paths:
- ./ffmpeg-static/bin/*
複製程式碼
然後push到gitlab,自動觸發ci。半個小時後,得到結果:
gitlab project: gitlab.com/BlackHole1/…