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

Express搭建HLS流服务:浏览器可访问但播放器报片段加载错误

解决Express+HLS播放时TS片段404的问题

你的核心问题是HLS清单(m3u8)中的TS片段路径解析错误,加上Express未配置对应路由返回TS文件,导致播放器请求错误路径的文件返回404。以下是具体分析和修复方案:

问题原因拆解

  • 播放器请求/cameras/cam1拿到m3u8后,会把里面的TS片段路径(如index133.ts)解析为相对于当前请求路径的父路径,也就是/cameras/index133.ts,但你的TS文件实际存在./cameras/cam1/目录下,路径不匹配。
  • Express当前只配置了/cameras/cam1的路由,没有处理TS文件的请求,所以任何/cameras/*.ts的请求都会返回404。

具体修复步骤

1. 配置Express静态文件服务,让TS文件可被正确请求

在index.js中添加静态文件服务,将本地./cameras目录映射到/cameras路由下,这样Express会自动处理TS文件的请求:

// 在app.use("/cameras", cameras);之前添加
app.use("/cameras", express.static("./cameras"));

添加后,请求/cameras/cam1/index133.ts时,Express会自动返回./cameras/cam1/index133.ts文件。

2. 修正m3u8中的TS片段路径

打开./cameras/cam1/index.m3u8,把里面的TS片段路径从indexxxx.ts改成cam1/indexxxx.ts,播放器会自动请求正确路径/cameras/cam1/indexxxx.ts。

如果是用FFmpeg生成HLS流,可直接在命令中添加hls_base_url参数指定基础路径,避免手动修改m3u8:

ffmpeg -i rtsp://你的RTSP地址 -c:v h264 -c:a aac -hls_time 2 -hls_list_size 5 -hls_base_url "/cameras/cam1/" -f hls ./cameras/cam1/index.m3u8

3. 优化m3u8请求的响应逻辑

在cameras.js中,设置HLS标准响应头,并用流读取文件(避免大文件占用内存):

const express = require("express");
const router = express.Router();
const fs = require("fs");
const path = require("path");

// 用绝对路径避免环境差异
const camOneStream = path.resolve(__dirname, "../cameras/cam1/index.m3u8");

router.get("/cam1", (req, res) => {
    console.log('Request Incoming for CAM1 from...', new Date());
    
    // 设置HLS标准响应头,已通过全局cors处理跨域,无需重复设置
    res.set({
        'Content-Type': 'application/vnd.apple.mpegurl',
        'Access-Control-Allow-Headers': 'Range',
        'Access-Control-Expose-Headers': 'Content-Length, Content-Range'
    });

    // 流式读取文件,适合大文件场景
    const stream = fs.createReadStream(camOneStream);
    stream.on('error', (err) => {
        console.error(err);
        res.status(500).send(`Server error: ${err.code}`);
    });
    stream.pipe(res);
});

module.exports = router;

额外优化建议

  • 用path.resolve处理文件路径,避免相对路径在不同运行环境下的异常。
  • 实时转码RTSP流时,用child_process.spawn代替exec,能更好地处理进程输出和错误,避免缓冲区溢出。
  • 可给FFmpeg添加hls_delete_threshold参数,自动删除旧的TS片段,避免磁盘空间被占满。

学习资源建议

  • 先掌握HLS基本原理:HLS通过将视频分割为小TS片段,用m3u8清单管理片段,播放器通过请求清单和片段实现流式播放。
  • 熟悉Express静态文件服务用法:了解如何映射本地目录到路由,处理静态资源请求。
  • 学习FFmpeg转HLS核心参数:hls_time(片段时长)、hls_list_size(保留片段数量)、hls_flags(如delete_segments自动删片段)等。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 21:53:23