diff --git a/lib/pages/livecare/incoming_call.dart b/lib/pages/livecare/incoming_call.dart index 907d6b23..923e32b0 100644 --- a/lib/pages/livecare/incoming_call.dart +++ b/lib/pages/livecare/incoming_call.dart @@ -4,10 +4,11 @@ import 'package:camera/camera.dart'; import 'package:diplomaticquarterapp/models/LiveCare/IncomingCallData.dart'; import 'package:diplomaticquarterapp/pages/conference/widgets/platform_exception_alert_dialog.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/pages/videocall-webrtc-rnd/webrtc/signaling.dart'; import 'package:diplomaticquarterapp/pages/videocall-webrtc-rnd/webrtc/start_video_call.dart'; import 'package:diplomaticquarterapp/pages/webRTC/OpenTok/OpenTok.dart'; -import 'package:diplomaticquarterapp/pages/webRTC/signaling.dart'; import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -15,6 +16,7 @@ import 'package:flutter/material.dart'; import 'package:just_audio/just_audio.dart'; import '../../config/config.dart'; +import '../videocall-webrtc-rnd/utils/device_info.dart'; class IncomingCall extends StatefulWidget { @@ -27,6 +29,7 @@ class IncomingCall extends StatefulWidget { } class _IncomingCallState extends State with SingleTickerProviderStateMixin { + AnimationController _animationController; bool openCallInWeb = true; @@ -34,7 +37,9 @@ class _IncomingCallState extends State with SingleTickerProviderSt CameraController _controller; Future _initializeControllerFuture; bool isCameraReady = false; - Signaling signaling = Signaling()..init(); + + Signaling _signaling; + SessionOneToOne _session; @override void initState() { @@ -51,16 +56,25 @@ class _IncomingCallState extends State with SingleTickerProviderSt player.stop(); _controller.dispose(); disposeAudioResources(); + + // _signaling.close(); + super.dispose(); } + + Future future() async { + await connectSignaling(); + // await _initializeControllerFuture(); + } + @override Widget build(BuildContext context) { return AppScaffold( isShowAppBar: false, isShowDecPage: false, body: FutureBuilder( - future: _initializeControllerFuture, + future: future(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { return Stack( @@ -214,9 +228,9 @@ class _IncomingCallState extends State with SingleTickerProviderSt ); _initializeControllerFuture = _controller.initialize(); - setState(() { - isCameraReady = true; - }); + // setState(() { + // isCameraReady = true; + // }); setAudioFile(); for (int i = 0; i < 100; i++) { @@ -231,30 +245,35 @@ class _IncomingCallState extends State with SingleTickerProviderSt // final roomModel = RoomModel(name: widget.incomingCallData.name, token: widget.incomingCallData.sessionId, identity: widget.incomingCallData.identity); await _controller.dispose(); changeCallStatusAPI(4); - await Navigator.of(context).pushReplacement( - MaterialPageRoute( - // fullscreenDialog: true, - builder: (BuildContext context) { - final caller = widget.incomingCallData.callerID; - final receiver = widget.incomingCallData.receiverID; - final host = widget.incomingCallData.server; - if(widget.incomingCallData.isWebRTC == "true"){ - return StartVideoCall(caller: caller, receiver: receiver, iAmCaller: false, host: host); - }else{ - return OpenTokConnectCallPage( - apiKey: OPENTOK_API_KEY, - sessionId: widget.incomingCallData.sessionId, - token: widget.incomingCallData.token - ); - } - - // return VideoCallWebPage(receiverId: widget.incomingCallData.receiverID, callerId: widget.incomingCallData.callerID); // Web WebRTC VideoCall - - // return CallHomePage(receiverId: widget.incomingCallData.receiverID, callerId: widget.incomingCallData.callerID); // App WebRTC VideoCall - - }, - ), - ); + + + if(_session != null && _signaling != null){ + await Navigator.of(context).pushReplacement( + MaterialPageRoute( + // fullscreenDialog: true, + builder: (BuildContext context) { + if(widget.incomingCallData.isWebRTC == "true"){ + return StartVideoCall(signaling: _signaling, session: _session); + }else{ + return OpenTokConnectCallPage( + apiKey: OPENTOK_API_KEY, + sessionId: widget.incomingCallData.sessionId, + token: widget.incomingCallData.token + ); + } + + // return VideoCallWebPage(receiverId: widget.incomingCallData.receiverID, callerId: widget.incomingCallData.callerID); // Web WebRTC VideoCall + + // return CallHomePage(receiverId: widget.incomingCallData.receiverID, callerId: widget.incomingCallData.callerID); // App WebRTC VideoCall + + }, + ), + ); + }else{ + // Invalid Params/Data + AppToast.showErrorToast(message: "Failed to establish connection with server"); + } + } catch (err) { print(err); await PlatformExceptionAlertDialog( @@ -276,6 +295,7 @@ class _IncomingCallState extends State with SingleTickerProviderSt LandingPage.isOpenCallPage = false; player.stop(); changeCallStatusAPI(3); + _signaling.bye(_session, callRejected: true); Navigator.of(context).pop(); } @@ -297,4 +317,31 @@ class _IncomingCallState extends State with SingleTickerProviderSt print("Error: $e"); } } + + connectSignaling({@required bool iAmCaller = false}) async{ + + final caller = widget.incomingCallData.callerID; + final receiver = widget.incomingCallData.receiverID; + final host = widget.incomingCallData.server; + + final self_role = iAmCaller ? "Caller" : "Receiver"; + final self_id = iAmCaller ? caller : receiver; + final self_user = SocketUser(id: self_id, name: "$self_role-$self_id", userAgent: DeviceInfo.userAgent, moreInfo: {}); + + final remote_role = !iAmCaller ? "Caller" : "Receiver"; + final remote_id = !iAmCaller ? caller : receiver; + final remote_user = SocketUser(id: remote_id, name: "$remote_role-$remote_id", userAgent: DeviceInfo.userAgent, moreInfo: {}); + + final session_id = "$caller-$receiver"; + _session = SessionOneToOne(id: session_id, local_user: self_user, remote_user: remote_user); + + _signaling = Signaling(host, session: _session); + await _signaling.connect(); + + if(_signaling.state == SignalingState.Open){ + return; + } + + } + } diff --git a/lib/pages/videocall-webrtc-rnd/webrtc/signaling.dart b/lib/pages/videocall-webrtc-rnd/webrtc/signaling.dart index 3eb88502..e60857ec 100644 --- a/lib/pages/videocall-webrtc-rnd/webrtc/signaling.dart +++ b/lib/pages/videocall-webrtc-rnd/webrtc/signaling.dart @@ -50,6 +50,8 @@ class SocketUser{ } class Signaling { + SignalingState state; + var _host; var _turnCredential; @@ -141,10 +143,11 @@ class Signaling { _createOffer(session, media); } - void bye(SessionOneToOne session) { + void bye(SessionOneToOne session, {bool callRejected = false}) { _send('bye', { 'session_id': session.id, 'from': session.local_user.id, + 'call_rejected' : callRejected }); _closeSession(session); } @@ -258,6 +261,8 @@ class Signaling { _socket?.onOpen = () { print('onOpen'); + state = SignalingState.Open; + onSignalingStateChange?.call(SignalingState.Open); _send('connect', session.local_user.toJson()); }; @@ -268,10 +273,13 @@ class Signaling { }; _socket?.onClose = (int code, String reason) { + state = SignalingState.Closed; + print('Closed by server [$code => $reason]!'); onSignalingStateChange?.call(SignalingState.Closed); }; + await _socket?.connect(); } @@ -387,7 +395,7 @@ class Signaling { 'to': session.remote_user?.id, 'from': session.local_user.id, 'candidate': { - 'sdpMLineIndex': candidate.sdpMlineIndex, // sdpMlineIndex or sdpMLineIndex + 'sdpMLineIndex': candidate.sdpMLineIndex, // sdpMlineIndex or sdpMLineIndex 'sdpMid': candidate.sdpMid, 'candidate': candidate.candidate, }, diff --git a/lib/pages/videocall-webrtc-rnd/webrtc/start_video_call.dart b/lib/pages/videocall-webrtc-rnd/webrtc/start_video_call.dart index 80cc6f10..d9bb7e88 100644 --- a/lib/pages/videocall-webrtc-rnd/webrtc/start_video_call.dart +++ b/lib/pages/videocall-webrtc-rnd/webrtc/start_video_call.dart @@ -12,33 +12,22 @@ import 'package:flutter_webrtc/flutter_webrtc.dart'; class StartVideoCall extends StatefulWidget { static String tag = 'webrtc'; - final String host; + SessionOneToOne session; + Signaling signaling; - String caller; - String receiver; - bool iAmCaller; - StartVideoCall({@required this.caller, @required this.receiver, this.iAmCaller = false, @required this.host}); + StartVideoCall({@required this.signaling, @required this.session}); @override - StartVideoCallState createState() => StartVideoCallState(receiverId: receiver, callerId: caller, iAmCaller: iAmCaller); + StartVideoCallState createState() => StartVideoCallState(session: session, signaling: signaling); } class StartVideoCallState extends State { Signaling _signaling; SessionOneToOne _session; - StartVideoCallState({@required String callerId, @required String receiverId, @required bool iAmCaller}){ - - final self_role = iAmCaller ? "Caller" : "Receiver"; - final self_id = iAmCaller ? callerId : receiverId; - final self_user = SocketUser(id: self_id, name: "$self_role-$self_id", userAgent: DeviceInfo.userAgent, moreInfo: {}); - - final remote_role = !iAmCaller ? "Caller" : "Receiver"; - final remote_id = !iAmCaller ? callerId : receiverId; - final remote_user = SocketUser(id: remote_id, name: "$remote_role-$remote_id", userAgent: DeviceInfo.userAgent, moreInfo: {}); - - final session_id = "$callerId-$receiverId"; - _session = SessionOneToOne(id: session_id, local_user: self_user, remote_user: remote_user); + StartVideoCallState({@required SessionOneToOne session, @required Signaling signaling}){ + this._session = session; + this._signaling = signaling; } bool showNoise = true; @@ -57,7 +46,7 @@ class StartVideoCallState extends State { initState() { super.initState(); initRenderers(); - _connect(); + _setupEventListeners(); } initRenderers() async { @@ -112,12 +101,13 @@ class StartVideoCallState extends State { } - void _connect() async { + void _setupEventListeners() async { if(_session == null) return; - _signaling ??= Signaling(widget.host, session: _session)..connect(); + // _signaling ??= Signaling(widget.host, session: _session)..connect(); + _signaling?.callAccepted(_session); _signaling?.onSignalingStateChange = (SignalingState state) { switch (state) { case SignalingState.Closed: diff --git a/lib/uitl/push-notification-handler.dart b/lib/uitl/push-notification-handler.dart index f46ba2a6..ec9113a5 100644 --- a/lib/uitl/push-notification-handler.dart +++ b/lib/uitl/push-notification-handler.dart @@ -93,7 +93,7 @@ callPage(String sessionID, String token, String isWebrtc, String callerIdString) String caller = callerIdString.split("*")[3]; String receiver = callerIdString.split("*")[4]; String host = callerIdString.split("*")[5]; - return StartVideoCall(caller: caller, receiver: receiver, iAmCaller: false, host: host); + // return StartVideoCall(caller: caller, receiver: receiver, iAmCaller: false, host: host); }else{ await NavigationService.navigateToPage(OpenTokConnectCallPage(apiKey: OPENTOK_API_KEY, sessionId: sessionID, token: token)); } diff --git a/pubspec.yaml b/pubspec.yaml index 6bc27e53..d9986a05 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -146,7 +146,7 @@ dependencies: jiffy: ^4.1.0 #Flutter WebRTC - flutter_webrtc: ^0.8.0 + flutter_webrtc: ^0.9.8 screen_brightness: ^0.1.2