Closed Appleprabh closed 3 years ago
Please remove all var session = parse(description.sdp);
; You use sdp_transform to convert sdp to map, but when setting sdp for pc, it must be String,
Yeah It resolved it!
@cloudwebrtc I have got some issue that I connected a mobile in mobile data and another in wifi and there is no audio transfer so I sorted it and setted up my TURN server. But still It doesn't work the code is here.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'WebRTC lets learn together'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
CollectionReference firebaseInstance =
FirebaseFirestore.instance.collection("dmeet");
RTCPeerConnection _peerConnection;
MediaStream _localStream;
RTCVideoRenderer _remoteRenderer = RTCVideoRenderer();
var docId = TextEditingController();
var l;
var document;
_createOfferSdp() async {
RTCSessionDescription description =
await _peerConnection.createOffer({'offerToReceiveAudio': 1});
Map<String, dynamic> session = {"sdp": description.sdp};
document = firebaseInstance.doc();
document.collection("sdp").doc("offersdp").set(session);
await _peerConnection.setLocalDescription(description);
// document.collection("icecandidate").snapshots().listen((result) async {
// dynamic candidate = new RTCIceCandidate(
// result['candidate'], result['sdpMid'], result['sdpMlineIndex']);
// await _peerConnection.addCandidate(candidate);
// });
// print(session);
_peerConnection.onIceCandidate = (event) {
if (event.candidate != null) {
Map<String, dynamic> icecandidate = {
"candidate": event.candidate,
"sdpMid": event.sdpMid,
"sdpMlineIndex": event.sdpMlineIndex
};
document.collection("candidate").doc().set(icecandidate);
}
};
}
bool remotesaved = false;
_createAnswerSdp() async {
firebaseInstance
.doc(docId.text)
.collection("sdp")
.doc("offersdp")
.get()
.then((value) async {
var remoteSession = value.data()["sdp"];
RTCSessionDescription description1 =
RTCSessionDescription(remoteSession, "offer");
await _peerConnection
.setRemoteDescription(description1)
.then((value) async {
RTCSessionDescription description2 =
await _peerConnection.createAnswer({'offerToReceiveAudio': 1});
Map<String, dynamic> session = {"sdp": description2.sdp};
firebaseInstance
.doc(docId.text)
.collection("sdp")
.doc("answersdp")
.set(session);
final iceCandidate = await firebaseInstance
.doc(docId.text)
.collection("candidate")
.get();
iceCandidate.docs.forEach((element) async {
print("Candidate ${element.data()["candidate"]}");
dynamic candidate = RTCIceCandidate(element.data()['candidate'],
element.data()['sdpMid'], element.data()['sdpMlineIndex']);
await _peerConnection.addCandidate(candidate);
});
});
});
if (remotesaved) {}
}
showAlertDialog(BuildContext context) {
// set up the buttons
Widget cancelButton = FlatButton(
child: Text("Cancel"),
onPressed: () {},
);
Widget continueButton = FlatButton(
child: Text("Continue"),
onPressed: _createAnswerSdp,
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text("AlertDialog"),
content: TextField(
controller: docId,
),
actions: [
cancelButton,
continueButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
initRenderer() async {
await _remoteRenderer.initialize();
}
@override
void initState() {
_createPeerConnection().then((pc) {
_peerConnection = pc;
});
initRenderer();
// _localStream.initialize();
super.initState();
}
@override
void dispose() {
_remoteRenderer.dispose();
super.dispose();
}
_getUserMedia() async {
final Map<String, dynamic> mediaConstraints = {
'audio': true,
'video': false,
};
MediaStream stream = await navigator.getUserMedia(mediaConstraints);
// _localStream = stream;
// _peerConnection.addStream(stream);
return stream;
}
_createPeerConnection() async {
Map<String, dynamic> configuration = {
"iceServers": [
// {"url": "stun:stun.l.google.com:19302"},
{
"url": "turn:numb.viagenie.ca",
"username": "*******@gmail.com",
"credential": "*******",
}
]
};
final Map<String, dynamic> offerSdpConstraints = {
"mandatory": {
"OfferToReceiveAudio": true,
"OfferToReceiveVideo": false,
},
"optional": [],
};
_localStream = await _getUserMedia();
RTCPeerConnection pc =
await createPeerConnection(configuration, offerSdpConstraints);
pc.addStream(_localStream);
pc.onIceCandidate = (e) {
if (e.candidate != null) {
l = json.encode({
'candidate': e.candidate.toString(),
'sdpMid': e.sdpMid.toString(),
'sdpMlineIndex': e.sdpMlineIndex,
});
print("Her $l");
}
};
pc.onAddStream = (stream) {
print('addStream: ' + stream.id);
_remoteRenderer.srcObject = stream;
};
return pc;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Center(
child: Row(
children: [
Flexible(child: RTCVideoView(_remoteRenderer)),
ElevatedButton(
child: Text("Create"),
onPressed: _createOfferSdp,
),
ElevatedButton(
onPressed: () {
showAlertDialog(context);
},
child: Text("Join"),
)
],
),
),
),
);
}
}
What may be the possible solution?
SetRemoteDescription() creates a error as
Code:
The offer SDP produced is here
While setting this sdp as a remote sdp it produces the error.