我创建了一个 Node js 服务器来 1)接收 udp 中的图像并将其转换为视频和 2)在网站上显示它
node js 服务器代码:
const express = require('express');
const dgram = require('dgram');
const fs = require('fs');
const ffmpeg = require('fluent-ffmpeg');
const path = require('path');
const WebSocket = require('ws');
const app = express();
const httpPort = 3000;
const imageDir = path.join(__dirname, 'images');
if (!fs.existsSync(imageDir)) {
fs.mkdirSync(imageDir);
}
let imageCount = 0;
const udpPort = 15002;
const udpHost = '127.0.0.1';
const server = dgram.createSocket('udp4');
const wss = new WebSocket.Server({ noServer: true });
const createVideo = () => {
const outputVideo = path.join(__dirname, 'output_video.mp4');
ffmpeg()
.input(path.join(imageDir, '%d.jpg'))
.inputOptions('-framerate 30')
.output(outputVideo)
.outputOptions('-c:v libx264')
.on('end', () => {
console.log('Vidéo créée avec succès !');
wss.clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send('new-video');
}
});
})
.on('error', (err) => {
console.log('Erreur lors de la création de la vidéo:', err);
})
.run();
};
app.get('/feed-video', (req, res) => {
const videoPath = path.join(__dirname, 'output_video.mp4');
res.sendFile(videoPath);
});
server.on('message', (msg, rinfo) => {
console.log(`Reçu message de ${rinfo.address}:${rinfo.port}`);
const imageFilePath = path.join(imageDir, `${imageCount}.jpg`);
fs.writeFileSync(imageFilePath, msg);
console.log(`Image ${imageCount}.jpg reçue et sauvegardée`);
imageCount++;
if (imageCount > 100) {
createVideo();
imageCount = 0;
}
});
server.on('listening', () => {
const address = server.address();
console.log(`Serveur UDP en écoute sur ${address.address}:${address.port}`);
});
app.server = app.listen(httpPort, () => {
console.log(`Serveur HTTP et WebSocket démarré sur http://localhost:${httpPort}`);
});
app.server.on('upgrade', (request, socket, head) => {
wss.handleUpgrade(request, socket, head, (ws) => {
wss.emit('connection', ws, request);
});
});
server.bind(udpPort, udpHost);
html 页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Drone Video Feed</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #1a1a1a;
color: #ffffff;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}
h1 {
margin-bottom: 20px;
font-size: 2rem;
text-shadow: 1px 1px 5px #00bcd4;
}
video {
width: 80%;
max-width: 600px;
border: 2px solid #00bcd4;
border-radius: 8px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
}
</style>
</head>
<body>
<h1>Drone Video Feed</h1>
<video id="video" controls autoplay></video>
<script>
const video = document.getElementById('video');
const ws = new WebSocket('ws://localhost:3000');
ws.onmessage = (event) => {
const blob = new Blob([event.data], { type: 'video/mp4' });
video.src = URL.createObjectURL(blob);
video.play();
};
</script>
</body>
</html>
请你帮我解决这个问题吗?
我尝试使用 websocket 但没有成功。 视频已正确创建,当我重新加载页面时,播放器将播放新视频
但是我本来可以看到直播,而不必一直重新加载我的页面
为了在不重新加载页面的情况下直播视频,WebRTC 是比 WebSockets 更适合实时视频流的技术。 WebRTC 允许低延迟、点对点通信,广泛用于直播场景。
以下是示例代码:
Node.js 服务器:
const express = require('express');
const dgram = require('dgram');
const { Server } = require('socket.io');
const http = require('http');
const app = express();
const server = http.createServer(app);
const io = new Server(server);
const udpPort = 15002;
const udpHost = '127.0.0.1';
const udpServer = dgram.createSocket('udp4');
let clients = [];
// Serve static HTML file
app.use(express.static(__dirname));
udpServer.on('message', (msg, rinfo) => {
console.log(`Received message from ${rinfo.address}:${rinfo.port}`);
// Broadcast the image frame to connected WebRTC clients
clients.forEach(client => client.emit('video-frame', msg));
});
udpServer.on('listening', () => {
const address = udpServer.address();
console.log(`UDP Server listening on ${address.address}:${address.port}`);
});
io.on('connection', (socket) => {
console.log('New WebRTC client connected');
clients.push(socket);
socket.on('disconnect', () => {
console.log('WebRTC client disconnected');
clients = clients.filter(client => client !== socket);
});
});
// Start the servers
udpServer.bind(udpPort, udpHost);
server.listen(3000, () => {
console.log('HTTP and WebSocket server running on http://localhost:3000');
});
HTML代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Drone Video Feed</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #1a1a1a;
color: #ffffff;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}
h1 {
margin-bottom: 20px;
font-size: 2rem;
text-shadow: 1px 1px 5px #00bcd4;
}
video {
width: 80%;
max-width: 600px;
border: 2px solid #00bcd4;
border-radius: 8px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
}
</style>
</head>
<body>
<h1>Drone Video Feed</h1>
<video id="video" autoplay muted></video>
<script>
const video = document.getElementById('video');
const socket = io('http://localhost:3000');
const mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', () => {
const sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.42E01E"');
socket.on('video-frame', (frame) => {
const blob = new Blob([frame], { type: 'video/mp4' });
blob.arrayBuffer().then(buffer => {
sourceBuffer.appendBuffer(buffer);
});
});
});
</script>
<script src="https://cdn.socket.io/4.5.4/socket.io.min.js"></script>
</body>
</html>
希望这对您有帮助。