如何将来自 RTSP url 的 IP 摄像头源显示到 ReactJS 应用程序页面上?

问题描述 投票:0回答:4

我想在使用ReactJS构建的网页上显示网络摄像机的实时镜头。

我在互联网上找到了一些解决方案,但它们提供了使用 http url 的解决方案。但是我的相机有用户名和密码,但我不知道如何将用户名/密码嵌入到 http url 中。

我有一个正常运行的 rtsp url 以及用户名/密码。

我想在 React 应用程序中添加一个视频元素,如下所示:

render() {
   return (
     <div>
       <video
         ....
       />
     </div>
   );
}

我的功能 rtsp 网址如下:

rtsp://username:[email protected]:554

reactjs rtsp ip-camera
4个回答
4
投票

您的解决方案应由两部分组成:一个将从 RTSP 读取流的 NodeJS 应用程序和一个将从 NodeJS 应用程序获取该流的客户端画布。

将其视为“代理”

在服务器上:

Stream = require('node-rtsp-stream')
stream = new Stream({
  name: 'name',
  streamUrl: 'rtsp://username:[email protected]:554',
  wsPort: 9999,
  ffmpegOptions: { // options ffmpeg flags
    '-stats': '', // an option with no neccessary value uses a blank string
    '-r': 30 // options with required values specify the value after the key
  }
})

在客户端:

client = new WebSocket('ws://NODEJS_SERVER_IP:9999')
player = new jsmpeg(client, {
  canvas: canvas // Canvas should be a canvas DOM element
})

有一个很好的 npm 你可以使用它来做到这一点:

https://www.npmjs.com/package/node-rtsp-stream


0
投票

我认为你需要一个特殊的媒体播放器。您尝试过hls.js吗?您可以包含该库,然后构建您自己的组件并将链接传递给它,以便它可以播放。


0
投票

我们需要使用第三方 API,或者我们也可以使用 nginx 将闭路电视摄像机镜头显示到 React 应用程序中。正如我们所知,React 有虚拟 DOM,它不允许显示 rtsp 数据流,它最大允许接受 http 流数据或 hls 流数据,但进入 html,我们可以使用 websockets 显示流数据。因为没有虚拟 DOM .

Node js 代码:

       const express = require('express');
const Stream = require('node-rtsp-stream');

const app = express();
const port = 3002;
let stream = null;

app.get('/stream/:id', (req, res) => {
  const id = req.params.id;
  const newRtspStreamUrl = 'rtsp://*****:*******@address'

  // Create the WebSocket stream only if it doesn't exist or the RTSP URL has changed
  if (!stream || currentRtspStreamUrl !== newRtspStreamUrl) {
    if (stream) {
      stream.stop();
    }
    stream = new Stream({
      name: 'Camera Stream',
      streamUrl: newRtspStreamUrl,
      wsPort: 9999
    });
    currentRtspStreamUrl = newRtspStreamUrl;
  }


  res.send('Streaming started');
});

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

在这里,我们正在创建一个 websocket,并为其分配端口,当 rtsp 链接发生变化时,我们将停止流,但如果没有更改,则将在同一端口上创建新套接字,从而导致错误。

现在我们将在 REACTJS 中创建一个前端:

