Webrtc 检测MediaStreamTrack是否为黑色/空白

Webrtc 检测MediaStreamTrack是否为黑色/空白,webrtc,peer,peerjs,Webrtc,Peer,Peerjs,我正在创建与peerjs的视频聊天 我正在使用以下功能切换摄像头(开/关): function toggleCamera() { localStream.getVideoTracks()[0].enabled = !(localStream.getVideoTracks()[0].enabled); } 调用此函数后,视频变黑,接收器只显示黑屏(按预期工作)。 现在我想检测黑屏/黑屏,这样我就可以向用户显示一些消息或图标,说明相机已禁用,并且没有流 我怎样才能检测到呢?过了一段时间,我

我正在创建与peerjs的视频聊天

我正在使用以下功能切换摄像头(开/关):

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来检测黑帧是一种有效的方法,但计算成本更高