import 'dart:async'; import 'dart:convert'; import 'package:diplomaticquarterapp/pages/conference/web_rtc/widgets/cam_view_widget.dart'; import 'package:diplomaticquarterapp/pages/conference/widgets/noise_box.dart'; import 'package:diplomaticquarterapp/pages/webRTC/signaling.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart'; import '../conference_button_bar.dart'; class CallHomePage extends StatefulWidget { final String receiverId; final String callerId; const CallHomePage({Key key, this.receiverId, this.callerId}) : super(key: key); @override _CallHomePageState createState() => _CallHomePageState(); } class _CallHomePageState extends State { bool showNoise = true; RTCVideoRenderer _localRenderer = RTCVideoRenderer(); RTCVideoRenderer _remoteRenderer = RTCVideoRenderer(); final StreamController _audioButton = StreamController.broadcast(); final StreamController _videoButton = StreamController.broadcast(); final StreamController _onButtonBarVisibleStreamController = StreamController.broadcast(); final StreamController _onButtonBarHeightStreamController = StreamController.broadcast(); //Stream to enable video MediaStream localMediaStream; MediaStream remoteMediaStream; Signaling signaling = Signaling(); @override void initState() { // TODO: implement initState super.initState(); startCall(); } startCall() async{ await _localRenderer.initialize(); await _remoteRenderer.initialize(); await signaling.init(); final connected = await receivedCall(); } Future receivedCall() async { //Stream local media localMediaStream = await navigator.mediaDevices.getUserMedia({'video': true, 'audio': true}); _localRenderer.srcObject = localMediaStream; final connected = await signaling.acceptCall(widget.callerId, widget.receiverId, localMediaStream: localMediaStream, onRemoteMediaStream: (remoteMediaStream){ // print(remoteMediaStream.toString()); // print(json.encode(remoteMediaStream.getTracks().asMap())); this.remoteMediaStream = remoteMediaStream; _remoteRenderer.srcObject = remoteMediaStream; _remoteRenderer.addListener(() { print('_remoteRenderer'); print(_remoteRenderer); setState(() {}); }); }, onRemoteTrack: (track){ _remoteRenderer.srcObject.addTrack(track.track); // setState(() { // }); print(track.streams.first.getVideoTracks()); print(track.streams.first.getAudioTracks()); print(json.encode(track.streams.asMap())); } ); if(connected){ signaling.signalR.listen( onAcceptCall: (arg0){ print(arg0.toString()); }, onCandidate: (candidateJson){ signaling.addCandidate(candidateJson); }, onDeclineCall: (arg0,arg1){ // _onHangup(); }, onHangupCall: (arg0){ // _onHangup(); }, onOffer: (offerSdp, callerUser) async{ print('${offerSdp.toString()} | ${callerUser.toString()}'); await signaling.answerOffer(offerSdp); } ); } return connected; } @override void dispose() { // TODO: implement dispose super.dispose(); signaling.dispose(); _localRenderer?.dispose(); _remoteRenderer?.dispose(); _audioButton?.close(); _videoButton?.close(); localMediaStream?.dispose(); remoteMediaStream?.dispose(); _disposeStreamsAndSubscriptions(); } Future _disposeStreamsAndSubscriptions() async { if (_onButtonBarVisibleStreamController != null) await _onButtonBarVisibleStreamController.close(); if (_onButtonBarHeightStreamController != null) await _onButtonBarHeightStreamController.close(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, body: buildLayout(), ); } LayoutBuilder buildLayout() { return LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { return Stack( children: [ CamViewWidget( localRenderer: _localRenderer, remoteRenderer: _remoteRenderer, constraints: constraints, onButtonBarVisibleStreamController: _onButtonBarVisibleStreamController, onButtonBarHeightStreamController: _onButtonBarHeightStreamController, ), ConferenceButtonBar( audioEnabled: _audioButton.stream, videoEnabled: _videoButton.stream, onAudioEnabled: _onAudioEnable, onVideoEnabled: _onVideoEnabled, onSwitchCamera: _onSwitchCamera, onHangup: _onHangup, onPersonAdd: () {}, onPersonRemove: () {}, onHeight: _onHeightBar, onShow: _onShowBar, onHide: _onHideBar, ), ], ); }, ); } Function _onAudioEnable() { final audioTrack = localMediaStream.getAudioTracks()[0]; final mute = audioTrack.muted; Helper.setMicrophoneMute(!mute, audioTrack); _audioButton.add(mute); } Function _onVideoEnabled() { final videoTrack = localMediaStream.getVideoTracks()[0]; bool videoEnabled = videoTrack.enabled; localMediaStream.getVideoTracks()[0].enabled = !videoEnabled; _videoButton.add(!videoEnabled); } Function _onSwitchCamera() { Helper.switchCamera(localMediaStream.getVideoTracks()[0]); } void _onShowBar() { setState(() { }); _onButtonBarVisibleStreamController.add(true); } void _onHeightBar(double height) { _onButtonBarHeightStreamController.add(height); } void _onHideBar() { setState(() { SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]); }); _onButtonBarVisibleStreamController.add(false); } Future _onHangup() async { signaling.hangupCall(widget.callerId, widget.receiverId); print('onHangup'); Navigator.of(context).pop(); } }