公开>>INDEX.html

     <!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <title>React App</title>
    <style>
      .camera {
  background-color: aqua;
  width: 800px;
  height: 400px;
}
    </style>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <div id="cctv" style="position: fixed; display: none;width: 100%;height: 100%;background-color: aqua;">
      <button onclick="shoot1(),cctv_call()">Go back to dashboard</button>
      <p id="asdf">yasawnth</p>
        <input id="cctv_inputvalue" type="text" />
        <button onclick="cctv_call() ">Show stream</button>
      <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
      <script>
        // Fetch the stream URL
      
       
        window.onload = cctv_call();
        function cctv_call(){
          if(window.document.getElementById("cctv_inputvalue").value){
            sessionStorage.cameraid = window.document.getElementById("cctv_inputvalue").value;

          }
          else{
            sessionStorage.cameraid = sessionStorage.getItem("cameraid");
            window.document.getElementById("cctv_inputvalue").value = sessionStorage.getItem("cctv_inputvalue");
           
          }
          if(sessionStorage.getItem("root")=="none"){
                        root.style.display = "none";
                        cctv.style.display = "block";
          }
          const i=sessionStorage.getItem("cameraid");
          console.log(i);
        
          axios.get('http://localhost:3002/stream/'+i)
            .then(response => {
              const streamUrl = response.data.streamUrl;
              videoPlayer.src = streamUrl;
              console.log(videoPlayer.src)
            })
            .catch(error => {
              console.error('Error fetching video stream:', error);
            });
        }
      </script>
      <h1>Streaming Video</h1>
      <canvas class="camera" id="videoCanvas" style="background-color: aqua;" width="640" height="480"></canvas>
      <script src="jsmpeg.min.js"></script>
      <script>
        const canvas = document.getElementById('videoCanvas');
        const url = 'ws://localhost:9999';
        const player = new JSMpeg.Player(url, { canvas });
        // Handle WebSocket connection errors
        player.onError = (error) => {
          console.error('WebSocket error:', error);
        };
        // Handle WebSocket connection close
        player.onSourceEnd = () => {
          console.log('WebSocket connection closed');
        };
        //axios req
      </script>
    </div>
  </body>
  <script>

    function shoot1(){
      
      root.style.display="block";
      cctv.style.display="none";
      sessionStorage.root='block';
      sessionStorage.cctv = "none";
    
    }
  </script>
</html>

您需要使用 JSMPEG 在前端传输数据,现在我们需要编写

APP.JS

import React from 'react';
import './App.css';


const App = () => {
  const root=window.document.getElementById('root')
  const cctv=window.document.getElementById('cctv')
 
  const shoot = () => {
    root.style.display="none";
    cctv.style.display="block";
    sessionStorage.setItem("root","none");
    sessionStorage.setItem("cctv","block");
  }
  return (
    <div className='ra'>
      <button onClick={shoot}>cctv dashboard</button>
    </div>
  );
};

导出默认App; 这就是它的工作原理

@yaswanthsaipilla @bharathmaradana


0
投票

您可以随意重构它,但这应该为您提供在 React js 应用程序中成功显示 rtsp url 的基本块。

还要确保 rtsp feed 有效,您可以使用 vlc 媒体应用程序进行测试。

在服务器上

const express = require("express")
const Stream = require("node-rtsp-stream")
const cors = require("cors")

const app = express()
const port = 3002
let stream = null

app.use(
  cors({
    origin: "http://localhost:3000",
    credentials: true,
  })
)

app.get("/stream", (req, res) => {
  const newRtspStreamUrl = req.query.rtsp
  let currentRtspStreamUrl = ""

  // Create the WebSocket stream only if it doesn't exist or the RTSP URL has changed
  if (!stream || currentRtspStreamUrl !== newRtspStreamUrl) {
    if (stream || newRtspStreamUrl === "stop") {
      stream.stop()
    }
    stream = new Stream({
      name: "Camera Stream",
      streamUrl: newRtspStreamUrl,
      wsPort: 9999,
    })
    currentRtspStreamUrl = newRtspStreamUrl
  }

  res.send(200).json({ url: `ws://127.0.0.1:9999` })
})

app.listen(port, () => {
  console.log(`Server running on port ${port}`)
})

在客户端

import React from "react"
import JSMpeg from "@cycjimmy/jsmpeg-player"
import axios from "axios"

const StreamPlayer = () => {

useEffect(()=>{
    let canvas = document.getElementById("video-canvas")
    let url = "ws://localhost:9999"
    new JSMpeg.Player(url, { canvas: canvas })
  },[])

const rtspurl = ""//enter the rtsp url here
  
const httpRequest = (url) => {
   axios.get(`http://127.0.0.1:3002/stream?rtsp=${url}`)
}
    
const startRTSPFeed = () => {
   httpRequest(rtspurl)
}
    
const stopRTSPFeed = () => {
   httpRequest("stop")
}

return(
   <div>
      <div>
        <canvas id="video-canvas"></canvas>
      </div>
      <div>
        <button onClick={startRTSPFeed}>Start RTSP Feed</button>
        <button onClick={stopRTSPFeed}> Stop RTSP Feed</button>
      </div>
   </div>
)}
© www.soinside.com 2019 - 2024. All rights reserved.