Browse Source

add nginx-flv

reghao 2 days ago
parent
commit
bbf78baecb
6 changed files with 291 additions and 0 deletions
  1. 57 0
      Dockerfile
  2. 60 0
      README.md
  3. 11 0
      build.sh
  4. 26 0
      docker-compose.yml
  5. 15 0
      init_ngxflv.sh
  6. 122 0
      nginx.conf

+ 57 - 0
Dockerfile

@@ -0,0 +1,57 @@
+FROM registry.cn-chengdu.aliyuncs.com/reghao/debian:bullseye-slim
+
+# debian11 使用 ustc 源
+RUN sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list && \
+    sed -i 's|security.debian.org/debian-security|mirrors.ustc.edu.cn/debian-security|g' /etc/apt/sources.list
+
+# 安装编译 nginx 源码需要的依赖
+RUN apt clean && apt update -y && apt install -y --no-install-recommends \
+    gcc make zlib1g zlib1g-dev openssl libssl-dev libpcre3 libpcre3-dev libgd-dev libexif-dev && \
+    rm -rf /var/lib/apt/lists/*
+
+# 复制 nginx 和 nginx-http-flv-module 源码
+COPY nginx-1.18.0.tar.gz /nginx-1.18.0.tar.gz
+COPY v1.2.12.tar.gz /v1.2.12.tar.gz
+RUN tar zxf nginx-1.18.0.tar.gz && tar zxf v1.2.12.tar.gz
+
+# 创建 nginx 用户
+RUN useradd -M -s /sbin/nologin nginx
+# 切换至 nginx 源码目录
+WORKDIR /nginx-1.18.0
+
+# 配置编译选项, --add-module 指定了 nginx-http-flv-module 模块
+RUN ./configure \
+--prefix=/usr/local/nginx \
+--user=nginx \
+--group=nginx \
+--sbin-path=/usr/local/nginx/sbin/nginx \
+--modules-path=/usr/local/nginx/modules \
+--conf-path=/usr/local/nginx/conf/nginx.conf \
+--error-log-path=/usr/local/nginx/logs/error.log \
+--http-log-path=/usr/local/nginx/logs/access.log \
+--pid-path=/usr/local/nginx/logs/nginx.pid \
+--lock-path=/usr/local/nginx/logs/nginx.lock \
+--with-http_stub_status_module \
+--with-http_ssl_module \
+--add-module=/nginx-http-flv-module-1.2.12
+# 编译源码
+RUN make && make install
+
+# 将 nginx 日志重定向到 stdout 和 stderr, 这样可通过 docker logs 直接查看日志
+RUN ln -sf /dev/stdout /usr/local/nginx/logs/access.log && ln -sf /dev/stderr /usr/local/nginx/logs/error.log
+# 创建 rtmp 推流的 flv 文件存放位置, rtmp 的 record_path 参数中配置
+RUN mkdir -p /data/rtmp
+# 使用自定义的 nginx.conf
+COPY nginx.conf /usr/local/nginx/conf/nginx.conf
+WORKDIR /
+
+# 删除安装使用的文件和文件夹
+RUN rm -rf nginx-1.18.0.tar.gz
+RUN rm -rf nginx-1.18.0
+RUN rm -rf nginx-http-flv-module-1.2.12.tar.gz
+RUN rm -rf nginx-http-flv-module-1.2.12
+
+# nginx 默认以后台模式启动, docker 未执行到自定义的 CMD 之前 nginx 的 pid 是 1
+# 执行到 CMD 后 nginx 开始后台运行,bash 的 pid 变成了 1, 一旦执行完自定义 CMD,nginx 容器也就退出
+# 为了保证 nginx 容器不退出, 应该关闭 nginx 的后台运行
+CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]

+ 60 - 0
README.md

@@ -0,0 +1,60 @@
+## 启动 ngxflv
+使用 docker compose 启动
+```
+docker compose up -d
+```
+
+## 推流
+文件推流
+```
+ffmpeg -hide_banner -re -i test.mp4 -c copy -f flv rtmp://127.0.0.1/rtmp/cam1
+```
+
+PC 摄像头麦克风推流
+```
+ffmpeg -hide_banner \
+    -thread_queue_size 2048 \
+    -f video4linux2 -video_size 848x480 -framerate 30 -i /dev/video0 \
+    -thread_queue_size 2048 \
+    -f alsa -ac 2 -i pulse \
+    -vcodec libx264 \
+    -acodec aac \
+    -b:v 4M \
+    -b:a 128K \
+    -max_delay 1000000 -g 5 \
+    -preset:v ultrafast -tune:v zerolatency \
+    -vf "drawtext=fontsize=28:fontcolor=red:text='${cam_name}-%{localtime}'" \
+    -f flv rtmp://127.0.0.1/rtmp/cam1
+```
+
+HLS 协议推流
+```
+ffmpeg -hide_banner -re -i test.mp4 \
+    -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 \
+    -strict -2 -ac 1 \
+    -f flv -q 10 rtmp://127.0.0.1/hls/cam1
+
+ffmpeg -hide_banner -f v4l2 -framerate 10 -i /dev/video0 -q 10 -vcodec libx264 -acodec aac \
+    -vf drawtext=fontcolor=white:fontsize=40:fontfile=test.ttf:line_spacing=7:text='%{localtime}':x=20:y=20 \
+    -f flv rtmp://127.0.0.1/hls/cam1
+```
+
+## 拉流
+ffplay 拉流
+```
+ffplay -hide_banner -i rtmp://127.0.0.1/rtmp/cam1
+# 无缓冲模式播放(内网延迟控制在 5s 内)
+ffplay -hide_banner -fflags nobuffer -i rtmp://127.0.0.1/rtmp/cam1
+```
+
+web 端 flv 拉流
+```
+http://127.0.0.1/live?app=rtmp&stream=cam1
+http://127.0.0.1/live.flv?port=1935&app=rtmp&stream=cam1
+```
+
+web 端 hls 拉流
+```
+# hls 拉流
+http://127.0.0.1/hls/cam1.m3u8
+```

+ 11 - 0
build.sh

@@ -0,0 +1,11 @@
+#!/bin/bash
+
+set -e
+
+wget https://nginx.org/download/nginx-1.18.0.tar.gz
+wget https://github.com/winshining/nginx-http-flv-module/archive/refs/tags/v1.2.12.tar.gz
+
+tag=`date +'%Y%m%d'`
+image="registry.cn-chengdu.aliyuncs.com/reghao/ngxflv:${tag}"
+docker build -t ${image} .
+docker push ${image}

+ 26 - 0
docker-compose.yml

@@ -0,0 +1,26 @@
+services:
+  ngxflv:
+    image: registry.cn-chengdu.aliyuncs.com/reghao/ngxflv:20260503
+    container_name: ngxflv
+    restart: always
+    ports:
+      - "1935:1935"   # RTMP 推流端口
+      - "8080:80"     # HTTP 播放端口(映射到主机的 8080)
+      - "8443:443"     # HTTP 播放端口(映射到主机的 8443)
+    volumes:
+      - /etc/localtime:/etc/localtime:ro
+      - /opt/docker/ngxflv/conf/nginx.conf:/usr/local/nginx/conf/nginx.conf
+      - /opt/docker/ngxflv/ssl:/data/ssl
+      - /opt/docker/ngxflv/rtmp:/data/rtmp
+    deploy:
+      resources:
+        limits:
+          cpus: '1.0'
+          memory: 512M
+        reservations:
+          memory: 128M
+    logging:
+      driver: "json-file"
+      options:
+        max-size: "10m"
+        max-file: "3"

+ 15 - 0
init_ngxflv.sh

@@ -0,0 +1,15 @@
+#!/bin/bash
+
+echo "init ngxflv..."
+base_dir='/opt/docker/ngxflv'
+if [ -d ${base_dir} ]; then
+    echo ${base_dir}"已存在, 删除后重新创建..."
+    rm -rf ${base_dir}
+fi
+
+mkdir -p ${base_dir}/conf
+mkdir -p ${base_dir}/ssl
+mkdir -p ${base_dir}/rtmp
+chmod -R go+w ${base_dir}
+
+docker compose up -d

+ 122 - 0
nginx.conf

@@ -0,0 +1,122 @@
+user root;
+error_log /dev/stderr info;
+worker_processes 1;
+worker_rlimit_nofile 20000;
+
+events {
+    use epoll;
+    worker_connections 20000;
+    multi_accept on;
+}
+
+http {
+    include       mime.types;
+    default_type  application/octet-stream;
+    keepalive_timeout  60;
+    server_tokens off;
+    # HTTP 访问日志定向到标准输出
+    access_log /dev/stdout;
+
+    server {
+        listen 80;
+        server_name live.reghao.cn;
+        rewrite ^(.*) https://$host permanent;
+    }
+    server {
+        listen 443 ssl;
+        server_name live.reghao.cn;
+
+        ssl_certificate   /data/ssl/reghao.cn/fullchain.cer;
+        ssl_certificate_key  /data/ssl/reghao.cn/reghao.cn.key;
+        ssl_protocols TLSv1.2 TLSv1.3;
+        ssl_ciphers HIGH:!aNULL:!MD5;
+        ssl_prefer_server_ciphers on;
+        ssl_session_cache shared:SSL:10m;
+        ssl_session_timeout 10m;
+
+        location /live {
+            flv_live on; #打开 HTTP 播放 FLV 直播流功能
+            chunked_transfer_encoding on; #支持 'Transfer-Encoding: chunked' 方式回复
+
+            add_header 'Access-Control-Allow-Origin' '*'; #添加额外的 HTTP 头
+            add_header 'Access-Control-Allow-Credentials' 'true'; #添加额外的 HTTP 头
+        }
+        location /hls {
+            types {
+                application/vnd.apple.mpegurl m3u8;       ssl_protocols TLSv1.2 TLSv1.3;
+                ssl_ciphers HIGH:!aNULL:!MD5;
+                ssl_prefer_server_ciphers on;
+                ssl_session_cache shared:SSL:10m;
+                ssl_session_timeout 10m;
+                video/mp2t ts;
+            }
+
+            root /tmp;
+            add_header 'Cache-Control' 'no-cache';
+        }
+        location /dash {
+            root /tmp;
+            add_header 'Cache-Control' 'no-cache';
+        }
+        #如果需要 JSON 风格的 stat, 不用指定 stat.xsl
+        #但是需要指定一个新的配置项 rtmp_stat_format
+        location /stat {
+            rtmp_stat all;
+            rtmp_stat_format json;
+        }
+        location /control {
+            rtmp_control all; #rtmp 控制模块的配置
+        }
+        location / {
+            root   /var/www;
+            index  index.html index.htm;
+        }
+        error_page   500 502 503 504  /50x.html;
+        location = /50x.html {
+            root   html;
+        }
+    }
+}
+
+rtmp {
+    # log_format rtmp_log_format '$remote_addr [$time_local] $command "$app" "$name" "$args" - $bytes_received bytes';
+    # access_log /dev/stdout rtmp_log_format;
+
+    server {
+        listen 1935;
+        chunk_size 4096;
+
+        # /rtmp/cam201
+        application rtmp {
+            live on;
+            gop_cache on; #打开 GOP 缓存,减少首屏等待时间
+            
+	        record all;
+            record_suffix _%Y%m%d_%H%M%S.flv;
+            record_path /data/rtmp;
+	        record_max_size 1M; # 录制的单个 flv 文件最大值
+	        record_unique on;
+
+            #on_publish https://auth.reghao.cn/api/auth/rtmp/on_publish;
+            #on_publish_done https://auth.reghao.cn/api/auth/rtmp/on_publish_done;
+  			#on_play https://auth.reghao.cn/api/auth/rtmp/on_play;
+            #on_play_done https://auth.reghao.cn/api/auth/rtmp/on_play_done;
+            #on_record_done https://auth.reghao.cn/api/auth/rtmp/on_record_done;
+        }
+        application vod {
+            live on;
+            gop_cache on; #打开 GOP 缓存,减少首屏等待时间
+        }
+        application hls {
+            live on;
+            hls on;
+            hls_path /tmp/hls;
+        }
+        application dash {
+            live on;
+            dash on;
+            dash_path /tmp/dash;
+            hls_fragment 10s;
+        }
+    }
+}