如何用Serverless實現視訊剪輯批量化、自動化與定製化

Woody發表於2022-03-23

前言

1.jpg

開始講之前先解決大家看到這個標題時心裡的3個疑惑:

  1. 視訊剪輯不是用Adobe的軟體就可以做了嗎?
  2. 為什麼要用Serverless?
  3. 如何寫程式碼做視訊剪輯?

首先說說哪些視訊剪輯場景是Adobe等軟體無法完成的

大家平常接觸到的視訊剪輯通常都是使用Premiere,AE等這類專業工具來完成視訊剪輯。他們能完成一些複雜的效果,比如做宣傳視訊,廣告視訊等。

但有些企業在某些業務場景下是期望能批量且自動化的完成視訊剪輯。

比如以下幾種場景:

  1. 假設學校期望能在學生上完網課之後馬上呈現所有學生學習過程中的精彩視訊,配上學校的logo和宣傳語等,讓學生一鍵分享自己的成果。假設有1萬個學生,需要為每個學生製作獨一無二的視訊,所以需要批量且自動化的完成1萬個不同的視訊剪輯。
  2. 某次營銷活動中,需要為不同的使用者生成不同的頭像視訊來吸引使用者參與。每個使用者的頭像都是獨一無二的,生成的視訊也是獨一無二的,使用者可能成千上萬,因此自動化完成是必須的條件。
  3. 網紅運營公司期望能給所有主播生成統一的營業視訊。可能有100個主播,專門找一個人剪輯100個視訊好像勉強能接受,但如果每週都要剪一次不同的視訊呢?所以自動化,批量和可定製化的剪輯就成了主要需求。

以上的場景中有三個特點:

  1. 批量
  2. 自動化
  3. 可定製

對於符合以上特點的場景,是傳統的視訊剪輯工具或者模版化的視訊處理軟體無法輕鬆完成的。

再來說說為什麼用Serverless

因為視訊剪輯這樣的業務有幾個特點:

  • 使用時段集中。
  • 計算量大。

單獨購買高規格的伺服器利用率很低,買便宜的伺服器計算能力又跟不上。

因此Serverless按量計費的特點,以及高效能的計算能力,完美匹配了這樣的需求場景。

既能達到100%的利用率,又能按量使用它的高效能運算能力。

同時,Serverless擁有多變的可程式設計環境,可以使用熟悉的程式語言,靈活性很高。

最後說說如何寫程式碼做視訊剪輯

本文章提到的所有視訊剪輯的功能,都是用FFmpeg這個工具,所以先給大家講講什麼是FFmpeg。

FFmpeg是一個用來做視訊處理的開源工具,它有非常強大的功能,它支援視訊剪輯、視訊轉碼、視訊編輯、音訊處理、新增文字、視訊拼接、拉流推流直播等功能。

我們通過不同的FFmpeg命令就可以程式設計完成不同的視訊剪輯功能,組合編排起來,就可以應對各種批量自動化的場景了。

視訊剪輯批量化、自動化與定製化實踐

常見的視訊剪輯場景主要包含以下幾種:

  1. 視訊轉碼
  2. 視訊裁剪
  3. 視訊加文字
  4. 視訊加圖片
  5. 視訊拼接
  6. 視訊加音訊
  7. 視訊轉場
  8. 視訊特效
  9. 視訊加速慢速播放

接下來給大家展示一些具體的FFmpeg命令例子,如果你在本地安裝了FFmpeg,也可以在本地執行這些命令。關於怎麼安裝FFmpeg,可以去看官網的教程。

// 將MOV視訊轉成mp4視訊
ffmpeg -i input.mov output.mp4

// 將原視訊的幀率修改為24
ffmpeg -i input.mp4 -r 24 -an output.mp4

// 將mp4視訊轉為可用於直播的視訊流
ffmpeg -i input.mp4 -codec: copy -bsf:v h264_mp4toannexb -start_number 0 -hls_time 10 -hls_list_size 0 -f hls output.m3u8

// 將視訊分別變為480x360,並把位元速率改400
ffmpeg -i input.mp4 -vf scale=480:360,pad=480:360:240:240:black -c:v libx264 -x264-params nal-hrd=cbr:force-cfr=1 -b:v 400000 -bufsize 400000 -minrate 400000 -maxrate 400000 output.mp4

// 給視訊新增文字,比如字幕、標題等。
// `fontfile`是要使用的字型的路徑,`text`是你要新增的文字,
// `fontcolor`是文字的顏色,`fontsize`是文字大小,`box`是給文字新增底框。
// `box=1`表示enable,`0`表示disable,`boxcolor`是底框的顏色,black@0.5表示黑色透明度是50%,`boxborderw`是底框距文字的寬度
// `x`和`y`是文字的位置,`x`和`y`不只支援數字,還支援各種表示式,具體可以去官網檢視
ffmpeg -i input.mp4 -vf "drawtext=fontfile=/path/to/font.ttf:text='你的文字':fontcolor=white:fontsize=24:box=1:boxcolor=black@0.5:boxborderw=5:x=(w-text_w)/2:y=(h-text_h)/2" -codec:a copy output.mp4

// 給視訊新增圖片,比如新增logo、頭像、表情等。filter_complex表示複合的濾鏡,overlay表示表示圖片的x和y,enable表示圖片出現的時間段,從0-20秒
ffmpeg -i input.mp4 -i avatar.JPG -filter_complex "[0:v][1:v] overlay=25:25:enable='between(t,0,20)'" -pix_fmt yuv420p -c:a copy output.mp4

