为什么我的 HLS 流在 iOS 15 safari 上无限加载,但在 iOS 14 上工作正常?
Why is my HLS stream infinitely loading on iOS 15 safari but works fine on iOS 14?
所以我有一个小网站,显示来自城市周围网络摄像机的不同流。 (例如:https://camstream.alteco.lv:8443/live/camera1.m3u8). The stream can be viewed here: https://camstream.alteco.lv/camera/76d4b7f895df
这是一个简单的页面,只有视频播放器尝试使用 hls.js 可以使用的流和用于 iOS 设备的本机 <video>
标签播放流。
一切正常,直到 iOS 15 推出中断了流,因此它们不再可见。它只是表明它正在加载,但没有任何反应。有趣的是,如果我尝试全屏打开视频并尝试搜索,视频会立即显示出来。我还使用 Inspect Element 检查了传入的 .m3u8 和 .ts 文件,一切似乎都很好。
起初,我认为问题出在流本身,但似乎并非如此,因为我尝试了各种不同的选项和配置文件(基线、主要、高)但是没有任何变化,所以它几乎感觉像是 safari 视频播放器的错误,但我发现来自不同站点的其他流工作正常。我还在 iPhone 上使用 VLC 应用程序测试了流,它在那里工作正常。它只在 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 天我一直在尝试解决这个问题,但没有成功,所以我希望有人遇到过类似的事情,这可以为我指出一个方向
最后用nginx-rtmp模块解决不了问题,干脆换成Node-Media-Server https://github.com/illuspas/Node-Media-Server
有了这个,流在所有 iOS 版本上都能很好地工作
我遇到了类似的问题,我是这样解决的:
我有一个 nginx-rtmp 容器,图像 alfg/nginx-rtmp,基于 alpine linux。我尝试使用其他 nginx-rtmp docker 容器解决问题,所有这些图像都基于 alpine linux.
我通过基于 ubuntu linux 创建新图像解决了这个问题,在 nginx.conf 配置中我更改了 exec ffmpeg 的命令推送。
如果我不更改 exec ffmpeg 的 push 命令,问题没有解决。
我的场景是:
CAMS RTMP/RTSP --> SERVER 1(仅用于接收摄像头的实时图像和使用 ffmpeg 进行的处理)--> SERVER 2(从 SERVER1 接收实时图像并为用户直播)
我需要在 SERVER1 和 SERVER2
中更改为 ubuntu
所以我有一个小网站,显示来自城市周围网络摄像机的不同流。 (例如:https://camstream.alteco.lv:8443/live/camera1.m3u8). The stream can be viewed here: https://camstream.alteco.lv/camera/76d4b7f895df
这是一个简单的页面,只有视频播放器尝试使用 hls.js 可以使用的流和用于 iOS 设备的本机 <video>
标签播放流。
一切正常,直到 iOS 15 推出中断了流,因此它们不再可见。它只是表明它正在加载,但没有任何反应。有趣的是,如果我尝试全屏打开视频并尝试搜索,视频会立即显示出来。我还使用 Inspect Element 检查了传入的 .m3u8 和 .ts 文件,一切似乎都很好。
起初,我认为问题出在流本身,但似乎并非如此,因为我尝试了各种不同的选项和配置文件(基线、主要、高)但是没有任何变化,所以它几乎感觉像是 safari 视频播放器的错误,但我发现来自不同站点的其他流工作正常。我还在 iPhone 上使用 VLC 应用程序测试了流,它在那里工作正常。它只在 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 天我一直在尝试解决这个问题,但没有成功,所以我希望有人遇到过类似的事情,这可以为我指出一个方向
最后用nginx-rtmp模块解决不了问题,干脆换成Node-Media-Server https://github.com/illuspas/Node-Media-Server
有了这个,流在所有 iOS 版本上都能很好地工作
我遇到了类似的问题,我是这样解决的:
我有一个 nginx-rtmp 容器,图像 alfg/nginx-rtmp,基于 alpine linux。我尝试使用其他 nginx-rtmp docker 容器解决问题,所有这些图像都基于 alpine linux.
我通过基于 ubuntu linux 创建新图像解决了这个问题,在 nginx.conf 配置中我更改了 exec ffmpeg 的命令推送。
如果我不更改 exec ffmpeg 的 push 命令,问题没有解决。
我的场景是:
CAMS RTMP/RTSP --> SERVER 1(仅用于接收摄像头的实时图像和使用 ffmpeg 进行的处理)--> SERVER 2(从 SERVER1 接收实时图像并为用户直播)
我需要在 SERVER1 和 SERVER2
中更改为 ubuntu