缩放视频时,nginx-rtmp 模块内的 ffmpeg 不起作用

缩放视频时,nginx-rtmp 模块内的 ffmpeg 不起作用

所以我使用以下方式设置了一个 nginx RTMP 服务器这个 rtmp 模块。下面是我按照以下方法创建的 nginx.conf本指南

rtmp {
        server {
                listen 1935;
                chunk_size 4096;

                application live {
                        live on;
                        record off;
                }

                application movie {
                        live on;
                        record off;

                        exec ffmpeg -i rtmp://localhost:1935/movie -async 1 -vsync -1
                                -c:v libx264 -c:a libvo_aacenc -b:v 256k -b:a 32k -vf "scale=480:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://localhost:1935/hls/movie_low
                                -c:v libx264 -c:a libvo_aacenc -b:v 768k -b:a 96k -vf "scale=720:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://localhost:1935/hls/movie_mid
                                -c:v libx264 -c:a libvo_aacenc -b:v 1024k -b:a 128k -vf "scale=960:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://localhost:1935/hls/movie_high
                                -c:v libx264 -c:a libvo_aacenc -b:v 1920k -b:a 128k -vf "scale=1280:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://localhost:1935/hls/movie_hd720
                                -c copy -f flv rtmp://localhost:1935/hls/movie_src;
                }

                application hls {
                        live on;
                        hls on;
                        hls_path /tmp/hls;
                        hls_nested on;

                        hls_variant _low BANDWIDTH=288000; # Low bitrate, sub-SD resolution
                        hls_variant _mid BANDWIDTH=448000; # Medium bitrate, SD resolution
                        hls_variant _high BANDWIDTH=1152000; # High bitrate, higher-than-SD resolution
                        hls_variant _hd720 BANDWIDTH=2048000; # High bitrate, HD 720p resolution
                        hls_variant _src BANDWIDTH=4096000; # Source bitrate, source resolution
                }
        }
}

由于某种原因,使用缩放视频-vf "scale=..."不起作用(使用标志也是如此-s wxh),因为没有创建输出。我通过检查 rtmp 模块提供的统计页面来验证这一点。当我开始向服务器流式传输时,/movie 应用程序显示数据流,但 /hls 应用程序什么也没有得到。如果我删除标志,-vf "scale=..."那么 /hls 应用程序下的 5 个流的一切都按预期工作。我做错了什么吗?我想要缩放,因为我不想在不同的比特率上发送相同的分辨率。我的 nginx 版本是 1.16.1,所有这些都在 Ubuntu 18.04 上运行。

答案1

按照@BenXO 的建议在命令行中运行 ffmpeg 命令后,我收到有关未找到 libvo_aacenc 的错误,即此代码片段是问题所在:-c:a libvo_aacenc。快速搜索发现 ffmpeg 不再支持此编码器,建议仅使用aac。将所有实例更改为-c:a libvo_aacenc解决-c:a aac了该问题。

答案2

worker_processes  1;
error_log  logs/error.log;

events {
    worker_connections  1024;
    }

