Я создаю приложение WebRT C HTML5, которое включает аудио + видео + RTCDataChannel. Проблема заключается в том, что, когда поставщик отключается и повторно подключается, SDP содержит канал данных только по какой-то странной причине, что приводит к ошибке Не удалось установить удаленное предложение sdp: порядок m-строк в последующем предложении не совпадает с порядком предыдущего предложение / ответ.
Как заставить его отправить полный SDP при повторном согласовании, включая видео / аудио потоки?
Если я удалить все канал данных logi c, он безупречно согласовывает только видео / аудио.
// signaling logic
droneRoomName = 'observable-XXXX';
room = drone.subscribe(droneRoomName);
room.on('open', error => {
if (error) {
onError(error);
}
});
room.on('members', members => { console.log('MEMBERS', members);
const isOfferer = members.length === 2;
startWebRTC(isOfferer);
});
// start WebRTC
function startWebRTC(isOfferer) {
peerConnection = new RTCPeerConnection(configuration);
var dataChannelOptions = {
ordered: false, //no guaranteed delivery, unreliable but faster
maxRetransmitTime: 1000, //milliseconds
negotiated: true,
id: 0,
};
dataChannel = peerConnection.createDataChannel("data", dataChannelOptions);
dataChannel.onopen = () => {
console.log("dataChannel.onopen");
};
dataChannel.onmessage = event => {
console.log(event);
};
dataChannel.onclose = () => {
console.log("dataChannel.onclose");
};
// 'onicecandidate' notifies us whenever an ICE agent needs to deliver a
// message to the other peer through the signaling server
peerConnection.onicecandidate = event => {
console.log("onicecandidate");
if (event.candidate) {
sendMessage({'candidate': event.candidate});
}
};
// If user is offerer let the 'negotiationneeded' event create the offer
if (isOfferer) {
peerConnection.onnegotiationneeded = () => {
console.log("onnegotiationneeded");
peerConnection.createOffer().then(localDescCreated).catch(onError);
}
}
// When a remote stream arrives display it in the #remoteVideo element
peerConnection.ontrack = event => {
console.log("ontrack");
const stream = event.streams[0];
if (!remoteVideo.srcObject || remoteVideo.srcObject.id !== stream.id) {
remoteVideo.srcObject = stream;
}
};
navigator.mediaDevices.getUserMedia({
audio: true,
video: true,
}).then(stream => {
// Display your local video in #localVideo element
localVideo.srcObject = stream;
// Add your stream to be sent to the conneting peer
stream.getTracks().forEach(track => peerConnection.addTrack(track, stream));
}, onError);
// Listen to signaling data from Scaledrone
room.on('data', (message, client) => {
// Message was sent by us
if (client.id === drone.clientId) {
return;
}
if (message.sdp) {
console.log("remoteDescription", message.sdp);
// This is called after receiving an offer or answer from another peer
peerConnection.setRemoteDescription(new RTCSessionDescription(message.sdp), () => {
// When receiving an offer lets answer it
if (peerConnection.remoteDescription.type === 'offer') {
peerConnection.createAnswer().then(localDescCreated).catch(onError);
}
}, onError);
} else if (message.candidate) {
// Add the new ICE candidate to our connections remote description
peerConnection.addIceCandidate(
new RTCIceCandidate(message.candidate), onSuccess, onError
);
} else if(message.ping) {
sendMessage({'pong': true});
}
});
}
function localDescCreated(desc) {
console.log("localDescription", desc.sdp);
peerConnection.setLocalDescription(
desc,
() => sendMessage({'sdp': peerConnection.localDescription}),
onError
);
}
SDP при первой загрузке источника:
localDescription v=0
o=- 2950277739109777549 3 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1 2
a=msid-semantic: WMS 52o0SqtToQ3i0mHtcEl7qOq9TG7o9gXlVBfk
m=application 54727 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 67.188.117.119
a=candidate:609662338 1 udp 2122262783 2601:647:4e00:6042:2834:e7d:4c4a:53a7 43536 typ host generation 0 network-id 2
a=candidate:4278134664 1 udp 2122194687 192.168.1.8 54727 typ host generation 0 network-id 1
a=candidate:1470146653 1 udp 1685987071 67.188.117.119 54727 typ srflx raddr 192.168.1.8 rport 54727 generation 0 network-id 1
a=candidate:1792362866 1 tcp 1518283007 2601:647:4e00:6042:2834:e7d:4c4a:53a7 9 typ host tcptype active generation 0 network-id 2
a=candidate:2960972664 1 tcp 1518214911 192.168.1.8 9 typ host tcptype active generation 0 network-id 1
a=ice-ufrag:5kh8
a=ice-pwd:VnGKhFZeKe4D2BnJznd8Uoom
a=ice-options:trickle
a=fingerprint:sha-256 BB:83:E7:6E:23:42:5B:23:7B:91:46:2B:E4:37:65:1A:B7:D8:74:BE:B1:37:3A:77:5C:2B:B1:B1:EC:BC:86:25
a=setup:actpass
a=mid:0
a=sctp-port:5000
a=max-message-size:262144
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:5kh8
a=ice-pwd:VnGKhFZeKe4D2BnJznd8Uoom
a=ice-options:trickle
a=fingerprint:sha-256 BB:83:E7:6E:23:42:5B:23:7B:91:46:2B:E4:37:65:1A:B7:D8:74:BE:B1:37:3A:77:5C:2B:B1:B1:EC:BC:86:25
a=setup:actpass
a=mid:1
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:5 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:6 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
a=sendrecv
a=msid:52o0SqtToQ3i0mHtcEl7qOq9TG7o9gXlVBfk 93da1a12-4f39-4f4b-839a-456af7e65006
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:106 CN/32000
a=rtpmap:105 CN/16000
a=rtpmap:13 CN/8000
a=rtpmap:110 telephone-event/48000
a=rtpmap:112 telephone-event/32000
a=rtpmap:113 telephone-event/16000
a=rtpmap:126 telephone-event/8000
a=ssrc:1756083896 cname:h4MDz4QqDQ06Lk+E
a=ssrc:1756083896 msid:52o0SqtToQ3i0mHtcEl7qOq9TG7o9gXlVBfk 93da1a12-4f39-4f4b-839a-456af7e65006
a=ssrc:1756083896 mslabel:52o0SqtToQ3i0mHtcEl7qOq9TG7o9gXlVBfk
a=ssrc:1756083896 label:93da1a12-4f39-4f4b-839a-456af7e65006
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 102 122 127 121 125 107 108 109 124 120 123
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:5kh8
a=ice-pwd:VnGKhFZeKe4D2BnJznd8Uoom
a=ice-options:trickle
a=fingerprint:sha-256 BB:83:E7:6E:23:42:5B:23:7B:91:46:2B:E4:37:65:1A:B7:D8:74:BE:B1:37:3A:77:5C:2B:B1:B1:EC:BC:86:25
a=setup:actpass
a=mid:2
a=extmap:14 urn:ietf:params:rtp-hdrext:toffset
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:13 urn:3gpp:video-orientation
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:12 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=extmap:11 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
a=extmap:8 http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07
a=extmap:9 http://www.webrtc.org/experiments/rtp-hdrext/color-space
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:5 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:6 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
a=sendrecv
a=msid:52o0SqtToQ3i0mHtcEl7qOq9TG7o9gXlVBfk 301f4cee-05f6-482f-bef9-f00ba4e464b2
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:96 VP8/90000
a=rtcp-fb:96 goog-remb
a=rtcp-fb:96 transport-cc
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=rtpmap:97 rtx/90000
a=fmtp:97 apt=96
a=rtpmap:98 VP9/90000
a=rtcp-fb:98 goog-remb
a=rtcp-fb:98 transport-cc
a=rtcp-fb:98 ccm fir
a=rtcp-fb:98 nack
a=rtcp-fb:98 nack pli
a=fmtp:98 profile-id=0
a=rtpmap:99 rtx/90000
a=fmtp:99 apt=98
a=rtpmap:100 VP9/90000
a=rtcp-fb:100 goog-remb
a=rtcp-fb:100 transport-cc
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=fmtp:100 profile-id=2
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=rtpmap:102 H264/90000
a=rtcp-fb:102 goog-remb
a=rtcp-fb:102 transport-cc
a=rtcp-fb:102 ccm fir
a=rtcp-fb:102 nack
a=rtcp-fb:102 nack pli
a=fmtp:102 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f
a=rtpmap:122 rtx/90000
a=fmtp:122 apt=102
a=rtpmap:127 H264/90000
a=rtcp-fb:127 goog-remb
a=rtcp-fb:127 transport-cc
a=rtcp-fb:127 ccm fir
a=rtcp-fb:127 nack
a=rtcp-fb:127 nack pli
a=fmtp:127 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f
a=rtpmap:121 rtx/90000
a=fmtp:121 apt=127
a=rtpmap:125 H264/90000
a=rtcp-fb:125 goog-remb
a=rtcp-fb:125 transport-cc
a=rtcp-fb:125 ccm fir
a=rtcp-fb:125 nack
a=rtcp-fb:125 nack pli
a=fmtp:125 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
a=rtpmap:107 rtx/90000
a=fmtp:107 apt=125
a=rtpmap:108 H264/90000
a=rtcp-fb:108 goog-remb
a=rtcp-fb:108 transport-cc
a=rtcp-fb:108 ccm fir
a=rtcp-fb:108 nack
a=rtcp-fb:108 nack pli
a=fmtp:108 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f
a=rtpmap:109 rtx/90000
a=fmtp:109 apt=108
a=rtpmap:124 red/90000
a=rtpmap:120 rtx/90000
a=fmtp:120 apt=124
a=rtpmap:123 ulpfec/90000
a=ssrc-group:FID 2751120894 95407708
a=ssrc:2751120894 cname:h4MDz4QqDQ06Lk+E
a=ssrc:2751120894 msid:52o0SqtToQ3i0mHtcEl7qOq9TG7o9gXlVBfk 301f4cee-05f6-482f-bef9-f00ba4e464b2
a=ssrc:2751120894 mslabel:52o0SqtToQ3i0mHtcEl7qOq9TG7o9gXlVBfk
a=ssrc:2751120894 label:301f4cee-05f6-482f-bef9-f00ba4e464b2
a=ssrc:95407708 cname:h4MDz4QqDQ06Lk+E
a=ssrc:95407708 msid:52o0SqtToQ3i0mHtcEl7qOq9TG7o9gXlVBfk 301f4cee-05f6-482f-bef9-f00ba4e464b2
a=ssrc:95407708 mslabel:52o0SqtToQ3i0mHtcEl7qOq9TG7o9gXlVBfk
a=ssrc:95407708 label:301f4cee-05f6-482f-bef9-f00ba4e464b2
SDP при второй загрузке предложения ( простой refre sh:
localDescription v=0
o=- 967640525921775448 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0
a=msid-semantic: WMS
m=application 9 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 0.0.0.0
a=ice-ufrag:lK7b
a=ice-pwd:OmiPQJ6hDK9zTlQ2p7yFRnoD
a=ice-options:trickle
a=fingerprint:sha-256 47:0B:EF:30:49:B6:94:05:06:5C:FD:4B:B5:16:19:1F:34:5D:CE:49:87:E3:FB:01:FC:F6:CE:24:27:A4:B9:2E
a=setup:actpass
a=mid:0
a=sctp-port:5000
a=max-message-size:262144