【串流影音】大家一起來當直播主吧…
前幾年直播一直很熱門,一大票的直播主都紛紛的出現,不管是YouTube的,或者是一些交友APP,甚至是網路購物,之前很有很熱門的賣魚哥-王雷也是帶來了直播帶貨的熱潮。 其實本來是想學學WebRTC的,它主是要基於UDP協定,速度快,但是光看到它要自己編碼,還要裝一些有的沒的,很麻煩,再加上它的Server又不是很容易,最後還是選擇了基於HTTP的HLS協定,也就是大家在一般影音平臺常看到的.m3u8檔,而且nginx直接就支援,馬上難度就降低了許多了,這裡我們使用Docker來安裝nginx-rtmp這個帶有RTMP模組的image檔,安全又快速…
作業環境
項目 | 版本 |
---|---|
macOS | Sonoma 14.7.1 |
FFmpeg | 7.1 |
OrbStack | 1.9.4 |
nginx-rtmp | 1.2.2 |
安裝ffmepg
- 安裝ffmepg主要是要用它來產生.m3u8的功能,也就是.ts檔案的目錄檔…
brew install ffmpeg
下載nginx-rtmp
- 這裡我們使用OrbStack來處理Docker的image檔…
- 不過我想應該還是有很多人裝官方的Docker-Desktop,它是可以切換的…
docker context use orbstack # Switch to OrbStack
docker context use desktop-linux # Switch to Docker Desktop
- 下載這個安裝設定檔docker-compose.yml執行就可以了…
- 下載完成就會出現在OrbStack的列表內了…
services:
nginx-rtmp:
image: tiangolo/nginx-rtmp
restart: always
container_name: nginx-rtmp
ports:
- "1935:1935"
- "8088:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./stat.xsl:/usr/local/nginx/html/stat.xsl
docker-compose up -d
播放串流影片
- 在這裡呢,我們先準備一個在線的影片連接,一個.m3u8網址…
http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8
- 這裡我們可以先使用ffmpeg內的ffplay來播放網路上的m3u8…
- 當然,用其它的支援m3u8的放播器都可以…
ffplay http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8
影片串流
- 接下來要像一般線上的影片一樣串流放送…
- 要先把這個影片下載下來,放到資料夾中…
- 這是一部約10分鐘的短片…
http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4
- 然後利用ffmpeg指令來推動 / 播放串流…
- 在推動的過程中,可以看到.m3u8 / .ts的檔案在產生,然後播完就不見了…
- 其中test目錄名稱,就是m3u8的名字…
ffmpeg -re -stream_loop -1 -i BigBuckBunny.mp4 -c:v copy -c:a copy -f flv rtmp://localhost:1935/live/test
ffplay http://localhost:8088/test.m3u8
ffmpeg
-re # 讀取輸入來源(流)原生的 frame rate
-stream_loop <count> # 循環次數 / -1 (循環)
-i <video> # 輸入來源
-c:v <format> # 影片格式 (copy 代表與來源相同)
-c:a <format> # 聲音格式 (copy 代表與來源相同)
-f <format> # 轉檔格式
rtmp://<url> # 串流URL
加上濾鏡
- 在這裡我們來加上浮水印的功能…
ffmpeg -re -i BigBuckBunny.mp4 -i William.jpg -filter_complex "overlay=W-w" -c:v libx264 -c:a aac -r 30 -preset ultrafast -f flv rtmp://localhost:1935/live/test_logo
ffplay http://localhost:8088/test_logo.m3u8
ffmpeg
re
-i BigBuckBunny.mp4
-i William.jpg # 濾鏡圖片
-filter_complex "overlay=W-w" # 設定影片的濾鏡,加在右上角
-c:v libx264 # 影片轉成h264
-c:a aac # 聲音aac壓縮
-r 30 # 30fps
-preset ultrafast # 編碼速度
-f flv # flv格式
rtmp://localhost:1935/live/test_logo
- 然後也可以來這裡看一下串流的狀態…
http://localhost:8088/stat
串流直播
- 這裡就是我們的重頭戲啦,使用手機上的相機直播…
- 首先,因為是macOS系統,所以是選用AVFoundation來做處理…
- 先使用指令找出能用的WebCamera的編號列表…
- 然後就來直播囉…
ffmpeg -f avfoundation -list_devices true -i ""
ffmpeg -f avfoundation -framerate 30 -video_size 640x480 -i "1" -c:v libx264 -preset ultrafast -f flv rtmp://localhost:1935/live/test_webcam
ffplay http://localhost:8088/test_webcam.m3u8
線上影音
- 相信大家在看線上影音的時候,一定都是可以快轉的嘛…
- 所以這些.ts一定要先轉出來才能有這個功能…
- 我們可以利用指令/程式來處理…
- 然後把轉好的檔案貼到Docker的對應資料夾中…
- 最後記得改nginx.conf,加上hls_cleanup off,不然就只能播一次就會被刪掉了…
- 然後就可以播放了,當然用手機也可以看到的…
ffplay http://localhost:8088/playlist.m3u8
package main
import "os/exec"
func main() {
convertToHLS("BigBuckBunny.mp4", "./hls/")
}
func convertToHLS(inputFile, outputPath string) error {
cmd := exec.Command("ffmpeg",
"-i", inputFile,
"-profile:v", "baseline",
"-level", "3.0",
"-start_number", "0",
"-hls_time", "10",
"-s", "640x480",
"-hls_list_size", "0",
"-f", "hls",
outputPath+"/playlist.m3u8")
return cmd.Run()
}
worker_processes auto;
rtmp_auto_push on;
events {}
rtmp {
server {
listen 1935;
chunk_size 4096; # default 4096
application live {
live on;
interleave on;
# access
allow play 127.0.0.1;
deny play all;
# hls
hls on;
hls_path /tmp/hls;
hls_cleanup off; # 自動刪除關閉
}
}
}
http {
include mime.types;
default_type application/octet-stream;
keepalive_timeout 65;
server {
listen 80;
listen [::]:80;
location / {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /tmp/hls;
}
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root html;
}
}
}
範例程式碼下載
後記
- 總覺得自己技能樹越點越歪了,好像慢慢的往後端去了…
- 其實啊,雖然前端難入門,但是學到後面除了畫面之外,難的就是跟硬體的互動了…
- 但是後端啊,入門容易,就CRUD嘛,但是要學到深的話,除了一大堆的協定之外,還有速度 / 穩定度 / 多人使用的處理,這都是在手機上碰不到的問題,所以啊還是自己要懂一點,也比較可以跟後端的人溝通,不然手機端實在太依靠後端了,很沒有地位啊…