问题:当我们使用内置的Mediarecorder API记录远程视频(仅)流中时,它将返回blob对象;当我们将所有斑点文件与blob api合并并创建对象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();
在该代码示例中,我们正在从远程流录制视频。一旦录制停止,我们将创建一个blob文件,该文件在Chrome中无法播放。
blob文件具有预期的大小和类型。
如果我们将_this.recorder = new MediaRecorder(e.stream, options)
更改为_this.recorder = new MediaRecorder(localMediaStream, options)
,则可以记录文件并且可以播放。
如果我们直接播放远程或本地流到视频对象,那么视频正在播放,并且没有问题。
与远程和本地媒体流相同的代码在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
这里可能有什么问题?
我在一个类似的问题上挣扎,所以我认为我发现的可能会对您有所帮助。
Chrome不支持MediaRecorder
的IgnoreMutedMedia
属性,因此媒体录音机正在等待音轨在开始录制之前启动。您可以通过运行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);
希望这对您有用。