ffmpeg 用於網路線上轉檔
假設我要做一個視訊網站服務,讓使用者上傳視訊檔供其他人觀賞。 但是顧慮到視訊有著像 rmvb, avi, 3gp, mod, mkv, mp4 等等格式的多樣性,為了讓其他人可以順利地觀賞視訊,故打算將上傳的視訊統一轉成目前使用率最普遍的 mp4 格式。
欲達此目的,最簡單的作法就是上傳完成後,再執行轉檔工具。缺點是轉檔要花點時間,故使用者上傳後不能馬上觀賞轉檔後的 mp4 。不過只要對 CGI 規格有所了解的人,就會知道要實現一邊上傳一邊轉檔的功能,其實是一件簡單的事。
基本概念
基於普遍性,選擇 ffmpeg 為轉檔工具。ffmpeg 的輸入檔名若為 - 號,就會從 stdin 讀取資料。 CGI 這一端只要一邊接收上傳資料,一邊將接收到的資料透過 pipe 寫到 ffmpeg 的 stdin 端即可。概念類似下列的命令列操作:
$ cat uploaded_file | ffmpeg -i - -codec copy output.mp4
只是目前多數的 CGI 實作品(所有的 Web 開發框架或工具,都屬於 CGI 實作品)不會讓使用者接觸到如此「低階」、「原始」的處理步驟。以 PHP 為例, Apache + mod-php 內定的檔案上傳策略就是先把上傳資料儲存為檔案後,才開始執行 PHP script 。在這個過程中,使用者不會接觸到上傳中的資料串流,只會摸到上傳完成後的成品。 所以對透過 mod-php 執行的 PHP script 來說,它只適合這樣做:
$uploadfile = '/uploaded/files_' . $rnd; move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile) system("ffmpeg -i $uploadfile -codec copy output.mp4");
若是用 CGI 模式執行 PHP script ,要實現一邊上傳一邊轉檔的線上轉檔功能就簡單了。你只需要拋開 Web 開發框架帶給你的思想制約,就會發現這件事。
ffmpeg
安裝 ffmpeg 套件。在 Debian 或 Ubuntu 下,需下列套件:
- ffmpeg
- libavcodec-extra-52 或 libavcodec52 或 libavcodec 或 libavcodec-extra-53 。 不同的套件名稱提供不同的 codec 。
ffmpeg 有新舊版本不同的參數語法,請執行 ffmpeg -h
自行查看。
此外,ffmpeg 在編譯時就會決定它可用的 codec 內容。
不同的 Linux 散佈套件所啟用的 codec 也會不同,也要自己查看。
有兩種參數語法可以查看你安裝的 ffmpeg 支援的 codec 。
第一種是: ffmpeg -formats
;有些版本則是用第二種: ffmpeg -codecs
。
查詢結果第一欄的 D 表示此 codec 可用於解碼(Decode)。
第二欄的 E 表示此 codec 可用於編碼(Encode)。
第三欄的 V 或 A 表示此 codec 用於處理視訊(video)或音訊(audio)。
以 MP4 為例,建議的 codec 組合是: -vcodec libx264 -acodec libvo_aacenc
。
不過並非每一種 ffmpeg 編成品都提供 libx264 和 libvo_aacenc 這兩種編碼器。
可參考「ffmpeg 轉檔與影片連接範例」了解其他 ffmpeg 的使用範例。
PHP 實作
ffmpeg.cgi 是用於線上轉檔的 PHP script 。這不一定要用 PHP 實作,你有興趣的話,會發現用 C 語言來寫也不難。
ffmpeg.cgi 預設的輸出目錄是 /tmp ,轉檔後的視訊檔名的主檔名同上傳檔的主檔名。 例如上傳 123.avi ,那麼轉檔後的視訊檔會是 /tmp/123.mp4 。 當然實務上不會這麼直接地儲存,這就看實作者的設計了。
查看 Apache 的組態文件,啟用 CGI 設定。 將 ffmpeg.cgi 放在 CGI 目錄下。 ffmpeg.cgi 要設置可執行屬性,以便執行。(因為要用 CGI 模式執行,所以 Debian/Ubuntu 必須安裝 php5-cli 套件) 根據你安裝的 ffmpeg 的參數語法與可用的 codec 內容,修改 ffmpeg.cgi 中呼叫 ffmpeg 的參數內容。
ffmpeg.html 則是示範用的檔案上傳頁面。
選擇一個檔案上傳, ffmpeg.cgi 就會一邊讀取上傳的內容,一邊將已讀取的資料內容交給 ffmpeg 轉檔。 轉換後的新檔會放在 /tmp 目錄下 (可以修改參數的儲存路徑)。
基本上,除非你是區域網路上傳,否則在一般 Internet 環境下,轉檔速度通常快過上傳速度。所以上傳完成時,同時就完成傳換格式的工作了。