http {

    keepalive_timeout   60;
    send_timeout        10;
    keepalive_requests  10;
    client_body_timeout 10;

    #gzip       on;
    sendfile        on;
    include     mime.types;
    default_type    application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  logs/access.log  main;

    server {

    listen      80;
    # listen [::]:  80 ipv6only;

    server_name localhost;
    access_log  logs/host.access.log  main;
    add_header  Strict-Transport-Security "max-age=63072000;";
    index index.php index-nginx.html index.html index.htm index.m3u8 index.mpd;

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
        root   site;
        }

        # location ~ \.php$ {
    #   include        fastcgi_params;
    #   fastcgi_pass   127.0.0.1:9000;
    #   fastcgi_index  index.php;
    #   fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    #   }

    location / {
        location ~* \.m3u8$ {
        add_header Cache-Control no-cache;
        }
        try_files $uri $uri/ =404;
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Strict-Transport-Security' 'max-age=31536000';
        add_header 'X-Content-Type-Options' "nosniff" 'always';
        if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Max-Age' 1728000;
        # add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        return 204;
        }
        if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length';
        }
        if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
        }

        root site;
        index index.php index.html index-nginx.html index.htm index.m3u8 index.mpd;
        }

        location /stat {
        rtmp_stat all;
        rtmp_stat_stylesheet stat.xsl;
        # auth_basic "Restricted Content";
        # auth_basic_user_file .htpasswd;
        }

        location /stat.xsl {
        root site;
        }

        #location /control {
        #rtmp_control all;
        # auth_basic "stream";
        # auth_basic_user_file .htpasswd;
        #}

        #location /publish {
        #    return 201;
        #}
        #location /play {
        #    return 202;
        #}
        #location /record_done {
        #    return 203;
        #}
        
    location /tmp_hls {
        if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        return 204;
        }
        if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length';
        }
        if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length';
        }
        types {
        application/vnd.apple.mpegurl m3u8;
        text/html html;
        }
        autoindex on;
        autoindex_localtime on;
        autoindex_exact_size off;
        alias X:/temp/tmp_hls;                          # <----- 
        expires -1;
        }

    location /tmp_dash {
        alias X:/temp/tmp_dash;                         # <----- 
        autoindex on;
        autoindex_localtime on;
        autoindex_exact_size off;
        expires -1;

        if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        return 204;
        }
        if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length';
        }
        if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length';
        }
    types {
        application/dash+xml mpd;
        application/vnd.apple.mpegurl m3u8;
        video/mp2t ts;
        text/html html;
        }
    }

    location /recordings {
        alias recordings;  
        autoindex on;
        autoindex_localtime on;
        autoindex_exact_size off;
        expires -1;

        if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        return 204;
        }
        if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length';
        }
        if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length';
        }
        types {
            application/dash+xml mpd;
            application/vnd.apple.mpegurl m3u8;
            video/mp2t ts;
            video/mp4 mp4;
            text/html html;
            }
        }
    }
}

rtmp {
    server {
    listen 1935;
    chunk_size 4096;

    application live {
            live on;
        interleave on;
        meta on;
        session_relay on;
        max_connections 1500;
            record_path recordings;
        record_suffix all-%d-%b-%y-%T.flv;
        # record_interval 30s;
        # record keyframes;

        push rtmp://localhost/hls;
        # push rtmp://localhost/dash;
        # push rtmp://localhost/youtube;

            exec ffmpeg -i rtmp://localhost/$app/$name  -async 1 -vsync -1 
            -c:v libx264 -acodec copy -b:v 256k -vf "scale=480:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -g 60 -hls_list_size 0 -f flv rtmp://localhost/hls/$name_low
            -c:v libx264 -acodec copy -b:v 768k -vf "scale=720:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -g 60 -hls_list_size 0 -f flv rtmp://localhost/hls/$name_mid
            -c:v libx264 -acodec copy -b:v 1024k -vf "scale=960:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -g 60 -hls_list_size 0 -f flv rtmp://localhost/hls/$name_high
            -c:v libx264 -acodec copy -b:v 1920k -vf "scale=1280:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -g 60 -hls_list_size 0 -f flv rtmp://localhost/hls/$name_higher
            -c copy -f flv rtmp://localhost/hls/$name_src;
        }
    
    application hls {
            live on;
        hls on;
        hls_nested on;
        hls_cleanup on;
        meta copy;
        # hls_sync 100ms;
        hls_type live;
        hls_fragment 1s;
        hls_playlist_length 3s;
        hls_path X:/temp/tmp_hls;                           # <----- 
        hls_fragment_naming system;

        hls_variant _low BANDWIDTH=288000;  # Low bitrate, sub-SD resolution
        hls_variant _mid BANDWIDTH=448000;  # Medium bitrate, SD resolution
        hls_variant _high BANDWIDTH=1152000;    # Higher-than-SD resolution 
        hls_variant _higher BANDWIDTH=2048000;  # High bitrate, HD 720p resolution
        hls_variant _src BANDWIDTH=4096000; # Source bitrate, source resolution
        }

    application dash {
            live on;
        dash on;
        dash_nested on;
        dash_cleanup on;
        dash_fragment 1s;
        dash_playlist_length 3s;
        dash_path X:/temp/tmp_dash;                     # <----- 
        }

    #application youtube {
            #live on;
            #push rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY;
        #allow publish 127.0.0.1;
        #deny publish all;
        #}
    }
}

相关内容