【问题标题】:Chrome MediaRecorder API can not record REMOTE video from FreeSwitch, but local media can be recordedChrome MediaRecorder API 无法从 FreeSwitch 录制 REMOTE 视频,但可以录制本地媒体
【发布时间】:2018-02-08 17:19:38
【问题描述】:

问题:当我们使用内置的 MediaRecorder API 在 Chrome 中录制 remote 视频流(仅限)时,它会返回 blob 对象;当我们使用 Blob API 合并所有 blob 文件并创建一个对象 URL 时,它无法在 html5 播放器中播放。

我在客户端使用 jssip,在服务器端使用 FreeSwitch。

示例代码:

var options = {
    videoBitsPerSecond: 2500000,
    ignoreMutedMedia: true,
    mimeType: 'video/webm'
}
_this.recorder = new MediaRecorder(e.stream, options);
_this.recorder.ondataavailable = function (event) {
    if (event.data.size > 0) {
        chunks.push(event.data);
    }
};
_this.recorder.onstop = function () {
    var superBuffer = new Blob(chunks, {
        type: 'video/webm'
    });

    var url = URL.createObjectURL(superBuffer);
    var a = document.createElement('a');
    document.body.appendChild(a);
    a.style = 'display: none';
    a.href = url;
    a.download = 'test.webm';
    a.click();
}

_this.recorder.start();

通过该代码示例,我们正在从远程流中录制视频。停止录制后,我们将创建一个无法在 Chrome 中播放的 blob 文件。

blob 文件具有预期的大小和类型。

如果我们把_this.recorder = new MediaRecorder(e.stream, options)改成_this.recorder = new MediaRecorder(localMediaStream, options),那么文件就可以被录制,并且可以播放了。

如果我们直接向视频对象播放远程或本地流,则视频正在播放,这没有问题。

REMOTE 和 LOCAL 媒体流的代码在 FireFox 中运行良好。问题仅在 Chrome 中。

我的mediaConstraints 是这个:

mediaConstraints = {
    audio: false,
    video: true
}

对于那些mediaConstraints,录制不起作用。

但是当我将mediaConstraints 更改为:

mediaConstraints = {
    audio: true,
    video: true
}

...然后可以录制远程视频,并且可以在 Chrome 中播放。

这是邀请 SDP 正文:

>     v=0
>     o=- 8064839774906199900 2 IN IP4 127.0.0.1
>     s=-
>     t=0 0
>     a=group:BUNDLE video
>     a=msid-semantic: WMS mn9jKVP8YQWdoANy4IuThCbAkYDNH6Rn48wy
>     m=video 45331 UDP/TLS/RTP/SAVPF 96 98 100 102 127 97 99 101 125
>     c=IN IP4 x.x.x.x
>     a=rtcp:9 IN IP4 0.0.0.0
>     a=candidate:2702239670 1 udp 2122260223 192.168.1.103 45331 typ host generation 0 network-id 2 network-cost 10
>     a=candidate:542695682 1 udp 1686052607 x.x.x.x 45331 typ srflx raddr 192.168.1.103 rport 45331 generation 0 network-id 2
> network-cost 10
>     a=candidate:4019395398 1 tcp 1518280447 192.168.1.103 9 typ host tcptype active generation 0 network-id 2 network-cost 10
>     a=ice-ufrag:WoJH
>     a=ice-pwd:0plhRV6alFSPYNFZzPeLIQjD
>     a=fingerprint:sha-256 76:74:B1:90:73:A5:7C:AC:1F:D5:F6:99:63:FC:60:6F:07:C0:F6:6A:CB:78:30:A4:19:3E:09:27:F0:EB:04:5E
>     a=setup:actpass
>     a=mid:video
>     a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
>     a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
>     a=extmap:4 urn:3gpp:video-orientation
>     a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
>     a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
>     a=sendrecv
>     a=rtcp-mux
>     a=rtcp-rsize
>     a=rtpmap:96 VP8/90000
>     a=rtcp-fb:96 ccm fir
>     a=rtcp-fb:96 nack
>     a=rtcp-fb:96 nack pli
>     a=rtcp-fb:96 goog-remb
>     a=rtcp-fb:96 transport-cc
>     a=rtpmap:98 VP9/90000
>     a=rtcp-fb:98 ccm fir
>     a=rtcp-fb:98 nack
>     a=rtcp-fb:98 nack pli
>     a=rtcp-fb:98 goog-remb
>     a=rtcp-fb:98 transport-cc
>     a=rtpmap:100 H264/90000
>     a=rtcp-fb:100 ccm fir
>     a=rtcp-fb:100 nack
>     a=rtcp-fb:100 nack pli
>     a=rtcp-fb:100 goog-remb
>     a=rtcp-fb:100 transport-cc
>     a=fmtp:100 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
>     a=rtpmap:102 red/90000
>     a=rtpmap:127 ulpfec/90000
>     a=rtpmap:97 rtx/90000
>     a=fmtp:97 apt=96
>     a=rtpmap:99 rtx/90000
>     a=fmtp:99 apt=98
>     a=rtpmap:101 rtx/90000
>     a=fmtp:101 apt=100
>     a=rtpmap:125 rtx/90000
>     a=fmtp:125 apt=102
>     a=ssrc-group:FID 2091687367 3809002701
>     a=ssrc:2091687367 cname:6FAXPNxjytcrrFeT
>     a=ssrc:2091687367 msid:mn9jKVP8YQWdoANy4IuThCbAkYDNH6Rn48wy 7369ece0-53c3-44b6-8ada-8fd112f8018b
>     a=ssrc:2091687367 mslabel:mn9jKVP8YQWdoANy4IuThCbAkYDNH6Rn48wy
>     a=ssrc:2091687367 label:7369ece0-53c3-44b6-8ada-8fd112f8018b
>     a=ssrc:3809002701 cname:6FAXPNxjytcrrFeT
>     a=ssrc:3809002701 msid:mn9jKVP8YQWdoANy4IuThCbAkYDNH6Rn48wy 7369ece0-53c3-44b6-8ada-8fd112f8018b
>     a=ssrc:3809002701 mslabel:mn9jKVP8YQWdoANy4IuThCbAkYDNH6Rn48wy
>     a=ssrc:3809002701 label:7369ece0-53c3-44b6-8ada-8fd112f8018b

