import 'package:flutter/material.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart'; import 'package:logger/logger.dart'; class Call extends StatefulWidget { final String host; const Call({required this.host, super.key}); @override _CallState createState() => _CallState(); } class _CallState extends State { Logger logger = Logger(); RTCVideoRenderer _remoteRenderer = RTCVideoRenderer(); void _connect(BuildContext context) async {} Future _createSesson() async { RTCPeerConnection peerConnection = await createPeerConnection({ // Ice servers; just use the Google one for now 'iceServers': [ {'url': 'stun:stun.l.google.com:19302'} ], }, { /* Empty config */ }); peerConnection.onAddStream = (stream) { // Stream has been added; connect it to our renderer _remoteRenderer.srcObject = stream; }; peerConnection.onIceCandidate = (candidate) { if (candidate.candidate == null) { logger.i("Out of candidates"); return; } // Send the candidate on to the signaling server }; peerConnection.onIceConnectionState = (state) {}; peerConnection.onRemoveStream = (stream) {}; peerConnection.onDataChannel = (channel) {}; // Get list of candidates from signaling server for (final remoteCandidate in []) { peerConnection.addCandidate(remoteCandidate); } // This will find the intersection of my candidates and the remote, // then propose one to use var offer = peerConnection.createOffer(); // Send offer through signaling server logger.i("Offer is $offer"); var session = Session(peerConnection); return session; } @override Widget build(BuildContext context) { return RTCVideoView(_remoteRenderer); } } class Session { RTCPeerConnection peerConnection; Session(this.peerConnection); List remoteCandidates = []; }