我想在使用ReactJS构建的网页上显示网络摄像机的实时镜头。
我在互联网上找到了一些解决方案,但它们提供了使用 http url 的解决方案。但是我的相机有用户名和密码,但我不知道如何将用户名/密码嵌入到 http url 中。
我有一个正常运行的 rtsp url 以及用户名/密码。
我想在 React 应用程序中添加一个视频元素,如下所示:
render() {
return (
<div>
<video
....
/>
</div>
);
}
我的功能 rtsp 网址如下:
rtsp://username:[email protected]:554
您的解决方案应由两部分组成:一个将从 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 你可以使用它来做到这一点:
我认为你需要一个特殊的媒体播放器。您尝试过hls.js吗?您可以包含该库,然后构建您自己的组件并将链接传递给它,以便它可以播放。
我们需要使用第三方 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
您可以随意重构它,但这应该为您提供在 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>
)}