WebRTC PeerConnection在Safari 11上显示黑屏(Mac OS X 10.13)

时间:2018-01-26 10:26:50

标签: javascript macos safari webrtc

我正在使用WebRTC将视频(无音频)从Raspberry Pi上的网络摄像头流式传输到用户的浏览器。在RPi上,我已经安装了kclyu/rpi-webrtc-streamer,我也从该回购中复制了浏览器客户端的一些测试代码。

在我的Mac OS X 10.13桌面上,客户端代码在Chrome 63和Firefox 58上显示视频就好了,但在Safari 11上,我得到a black screen (albeit of the correct size)。虽然Safari支持似乎在WebRTC中是最新的,但我读过的内容表明它至少应该能够在这个版本的Safari中支持带有H.264编解码器的RTCPeerConnection。关于可能出现什么问题的任何想法?

这是我们JavaScript的摘录(它不是最好的,但希望只有这里的部分才能理解):

var pcConfig = {"iceServers": [{"urls": "stun:stun.l.google.com:19302"}]};
var pcOptions = {optional: [{DtlsSrtpKeyAgreement: true}]};

this.createPeerConnection = function() {
    var that = this;
    this.peerConnection = new RTCPeerConnection(pcConfig, pcOptions);
    this.peerConnection.onicecandidate = function(event) {
        if (event.candidate) {
            var candidate = {
                type: 'candidate',
                label: event.candidate.sdpMLineIndex,
                id: event.candidate.sdpMid,
                candidate: event.candidate.candidate
            };
            // send(data) sends the data over the established WebSocket connection
            send(JSON.stringify(candidate));
        }
    };
    this.peerConnection.onconnecting = onSessionConnecting.bind(this);
    this.peerConnection.onopen = onSessionOpened.bind(this);
    this.peerConnection.onaddstream = onRemoteStreamAdded.bind(this);
    this.peerConnection.onremovestream = onRemoteStreamRemoved.bind(this);
}

function onRemoteStreamAdded(event) {
    this.videoEl.srcObject = event.stream;
}

// the rest of the callbacks only log, and do nothing else
// includes onSessionConnecting, onSessionOpened, onRemoteStreamRemoved

this.doHandlePeerMessage = function(data) {
    ++this.messageCounter;
    var dataJson = JSON.parse(data);
    if (dataJson["type"] == "offer") {
        var that = this;
        var data = '';
        var sdp_returned = forceChosenVideoCodec(dataJson.sdp, 'H264/90000');
        dataJson.sdp = sdp_returned;
        this.createPeerConnection();
        this.peerConnection.setRemoteDescription(
            new RTCSessionDescription(dataJson),
            onRemoteSdpSuccess,
            onRemoteSdpError
        );
        this.peerConnection.createAnswer({iceRestart: false}).then(function(sessionDescription) {
            data = JSON.stringify(sessionDescription);
            return that.peerConnection.setLocalDescription(sessionDescription);
        }).then(function() {
            // again, send(data) sends the data over the established WebSocket connection
            send(data);
        }).catch(function(error) {
            // log error
        });
    } else if (dataJson["type"] == "candidate") {
        var candidate = new RTCIceCandidate({sdpMLineIndex: dataJson.label, candidate: dataJson.candidate});
        this.peerConnection.addIceCandidate(candidate, aic_success_cb, aic_failure_cb);
    }
}

// again, the callbacks only log, and do nothing else
// includes aic_success_cb, aic_failure_cb, onRemoteSdpSuccess, onRemoteSdpError

(我对WebRTC很新,所以如果有任何明显的错误,请告诉我!)

3 个答案:

答案 0 :(得分:0)

我认为您的问题是由于未在您的html视频元素中添加playsinline而引起的。

所以它必须是这样的:

<video id="local-video" playsinline autoplay muted></video>
<video id="remote-video" playsinline autoplay></video>

答案 1 :(得分:0)

我遇到了类似的问题,视频元素的建议道具没有帮助。为我解决的问题是为Safari用户添加了一个按钮,该按钮在视频元素上调用了play方法:

<button onclick="document.getElementById('webcam').play()">Play</button>

如果您尝试从控制台或以编程方式调用play方法,则会得到:

  

未处理的承诺拒绝:NotAllowedError(DOM异常35):在当前上下文中,用户代理或平台不允许该请求,可能是因为用户拒绝了权限

答案 2 :(得分:-1)

您需要在视频广告代码中添加一些道具

<video playsinline controls autoplay/>