为什么我的HLS流在iOS 15 safari上无限加载,但在iOS 14上工作正常?

lawou6xi  于 2023-01-27  发布在  iOS
关注(0)|答案(3)|浏览(248)

因此,我有一个小网站,显示不同的流从网络摄像机在城市。(例如:https://camstream.alteco.lv:8443/live/camera1.m3u8)。可在此处查看流:https://camstream.alteco.lv/camera/76d4b7f895df
这是一个简单的页面,只有视频播放器尝试使用hls.js播放流,在那里可以使用它和iOS设备的本地<video>标记。
一切都很好,直到iOS 15推出,打破了流,所以他们是不可见的了。它只是显示它的加载,但什么也没发生。有趣的是,如果我试图打开全屏视频,并尝试寻找,视频立即显示。我还检查了传入的.m3u8和.ts文件使用Inspect元素,一切似乎都很好。
起初,我以为问题出在流本身,但事实似乎并非如此,因为我尝试了各种不同的选项和配置文件(基线,主,高)但没有任何变化,所以几乎感觉像是Safari视频播放器的bug,但是我发现其他网站的视频流运行良好。我也用iPhone上的VLC应用程序测试了视频流,它运行良好。Don“我不会在Safari上工作。
我使用带有nginx-rtmp模块的nginx将流服务到客户端。

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 aac -c:v libx264 -vf yadif -b:v 1100k -f flv -g 60 -r 30 -s 1280x720 -force_key_frames expr:gte(t,n_forced*2) -preset superfast -profile:v main rtmp://localhost:1935/hls/$name_720p2628kbs
              -c:a aac -c:v libx264 -vf yadif -b:v 600k -f flv -g 60 -r 30 -s 854x480 -force_key_frames expr:gte(t,n_forced*2) -preset superfast -profile:v main rtmp://localhost:1935/hls/$name_480p1128kbs
              -c:a aac -c:v libx264 -vf yadif -b:v 300k -f flv -g 60 -r 30 -s 640x360 -force_key_frames expr:gte(t,n_forced*2) -preset superfast -profile:v main rtmp://localhost:1935/hls/$name_360p878kbs;
        }

        application hls {
            live on;
            hls on;
            hls_fragment_naming system;
            hls_fragment 6s;
            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 {
    server {
        listen 80;

        listen 443 ssl;

        ssl_certificate /etc/nginx/ssl/fullchain.pem;
        ssl_certificate_key /etc/nginx/ssl/privkey.pem;

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

        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 = /crossdomain.xml {
            root /www/static;
            default_type text/xml;
            expires 24h;
        }
    }
}

播放器页面的代码也非常简单

<video id="video" autoplay muted controls playsinline preload="metadata"></video>

    <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
    <script src="//code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
            crossorigin="anonymous"></script>

<script>
$(document).ready(function () {

        var video = document.getElementById('video');

        if (Hls.isSupported()) {

            var hls = new Hls();
            hls.loadSource('{{$camera->m3u8}}');
            hls.attachMedia(video);
            hls.on(Hls.Events.MANIFEST_PARSED, function () {
                video.play();
            });
            hls.on(Hls.Events.MEDIA_ATTACHED, function () {
                //can we get cam on load?
                setTimeout(function () {
                    fitToScreen()
                }, 500);
            })
        } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
            console.log("No HLS support. Switching to native <video>")

            video.src = '{{$camera->m3u8}}';
            video.addEventListener('loadedmetadata', function () {
                console.log("loadedmetadata");

                video.play();
            });
        }

        $(window).resize(function () {
            fitToScreen()
        }).resize();

        setInterval(function () {
            fitToScreen()
        }, 3000);
    })
</script>

我也试过切换到video.js,但没有帮助。同样的问题发生了。
过去4天,我一直在尝试解决此问题,但没有任何成功,因此我希望有人遇到类似的问题,可以为我指明一个方向,看看

11dmarpk

11dmarpk1#

最后,我无法使用nginx-rtmp模块解决问题,我只是简单地切换到Node-Media-Server https://github.com/illuspas/Node-Media-Server
有了这个,流在所有iOS版本上都能很好地工作

szqfcxe2

szqfcxe22#

我也遇到过类似的问题,我是这样解决的:
我有一个nginx-rtmp容器,里面有alfg/nginx-rtmp的图像,基于alpine linux。我试着用其他的nginx-rtmp docker容器来解决这个问题,所有这些图像都是基于alpine linux的。
我通过创建基于ubuntulinux的新图像解决了这个问题,并在nginx.conf配置中更改了execffmpeg的命令push。
如果我不更改exec ffmpeg的push命令,则无法解决问题。
我的设想是:
CAMS RTMP/RTSP --〉SERVER 1(仅用于接收摄像头的实时图像,并使用ffmpeg进行处理)--〉SERVER 2(接收来自SERVER 1的实时图像,并为用户进行流媒体直播)
我需要在服务器1和服务器2中更改为Ubuntu

9gm1akwq

9gm1akwq3#

此问题似乎存在于iOS 15或更高版本+ nginx_rtmp_module的组合中。
我们用ffmpeg解决了这个问题。在nginx.conf(nginx_rtmp_module)中添加了“exec ffmpeg ....”函数。所以HLS流是由ffmpeg创建的。

相关问题