对于使用node.js创建的mjpeg流,如何将其编码为其他格式然后进行流传输?
我使用 nodejs 创建一个小应用程序,将 multipart/x-mixed-replace 数据流式传输到浏览器。
该数据是用图像数据创建的,但图像数据可能会随着时间而改变,因此在浏览器中它看起来像视频。图像数据是从网络摄像头创建的,因此在浏览器中它看起来就像实时流媒体。
但表现不是很好。
我尝试过其他一些方法: - 第一:使用socket.io将图像推送到浏览器,这里我使用图像中的base64数据(推送此数据),并在浏览器中重新创建图像(jpeg):效果很好,但仅限于一两个客户端。 _ 第二:使用从浏览器到nodejs服务器的轮询..这不喜欢我。
所以这是代码:(我的nodejs服务器的部分代码)我使用express来制作http服务器:
app.get('/videoStream',function(req,response){
response.writeHead(200,{
'Content-Type': 'multipart/x-mixed-replace;boundary="' + boundary + '"',
'Connection': 'keep-alive',
'Expires': 'Fri, 01 Jan 1990 00:00:00 GMT',
'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate',
'Pragma': 'no-cache'
});
response.write('--'+boundary+'\n');
events.addListener('imagen_recibida',function(){
fs.readFile(__dirname + '/image.jpeg',function(err,data){
if(err) return send404(response);
response.write('Content-Type: image/jpeg\n Content-Length: '+data.length+'\n\n');
response.write(data);
response.write('\n--'+boundary+'\n');
});
});
当事件“imagen_recibida”上升时,它从磁盘读取图像并将数据写入浏览器。
那么两个问题:
有没有什么方法可以提高这个性能? (将图像写入磁盘,然后读取并发送到浏览器看起来不是一个好技巧)
是否有一种方法可以将其编码为另一种格式以提高性能?
多谢。
PD:图像被写入磁盘,然后读取发送到浏览器,因为我通过RPC调用从另一个函数中的另一个进程接收图像数据。
I create a little application with nodejs that stream a multipart/x-mixed-replace data to browser.
This data is created with image data, but the image data may change over time, so in the browser it looks like a video. The image data is created from a webcam, so in the browser it looks like live streaming.
But the performance isn't very good.
I've tried some other approaches:
- First: Use socket.io to push images to browser, here i use the base64 data from the image (push this data) and in the browser i recreate the image (jpeg): works good, but only with one or two clients.
_ Second: Use polling from browser to nodejs server.. this doesn't like me.
So this is the code: (some part of the code of my nodejs server) I use express to make the http server:
app.get('/videoStream',function(req,response){
response.writeHead(200,{
'Content-Type': 'multipart/x-mixed-replace;boundary="' + boundary + '"',
'Connection': 'keep-alive',
'Expires': 'Fri, 01 Jan 1990 00:00:00 GMT',
'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate',
'Pragma': 'no-cache'
});
response.write('--'+boundary+'\n');
events.addListener('imagen_recibida',function(){
fs.readFile(__dirname + '/image.jpeg',function(err,data){
if(err) return send404(response);
response.write('Content-Type: image/jpeg\n Content-Length: '+data.length+'\n\n');
response.write(data);
response.write('\n--'+boundary+'\n');
});
});
When the event "imagen_recibida" rise, it reads the image from disk and write the data to browser.
So the two questions:
Is there any approach to improve the performance of this? (write the image to disk and then read to send to browser doesn't see like a good trick)
Is there a method to encode this into another format to improve performance?
Thanks a lot.
PD: The image is written to disk and then read to send to browser, because I receive the image data from another process in another function via RPC calls.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以尝试使用 socket.io 仅推送生成文件的 URL,然后在客户端上使用 Javascript 替换显示框架的 img 标签的“src”属性。在这种情况下,您可以使用常规 Web 服务器来提供静态文件,或使用连接模块来提供静态文件。这可能比推送 Base64 编码数据更有效。
如果您打算使用上面的方法,至少不要使用 fs.readFile ...这每次都会将整个文件带入内存。使用 util.pump() 或手动将 ReadStream/WriteStream 与“drain”事件一起使用,以最大限度地减少内存使用。当连接多个客户端时,您的性能问题可能是由于垃圾收集造成的。
另一种方法可能是有一个后台进程,将图像提供给 ffmpeg 以编码正确的视频流,然后提供给 ffserver 将其流式传输到视频播放器。
You could trying using socket.io to just push URLs of the generated files and then on the client use Javascript to replace the "src" attribute of the img tag showing the frame. In this case you could use a regular web server for server the static files or the connect module for serving static files. This is likely more efficient than pushing the base64 encoded data.
If you are going to use the approach above, at least don't use fs.readFile... this brings the whole file into memory every time. Use util.pump() or manually use ReadStream/WriteStream with 'drain' events to minimize memory usage. Its possible that your performance issues are due to garbage collection when there are multiple clients connected.
Another approach might be to have a background process that feeds the images to ffmpeg to encode a proper video stream and then to ffserver to stream it to a video player.