ffmpeg/nginx 的 RTMP 到 HLS 转换帧率问题

ffmpeg/nginx 的 RTMP 到 HLS 转换帧率问题

目前,我正在使用以下命令从 Raspberry Pi 3 相机将 RTMP 流推送到在 Ubuntu 18.04 LTS 上运行的 nginx 1.15.3(它本身似乎运行良好,我可以在 VLC 上毫无问题地拉取流并验证它是否正常工作):

raspivid -w 640 -h 480 -fps 5 -t 0 -b 1800000 -o - | ffmpeg -y -framerate 5 -f h264 -i - -c:v copy -map 0:0 -f flv -rtmp_buffer 100 -rtmp_live live rtmp://10.2.10.149/cam01/test

如果我将 raspivid 上的 fps 参数设置为 25,然后删除 ffmpeg 帧速率参数,那么这会将其转换为 HLS 流,并在 nginx 服务器上运行以下命令:

ffmpeg -i rtmp://10.2.10.149/cam01/test -vcodec libx264 -vprofile baseline -acodec h264 -strict -2 -f flv rtmp://10.2.10.149/show1/stream1

但是,我需要较低的帧速率,而且似乎尝试以任何方式执行此操作都会真正扰乱 ffmpeg,因为它会导致流卡顿很多,就像在等待加载一样。我怀疑这与 ffmpeg 的默认帧速率为 25 或其他有关,因为在 RTMP 流中,如果我尝试仅将 raspivid 中的 fps 参数设置为 5 而不在 ffmpeg 中包含帧速率参数,那么它会使视频卡顿几秒钟,然后以 5 倍的视频速度运行一秒钟,因为 ffmpeg 似乎仍在尝试运行 25 fps 的视频。

在 ffmpeg 转换命令上添加帧速率参数似乎使情况变得更糟,我不明白为什么这不起作用,因为它似乎对许多其他人都很好用。我主要使用本指南来尝试帮助我设置 nginx 和其他东西:https://docs.peer5.com/guides/setting-up-hls-live-streaming-server-using-nginx/#4-pushing-live-stream-to-nginx-using-rtmp

我还将把我的 nginx.conf 放在这里供大家查看,并注意,每当我尝试通过网页拉取视频或使用 VLC 直接获取网络流时都会遇到这个问题:

worker_processes  auto;
events {
worker_connections  1024;
}

# RTMP configuration
rtmp {
server {
    listen 1935; # Listen on standard RTMP port
    chunk_size 4096;

    application show1 {
        live on;
        # Turn on HLS
        hls on;
        hls_path /mnt/hls1/;
        hls_fragment 3;
        hls_playlist_length 60;
    }
application show2 {
        live on;
        # Turn on HLS
        hls on;
        hls_path /mnt/hls2/;
        hls_fragment 3;
        hls_playlist_length 60;
    }
application show3 {
        live on;
        # Turn on HLS
        hls on;
        hls_path /mnt/hls3/;
        hls_fragment 3;
        hls_playlist_length 60;
    }
application show4 {
        live on;
        # Turn on HLS
        hls on;
        hls_path /mnt/hls4/;
        hls_fragment 3;
        hls_playlist_length 60;
    }
application show5 {
        live on;
        # Turn on HLS
        hls on;
        hls_path /mnt/hls5/;
        hls_fragment 3;
        hls_playlist_length 60;
    }
application show6 {
        live on;
        # Turn on HLS
        hls on;
        hls_path /mnt/hls6/;
        hls_fragment 3;
        hls_playlist_length 60;
    }
application show7 {
        live on;
        # Turn on HLS
        hls on;
        hls_path /mnt/hls7/;
        hls_fragment 3;
        hls_playlist_length 60;
    }
    application cam01 {
        live on;
        record off;
    }
application cam02 {
        live on;
        record off;
    }
application cam03 {
        live on;
        record off;
    }
application cam04 {
        live on;
        record off;
    }
application cam05 {
        live on;
        record off;
    }
application cam06 {
        live on;
        record off;
    }
application cam07 {
        live on;
        record off;
    }
}
}

http {
sendfile off;
tcp_nopush on;
default_type application/octet-stream;

server {
    listen 80;
    server_name localhost;
    location / {
        # Disable cache
        add_header 'Cache-Control' 'no-cache';

        # CORS setup
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Expose-Headers' 'Content-Length';

        # allow CORS preflight requests
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Max-Age' 1728000;
            add_header 'Content-Type' 'text/plain charset=UTF-8';
            add_header 'Content-Length' 0;
            return 204;
        }

        types {
            application/dash+xml mpd;
            application/vnd.apple.mpegurl m3u8;
            video/mp2t ts;
        }

        root /mnt/;
        location /index.html {
            default_type "text/html";
        }
        location /testing.html {
            default_type "text/html";
        }
        location /test.html {
            default_type "text/html";
        }
    location /cam01.html {
            default_type "text/html";
        }
    location /cam02.html {
            default_type "text/html";
        }
    location /cam03.html {
            default_type "text/html";
        }
    location /cam04.html {
            default_type "text/html";
        }
    location /cam05.html {
            default_type "text/html";
        }
    location /cam06.html {
            default_type "text/html";
        }
    location /cam07.html {
            default_type "text/html";
        }
    }
}
}

如果我需要包含更多详细信息,请随时告诉我,我只需要让它正常工作,而不是我刚才解释的所有问题,任何帮助都将不胜感激,谢谢。

编辑 1:我还注意到,除了使用前面描述的第二个命令从流中产生的故障和剪切之外,它有时似乎会“卡”在某个帧上,不确定这是否更有帮助,只是想确保我拥有在这里可以获得的所有信息。

编辑 2:我开始相信这更多的是 nginx 的问题,因为当我将第一个命令指向 /show1/stream1 位置时,该位置将 rtmp 转换为 hls,而无需运行我认为完全必要的第二个命令,我以同样的方式遇到了完全相同的问题。我对 nginx 了解不多,我在网上找到的任何东西也帮不上什么忙。非常感谢您的见解,我确实知道 hls 总是会有很大延迟,这不是我要修复的,我要求修复剪切和卡顿。

编辑 3:我可能实际上已经破解了这个问题,我注意到在 raspivid 命令上,将比特率设置得更高似乎确实可以缓解这个问题,但是,即使我将比特率设置为荒谬的甚至不那么荒谬的,但仍然过度的量,它仍然会每隔几分钟随机地剪掉几帧,我不完全确定为什么。如果能得到任何见解,我将不胜感激。

答案1

抱歉,我给大家造成了困惑,但事实证明,这段代码完全正确(实际上,我甚至不需要第二个命令,我可以直接从 pi 将其提供给 nginx 中的 hls,不会有问题)。问题是,在进行这种流式传输时,ffmpeg 真的不喜欢接收低于 7 FPS 的任何数据,但这对于我的目的来说仍然足够。这应该在某个地方记录下来(好吧,我想现在应该有,但仍然有)。

编辑:我使用的相机可能也会影响它,因为我刚刚意识到我的一些相机的最低帧速率为 7。

相关内容