node.js - 通过连接 ArrayBuffers 客户端实时流式传输视频
问题描述
我正在尝试制作一个简单的实时网络摄像头流媒体(1 个流媒体到许多客户端),但在客户端显示视频时遇到了问题。
我的基本系统是使用 MediaRecorder 将网络摄像头录制成 1000 毫秒的块,使用 WebSocket 发送到服务器,然后广播该记录的所有其他用户,并且这些 ArrayBuffers 被转换并在用户网页上连续播放。这是我的代码:
//recieve video chunks from server
socket.on('video-stream', (stream) => {
console.log(stream);
createVideo(URL.createObjectURL(new Blob(stream)), 1);
});
//record video in chunks, send over websocket
navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then((stream) => {
setInterval(function () {
record(stream, 1000).then((recording) => {
socket.emit('video-stream', {
stream: recording,
room: window.location.pathname.split('/')[0] || '/',
cam: 1,
});
});
}, 1000);
});
var record = (stream, ms) => {
var rec = new MediaRecorder(stream),
data = [];
rec.ondataavailable = (e) => data.push(e.data);
rec.start();
var stopped = new Promise(
(y, n) => ((rec.onstop = y), (rec.onerror = (e) => n(e.error || e.name)))
);
return Promise.all([stopped, wait(ms).then(() => rec.stop())]).then(() => data);
};
var wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
function createVideo(stream, cam) {
var video = document.getElementById('cam-' + cam + '-embed');
video.src = stream;
//video.addEventListener('click', () => {
// if (video.volume != 0) video.volume = 0;
// else video.volume = 1;
//});
}
问题是这需要每 1000 毫秒更改一次页面上视频元素的 src,这使得视频不断闪烁并且不流畅。我需要一些方法来合并客户端的传入视频缓冲区,而不是不断更改视频元素。我一直在试图弄清楚如何在没有运气的情况下做到这一点。有人可以帮我将传入的数据合并到 1 个视频中吗?
我也尝试过:-RTC - 不起作用,因为流媒体用户需要大量带宽。- 在服务器端对视频进行编码和连接,然后将其作为可读流传输到响应中。这也没有奏效。
解决方案
你需要 mediasource 和 sourcebuffer。像这样的东西:
var video = document.querySelector("#video");
video.src = URL.createObjectURL(mediaSource)
socket.on('onChunk', (d) => {
if(mediaSource.readyState == 'open') {
sourceBuffer.appendBuffer(d);
}
})
var mediaSource = new MediaSource();
var sourceBuffer = null;
mediaSource.addEventListener("sourceopen", function()
{
sourceBuffer = mediaSource.addSourceBuffer("video/webm;codecs=vp8,opus");
});
推荐阅读
- java - 我怎样才能使它在这里 \\.(....|..) 点只是数字 [\\.(....|..)0-9]?(Java)正则表达式,匹配?
- javascript - 随机base64图像(javascript)
- react-native - 添加集群样式时性能不佳
- html - Xml 到 XSLT:获取属性值等等
- mysql - 三个表,一个具有引用其他两个表的外键
- emacs - 如何获取我所有 org-agenda 文件的 TODO 总数 - orgmode
- php - 未定义类型'App\Providers\Passport' laravel 8
- react-native - 在 Redux Saga 函数中放置反应导航的方法
- c++ - 在 std::vector 中就地构造一对不可移动的、不可复制的
- javascript - 使用 AJAX 有效负载的 Playwright 步骤的输出执行时间