nginx搭建直播rtmp推流,httpflv拉流環境

背景

工作中發現挺多直播CDN在實現httpflv拉流時都沒有使用http chunk編碼,而是直接使用no-content-length的做法。所以想自己搭建一個直播CDN支持 http chunk編碼。

環境搭建

系統環境 Ubuntu 18.04.4 LTS
軟件 nginx-1.18.0
nginx擴展模塊 nginx-http-flv-module

nginx-http-flv-modulex下載

git clone https://github.com/winshining/nginx-http-flv-module.git

nginx配置安裝

./configure --add-module=/home/wanghao/worker/opensourcecode/nginx_module/nginx-http-flv-module
make -j 4 && make install
cd /usr/local/nginx/

nginx.conf配置文件

#user  nobody;
worker_processes  1;

events {
    worker_connections  1024;
}

http { // http拉流的配置
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;
	
    server {
        listen       80;
        server_name  www.wawa.com;

        location /live {
            flv_live on;
        }
    }
}

rtmp {  // rtmp推流的配置
    server {
        listen 1935;
        application myapp{
            live on;
            record off;
        }
    }
}

對於不知道文件長度的情況下(例如直播),nginx默認使用chunked_transfer_encoding來傳輸。 所以,配置文件中不用顯示的去設置

Syntax:	 chunked_transfer_encoding on | off;
Default:chunked_transfer_encoding on;
Context: http, server, location

官方連接請點擊

ffmepg推送本地文件到直播服務器

ffmpeg -re -i q00307z84wz.321002.1.ts -f flv rtmp://192.168.116.130:1935/myapp/123

q00307z84wz.321002.1.ts是一個5分鐘的文件,則ffmpeg大概在5分鐘後退出。

real    5m0.382s
user    0m22.750s
sys     0m8.141s

httpflv拉流

填寫正確的IP地址端口和流ID後進行拉流

# curl -L -v "http://192.168.116.130/live?port=1935&app=myapp&stream=123" -o 1.flv
*   Trying 192.168.116.130...
* TCP_NODELAY set
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 192.168.116.130 (192.168.116.130) port 80 (#0)
> GET /live?port=1935&app=myapp&stream=123 HTTP/1.1
> Host: 192.168.116.130
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.18.0
< Date: Fri, 03 Jul 2020 13:49:52 GMT
< Content-Type: video/x-flv
< Transfer-Encoding: chunked
< Connection: keep-alive
< Expires: -1
<
{ [449 bytes data]
100 1068k    0 1068k    0     0    97k      0 --:--:--  0:00:10 --:--:--  117k

可以在響應頭中看到使用了http chunk協議,且沒有content-length

< Transfer-Encoding: chunked

繼續修改nginx.conf,關閉http chunk編碼

location /live {
    flv_live on;
    chunked_transfer_encoding off;
}

使用curl拉流測試

# curl -L -v "http://192.168.116.130/live?port=1935&app=myapp&stream=123" -o 1.flv
*   Trying 192.168.116.130...
* TCP_NODELAY set
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 192.168.116.130 (192.168.116.130) port 80 (#0)
> GET /live?port=1935&app=myapp&stream=123 HTTP/1.1
> Host: 192.168.116.130
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.18.0
< Date: Fri, 03 Jul 2020 13:59:43 GMT
< Content-Type: video/x-flv
< Connection: keep-alive
< Expires: -1
* no chunk, no close, no size. Assume close to signal end
<
{ [1504 bytes data]
100  668k    0  668k    0     0    98k      0 --:--:--  0:00:06 --:--:--  112k

可以看到已經沒有 "Transfer-Encoding: chunked" 的響應頭部了,仔細觀察,輸出了一行英文

* no chunk, no close, no size. Assume close to signal end

no size 就是沒有content-length
no chunk 就是沒有 Transfer-Encoding: chunked
Assume close to signal end 可以理解爲直播服務器主動關閉socket就代表直播流結束了
但是HTTP協議標準是content-length和Transfer-Encodinge二選一,所以no-centent-length的方案是非標準的。

測試其他直播APP

通過adb logcat抓取快手,鬥魚,虎牙等頭部直播APP的日誌後,找到拉流地址,自己本地用curl拉流也是發現有挺多流都是
no-content-length,Google下得知,使用這種非標準的no-centengt-length的原因是實現簡單。

未完成事項

在拉流http chunk流的時候,使用tcpdump抓包,wireshark分析後,均沒有看到http chunk協議,與網上其他教程不符合。還需要再探索下。

tcpdump -i lo host 192.168.116.130  -nnvv -w live2.pcap

因爲拉流端和nginx服務器同一臺機器,則從本地環回口拉取(lo)抓包,192.168.116.130是本地的內網IP。


作者:feelc
鏈接:https://juejin.im/post/5eff33f3f265da22ee7fa1d2

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章