WebRTC setRemoteDescription Session is Null error in flutter

如何解决WebRTC setRemoteDescription Session is Null error in flutter

所以,我试图编写一个 webRTC 移动应用程序。发现一些错误

import 'dart:convert';

import 'package:Flutter/material.dart';
import 'package:Flutter_webrtc/Flutter_webrtc.dart';
import 'package:sdp_transform/sdp_transform.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;

  _createOfferSdp() async {
    RTCSessionDescription description =
        await _peerConnection.createOffer({'offerToReceiveAudio': 1});
    var session = parse(description.sdp);
    Map<String,dynamic> sdp = {
      "sdp": session.toString(),};
    var k = firebaseInstance.doc().collection("sdp").doc("offersdp").set(sdp);
    print("K val: $k");
    _peerConnection.setLocalDescription(description);
    // print(session);
  }

  bool remotesaved = false;
  _createAnswerSdp() async {
    firebaseInstance
        .doc(docId.text)
        .collection("sdp")
        .doc("offersdp")
        .get()
        .then((value) async {
      print("here");
      var temp = (value.data()["sdp"]).toString();

      // var session = await jsonDecode(temp.toString());
      // print("here3");
      // print("session: $session");
      // String sdp = write(session,null);
      print(temp);
      if (temp != null) {
        RTCSessionDescription description1 =
            RTCSessionDescription(temp,"offer");

        await _peerConnection.setRemoteDescription(description1).then((value) {
          setState(() {
            remotesaved = true;
          });
        });
      }
    });

    if (remotesaved) {
      RTCSessionDescription description = await _peerConnection
          .createAnswer({'offerToReceiveVideo': 0,'offerToReceiveAudio': 1});

      var session = parse(description.sdp);
      firebaseInstance
          .doc(docId.text)
          .collection("sdp")
          .doc("answersdp")
          .set(session);
      if (l != null) {
        firebaseInstance
            .doc(docId.text)
            .collection("icecandidate")
            .doc("answerice")
            .set(l);
      }
    }
  }

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

  @override
  void initState() {
    _createPeerConnection().then((pc) {
      _peerConnection = pc;
    });
    super.initState();
  }

  @override
  void 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"},]
    };

    final Map<String,dynamic> offerSdpConstraints = {
      "mandatory": {
        "OfferToReceiveAudio": true,"OfferToReceiveVideo": false,},"optional": [],};

    _localStream = await _getUserMedia();

    RTCPeerConnection pc =
        await createPeerConnection(configuration,offerSdpConstraints);
    // if (pc != null) print(pc);
    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(l);
      }
    };

    pc.onIceConnectionState = (e) {
      print(e);
    };

    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: [
              ElevatedButton(
                child: Text("Create"),onpressed: _createOfferSdp,ElevatedButton(
                onpressed: () {
                  showAlertDialog(context);
                },child: Text("Join"),)
            ],);
  }
}

因此,在我的手机代码中,将创建一个优惠并将其存储在 Firestore 中。

dmeet->(AUTO ID)->sdp->offersdp->sdp:sdpvaluesstored

所以在那之后我在加入按钮中手动给出了documentId,当我尝试获取offersdp并设置远程描述时。我想出了一些错误

D/FlutterWebRTCPlugin( 7232): peerConnectionSetRemoteDescription(): WEBRTC_SET_REMOTE_DESCRIPTION_ERROR: SessionDescription is NULL.
E/Flutter ( 7232): [ERROR:Flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: Unable to RTCPeerConnection::setRemoteDescription: peerConnectionSetRemoteDescription(): WEBRTC_SET_REMOTE_DESCRIPTION_ERROR: SessionDescription is NULL.
E/Flutter ( 7232): #0      RTCPeerConnectionNative.setRemoteDescription
package:Flutter_webrtc/…/native/rtc_peerconnection_impl.dart:328
E/Flutter ( 7232): <asynchronous suspension>
E/Flutter ( 7232): #1      _MyHomePageState._createAnswerSdp.<anonymous closure>.<anonymous closure> (package:Flutter_voip_calling/main.dart)

我正在使用教程代码,它使用与我将在文本框中粘贴 sdp 并设置远程描述相同的概念,教程代码here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?