概述
本文介紹谷歌云 Transcoder API 的基本使用,以及應(yīng)用 Transcoder API , Cloud Functions , Cloud Pub/Sub 等服務(wù)搭建自動(dòng)化視頻轉(zhuǎn)碼工作流的通用方案。該方案的架構(gòu)如下圖所示。后面的章節(jié)會(huì)介紹一些關(guān)鍵步驟的實(shí)現(xiàn)方法和示例。
以下為配置自動(dòng)化轉(zhuǎn)碼任務(wù)的主要步驟。
在本地配置谷歌云命令運(yùn)行環(huán)境
在谷歌云對象存儲(chǔ)服務(wù)創(chuàng)建輸入存儲(chǔ)桶和輸出存儲(chǔ)桶
創(chuàng)建轉(zhuǎn)碼 Job Template ,做自定義轉(zhuǎn)碼配置
上傳待轉(zhuǎn)碼視頻文件并提交轉(zhuǎn)碼任務(wù)
輪詢轉(zhuǎn)碼狀態(tài),或者使用消息隊(duì)列接收轉(zhuǎn)碼完成通知
因?yàn)槟壳肮雀柙妻D(zhuǎn)碼服務(wù)暫時(shí)還不支持控制臺(tái)界面話配置,下面的步驟都是使用 REST API 完成。為了生成鑒權(quán)的 OAuth Token ,也需要執(zhí)行命令的環(huán)境安裝谷歌云 gcloud 命令行工具,具體參考[4]Installing Google Cloud SDK
也可以在控制臺(tái) Cloud Shell 內(nèi)執(zhí)行命令,該環(huán)境自帶谷歌云命令行工具。
谷歌云轉(zhuǎn)碼服務(wù)簡介
谷歌云 Transcoder API 目前可以支持如下功能。
● 不同容器格式的輸出 ,包括 MPEG-4 (MP4)、基于 HTTP 的動(dòng)態(tài)自適應(yīng)流式傳輸(DASH,也稱為 MPEG-DASH)和 HTTP Live Streaming (HLS)
● 以不同的比特率和分辨率輸出
● 以編程方式優(yōu)化視頻輸出,包括:
○ 剪裁視頻尺寸
○ 插入重疊式圖片或動(dòng)畫
● 配置低層級編碼參數(shù),例如比特率
● 使用綜合的編輯列表重新合成現(xiàn)有媒體內(nèi)容
● 通過數(shù)字版權(quán)管理 ( DRM ) 系統(tǒng)加密內(nèi)容以保護(hù)內(nèi)容,包括:
○ 適用于 HLS 格式的 FairPlay 流式傳輸
○ 適用于 MPEG-DASH 格式的 PlayReady
○ 適用于 Chromium Web 瀏覽器和 Android 上的 MPEG-DASH 和 HLS 的Widevine
● 插入廣告關(guān)鍵幀以允許視頻播放器客戶端插入廣告
● 使用生成的視頻幀精靈表創(chuàng)建縮略圖。
● 創(chuàng)建作業(yè)模板以保存和重復(fù)使用自定義或復(fù)雜的配置,從而對作業(yè)進(jìn)行轉(zhuǎn)碼
對于轉(zhuǎn)碼的媒體文件,支持如下輸入編碼格式
支持如下輸出編碼格式
開通Transcoder API
可以用下面步驟在谷歌云控制臺(tái)開通 Transcoder API。首先在控制臺(tái)搜索欄搜索 Transcoder API,并進(jìn)入 Transcoder API 管理界面。
在 Transcoder API 管理界面,如果該服務(wù)沒有開通,會(huì)有一個(gè)藍(lán)色 ENABLE 按鈕。點(diǎn)擊此按鈕以開通此服務(wù)。開通服務(wù)并不會(huì)產(chǎn)生任何費(fèi)用。
服務(wù)開通后,可以點(diǎn)擊 MANAGE 按鈕來查看服務(wù)使用狀態(tài)。
創(chuàng)建轉(zhuǎn)碼模板 Job Template
根據(jù)業(yè)務(wù)的需要,參照文檔[3] JobConfig reference來創(chuàng)建 Job Template(轉(zhuǎn)碼模板)。下面為將輸入文件轉(zhuǎn)碼為多碼率 H264 編碼 HLS 視頻流的模板樣例。
附錄B. Job Template 示例(下拉文章)
該示例也可以從 Github 地址下載。
https://github.com/eugeneyu/cloud-demos/blob/master/transcode/transcode-template-multi-bitrate.json
要?jiǎng)?chuàng)建 Job Template,首先配置環(huán)境變量
其中 PROJECT_ID 是谷歌云項(xiàng)目的 ID,LOCATION 是使用轉(zhuǎn)碼服務(wù)的谷歌云區(qū)域,TEMPLATE_ID 是客戶自己定義的轉(zhuǎn)碼模板 ID 。
然后執(zhí)行下面命令來創(chuàng)建 Job Template 轉(zhuǎn)碼模板。
注意,Job Template 不能更新,只能新加,或者對現(xiàn)有的刪除后重建。刪除 Job Template 可以用下面命令。
轉(zhuǎn)碼配置還要注意下面幾點(diǎn)。
● 如果使用 Fragmented MP4 (fmp4) 封裝格式,可以用同一組媒體文件來提供 DASH 和 HLS 流,僅是播放列表內(nèi)容不一樣,這樣可以節(jié)省存儲(chǔ),方便管理。但是要注意,fmp4 封裝不能混裝( multiplex )音頻和視頻流在一個(gè)文件里,而需要把音頻單獨(dú)輸出成一個(gè)文件。
● 如果使用傳統(tǒng)的 TS 封裝格式來提供 HLS 流,要注意可以使用 H264 或 H265 視頻編碼,但是不能使用 VP9 編碼。
提交轉(zhuǎn)碼任務(wù)
轉(zhuǎn)碼任務(wù)配置主要指定輸入文件,輸出路徑,和轉(zhuǎn)碼模板。輸入文件需要是在谷歌云存儲(chǔ)中的媒體文件。
如果提交任務(wù)順利,命令行會(huì)輸出任務(wù)的信息,其中含有如下的任務(wù)名稱。
可以用命令輪詢?nèi)蝿?wù)的執(zhí)行情況,直到任務(wù)完成。
查詢?nèi)蝿?wù)信息可以看到類似下面的輸出。
當(dāng) state 為 RUNNING 時(shí),任務(wù)仍在進(jìn)行。當(dāng)其為 SUCCEEDED 時(shí),表示任務(wù)成功完成。
創(chuàng)建 Pub/Sub 消息隊(duì)列接收轉(zhuǎn)碼完成通知
可以配置轉(zhuǎn)碼任務(wù)將轉(zhuǎn)碼結(jié)果自動(dòng)投遞到谷歌云 Pub/Sub 消息隊(duì)列,來觸發(fā)后續(xù)工作流。首先創(chuàng)建一個(gè) Pub/Sub 的 Topic 來接收消息。
然后在剛創(chuàng)建的 Topic 的詳情頁點(diǎn)擊創(chuàng)建 Subscription ,并選擇 Create subscription。
給 Subscription 命名,其它配置保留缺省值即可。這個(gè) Subscription 可以用來消費(fèi)消息。
在 Subscription 詳情頁,可以點(diǎn)擊 VIEW MESSAGES 按鈕,在控制臺(tái)查看隊(duì)列中的消息。在轉(zhuǎn)碼任務(wù)提交并成功完成后,隊(duì)列中會(huì)添加一條新消息,通知任務(wù)完成。
消息查看界面如下圖。
使用 Cloud Functions 自動(dòng)觸發(fā)轉(zhuǎn)碼任務(wù)
如果想自動(dòng)對新上傳的視頻文件進(jìn)行轉(zhuǎn)碼,使用文件上傳觸發(fā)的 Cloud Functions 是一個(gè)比較合適的選擇。下面步驟介紹如何配置一個(gè)自動(dòng)轉(zhuǎn)碼的 Cloud Functions 云函數(shù)。
首先創(chuàng)建一個(gè) Cloud Functions 實(shí)例。在配置中選擇觸發(fā)項(xiàng)為對象存儲(chǔ)的文件創(chuàng)建事件。
在 Service Account 配置中選擇可以讀寫對應(yīng)對象存儲(chǔ),并執(zhí)行 Transcoder API 的服務(wù)賬號,比如 GCE 缺省服務(wù)賬號。
在其它配置中的環(huán)境變量配置界面,配置如下幾個(gè)環(huán)境變量。這幾個(gè)變量會(huì)被下面的云函數(shù)代碼讀取,來進(jìn)行一些自定義的輸入輸出配置。
注意函數(shù)的觸發(fā)桶( Trigger Bucket )和轉(zhuǎn)碼文件的輸出目的桶( DEST_LOCATION )不要配置成同一個(gè),否則會(huì)導(dǎo)致循環(huán)轉(zhuǎn)碼。
在下面的界面填寫 Cloud Functions 的 Python 代碼和依賴包。
其中,依賴包為
Python 代碼如下。也可以從 https://github.com/eugeneyu/cloud-demos/blob/master/cloud-functions/gcs_start_transcode.py 下載。
from google.auth import compute_engine
import google.auth.transport.requests
import os
import requests
import logging
from flask import abort
PROJECT_ID = os.environ['PROJECT_ID']
PROJECT_LOCATION = os.environ['PROJECT_LOCATION']
DEST_LOCATION = os.environ['DEST_LOCATION']
TEMPLATE_ID = os.environ['TEMPLATE_ID']
def exit_abort():
return abort(500)
def start_transcode(event, context):
bucket_name_input = event['bucket']
object_name_input = event['name']
file_name = os.path.split(object_name_input)[1]
file_name_wo_extension = os.path.splitext(file_name)[0]
cred = compute_engine.credentials.Credentials()
auth_req = google.auth.transport.requests.Request()
cred.refresh(auth_req)
#print(cred.token)
api_url = "https://transcoder.googleapis.com/v1beta1/projects/{}/locations/{}/jobs".format(PROJECT_ID, PROJECT_LOCATION)
headers = {
"Authorization": "Bearer {}".format(cred.token),
"Content-Type": "application/json"
}
test = "gs://{}/{}".format(bucket_name_input, object_name_input)
print("Bucket: {}, inputUri: {}\n".format(bucket_name_input, test))
data = {
"inputUri": "gs://{}/{}".format(bucket_name_input, object_name_input),
"outputUri": "{}/{}/".format(DEST_LOCATION, file_name_wo_extension),
"templateId": "{}".format(TEMPLATE_ID)
}
response = requests.post(url = api_url, headers=headers, json = data)
if not response.ok or "error" in response.text:
logging.error(RuntimeError(response.text))
exit_abort()
response_json = response.json()
print("New job started - Job Name: {}".format(response_json['name']))
部署完云函數(shù)后,可以往輸入桶上傳一個(gè)視頻文件,然后在云函數(shù)詳情頁查看執(zhí)行日志。轉(zhuǎn)碼任務(wù)提交完成后,可以到 Pub/Sub 界面查看轉(zhuǎn)碼完成通知。也可以到對象存儲(chǔ)響應(yīng)輸出目錄查看結(jié)果文件。也可以用瀏覽器或[5] Shaka 播放器測試播放。
使用 Cloud Functions 自動(dòng)發(fā)布轉(zhuǎn)碼后視頻與上一節(jié)步驟類似,可以新建一個(gè) Cloud Functions 云函數(shù),設(shè)置其觸發(fā)源為 Pub/Sub 消息隊(duì)列。根據(jù)轉(zhuǎn)碼任務(wù)的完成消息,可以進(jìn)行將輸出文件移動(dòng)到發(fā)布路徑,并更新媒資系統(tǒng)或內(nèi)容數(shù)據(jù)庫。如果消息隊(duì)列中收到的是轉(zhuǎn)碼失敗消息,則做相應(yīng)的錯(cuò)誤處理和通知,比如將源視頻文件移動(dòng)到單獨(dú)的目錄。對于這些處理本文不提供示例代碼,但是可以參考以下移動(dòng)對象存儲(chǔ)中文件的云函數(shù)。
https://github.com/eugeneyu/cloud-demos/blob/master/cloud-functions/bucket_to_bucket.py