Docker中使用nginx-rtmp推拉网络摄像头视频流

前言:

该部分比较麻烦,闹腾了好久(ffmpeg推拉流没学过,事实证明依葫芦画瓢是不行滴,后面有时间再学吧),后来借助chatGPT勉强解决,但不是很懂。因个人能力有限,只复述操作过程,欢迎佬指导。

准备工作:

  • 搭建好了docker
  • 下载好nginx-rtmp镜像
  • 网络摄像头

Step1:

测试网络摄像头可用,python代码获取到的视频流如下:

Untitled

Step2:

在流媒体服务器中创建一个文件夹,然后里面添加nginx.conf文件,写此文时内容变成如下(这个是最后比较好的推流的时候自动生成的):

daemon off;

error_log /dev/stdout info;

events {
    worker_connections 1024;
}

rtmp {
    server {
        listen 1935;
        chunk_size 4000;

        application stream {
            live on;

            exec ffmpeg -i rtmp://localhost:1935/stream/$name
              -c:a libfdk_aac -b:a 128k -c:v libx264 -b:v 2500k -f flv -g 30 -r 30 -s 1280x720 -preset superfast -profile:v baseline rtmp://localhost:1935/hls/$name_720p2628kbs
              -c:a libfdk_aac -b:a 128k -c:v libx264 -b:v 1000k -f flv -g 30 -r 30 -s 854x480 -preset superfast -profile:v baseline rtmp://localhost:1935/hls/$name_480p1128kbs
              -c:a libfdk_aac -b:a 128k -c:v libx264 -b:v 750k -f flv -g 30 -r 30 -s 640x360 -preset superfast -profile:v baseline rtmp://localhost:1935/hls/$name_360p878kbs
              -c:a libfdk_aac -b:a 128k -c:v libx264 -b:v 400k -f flv -g 30 -r 30 -s 426x240 -preset superfast -profile:v baseline rtmp://localhost:1935/hls/$name_240p528kbs
              -c:a libfdk_aac -b:a 64k -c:v libx264 -b:v 200k -f flv -g 15 -r 15 -s 426x240 -preset superfast -profile:v baseline rtmp://localhost:1935/hls/$name_240p264kbs;
        }

        application hls {
            live on;
            hls on;
            hls_fragment_naming system;
            hls_fragment 5;
            hls_playlist_length 10;
            hls_path /opt/data/hls;
            hls_nested on;

            hls_variant _720p2628kbs BANDWIDTH=2628000,RESOLUTION=1280x720;
            hls_variant _480p1128kbs BANDWIDTH=1128000,RESOLUTION=854x480;
            hls_variant _360p878kbs BANDWIDTH=878000,RESOLUTION=640x360;
            hls_variant _240p528kbs BANDWIDTH=528000,RESOLUTION=426x240;
            hls_variant _240p264kbs BANDWIDTH=264000,RESOLUTION=426x240;
        }
    }
}