这是服务器响应 SDP:

v=0
o=matrix 1346400881 1346400882 IN IP4 x.x.x.x
s=matrix
c=IN IP4 x.x.x.x
t=0 0
m=video 27194 UDP/TLS/RTP/SAVPF 96
b=AS:1024
a=rtpmap:96 VP8/90000
a=fingerprint:sha-256 8E:7D:E1:1A:77:BA:97:64:39:B1:41:FC:E5:28:8A:9E:85:EB:FB:DB:A7:57:0F:EF:E6:CA:AF:EE:45:89:47:D5
a=setup:active
a=rtcp-mux
a=rtcp:27194 IN IP4 x.x.x.x
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=ssrc:1346687882 cname:v1aY4xDDn9cbcqMy
a=ssrc:1346687882 msid:NcXTCdxPIZFIYcoKvW2crReVhSijNter v0
a=ssrc:1346687882 mslabel:NcXTCdxPIZFIYcoKvW2crReVhSijNter
a=ssrc:1346687882 label:NcXTCdxPIZFIYcoKvW2crReVhSijNterv0
a=ice-ufrag:dEAumFftnoD1HHi2
a=ice-pwd:yiQtGkWTkZVmgxKj2bEfGKyU
a=candidate:1419127948 1 udp 659136 x.x.x.x 27194 typ host generation 0
a=end-of-candidates

这可能是什么问题?

【问题讨论】:

    标签: html google-chrome mediarecorder freeswitch jssip


    【解决方案1】:

    我正在努力解决类似的问题,所以我认为我的发现可能会对您有所帮助。

    Chrome 不支持 MediaRecorderIgnoreMutedMedia 属性,因此媒体录制器在开始录制之前正在等待音轨启动。您可以通过运行mediaRecorder.requestData() 来触发ondataavailable 事件来对此进行测试,然后查看event.data.size 的值:

    setInterval(function(){
        _this.recorder.requestData(); // request data every second
    },1000);
    
    _this.recorder.ondataavailable = function (event) {
        console.log("DATA Size: " + event.data.size) // print data size
        if (event.data.size > 0) {
            chunks.push(event.data);
        }
    };
    

    所以我要做的就是只隔离视频轨道,然后创建一个新的 MediaStream 对象,其中只有来自原始流的视频轨道。

    _this.recorder = new MediaRecorder(new MediaStream(e.stream.getVideoTracks()), options);
    

    希望这对你有用。

    【讨论】:

    • 非常感谢您提供的信息!但是这样我录制的视频仍然无法播放。如果我从 e.remoteStream.getVideoTracks() 更改为 localStream,它可以被记录并且可以播放。但我需要的是让记录远程流成为可能:(
    • 通话是有音频还是只有视频?
    • 我的意思是你没有录制音频是因为它不在通话中,还是因为安全或其他原因你没有录制它?
    • 通话中没有音频。这是我们系统的特殊设计,我们不能同时允许音频和视频。
    • 我认为帧速率会因为没有音频而变得混乱。我能够用 dtmf 音调来启动录音。您可能需要找到一种方法来输入一些白噪声以使其正确记录
    猜你喜欢
    • 2020-09-09
    • 2013-04-08
    • 1970-01-01
    • 1970-01-01
    • 2012-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多