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

React中HLS流媒体无法播放问题求助(树莓派4推流场景)

问题描述

我在树莓派4上搭建视频推流服务:用picamera2采集视频,通过内部集成的ffmpeg生成HLS流媒体的m3u8文件,再用http.server托管静态HLS文件。

用以下静态HTML测试时,推流可在其他设备正常播放:

<!DOCTYPE html>
<html>
  <head>
    <meta charset=utf-8 />
    <title>Your title</title>

    <link href="https://unpkg.com/video.js/dist/video-js.css" rel="stylesheet">
    <script src="https://unpkg.com/video.js/dist/video.js"></script>
    <script
      src="https://unpkg.com/videojs-contrib-hls/dist/videojs-contrib-hls.js"></script>
  </head>
  <body>
    <video id="my_video_1" class="video-js vjs-fluid vjs-default-skin" controls
      preload="auto"
      data-setup='{}'>
      <source src="http://192.168.1.8:8000/live/stream.m3u8"
        type="application/x-mpegURL">
    </video>

    <script>
var player = videojs('my_video_1');
player.play();
</script>

  </body>
</html>

但在React前端中无法正常加载该推流:用ReactPlayer编写的代码能播放在线HLS链接,但加载树莓派的推流时一直处于加载状态。也试过video.js、react-hls-player等库,ReactPlayer在兼容性上表现最优,但针对该推流仍无法工作。React代码如下:

import * as React from 'react';
import { useContext } from "react";
import Card from '@mui/material/Card';
import CardHeader from '@mui/material/CardHeader';
import CardContent from '@mui/material/CardContent';
import Avatar from '@mui/material/Avatar';
import { red } from '@mui/material/colors';
import VideoCameraBackIcon from '@mui/icons-material/VideoCameraBack';
import ReactPlayer from 'react-player/lazy'
import { Typography } from '@mui/material';
// import { UserContext } from "./context/UserContext";

export default function VideoCard({ alerter }) {
    var url = "http://192.168.1.8:8000/live/stream.m3u8"
    return (
        <Card sx={{ height: '820px' }} variant="outlined">
            <CardHeader
                avatar={
                    <Avatar sx={{ bgcolor: red[500] }} >
                        <VideoCameraBackIcon />
                    </Avatar>
                }
                title={<Typography component="div" variant="h6">
                    Video Stream
                </Typography>}
                subheader="from Camera"
            />
            <CardContent>
                <div >
                    <ReactPlayer
                        playing
                        url={url}
                        controls={true}
                        width="100%"
                        height="100%" />
                </div>
            </CardContent>
        </Card>
    );
}
解决方案

1. 解决跨域(CORS)问题

React开发服务器(通常是localhost:3000)和树莓派的http.server属于不同域名,默认情况下http.server不会返回CORS允许头,导致浏览器拦截请求。

替换默认的http.server,用自定义Python脚本添加CORS头:

from http.server import HTTPServer, SimpleHTTPRequestHandler

class CORSRequestHandler(SimpleHTTPRequestHandler):
    def end_headers(self):
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, OPTIONS')
        self.send_header('Access-Control-Allow-Headers', 'Content-Type')
        super().end_headers()

if __name__ == '__main__':
    HTTPServer(('', 8000), CORSRequestHandler).serve_forever()

将该脚本保存为server.py,在HLS文件目录执行python server.py启动服务,替代原来的python -m http.server。

2. 优化HLS流的兼容性

调整picamera2的ffmpeg参数,确保生成的HLS流符合浏览器兼容标准:

  • 设置较短的分片时长(比如2秒),降低加载延迟
  • 限制分片列表长度,避免浏览器加载过多历史片段
  • 使用H.264 baseline编码 profile,确保全浏览器支持

修改picamera2的录制配置:

from picamera2 import Picamera2
from picamera2.encoders import H264Encoder
from picamera2.outputs import FfmpegOutput

picam2 = Picamera2()
# 配置视频参数,可根据需求调整分辨率
video_config = picam2.create_video_configuration(main={"size": (1280, 720)})
picam2.configure(video_config)

encoder = H264Encoder(bitrate=1000000)  # 调整码率适配网络
# 添加ffmpeg的HLS兼容参数
output = FfmpegOutput(
    'live/stream.m3u8',
    audio=False,
    options={
        'hls_time': '2',
        'hls_list_size': '5',
        'hls_flags': 'delete_segments',
        'vcodec': 'libx264',
        'profile:v': 'baseline',
        'preset': 'ultrafast'  # 快速编码适配树莓派性能
    }
)
picam2.start_recording(encoder, output)

3. 调整ReactPlayer配置

强制ReactPlayer使用hls.js内核,并配置低延迟选项:

  1. 先安装依赖:npm install hls.js
  2. 修改ReactPlayer组件配置:
<ReactPlayer
  playing
  url={url}
  controls={true}
  width="100%"
  height="100%"
  config={{
    file: {
      hlsOptions: {
        enableWorker: true,
        lowLatencyMode: true,
        maxBufferLength: 3  // 限制缓冲长度,降低延迟
      }
    }
  }}
/>

4. 验证网络连通性

  • 在React设备上执行curl http://192.168.1.8:8000/live/stream.m3u8,确认能获取到m3u8文件内容
  • 检查树莓派的8000端口是否开放,没有被防火墙拦截(树莓派默认无防火墙,若开启需添加规则)
  • 确保React设备和树莓派在同一局域网网段内

内容的提问来源于stack exchange,提问作者Shashi Kumar Fagna

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 21:05:25