There is no transfer of audio between two device in WebRTC over WIFI neither Mobile data(LTE)

Viewed 209

I have used STUN server but while connecting a mobile with mobile data then there is no audio from the connection. So I got a TURN Server and I have setted up the TURN server in flutter app but still there is no data transfer

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"),
              )
            ],
          ),
        ),
      ),
    );
  }
}

Though I have Used TURN server still there is no audio transfer what may be the possible solution for it?

0 Answers
Related