HLS从不在iPhone上播放ffmpeg提供的Nginx.适用于Desktop Safari和iPad



我正在通过RTMP将相机直播到Nginx RTMP服务器,如下所示:

ffmpeg -rtsp_transport tcp -i rtsp://user:pass@192.168.1.XXX/ -f image2 -stream_loop -1 -re -i /tmp/overlay.png -filter_complex "overlay" -vcodec libx264 -preset ultrafast -profile baseline -pix_fmt yuv420p -an -f flv -rtmp_live live -s 1280x720 rtmp://remote.server.com:1935/show/stream

我的Nginx服务器配置:

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
# sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/myccam-access.log;
error_log /var/log/nginx/myccam-error.log;
##
# Gzip Settings
##
gzip on;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
# include /etc/nginx/sites-enabled/*;
server {
listen 8080;
location ~ .(mp4|m4a|m4v|mov)$ {
add_header content_disposition filename=$request_uri;
add_header accept_ranges bytes;
}

location /hls {
# 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';
add_header Cache-Control no-cache;
add_header Last-Modified "";
# 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/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /tmp/;
}
}
}

rtmp {
server {
listen 1935; # Listen on standard RTMP port
chunk_size 4000;
application show {
live on;
hls on;
hls_fragment_naming system;
hls_fragment 1s;
hls_path /tmp/hls;
hls_continuous on;
hls_variant _720p2628kbs BANDWIDTH=2628000;
}
}
}

我通过一个运行中的Apache服务器代理这个设置,该服务器已经具有有效的SSL证书。我可以通过VLC访问这样的流,而不会出现问题。https://myserver.com/CameraName/hls/stream.m3u8

为了在浏览器中查看,我使用了公认的从其他人那里借来的HTML:

<!DOCTYPE html>
<html lang="en"><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Camera</title>
<style>
html, body {
background: none !important;
overflow: hidden;
margin: 0;
padding: 0;
}
video {
margin: 0 auto;
width: 100%;
height: 100vh;
}
.video-container {
width: 100%;
height: 100vh
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"</script>
<script>
function waitForPublishedStream(showMsg) {
if (typeof showMsg === 'undefined') showMsg = true;
$.get('https://myserver.com/CameraName/hls/stream.m3u8', function (response) {
if (showMsg) {
$('.container-loader .alert-warning').html('Pieslēdzamies kamerai..')
}
if (response.state == 'success') {
if (response.published) {
document.location.reload(true)
} else {
setTimeout(function () {
waitForPublishedStream();
}, 2000)
}
}
})
}
</script>
</head>
<body>
<div class="video-container">
<video id="video" autoplay="autoplay" muted="muted" controls="controls" playsinline="" src="https://myserver.com/CameraName/hls/stream.m3u8">
<source src="https://myserver.com/CameraName/hls/stream.m3u8" type="application/vnd.apple.mpegurl">
</video>
</div>
<script src="https://cdn.jsdelivr.net/npm/hls.js"></script>
<script>
$(document).ready(function () {
const video = document.getElementById('video');
if (Hls.isSupported()) {
const hls = new Hls();
hls.loadSource('https://myserver.com/CameraName/hls/stream.m3u8');
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED, function () {
video.play();
});
}
})
</script>
</body></html>

这适用于我测试过的除iPhone以外的所有设备。这是它最重要的工作平台。在iPhone上,流永远不会显示任何内容。调试器显示设备正在正确下载.ts文件。有趣的是,如果我全屏弹出并快进流,流将加载大约10%的时间。当这种情况发生时,播放器上的时间戳会显示出一些偏离。大概是-11:21:42。我怀疑这个问题可能与ffmpeg提供的PTS有关。

Apples的mediastreamvalidatorCLI工具显示,一些.ts文件被踢回为404。但我无法在任何浏览器调试器上重现这一点。非常感谢您的帮助:(

参考文献:


https://developer.apple.com/forums/thread/690298

https://github.com/arut/nginx-rtmp-module/issues/1656

我通过完全脱离Nginx并使用节点媒体服务器代替解决了这个问题

非常确定Hls.isSupported()解析为iPhone的false。iPad和Mac电脑则不然。关键在于";HLS.js依靠HTML5视频和MediaSource扩展进行播放"iPhone Safari不支持此功能。

这是一个老问题,但我遇到了同样的问题,花了几个小时解决了它。所以也许我的答案对某人有用。

与OP(使用相同的配置:nginx和hls.js(一样,我的hls流正在加载,但从未在我的iPhone上播放过(其他所有设备都无法使用苹果(。事实证明,苹果公司希望流中有音频,而我的网络摄像头没有提供音频。我解决了在从网络摄像头转换为HLS:时向流中添加空音频通道的问题

ffmpeg -i camerastream -f lavfi -i anullsrc=channel_layout=mono:sample_rate=24000 -c:a aac -shortest

这导致HLS流带有一个非常轻量级的音频通道,现在该流在任何设备上都可以完美工作,包括iPhone。

答案在这里找到,苹果规格在这里找到

相关内容

  • 没有找到相关文章