"Unable to RTCPeerConnection::setRemoteDescription: Failed to set remote answer sdp: Called in wrong state: kStable"
638
I cannot comment yet under your post but I had this problem with the newest version of flutter_webrtc. Three days of head-scratching later and I used:
flutter_webrtc: ^0.2.7
Worked on the first try. Cheers.
Author by
ilovecse
Updated on December 13, 2022Comments
-
ilovecse 11 months
I am using flutter_webrtc to connect to users peer to peer. I am getting this error on the offer side. I have been looking all over the internet for a fix but couldn't find the solution.
class Webrtc { bool _offer = false; RTCPeerConnection _peerConnection; MediaStream _localStream; RTCVideoRenderer _localRenderer = new RTCVideoRenderer(); RTCVideoRenderer _remoteRenderer = new RTCVideoRenderer(); get localRe nderer => _localRenderer; get remoteRenderer => _remoteRenderer; //final sdpController = TextEditingController(); Webrtc() { initRenderers(); _createPeerConnection().then((pc) { _peerConnection = pc; }); } initRenderers() async { await _localRenderer.initialize(); await _remoteRenderer.initialize(); } createOffer() async { _offer = true; RTCSessionDescription description = await _peerConnection.createOffer({'offerToReceiveVideo': 1}); // var session = parse(description.sdp); // print(json.encode(session)); // _offer = true; var roomDef = Firestore.instance.collection("rooms").document("test"); var data = { "offer": { 'sdp': description.sdp.toString(), 'type': description.type.toString(), } }; await roomDef.setData(data, merge: true); await _peerConnection.setLocalDescription(description); Firestore.instance.collection("rooms").document("test").snapshots().listen((event) { if(event.data["answer"] != null){ _setRemoteDescription(event.data["answer"]); } }); } createAnswer() async { // Firestore.instance.collection("rooms").document("test").snapshots().listen((event) { // if(event.data["offer"] != null){ // _setRemoteDescription(event.data["offer"]); // } // }); var doc = await Firestore.instance.collection("rooms").document("test").get(); print(doc.data["offer"]); await _setRemoteDescription(doc.data["offer"]); RTCSessionDescription description = await _peerConnection.createAnswer({'offerToReceiveVideo': 1}); //var session = parse(description.sdp); //print(json.encode(session)); await _peerConnection.setLocalDescription(description); var data = { "answer": { 'sdp': description.sdp.toString(), 'type': description.type.toString(), } }; Firestore.instance .collection("rooms") .document("test") .setData(data, merge: true); } _setRemoteDescription(doc) async { // String jsonString = doc.toString(); // dynamic session = await jsonDecode('$jsonString'); //String sdp = write(session, null); // RTCSessionDescription description = // new RTCSessionDescription(session['sdp'], session['type']); RTCSessionDescription description = new RTCSessionDescription(doc["sdp"],doc["type"]); print(description.toMap()); await _peerConnection.setRemoteDescription(description); } void _addCandidate(data) async { dynamic session = data; dynamic candidate = new RTCIceCandidate( session['candidate'], session['sdpMid'], session['sdpMlineIndex']); await _peerConnection.addCandidate(candidate); } _createPeerConnection() async { Map<String, dynamic> configuration = { "iceServers": [ {"url": "stun:stun.l.google.com:19302"}, ] }; final Map<String, dynamic> offerSdpConstraints = { "mandatory": { "OfferToReceiveAudio": true, "OfferToReceiveVideo": true, }, "optional": [], }; _localStream = await _getUserMedia(); RTCPeerConnection pc = await createPeerConnection(configuration, offerSdpConstraints); // if (pc != null) print(pc); pc.addStream(_localStream); pc.onIceCandidate = (e) { if (_offer && e.candidate != null) { Firestore.instance.collection("caller").add({ 'candidate': e.candidate.toString(), 'sdpMid': e.sdpMid.toString(), 'sdpMlineIndex': e.sdpMlineIndex, }); Firestore.instance.collection("callee").snapshots().listen((event) { event.documentChanges.forEach((element) { print(element.document.data); _addCandidate(element.document.data); }); }); } if (!_offer && e.candidate != null) { Firestore.instance.collection("callee").add({ 'candidate': e.candidate.toString(), 'sdpMid': e.sdpMid.toString(), 'sdpMlineIndex': e.sdpMlineIndex, }); Firestore.instance.collection("caller").snapshots().listen((event) { event.documentChanges.forEach((element) { print(element.document.data); _addCandidate(element.document.data); }); }); } // if (e.candidate != null) { // print(json.encode({ // 'candidate': e.candidate.toString(), // 'sdpMid': e.sdpMid.toString(), // 'sdpMlineIndex': e.sdpMlineIndex, // })); // } }; pc.onIceConnectionState = (e) { print(e); }; pc.onAddStream = (stream) { print('addStream: ' + stream.id); _remoteRenderer.srcObject = stream; }; return pc; } _getUserMedia() async { final Map<String, dynamic> mediaConstraints = { 'audio': true, 'video': { 'facingMode': 'user', }, }; MediaStream stream = await navigator.getUserMedia(mediaConstraints); // _localStream = stream; _localRenderer.srcObject = stream; _localRenderer.mirror = true; // _peerConnection.addStream(stream); return stream; } }
I tried switching the setlocaldescption and setremotedescption but no use. Offer button calls create offer from the ui and answer button calls createanswer function.
-
ilovecse over 3 yearsManaged to fix the issue..but now remote stream not working on both peers
-
ilovecse over 3 yearsAudio is also not working
-
ilovecse over 3 yearsremote stream is blank screen
-