http {
    root /www/static;
    sendfile off;
    tcp_nopush on;
    server_tokens off;
    access_log /dev/stdout combined;

    # Uncomment these lines to enable SSL.
    # ssl_protocols TLSv1.2 TLSv1.3;
    # ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    # ssl_prefer_server_ciphers off;
    # ssl_session_cache shared:SSL:10m;
    # ssl_session_timeout 1d;

    server {
        listen 80;

        # Uncomment these lines to enable SSL.
        # Update the ssl paths with your own certificate and private key.
            
        # listen 443 ssl;
        # ssl_certificate     /opt/certs/example.com.crt;
        # ssl_certificate_key /opt/certs/example.com.key;

        location /hls {
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }
            root /opt/data;
            add_header Cache-Control no-cache;
            add_header Access-Control-Allow-Origin *;
        }

        location /live {
          alias /opt/data/hls;
          types {
              application/vnd.apple.mpegurl m3u8;
              video/mp2t ts;
          }
          add_header Cache-Control no-cache;
          add_header Access-Control-Allow-Origin *;
        }

        location /stat {
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }

        location /stat.xsl {
            root /www/static;
        }

        location /crossdomain.xml {
            default_type text/xml;
            expires 24h;
        }

我的原先版本借鉴了正点原子的文档(我太菜没搞好):

在这里插入图片描述

Step3:

创建一个容器,此处运行命令与上一篇不同:

docker run -it -p 1935:1935 -p 8080:80 --name my-nginx-rtmp-test -v /nginx/nginx.conf:/etc/nginx/nginx.conf -d alfg/nginx-rtmp
  • docker run:这是运行 Docker 容器的命令。

  • it:这两个选项结合了两个标志:

    • i:保持 STDIN 开启,即使未连接。
    • t:分配一个伪终端(tty)。

    它们一起允许你与容器进行交互,使容器在前台运行。

  • p 1935:1935:此标志将主机的端口 1935 映射到容器中的端口 1935。通常用于 RTMP(实时消息传递协议)流媒体。

  • p 8080:80:此标志将主机的端口 8080 映射到容器中的端口 80。通常用于提供 HTTP 流量服务。

  • -name my-nginx-rtmp-test:此标志为容器指定一个名称,这里是 “my-nginx-rtmp-test”。

  • v /nginx/nginx.conf:/etc/nginx/nginx.conf:此标志将本地文件 /nginx/nginx.conf 挂载到容器的路径 /etc/nginx/nginx.conf。这用于提供自定义的 Nginx 配置。

  • d:此标志以后台模式(detached mode)运行容器。

  • alfg/nginx-rtmp:这是用于创建容器的 Docker 镜像的名称。在这种情况下,它是一个配置了 RTMP 支持的 Nginx 服务器镜像。

至此,流媒体服务器创建成功:
在这里插入图片描述

Step4:

推流(这才是难点啊),在推流尝试中出现过如下问题:

  • 视频流是HEVC编码,而FLV格式不支持HEVC编码
  • HEVC找不到参考帧:
  • RTSP流延迟和数据包丢失
  • FLV头更新失败

解决:

在控制台先推流一段时间,看看报了那些错误,然后根据这些错误提示去搜索解决的办法(确实不懂ffmpeg),然后一个个尝试,然后比较好点的推流解决方法建议是:使用 -use_wallclock_as_timestamps 1 选项,该选项可以将系统时钟作为时间戳,而不是依赖于从 RTSP 流中提取的时间戳。这有时可以解决时间戳问题。
推流命令如下:

ffmpeg -use_wallclock_as_timestamps 1 -rtsp_transport tcp -i rtsp://admin:admin@ip -c:v libx264 -b:v 1000k -c:a aac -ar 44100 -f flv rtmp://ip:1935/stream/example
  • use_wallclock_as_timestamps 1:使用 wallclock 作为时间戳。
  • rtsp_transport tcp:使用 TCP 作为 RTSP 传输协议。
  • i rtsp://admin:admin@ip:输入源是一个 RTSP 地址,包括用户名和密码,以及相应的 IP 地址。
  • c:v libx264:设置视频编码器为 libx264。
  • b:v 1000k:设置视频比特率为 1000k(1000 kbps)。
  • c:a aac:设置音频编码器为 AAC。
  • ar 44100:设置音频采样率为 44100 Hz。
  • f flv:指定输出格式为 FLV。
  • rtmp://ip:1935/stream/example:指定输出的 RTMP 地址,包括服务器的 IP 地址和端口,以及流的名称为 “example”。

效果:

上面的图是python中测试的,下图是在局域网下其他电脑上拉取流的情况,有延迟!!!后面再琢磨吧,欢迎佬指导
在这里插入图片描述

  • 22
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要在 Docker 部署配置 Nginx-RTMP,可以按照以下步骤进行操作: 1. 创建一个 Dockerfile 文件,以便构建自己的 Nginx 镜像。Dockerfile 内容如下: ``` FROM nginx:latest RUN apt-get update && apt-get install -y wget build-essential libpcre3 libpcre3-dev libssl-dev zlib1g-dev RUN wget https://github.com/arut/nginx-rtmp-module/archive/master.zip && \ unzip master.zip RUN wget http://nginx.org/download/nginx-1.19.1.tar.gz && \ tar -zxvf nginx-1.19.1.tar.gz && \ cd nginx-1.19.1 && \ ./configure --with-http_ssl_module --add-module=../nginx-rtmp-module-master && \ make && \ make install COPY nginx.conf /usr/local/nginx/conf/ ``` 2. 在 Dockerfile 目录创建一个名为 nginx.conf 的 Nginx 配置文件,内容如下: ``` worker_processes 1; events { worker_connections 1024; } rtmp { server { listen 1935; chunk_size 4096; application live { live on; record off; } application hls { live on; hls on; hls_path /tmp/hls; } } } http { server { listen 80; location /hls { types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; } root /tmp; add_header Cache-Control no-cache; } } } ``` 3. 构建 Docker 镜像,执行以下命令: ``` docker build -t nginx-rtmp . ``` 4. 运行 Docker 容器,执行以下命令: ``` docker run -d -p 1935:1935 -p 80:80 nginx-rtmp ``` 这将会在 Docker 容器运行 Nginx,并将 RTMP 端口映射到主机的 1935 端口,将 HTTP 端口映射到主机的 80 端口。 现在,您可以使用 OBS 或其他 RTMP 客户端将视频流发送到 RTMP://<your-ip-address>:1935/live,并使用 VLC 播放器或其他支持 HLS 的浏览器,在 http://<your-ip-address>/hls 查看视频。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值