• 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配置安装

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

    nginx.conf配置文件

    1. #user nobody;
    2. worker_processes 1;
    3. events {
    4. worker_connections 1024;
    5. }
    6. http { ## http拉流的配置
    7. include mime.types;
    8. default_type application/octet-stream;
    9. sendfile on;
    10. keepalive_timeout 65;
    11. server {
    12. listen 80;
    13. server_name www.wawa.com;
    14. location /live {
    15. flv_live on;
    16. }
    17. }
    18. }
    19. rtmp { ## rtmp推流的配置
    20. server {
    21. listen 1935;
    22. application myapp{
    23. live on;
    24. record off;
    25. }
    26. }
    27. }

    对于不知道文件长度的情况下(例如直播),nginx默认使用chunked_transfer_encoding来传输。 所以,配置文件中不用显示的去设置

    1. Syntax: chunked_transfer_encoding on | off;
    2. Default:chunked_transfer_encoding on;
    3. Context: http, server, location

    官方连接请点击

    【免费分享】音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击788280672加群免费领取~

    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分钟后退出。

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

    httpflv拉流

    填写正确的IP地址端口和流ID后进行拉流

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

    可以在响应头中看到使用了http chunk协议,且没有content-length

    < Transfer-Encoding: chunked

    继续修改nginx.conf,关闭http chunk编码

    1. location /live {
    2. flv_live on;
    3. chunked_transfer_encoding off;
    4. }

    使用curl拉流测试

    1. # curl -L -v "http://192.168.116.130/live?port=1935&app=myapp&stream=123" -o 1.flv
    2. * Trying 192.168.116.130...
    3. * TCP_NODELAY set
    4. % Total % Received % Xferd Average Speed Time Time Time Current
    5. Dload Upload Total Spent Left Speed
    6. 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 192.168.116.130 (192.168.116.130) port 80 (#0)
    7. > GET /live?port=1935&app=myapp&stream=123 HTTP/1.1
    8. > Host: 192.168.116.130
    9. > User-Agent: curl/7.58.0
    10. > Accept: */*
    11. >
    12. < HTTP/1.1 200 OK
    13. < Server: nginx/1.18.0
    14. < Date: Fri, 03 Jul 2020 13:59:43 GMT
    15. < Content-Type: video/x-flv
    16. < Connection: keep-alive
    17. < Expires: -1
    18. * no chunk, no close, no size. Assume close to signal end
    19. <
    20. { [1504 bytes data]
    21. 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的方案是非标准的。
    继续深入发现"Connection: keep-alive",一般在直播场景Connection都是close。 HTTP1.1默认使用keep-alive的方式,但是客户端可以在请求的头部中指定使用http短链接的方式。

    1. root@PF1YTXHH-ZTB:/storage/log_live# curl -L -H "Connection:Close" -v "http://192.168.116.130/live?port=1935&app=myapp&stream=123" -o 1.flv
    2. * Trying 192.168.116.130...
    3. * TCP_NODELAY set
    4. % Total % Received % Xferd Average Speed Time Time Time Current
    5. Dload Upload Total Spent Left Speed
    6. 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 192.168.116.130 (192.168.116.130) port 80 (#0)
    7. > GET /live?port=1935&app=myapp&stream=123 HTTP/1.1
    8. > Host: 192.168.116.130
    9. > User-Agent: curl/7.58.0
    10. > Accept: */*
    11. > Connection:Close # 客户端指定使用close的方式
    12. >
    13. < HTTP/1.1 200 OK
    14. < Server: nginx/1.18.0
    15. < Date: Tue, 07 Jul 2020 13:14:43 GMT
    16. < Content-Type: video/x-flv
    17. < Connection: close # 服务端也返回了close
    18. < Expires: -1
    19. <
    20. { [1637 bytes data]
    21. 100 236k 0 236k 0 0 89583 0 --:--:-- 0:00:02 --:--:-- 89583^C

    测试其他直播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。

    原文链接 nginx搭建直播rtmp推流,httpflv拉流环境 - 掘金

  • 相关阅读:
    DDD实战(一):如何设计分层架构?
    QT day3
    mysql连接池和redis连接池
    空间参考简介
    git还原到之前某个版本
    Jetty各版本历史
    mysql——面试题初体验
    2016 ZCTF note3:一种新解法
    深入理解Java消息中间件-ActiveMQ
    Repetition Improves Language Model Embeddings论文阅读笔记
  • 原文地址:https://blog.csdn.net/qq_52703909/article/details/136272712