Webrtc 检测MediaStreamTrack是否为黑色/空白
我正在创建与peerjs的视频聊天 我正在使用以下功能切换摄像头(开/关):Webrtc 检测MediaStreamTrack是否为黑色/空白,webrtc,peer,peerjs,Webrtc,Peer,Peerjs,我正在创建与peerjs的视频聊天 我正在使用以下功能切换摄像头(开/关): function toggleCamera() { localStream.getVideoTracks()[0].enabled = !(localStream.getVideoTracks()[0].enabled); } 调用此函数后,视频变黑,接收器只显示黑屏(按预期工作)。 现在我想检测黑屏/黑屏,这样我就可以向用户显示一些消息或图标,说明相机已禁用,并且没有流 我怎样才能检测到呢?过了一段时间,我
function toggleCamera() {
localStream.getVideoTracks()[0].enabled = !(localStream.getVideoTracks()[0].enabled);
}
调用此函数后,视频变黑,接收器只显示黑屏(按预期工作)。
现在我想检测黑屏/黑屏,这样我就可以向用户显示一些消息或图标,说明相机已禁用,并且没有流
我怎样才能检测到呢?过了一段时间,我终于找到了解决方案:
var previousBytes = 0;
var previousTS = 0;
var currentBytes = 0;
var currentTS = 0;
// peer - new Peer()
// stream - local camera stream (received from navigator.mediaDevices.getUserMedia(constraints))
let connection = peer.call(peerID, stream);
// peerConnection - reference to RTCPeerConnection (https://peerjs.com/docs.html#dataconnection-peerconnection)
connection.peerConnection.getStats(null).then(stats => {
stats.forEach(report => {
if (report.type === "inbound-rtp") {
currentBytes = report.bytesReceived;
currentTS = report.timestamp;
if (previousBytes == 0) {
previousBytes = currentBytes;
previousTS = currentTS;
return;
}
console.log({ previousBytes })
console.log({ currentBytes })
var deltaBytes = currentBytes - previousBytes;
var deltaTS = currentTS - previousTS;
console.log("Delta: " + (deltaBytes / deltaTS) + " kB/s")
previousBytes = currentBytes;
previousTS = currentTS;
}
});
});
这段代码实际上是在函数中,它每秒钟被调用一次。当摄影机打开且未覆盖时,deltaBytes介于100和250之间,当摄影机关闭(编程)或覆盖(用餐巾纸或其他东西)时,摄影机流为黑色/空白,deltaBytes为med 1.5-3kbps。当你们打开相机后,会有一个以deltaBytes为单位的峰值,达到500kbps左右
这是简短的控制台日志:
124.52747252747253 kB/s
202.213 kB/s
194.64764764764766 kB/s
15.313 kB/s (this is where camera is covered)
11.823823823823824 kB/s
11.862137862137862 kB/s
2.164 kB/s
2.005 kB/s
2.078078078078078 kB/s
1.99 kB/s
2.059 kB/s
1.992992992992993 kB/s
159.89810189810188 kB/s (uncovered camera)
502.669 kB/s
314.7927927927928 kB/s
255.0909090909091 kB/s
220.042 kB/s
213.46353646353646 kB/s
编辑:
所以最后我还是照菲利普·汉克说的做了。我创建了主连接,它从页面加载时一直打开,直到用户关闭它。通过这个连接,我正在发送启动视频通话、取消视频会话、打开/关闭摄像头等命令,。。。然后在另一边,我解析这些命令并执行函数
function sendMutedMicCommand() { masterConnection.send(`${commands.MutedMic}`); }
function sendUnmutedMicCommand() { masterConnection.send(`${commands.UnmutedMic}`); }
function sendPromptVideoCallCommand() { masterConnection.send(`${commands.PromptVideoCall}`); }
function sendAcceptVideoCallCommand() { masterConnection.send(`${commands.AcceptVideoCall}`); }
function sendDeclineVideoCallCommand() { masterConnection.send(`${commands.DeclineVideoCall}`); }
Function which handles data:
function handleData(data) {
let actionType = data;
switch (actionType) {
case commands.MutedMic: ShowMuteIconOnReceivingVideo(true); break;
case commands.UnmutedMic: ShowMuteIconOnReceivingVideo(false); break;
case commands.PromptVideoCall: showVideoCallModal(); break;
case commands.AcceptVideoCall: startVideoConference(); break;
case commands.DeclineVideoCall: showDeclinedCallAlert(); break;
default: break;
}
}
const commands = {
MutedMic: "mutedMic",
UnmutedMic: "unmutedMic",
PromptVideoCall: "promptVideoCall",
AcceptVideoCall: "acceptVideoCall",
DeclineVideoCall: "declineVideoCall",
}
然后,当我收到mutedMic命令时,我会显示带有交叉麦克风的图标。当我收到AcceptVideoCall命令时,我创建了另一个对等方,即具有随机ID的videoCallPeer,然后将其发送到另一方。然后,另一方创建另一个具有随机ID的对等方,并使用接收到的ID启动视频会话。常用方法是发送信令消息(通过正常路径或数据通道)。轮询getStats来检测黑帧是一种有效的方法,但计算成本更高