You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Nginx+FFmpeg的HLS监控流加载异常问题求助

树莓派HLS流无法加载问题排查求助

我在树莓派上搭建HLS流,通过Web服务器对外广播连接在树莓派上的安防摄像头视频,实现网站可访问。目前.ts视频文件和.m3u8播放列表可从/var/www/html/hls正常获取,但在Safari及其他浏览器加载流时,视频持续处于加载状态,始终无法显示内容。

环境细节

  • 摄像头:Arducam 1080p日夜视USB摄像头,设备路径/dev/video0。
  • 服务器状态:Safari控制台和服务器日志均无错误;直接在浏览器访问.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主配置:/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
}

前端页面:/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多小时排查,恳请各位提供帮助。


内容的提问来源于stack exchange,提问作者Jacob Anderson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 17:55:58