我一直致力于在我的 Raspberry Pi 上设置 HLS 流,以广播来自安全摄像头的视频,该安全摄像头通过我的 Web 服务器物理连接到我的 Raspberry Pi,从而可以通过我的网站进行访问。
.ts
视频文件和 .m3u8
播放列表正确地从 /var/www/html/hls
提供。但是,当我尝试在 Safari(以及其他浏览器)上加载流时,视频似乎持续加载,但从未显示任何内容。
以下是有关我的设置的一些详细信息:
/dev/video0
上购买。.ts
文件时,它们仅显示黑屏,但确实可以播放。鉴于这种情况,我怀疑我的 FFmpeg 命令或我的 Nginx 配置可能有问题。
这是我所拥有的:
ffmpeg 流服务:
/etc/systemd/system/ffmpeg-stream.service
[Unit]
Description=FFmpeg RTMP Stream
After=network.target
[Service]
ExecStart=/usr/local/bin/start_ffmpeg.sh
Restart=always
User=jacobanderson
Group=jacobanderson
StandardError=syslog
SyslogIdentifier=ffmpeg-stream
Environment=FFMPEG_LOGLEVEL=error
[Install]
WantedBy=multi-user.target
ffmpeg 命令:
/usr/local/bin/start_ffmpeg.sh
#!/bin/bash
/usr/bin/ffmpeg -f v4l2 -input_format mjpeg -video_size 1280x720 -framerate 30 -i /dev/video0 -vcodec libx264 -preset veryfast -acodec aac -strict -2 -f flv rtmp://localhost/live/
nginx.conf:
/etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
rtmp {
server {
listen 1935;
chunk_size 4096;
#allow publish 127.0.0.1;
#deny publish all;
application live {
#allow 192.168.0.100;
live on;
hls on;
hls_path /var/www/html/hls;
hls_fragment 3;
hls_nested on;
#hls_fragment_naming stream;
hls_playlist_length 120;
hls_cleanup on;
hls_continuous on;
#deny play all;
}
}
}
http {
##
# Basic Settings
##
sendfile on;
#sendfile off;
tcp_nopush on;
types_hash_max_size 2048;
# server_tokens off;
# Additional for video
directio 512;
# 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 TLSv1.3;
#ssl_protocols TLSv1.2 TLSv1.3; # Use only secure protocols
ssl_prefer_server_ciphers on;
#ssl_ciphers "HIGH:!aNULL:!MD5";
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
#gzip on;
gzip off; # Ensure gzip is off for HLS
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
可用站点:
/etc/nginx/sites-available/myStream.mysite.com
server {
listen 443 ssl;
server_name myStream.mysite.com;
ssl_certificate /etc/letsencrypt/live/myStream.mysite.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/myStream.mysite.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
location / {
root /var/www/html/hls;
index index.html;
}
location /hls {
# Password protection
auth_basic "Restricted Content";
auth_basic_user_file /etc/nginx/.htpasswd;
# 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/vnd.apple.mpegurl m3u8;
video/mp2t ts;
text/html html;
text/css css;
}
root /var/www/html;
}
}
server {
listen 80;
server_name myStream.mysite.com;
if ($host = myStream.mysite.com) {
return 301 https://$host$request_uri;
}
return 404; # managed by Certbot
}
index.html:
/var/www/html/hls/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HLS Stream</title>
<link href="https://vjs.zencdn.net/7.10.2/video-js.css" rel="stylesheet" />
<script src="./js/hls.min.js"></script>
</head>
<body>
<video-js id="my-video" class="video-js vjs-default-skin" controls preload="auto" width="640" height="264"
autoplay muted data-setup='{"fluid": true}'>
<!--<source src="https://myStream.mysite.com/hls/index.m3u8" type="application/x-mpegURL">-->
<source src="https://myStream.mysite.com/hls/index.m3u8" type="application/vnd.apple.mpegurl">
</video-js>
<script src="https://vjs.zencdn.net/7.10.2/video.js"></script>
<script>
if (Hls.isSupported()) {
var video = document.getElementById('my-video_html5_api'); // Updated ID to target the correct video element
var hls = new Hls();
hls.loadSource('https://myStream.mysite.com/hls/index.m3u8');
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED,function() {
video.play();
});
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = 'https://myStream.mysite.com/hls/index.m3u8';
video.addEventListener('loadedmetadata', function() {
video.play();
});
}
</script>
</body>
</html>
有人遇到过类似的问题或者可以发现我的配置中的错误吗?任何帮助将不胜感激,因为我已经投入了 30 多个小时来尝试解决此问题。
我终于想出了解决办法,那就是改变:
#!/bin/bash
/usr/bin/ffmpeg -f v4l2 -input_format mjpeg -video_size 1280x720 -framerate 30 -i /dev/video0 -vcodec libx264 -preset veryfast -acodec aac -strict -2 -f flv rtmp://localhost/live/
到
#!/bin/bash
/usr/bin/ffmpeg -f v4l2 -input_format mjpeg -video_size 1280x720 -framerate 30 -i /dev/video0 -vcodec libx264 -preset veryfast -tune zerolatency -g 60 -sc_threshold 0 -acodec aac -b:a 128k -ar 44100 -maxrate 1500k -bufsize 3000k -f hls -hls_time 4 -hls_playlist_type event -hls_segment_filename '/var/www/html/hls/stream%03d.ts' /var/www/html/hls/index.m3u8