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

如何从React前端传递用户输入的RTSP地址到Node端rtsp-relay服务

实现方案

完全可以实现前端动态传入RTSP地址的需求,不需要额外用fetch发HTTP请求传地址,利用rtsp-relay本身支持的动态url配置能力,在建立WebSocket流连接时把用户输入的地址当参数传给服务端即可,实现逻辑比单独发fetch更简洁。


核心原理

rtsp-relay的proxy配置项中,url字段支持传入函数格式,函数可以读取当前WebSocket请求的上下文信息,动态返回要代理的RTSP地址,刚好适配动态传入地址的场景。

作者文档原文翻译:url配置支持传入(req) => string格式的函数,每次有新的WebSocket连接请求时,都会执行该函数获取实际要代理的RTSP流地址,可用于多摄像头切换、动态地址透传等场景。


服务端改造(Express)

把原来硬编码的url改成动态从请求query中读取的函数,同时增加基础的合法性校验,避免非法请求:

const express = require('express');
const app = express();
const { proxy, scriptUrl } = require('rtsp-relay')(app);

const streamProxy = proxy({
  url: (req) => {
    // 解析WS请求携带的query参数
    const reqUrl = new URL(req.url, `http://${req.headers.host}`);
    const rtspAddress = reqUrl.searchParams.get('rtspUrl');

    // 基础校验:必须是rtsp协议开头的合法地址
    if (!rtspAddress || !rtspAddress.startsWith('rtsp://')) {
      throw new Error('请传入合法的RTSP流地址');
    }

    return rtspAddress;
  },
  verbose: false,
  transport: 'tcp',
});

// 注册WS代理路由
app.ws('/api/stream', streamProxy);

app.get('/', (req, res) => res.send('hg'));

app.listen(5000);

前端改造(React + Material-UI)

不需要额外发fetch请求,用户在输入框填写地址提交后,把地址编码后拼接到WebSocket流地址上,重新建立流连接即可:

import React, { useState, useEffect, useRef } from 'react';
// 保留你原来的Box/FormGroup/FormControl/TextField/Button/Close/Trans等导入

const RtspPlayer = () => {
  // 输入框绑定的临时地址
  const [inputUrl, setInputUrl] = useState('');
  // 当前实际播放的RTSP地址
  const [activeUrl, setActiveUrl] = useState('');
  const playerRef = useRef(null);

  // 输入框值更新
  const handleChange = (e) => {
    setInputUrl(e.target.value);
  };

  // 表单提交:确认使用输入的地址播放
  const handleSubmit = (e) => {
    e.preventDefault();
    if (!inputUrl.startsWith('rtsp://')) {
      alert('请输入rtsp://开头的合法流地址');
      return;
    }
    setActiveUrl(inputUrl);
  };

  // 监听activeUrl变化,重新加载流
  useEffect(() => {
    if (!activeUrl || !playerRef.current) return;
    // 编码RTSP地址,避免特殊字符(@/?/&等)导致参数解析错误
    const wsUrl = `ws://${window.location.host}/api/stream?rtspUrl=${encodeURIComponent(activeUrl)}`;
    
    // 这里替换成你原来硬编码地址能正常播放的逻辑,把WS地址换成上面的wsUrl即可
    // 比如rtsp-relay官方示例里的JSMpeg播放器初始化逻辑
    new JSMpeg.Player(wsUrl, { canvas: playerRef.current });
  }, [activeUrl]);

  return (
    <>
      {/* 流播放画布 */}
      <canvas ref={playerRef} />

      <Box>
        <form onSubmit={handleSubmit}>
          <div>
            <Box>
              <Button
                onClick={() => setActiveUrl('')}
                aria-label="close-settings-popup">
                <Close />
              </Button>
            </Box>
          </div>
          <FormGroup>
            <Box>
              <FormControl>
                <TextField
                  type="text"
                  id="rtsp-url"
                  value={inputUrl}
                  onChange={handleChange}
                  label={<Trans i18nKey="form.cameraForm.source">RTSP地址</Trans>}
                />
              </FormControl>
            </Box>
          </FormGroup>
          <div>
            <Button type="submit" variant="contained" color="primary">
              确认播放
            </Button>
          </div>
        </form>
      </Box>
    </>
  );
};

export default RtspPlayer;

补充说明

  • 如果你坚持想用fetch传地址也可以实现,但属于冗余逻辑:需要先通过POST请求把地址发给服务端存在session/内存中,WS连接时再从服务端存储里读取,会多一次不必要的HTTP请求,还需要处理会话匹配问题,没有任何优势。
  • 服务端必须做地址校验:除了校验rtsp协议头,生产环境建议加IP白名单限制,避免被恶意利用发起内网请求(SSRF风险)。
  • 拼接WS地址时必须用encodeURIComponent编码RTSP地址,否则地址中携带的账号密码、路径参数会被错误截断,导致代理失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 16:18:20