// 視訊拼接,list.txt裡面按順序放所有要拼接的視訊的檔案路徑,如下。
// 注意,如果視訊的解析度不一致會導致拼接失敗。
ffmpeg -f concat -safe 0 -i list.txt -c copy -movflags +faststart output.mp4
// list.txt的格式如下
file 'xx.mp4'
file 'yy.mp4'

// 視訊加音訊,stream_loop表示是否迴圈音訊內容,-1表示無限迴圈,0表示不迴圈。shortest表示最短的MP3輸入流結束時完成編碼。
ffmpeg -y -i input.mp4 -stream_loop -1 -i audio.mp3 -map 0:v -map 1:a -c:v copy -shortest output.mp4

FFmpeg能做的事情非常多,這裡就不一一講解了。更多的玩法可以在FFmpeg官網上探索探索。

對於音訊的編輯也是同樣的道理,FFmpeg也支援單獨對音訊進行編輯。

如何執行FFmpeg命令

因為Python執行這些命令比較便捷,所以我們可以使用python來執行所有的FFmpeg命令。同時python在serverless雲函式上執行效能也比較好,部署也方便。

通過Python來使用FFmpeg的視訊剪輯程式碼在文章最後有開源連結。並且在官網上也有模版可以直接使用,覆蓋了常見的音視訊剪輯等操作。

這裡就展示一個簡單的呼叫程式碼示例。

child = subprocess.run('./ffmpeg -i input.mov output.mp4',
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE, close_fds=True, shell=True)
if child.returncode == 0:
  print("success:", child)
else:
  print("error:", child)
    raise KeyError("處理視訊失敗, 錯誤: ", child)

在serverless部署

上面提到的常見的視訊剪輯場景我已經實現並開源了,下載程式碼直接部署到serverless就可以使用了。

https://github.com/woodyyan/ffmpeg-composition

https://github.com/woodyyan/ffmpeg-splice

這裡分為了兩個函式,一個負責處理單個視訊,一個負責把多個視訊拼接成一個視訊並配上背景音樂。

目前支援以下功能:

  1. 在視訊中新增文字
  2. 視訊解析度轉換
  3. 在視訊中新增圖片
  4. 視訊拼接
  5. 新增背景音樂

原始碼裡展示的只是常見的一些視訊剪輯場景,大家可以根據自己的業務需要,編寫自己的視訊剪輯邏輯。

Serverless部署

方式一:Github Action自動部署

  1. Fork倉庫。
  2. 在倉庫的Settings-Secrets-Actions中新增TENCENT_SECRET_IDTENCENT_SECRET_KEY兩個金鑰。ID和KEY可以在騰訊雲的訪問控制裡面獲取。
  3. 新增之後,在Action中就可以發起部署了。每次修改程式碼推送後,也會自動觸發Action部署。
  4. 如果需要有一些自定義的配置,請修改serverless.yml。
  5. 雲函式最終會自動部署到TENCENT_SECRET_ID所在的賬號下。

方式二:雲函式控制檯手動部署

  1. 下載程式碼。
  2. 在根目錄把所有檔案和資料夾一起打包成一個ZIP檔案。
  3. 雲函式控制檯,新建一個函式。
  4. 選擇從頭開始:

    1. 選擇python語言。
    2. 上傳ZIP檔案。
    3. 函式記憶體建議選擇較大的記憶體。
    4. 開啟非同步執行。
    5. 執行超時時間根據視訊大小建議設定長一點,比如30秒以上。
    6. 配置觸發器,選擇API閘道器觸發器,關閉整合響應。
  5. 完成部署後,就可以通過API閘道器的URL開始呼叫了。

真實案例回顧

2.png

一個做網課的學校,需要每次在學生上完網課之後把上網課的錄影製作成一段30秒的視訊,作為學生的學習成果。

此案例有幾個關鍵的資訊點:

  1. 通常一堂課有200個學生,需要同時製作200個視訊。
  2. 需要把1小時的上課視訊剪輯成30秒。
  3. 由於每個學生的上課螢幕有所不同,因此錄製的視訊都是不同的。
  4. 最終的成果視訊還需要加上學生的名字和頭像。
  5. 學生結束上課的時間很集中,因此製作視訊時會有短時高併發。
  6. 每次上完課的時候才會需要製作視訊,時段比較固定且集中。

綜合上述特點,用Serverless來做這樣的視訊剪輯帶來了多個好處:

  1. 解決了200個併發的問題,不需要自己搭建過多的伺服器。
  2. 解決了只在發生時段使用的問題,其他時段都沒有成本產生。
  3. 解決了需要較強計算能力快速製作視訊的問題。

下面是這個案例的參考架構圖。

3.png

總結

通過編排、組合、複用上面列舉的各種音視訊剪輯的場景,就能製作出各種各樣想要的效果。

然後把視訊剪輯中用來控制各種效果的引數,變成呼叫服務時傳入的引數,就能實現各種效果的定製化了。

最後再總結一下通過這種寫程式碼的方式完成視訊剪輯的使用場景:

  1. 解決通過修改個別引數來批量製作視訊的場景。
  2. 解決通過使用者觸發來自動化製作視訊的場景。
  3. 解決不同場景需要不同定製化的製作視訊的場景。

同時,利用serverless來完成視訊剪輯,同樣也解決了以下幾個問題:

  1. 因為通常視訊剪輯不是全天執行,利用serverless按量付費的特效能優化成本。
  2. 因為視訊剪輯通常是重計算場景,利用serverless可選的高規格配置來應對這種重計算。
  3. 在批量製作視訊的場景中通常會存在高併發,利用serverless自動彈性伸縮的特效能輕鬆應對高併發。

關於Serverless使用上或者視訊剪輯大家有什麼問題,歡迎給我留言。

相關文章