有懂node、ffmpeg、html处理实时视频流,懂如何在前端html或vue项目中使用video直接播放rtsp流的大佬嘛,求指教
我根据一些网上的资料做了些许尝试,实现了以下效果:
- 利用ffmpeg、JSFpeg、ws将视频帧渲染到canvas里面去展示,主要流程为从RTSP源获取视频流并将其转换为MPEG-1格式,然后通过WebSocket协议广播给客户端。
出处链接

- 利用ffmpeg、flv.min.js、ws,将rtsp转成flv推到一个rtmp地址,最后用video标签展示最终视频。
出处链接

- 自己尝试改写node-media-server中videoStream源码,将rtsp重新编码成了H264格式的mpegts,但是始终无法在html中的video标签正常播放。
// 重新改写过后的videoStream.js
const fs = require('fs');
const path = require('path');
const ws = require('ws');
const util = require('util');
const events = require('events');
const child_process = require('child_process');
class VideoStream extends events.EventEmitter {
constructor(options) {
super();
this.options = options;
this.name = options.name;
this.streamUrl = options.streamUrl;
this.width = options.width;
this.height = options.height;
this.wsPort = options.wsPort;
this.inputStreamStarted = false;
this.stream = undefined;
this.ffmpegProcess = undefined;
this.startH264Stream();
this.pipeStreamToSocketServer();
}
startH264Stream() {
const ffmpegPath = this.options.ffmpegPath || 'ffmpeg';
const ffmpegArgs = [
'-i', this.streamUrl,
'-c:v', 'libx264',
'-preset', 'ultrafast',
'-tune', 'zerolatency',
'-b:v', '1M',
'-f', 'mpegts',
'-'
];
this.ffmpegProcess = child_process.spawn(ffmpegPath, ffmpegArgs);
this.ffmpegProcess.stdout.on('data', (data) => {
this.emit('camdata', data);
});
this.ffmpegProcess.stderr.on('data', (data) => {
console.error(`FFmpeg stderr: ${data}`);
});
this.ffmpegProcess.on('close', (code) => {
console.error(`FFmpeg process exited with code ${code}`);
this.emit('exitWithError');
});
}
pipeStreamToSocketServer() {
this.wsServer = new ws.Server({ port: this.wsPort });
this.wsServer.on("connection", (socket, request) => {
this.onSocketConnect(socket, request);
});
this.wsServer.broadcast = function(data) {
this.clients.forEach((client) => {
if (client.readyState === ws.OPEN) {
client.send(data, { binary: true });
} else {
console.log(`Error: Client from remoteAddress ${client._socket.remoteAddress} not connected.`);
}
});
};
this.on('camdata', (data) => {
this.wsServer.broadcast(data);
});
}
onSocketConnect(socket, request) {
const streamHeader = Buffer.alloc(8);
streamHeader.write('jsmp', 0, 4);
streamHeader.writeUInt16BE(this.width, 4);
streamHeader.writeUInt16BE(this.height, 6);
socket.send(streamHeader, { binary: true });
console.log(`${this.name}: New WebSocket Connection (${this.wsServer.clients.size} total)`);
socket.remoteAddress = request.connection.remoteAddress;
socket.on("close", (code, message) => {
console.log(`${this.name}: Disconnected WebSocket (${this.wsServer.clients.size} total)`);
});
}
stop() {
if (this.ffmpegProcess) {
this.ffmpegProcess.kill();
this.ffmpegProcess = undefined;
}
if (this.wsServer) {
this.wsServer.close();
}
this.inputStreamStarted = false;
return this;
}
}
module.exports = VideoStream
1396

被折叠的 条评论
为什么被折叠?



