用Python處理視訊

爾文發表於2014-02-10

Stickyworld 的網頁應用已經支援視訊撥放一段時間,但都是通過YouTube的嵌入模式實現。我們開始提供新的版本支援視訊操作,可以讓我們的使用者不用受制於YouTube的服務。

我過去曾經參與過一個專案,客戶需要視訊轉碼功能,這實在不是個容易達成的需求。需要大量的讀取每一個視訊、音訊與視訊容器的格式再輸出符合網頁使用與喜好的視訊格式。

考慮到這一點,我們決定將轉碼的工作交給 Encoding.com 。這個網站可以免費讓你編碼1GB大小的視訊,超過1GB容量的檔案將採取分級計價收費。

開發的程式碼如下,我上傳了一個178KB容量的兩秒視訊來測試程式碼是否成功運作。當測試過程沒有發生任何的例外錯誤後,我繼續測試其它更大的外部檔案。

 

階段一:使用者上傳視訊檔案

現在這的新的程式碼段提供了一個基於 HTML5且可以快速上手的 的上傳機制。用CoffeeScript撰寫的程式碼,可以從客戶端上傳檔案到伺服器端。

最好可以通過 (“slide_file”).files 且經由獨立的POST上傳每個檔案,而不是由一個POST需求上傳所有檔案。稍後我們會解釋這點。

 

階段二:驗證並上傳至 Amazon S3

後端我們執行了Django與RabbitMQ。主要的模組如下:

我建立了兩個模組:SlideUploadQueue 用來儲存每一次上傳的資料,SlideVideoMedia 則是用來儲存每個要上傳影片的資料。

我們的模組皆使用 filename_sanitiser。FileField 自動的將檔名調整成 <model>/<uuid4>.<extention> 格式。整理每個檔名並確保其獨一性。我們採用了有時效性簽署的網址列讓我們可以掌控哪些使用者在使用我們的服務,使用了多久。

拿來測試的檔案 testing.mov 將會轉換成以下網址:https://our-bucket.s3.amazonaws.com/slideuploadqueue/3fe27193-e87f-4244-9aa2-66409f70ebd3.mov 並經由Django Storages 模組上傳。

我們通過 Magic 驗證從使用者端瀏覽器上傳的檔案。Magic可以從檔案內容偵測是何種型別的檔案。

如果檔案型別符合MPEG v4 系統或是Apple QuickTime 電影,我們就知道該檔案轉碼不會有太大問題。如果格式不是上述所提的幾種,我們會標誌給使用者知悉。
接著,我們將通過SlideUploadQueue 模組將視訊儲存到佇列併傳送一個需求給 RabbitMQ。因為我們使用了Django Storages 模組,檔案將自動被上傳到 Amazon S3。

階段3:傳送視訊到第三方.

RabbitMQ 將控管 task.delay(slide_upload) 的呼叫。
我們現在只需要傳送視訊檔網址與輸出格式給Encoding.com。該網站會回覆我們一個工作碼讓我們檢查視訊轉碼的進度。

Encoding.com 推薦一些堪用的Python程式,可用來與它們的服務溝通。我修改了模組一些地方,但還需要修改一些功能才能達到我滿意的狀態。以下是修改過後目前正在使用的程式程式碼:

其他待完成事項包括通過HTTPS-only (加密聯機) 使用Encoding.com 嚴謹的SSL驗證,還有一些單元測試。

 

階段4:下載所有新的視訊檔格式

我們有個定期執行的程式,通過RabbitMQ每15秒檢查視訊轉碼的進度:

檢查Encoding.com的響應來驗證每個部分是否正確以利我們繼續下去。

到這裡我們已確認所有事項皆正常,所以我們可以儲存所有的視訊檔了:

階段5:經由HTML5播放視訊檔

在我們的前端網頁已經新增了一個有HTML5的影像單元的網頁。並採用對每個瀏覽器都有最佳支援的video.js來顯示視訊。

在我們的首頁有包含其他相依的檔案:

在Angular.js/JADE-based 框架下的模組,我們引入<video>卷標 與其<source>子卷標。每個視訊檔案都會有縮圖通過<video>卷標的 poster 元件顯示,縮圖的影像是由我們從視訊的前幾秒擷取下來。

還會顯示出我們轉換的每個視訊檔案格式,並使用在<source>標籤。Video.js 會根據使用者使用的瀏覽器決定播放哪種格式的視訊。

我們仍然有許多工作需要完成,建立單元測試與加強和Encoding.com服務溝通的程式。如果你對這些工作感興趣請與我連絡。

相關文章