diff --git a/lib/pages/conference/web_rtc/call_home_page_.dart b/lib/pages/conference/web_rtc/call_home_page_.dart index 1f36a8e9..a831a23f 100644 --- a/lib/pages/conference/web_rtc/call_home_page_.dart +++ b/lib/pages/conference/web_rtc/call_home_page_.dart @@ -1,204 +1,204 @@ -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(); - } -} +// 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(); +// } +// } diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index e9fbd62c..623c9298 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -81,7 +81,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { var themeNotifier; DateTime currentBackPressTime; - SignalRUtil signalRUtil; + // SignalRUtil signalRUtil; ToDoCountProviderModel toDoProvider; diff --git a/lib/pages/livecare/incoming_call.dart b/lib/pages/livecare/incoming_call.dart index da8c507e..7cea1153 100644 --- a/lib/pages/livecare/incoming_call.dart +++ b/lib/pages/livecare/incoming_call.dart @@ -34,7 +34,7 @@ class _IncomingCallState extends State with SingleTickerProviderSt CameraController _controller; Future _initializeControllerFuture; bool isCameraReady = false; - Signaling signaling = Signaling()..init(); + // Signaling signaling = Signaling()..init(); @override void initState() { diff --git a/lib/pages/webRTC/call_page.dart b/lib/pages/webRTC/call_page.dart index 8a5625b2..e75b2f8e 100644 --- a/lib/pages/webRTC/call_page.dart +++ b/lib/pages/webRTC/call_page.dart @@ -14,7 +14,7 @@ class CallPage extends StatefulWidget { } class _CallPageState extends State { - Signaling signaling = Signaling(); + // Signaling signaling = Signaling(); RTCVideoRenderer _localRenderer = RTCVideoRenderer(); RTCVideoRenderer _remoteRenderer = RTCVideoRenderer(); String roomId; @@ -73,7 +73,7 @@ class _CallPageState extends State { ), ElevatedButton( onPressed: () { - signaling.hangUp(_localRenderer); + // signaling.hangUp(_localRenderer); }, child: Text("Hangup"), ) diff --git a/lib/pages/webRTC/signaling.dart b/lib/pages/webRTC/signaling.dart index 9a4d1c48..53966bdc 100644 --- a/lib/pages/webRTC/signaling.dart +++ b/lib/pages/webRTC/signaling.dart @@ -1,277 +1,277 @@ -import 'dart:convert'; - -import 'package:diplomaticquarterapp/uitl/SignalRUtil.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter_webrtc/flutter_webrtc.dart'; - -typedef void StreamStateCallback(MediaStream stream); -typedef void RTCIceGatheringStateCallback(RTCIceGatheringState state); -typedef void RTCPeerConnectionStateCallback(RTCPeerConnectionState state); -typedef void RTCSignalingStateCallback(RTCSignalingState state); - -final Map constraints = { - 'mandatory': {}, - 'optional': [ - {'DtlsSrtpKeyAgreement': true}, - ] -}; - -Map snapsis_ice_config = { - 'iceServers': [ - { "urls": 'stun:15.185.116.59:3478' }, - { "urls": "turn:15.185.116.59:3479", "username": "admin", "credential": "admin" }, - ], - // 'sdpSemantics': 'unified-plan' -}; -Map twilio_ice_config = { - "ice_servers": [ - { - "url": "stun:global.stun.twilio.com:3478?transport=udp", - "urls": "stun:global.stun.twilio.com:3478?transport=udp" - }, - { - "url": "turn:global.turn.twilio.com:3478?transport=udp", - "username": "ce8042842b62c21bd20b176f80d6067fd3db81b1e9766312418ef5421d9ca2a2", - "urls": "turn:global.turn.twilio.com:3478?transport=udp", - "credential": "UzGOsiLwPZJ32cjafAebfDDpVrqeQjgpFHZEdau/8r4=" - }, - { - "url": "turn:global.turn.twilio.com:3478?transport=tcp", - "username": "ce8042842b62c21bd20b176f80d6067fd3db81b1e9766312418ef5421d9ca2a2", - "urls": "turn:global.turn.twilio.com:3478?transport=tcp", - "credential": "UzGOsiLwPZJ32cjafAebfDDpVrqeQjgpFHZEdau/8r4=" - }, - { - "url": "turn:global.turn.twilio.com:443?transport=tcp", - "username": "ce8042842b62c21bd20b176f80d6067fd3db81b1e9766312418ef5421d9ca2a2", - "urls": "turn:global.turn.twilio.com:443?transport=tcp", - "credential": "UzGOsiLwPZJ32cjafAebfDDpVrqeQjgpFHZEdau/8r4=" - } - ], - // 'sdpSemantics': 'unified-plan' -}; -Map google_ice_config = { - 'iceServers': [ - { - 'urls': [ - 'stun:stun.l.google.com:19302', - 'stun:stun1.l.google.com:19302', - 'stun:stun2.l.google.com:19302', - 'stun:stun3.l.google.com:19302' - ] - }, - ], - // 'sdpSemantics': 'unified-plan' -}; -Map aws_ice_config = { - 'iceServers': [ - {'url': "stun:ec2-15-185-116-59.me-south-1.compute.amazonaws.com:3478"}, - {'url': "turn:ec2-15-185-116-59.me-south-1.compute.amazonaws.com:3479", 'credential': "admin", 'username': "admin"} - ], - // 'sdpSemantics': 'unified-plan' -}; - -class Signaling { - dispose() { - if (peerConnection != null) { - peerConnection.dispose(); - peerConnection.getLocalStreams().forEach((e) => e.dispose()); - peerConnection.getRemoteStreams().forEach((e) => e.dispose()); - } - signalR.closeConnection(); - } - - init() async{ - // Create Peer Connection - peerConnection = await createPeerConnection(google_ice_config, constraints); - registerPeerConnectionListeners(); - } - - initializeSignalR(String userName) async { - if (signalR != null) await signalR.closeConnection(); - // https://vcallapi.hmg.com/webRTCHub?source=web&username=zohaib - // signalR = SignalRUtil(hubName: "https://vcallapi.hmg.com/webRTCHub?source=mobile&username=$userName"); - signalR = SignalRUtil(hubName: "http://35.193.237.29/webRTCHub?source=mobile&username=$userName"); - final connected = await signalR.openConnection(); - if (!connected) throw 'Failed to connect SignalR'; - } - - Map configuration = { - // 'iceServers': [ - // { - // 'urls': ['stun:stun1.l.google.com:19302', 'stun:stun2.l.google.com:19302'] - // } - // ] - - 'iceServers': [ - // {'url': "stun:ec2-15-185-116-59.me-south-1.compute.amazonaws.com:3478"}, - // {'url': "turn:ec2-15-185-116-59.me-south-1.compute.amazonaws.com:3479", 'credential': "admin", 'username': "admin"} - // {'url': "stun:15.185.116.59:3478"}, - // { - // "url":"turn:15.185.116.59:3479", - // "username": "admin", - // "credential":"admin" - // } - { - "url": "stun:global.stun.twilio.com:3478?transport=udp", - "urls": "stun:global.stun.twilio.com:3478?transport=udp" - }, - { - "url": "turn:global.turn.twilio.com:3478?transport=udp", - "username": "f18fc347ba4aeeaa1b00f5199b1e900834b464962d434a4a89b4cdba02510047", - "urls": "turn:global.turn.twilio.com:3478?transport=udp", - "credential": "WX16BB+9nKm0f+Whf5EwpM8S/Yv+T2tlvQWLfdV7oqo=" - } - ] - }; - - SignalRUtil signalR; - - RTCPeerConnection peerConnection; - MediaStream localStream; - MediaStream remoteStream; - RTCDataChannel dataChannel; - - // Future call(String patientId, String mobile, {@required RTCVideoRenderer localVideo, @required RTCVideoRenderer remoteVideo}) async { - // await initializeSignalR(patientId); - // - // // final isCallPlaced = await FCM.sendCallNotifcationTo(DOCTOR_TOKEN, patientId, mobile); - // if(!isCallPlaced) - // throw 'Failed to notify target for call'; - // - // return isCallPlaced; - // } - - Future acceptCall(String caller, String receiver, {@required MediaStream localMediaStream, @required Function(MediaStream) onRemoteMediaStream, @required Function(RTCTrackEvent) onRemoteTrack}) async { - await initializeSignalR(receiver); - signalR.setContributors(caller: caller, receiver: receiver); - await signalR.acceptCall(receiver, caller).catchError((e) => throw 'Failed to inform signalR that i accepted a call'); - - peerConnection.addStream(localMediaStream); - - // peerConnection?.onTrack = (track){ - // onRemoteTrack(track); - // }; - peerConnection?.onAddStream = (MediaStream stream) { - remoteStream = stream; - onRemoteMediaStream?.call(stream); - }; - return true; - } - - - Future declineCall(String caller, String receiver) async { - await initializeSignalR(receiver); - signalR.setContributors(caller: caller, receiver: receiver); - await signalR.declineCall(receiver, caller).catchError((e) => throw 'Failed to inform signalR that i accepted a call'); - - // peerConnection.addStream(localMediaStream); - // - // peerConnection?.onAddStream = (MediaStream stream) { - // remoteStream = stream; - // onRemoteMediaStream?.call(stream); - // }; - return true; - } - - Future hangupCall(String caller, String receiver) async { - await signalR.hangupCall(caller, receiver); - dispose(); - } - - answerOffer(String sdp) async { - final offer = jsonDecode(sdp); - final caller = offer['caller']; - final receiver = offer['target']; - final offerSdp = offer['sdp']; - peerConnection.setRemoteDescription(rtcSessionDescriptionFrom(offerSdp)).then((value) { - return peerConnection.createAnswer().catchError((e){ - print(e); - }); - }).then((anwser) { - return peerConnection.setLocalDescription(anwser).catchError((e){ - print(e); - }); - }).then((value) { - return peerConnection.getLocalDescription().catchError((e){ - print(e); - }); - }).then((answer) { - return signalR.answerOffer(answer, caller, receiver).catchError((e){ - print(e); - }); - }).catchError((e) { - print(e); - }); - } - - Future hangUp(RTCVideoRenderer localVideo) async {} - - Future createSdpAnswer(String toOfferSdp) async { - final offerSdp = rtcSessionDescriptionFrom(jsonDecode(toOfferSdp)); - peerConnection.setRemoteDescription(offerSdp).catchError((e){ - print(e); - }); - - final answer = await peerConnection.createAnswer().catchError((e){ - print(e); - }); - var answerSdp = json.encode(answer); // Send SDP via Push or any channel - return answerSdp; - } - - Future createSdpOffer() async { - final offer = await peerConnection.createOffer(); - await peerConnection.setLocalDescription(offer).catchError((e){ - print(e); - }); - final map = offer.toMap(); - var offerSdp = json.encode(map); // Send SDP via Push or any channel - return offerSdp; - } - - addCandidate(String candidateJson) { - peerConnection.addCandidate(rtcIceCandidateFrom(candidateJson)).catchError((e){ - print(e); - }); - } - - void registerPeerConnectionListeners() { - peerConnection.onRenegotiationNeeded = (){ - print('Renegotiation Needed...'); - }; - - peerConnection.onIceCandidate = (RTCIceCandidate candidate) { - // print(json.encode(candidate.toMap())); - signalR.addIceCandidate(json.encode(candidate.toMap())).catchError((e){ - print(e); - }); - }; - - peerConnection?.onIceGatheringState = (RTCIceGatheringState state) { - print('ICE gathering state changed: $state'); - }; - - peerConnection?.onConnectionState = (RTCPeerConnectionState state) { - print('Connection state change: $state'); - }; - - peerConnection?.onSignalingState = (RTCSignalingState state) { - print('Signaling state change: $state'); - }; - - - } -} - -rtcSessionDescriptionFrom(Map sdp) { - return RTCSessionDescription( - sdp['sdp'], - sdp['type'], - ); -} - -rtcIceCandidateFrom(String json) { - final map = jsonDecode(json)['candidate']; - return RTCIceCandidate(map['candidate'], map['sdpMid'], map['sdpMLineIndex']); -} +// import 'dart:convert'; +// +// import 'package:diplomaticquarterapp/uitl/SignalRUtil.dart'; +// import 'package:flutter/cupertino.dart'; +// import 'package:flutter_webrtc/flutter_webrtc.dart'; +// +// typedef void StreamStateCallback(MediaStream stream); +// typedef void RTCIceGatheringStateCallback(RTCIceGatheringState state); +// typedef void RTCPeerConnectionStateCallback(RTCPeerConnectionState state); +// typedef void RTCSignalingStateCallback(RTCSignalingState state); +// +// final Map constraints = { +// 'mandatory': {}, +// 'optional': [ +// {'DtlsSrtpKeyAgreement': true}, +// ] +// }; +// +// Map snapsis_ice_config = { +// 'iceServers': [ +// { "urls": 'stun:15.185.116.59:3478' }, +// { "urls": "turn:15.185.116.59:3479", "username": "admin", "credential": "admin" }, +// ], +// // 'sdpSemantics': 'unified-plan' +// }; +// Map twilio_ice_config = { +// "ice_servers": [ +// { +// "url": "stun:global.stun.twilio.com:3478?transport=udp", +// "urls": "stun:global.stun.twilio.com:3478?transport=udp" +// }, +// { +// "url": "turn:global.turn.twilio.com:3478?transport=udp", +// "username": "ce8042842b62c21bd20b176f80d6067fd3db81b1e9766312418ef5421d9ca2a2", +// "urls": "turn:global.turn.twilio.com:3478?transport=udp", +// "credential": "UzGOsiLwPZJ32cjafAebfDDpVrqeQjgpFHZEdau/8r4=" +// }, +// { +// "url": "turn:global.turn.twilio.com:3478?transport=tcp", +// "username": "ce8042842b62c21bd20b176f80d6067fd3db81b1e9766312418ef5421d9ca2a2", +// "urls": "turn:global.turn.twilio.com:3478?transport=tcp", +// "credential": "UzGOsiLwPZJ32cjafAebfDDpVrqeQjgpFHZEdau/8r4=" +// }, +// { +// "url": "turn:global.turn.twilio.com:443?transport=tcp", +// "username": "ce8042842b62c21bd20b176f80d6067fd3db81b1e9766312418ef5421d9ca2a2", +// "urls": "turn:global.turn.twilio.com:443?transport=tcp", +// "credential": "UzGOsiLwPZJ32cjafAebfDDpVrqeQjgpFHZEdau/8r4=" +// } +// ], +// // 'sdpSemantics': 'unified-plan' +// }; +// Map google_ice_config = { +// 'iceServers': [ +// { +// 'urls': [ +// 'stun:stun.l.google.com:19302', +// 'stun:stun1.l.google.com:19302', +// 'stun:stun2.l.google.com:19302', +// 'stun:stun3.l.google.com:19302' +// ] +// }, +// ], +// // 'sdpSemantics': 'unified-plan' +// }; +// Map aws_ice_config = { +// 'iceServers': [ +// {'url': "stun:ec2-15-185-116-59.me-south-1.compute.amazonaws.com:3478"}, +// {'url': "turn:ec2-15-185-116-59.me-south-1.compute.amazonaws.com:3479", 'credential': "admin", 'username': "admin"} +// ], +// // 'sdpSemantics': 'unified-plan' +// }; +// +// class Signaling { +// dispose() { +// if (peerConnection != null) { +// peerConnection.dispose(); +// peerConnection.getLocalStreams().forEach((e) => e.dispose()); +// peerConnection.getRemoteStreams().forEach((e) => e.dispose()); +// } +// signalR.closeConnection(); +// } +// +// init() async{ +// // Create Peer Connection +// peerConnection = await createPeerConnection(google_ice_config, constraints); +// registerPeerConnectionListeners(); +// } +// +// initializeSignalR(String userName) async { +// if (signalR != null) await signalR.closeConnection(); +// // https://vcallapi.hmg.com/webRTCHub?source=web&username=zohaib +// // signalR = SignalRUtil(hubName: "https://vcallapi.hmg.com/webRTCHub?source=mobile&username=$userName"); +// // signalR = SignalRUtil(hubName: "http://35.193.237.29/webRTCHub?source=mobile&username=$userName"); +// final connected = await signalR.openConnection(); +// if (!connected) throw 'Failed to connect SignalR'; +// } +// +// Map configuration = { +// // 'iceServers': [ +// // { +// // 'urls': ['stun:stun1.l.google.com:19302', 'stun:stun2.l.google.com:19302'] +// // } +// // ] +// +// 'iceServers': [ +// // {'url': "stun:ec2-15-185-116-59.me-south-1.compute.amazonaws.com:3478"}, +// // {'url': "turn:ec2-15-185-116-59.me-south-1.compute.amazonaws.com:3479", 'credential': "admin", 'username': "admin"} +// // {'url': "stun:15.185.116.59:3478"}, +// // { +// // "url":"turn:15.185.116.59:3479", +// // "username": "admin", +// // "credential":"admin" +// // } +// { +// "url": "stun:global.stun.twilio.com:3478?transport=udp", +// "urls": "stun:global.stun.twilio.com:3478?transport=udp" +// }, +// { +// "url": "turn:global.turn.twilio.com:3478?transport=udp", +// "username": "f18fc347ba4aeeaa1b00f5199b1e900834b464962d434a4a89b4cdba02510047", +// "urls": "turn:global.turn.twilio.com:3478?transport=udp", +// "credential": "WX16BB+9nKm0f+Whf5EwpM8S/Yv+T2tlvQWLfdV7oqo=" +// } +// ] +// }; +// +// // SignalRUtil signalR; +// +// RTCPeerConnection peerConnection; +// MediaStream localStream; +// MediaStream remoteStream; +// RTCDataChannel dataChannel; +// +// // Future call(String patientId, String mobile, {@required RTCVideoRenderer localVideo, @required RTCVideoRenderer remoteVideo}) async { +// // await initializeSignalR(patientId); +// // +// // // final isCallPlaced = await FCM.sendCallNotifcationTo(DOCTOR_TOKEN, patientId, mobile); +// // if(!isCallPlaced) +// // throw 'Failed to notify target for call'; +// // +// // return isCallPlaced; +// // } +// +// Future acceptCall(String caller, String receiver, {@required MediaStream localMediaStream, @required Function(MediaStream) onRemoteMediaStream, @required Function(RTCTrackEvent) onRemoteTrack}) async { +// await initializeSignalR(receiver); +// signalR.setContributors(caller: caller, receiver: receiver); +// await signalR.acceptCall(receiver, caller).catchError((e) => throw 'Failed to inform signalR that i accepted a call'); +// +// peerConnection.addStream(localMediaStream); +// +// // peerConnection?.onTrack = (track){ +// // onRemoteTrack(track); +// // }; +// peerConnection?.onAddStream = (MediaStream stream) { +// remoteStream = stream; +// onRemoteMediaStream?.call(stream); +// }; +// return true; +// } +// +// +// Future declineCall(String caller, String receiver) async { +// await initializeSignalR(receiver); +// signalR.setContributors(caller: caller, receiver: receiver); +// await signalR.declineCall(receiver, caller).catchError((e) => throw 'Failed to inform signalR that i accepted a call'); +// +// // peerConnection.addStream(localMediaStream); +// // +// // peerConnection?.onAddStream = (MediaStream stream) { +// // remoteStream = stream; +// // onRemoteMediaStream?.call(stream); +// // }; +// return true; +// } +// +// Future hangupCall(String caller, String receiver) async { +// await signalR.hangupCall(caller, receiver); +// dispose(); +// } +// +// answerOffer(String sdp) async { +// final offer = jsonDecode(sdp); +// final caller = offer['caller']; +// final receiver = offer['target']; +// final offerSdp = offer['sdp']; +// peerConnection.setRemoteDescription(rtcSessionDescriptionFrom(offerSdp)).then((value) { +// return peerConnection.createAnswer().catchError((e){ +// print(e); +// }); +// }).then((anwser) { +// return peerConnection.setLocalDescription(anwser).catchError((e){ +// print(e); +// }); +// }).then((value) { +// return peerConnection.getLocalDescription().catchError((e){ +// print(e); +// }); +// }).then((answer) { +// return signalR.answerOffer(answer, caller, receiver).catchError((e){ +// print(e); +// }); +// }).catchError((e) { +// print(e); +// }); +// } +// +// Future hangUp(RTCVideoRenderer localVideo) async {} +// +// Future createSdpAnswer(String toOfferSdp) async { +// final offerSdp = rtcSessionDescriptionFrom(jsonDecode(toOfferSdp)); +// peerConnection.setRemoteDescription(offerSdp).catchError((e){ +// print(e); +// }); +// +// final answer = await peerConnection.createAnswer().catchError((e){ +// print(e); +// }); +// var answerSdp = json.encode(answer); // Send SDP via Push or any channel +// return answerSdp; +// } +// +// Future createSdpOffer() async { +// final offer = await peerConnection.createOffer(); +// await peerConnection.setLocalDescription(offer).catchError((e){ +// print(e); +// }); +// final map = offer.toMap(); +// var offerSdp = json.encode(map); // Send SDP via Push or any channel +// return offerSdp; +// } +// +// addCandidate(String candidateJson) { +// peerConnection.addCandidate(rtcIceCandidateFrom(candidateJson)).catchError((e){ +// print(e); +// }); +// } +// +// void registerPeerConnectionListeners() { +// peerConnection.onRenegotiationNeeded = (){ +// print('Renegotiation Needed...'); +// }; +// +// peerConnection.onIceCandidate = (RTCIceCandidate candidate) { +// // print(json.encode(candidate.toMap())); +// signalR.addIceCandidate(json.encode(candidate.toMap())).catchError((e){ +// print(e); +// }); +// }; +// +// peerConnection?.onIceGatheringState = (RTCIceGatheringState state) { +// print('ICE gathering state changed: $state'); +// }; +// +// peerConnection?.onConnectionState = (RTCPeerConnectionState state) { +// print('Connection state change: $state'); +// }; +// +// peerConnection?.onSignalingState = (RTCSignalingState state) { +// print('Signaling state change: $state'); +// }; +// +// +// } +// } +// +// rtcSessionDescriptionFrom(Map sdp) { +// return RTCSessionDescription( +// sdp['sdp'], +// sdp['type'], +// ); +// } +// +// rtcIceCandidateFrom(String json) { +// final map = jsonDecode(json)['candidate']; +// return RTCIceCandidate(map['candidate'], map['sdpMid'], map['sdpMLineIndex']); +// } diff --git a/lib/uitl/SignalRUtil.dart b/lib/uitl/SignalRUtil.dart index d9a73a14..904155a2 100644 --- a/lib/uitl/SignalRUtil.dart +++ b/lib/uitl/SignalRUtil.dart @@ -1,173 +1,173 @@ -import 'dart:convert'; -import 'dart:io'; - -import 'package:flutter/cupertino.dart'; -import 'package:flutter_webrtc/flutter_webrtc.dart'; -import 'package:http/io_client.dart'; -import 'package:signalr_core/signalr_core.dart'; - -class SignalRUtil { - String hubName; - - String sourceUser; - String destinationUser; - setContributors({@required String caller, @required String receiver}){ - this.sourceUser = caller; - this.destinationUser = receiver; - } - - Function(bool) onConnected; - SignalRUtil({@required this.hubName}); - - - HubConnection connectionHub; - - closeConnection() async{ - if(connectionHub != null) { - connectionHub.off('OnIncomingCallAsync'); - connectionHub.off('OnCallDeclinedAsync'); - connectionHub.off('OnCallAcceptedAsync'); - connectionHub.off('nHangUpAsync'); - connectionHub.off('OnIceCandidateAsync'); - connectionHub.off('OnOfferAsync'); - await connectionHub.stop(); - } - } - - Future openConnection() async { - connectionHub = HubConnectionBuilder() - .withUrl( - hubName, - HttpConnectionOptions( - logMessageContent: true, - client: IOClient(HttpClient()..badCertificateCallback = (x, y, z) => true), - logging: (level, message) => print(message), - )).build(); - - await connectionHub.start(); - await Future.delayed(Duration(seconds: 1)); - - connectionHub.on('ReceiveMessage', (message) { - handleIncomingMessage(message); - }); - - return getConnectionState(); - } - - void handleIncomingMessage(List message) { - print(message.toString()); - } - - void sendMessage(List args) async { - await connectionHub.invoke('SendMessage', args: args); //['Bob', 'Says hi!'] - } - - listen({Function(CallUser) onAcceptCall, Function(CallUser) onHangupCall, Function(String, CallUser) onDeclineCall, Function(String, CallUser) onOffer, Function(String) onCandidate}){ - - connectionHub.on('OnIncomingCallAsync', (arguments) { - print('OnIncomingCallAsync: ${arguments.toString()}'); - }); - - connectionHub.on('OnCallDeclinedAsync', (arguments) { - print('OnCallDeclinedAsync: ${arguments.toString()}'); - onDeclineCall(arguments.first, CallUser.from(arguments.last)); - }); - - connectionHub.on('OnCallAcceptedAsync', (arguments) { - print('OnCallAcceptedAsync: ${arguments.toString()}'); - }); - - connectionHub.on('OnHangUpAsync', (arguments) { - print('nHangUpAsync: ${arguments.toString()}'); - onHangupCall(CallUser.from(arguments.first)); - }); - - connectionHub.on('OnIceCandidateAsync', (arguments) { - print('OnIceCandidateAsync: ${arguments.toString()}'); - onCandidate(arguments.first); - }); - - connectionHub.on('OnOfferAsync', (arguments) { - print('OnOfferAsync: ${arguments.toString()}'); - onOffer(arguments.first, CallUser.from(arguments.last)); - }); - - } - - // CallUserAsync(string currentUserId, string targerUserId) - Future callUser(String from, to) async{ - return await connectionHub.invoke('CallUserAsync', args: [from, to]); - } - - // CallDeclinedAsync(string currentUserId, string targerUserId) - Future declineCall(String from, to) async{ - return await connectionHub.invoke('CallDeclinedAsync', args: [from, to]); - } - - // AnswerCallAsync(string currentUserId, string targetUserId) - Future answerCall(String from, to) async{ - return await connectionHub.invoke('AnswerCallAsync', args: [from, to]); - } - - // IceCandidateAsync(string targetUserId, string candidate) - Future addIceCandidate(String candidate) async{ - final target = destinationUser; - return await connectionHub.invoke('IceCandidateAsync', args: [target, candidate]); - } - - // OfferAsync(string targetUserId,string currentUserId, string targetOffer) - Future offer(String from, to, offer) async{ - return await connectionHub.invoke('OfferAsync', args: [from, to, offer]); - } - - // AnswerOfferAsync(string targetUserId, string CallerOffer) - Future answerOffer(RTCSessionDescription answerSdp, caller, receiver) async{ - final payload = { - 'target': receiver, - 'caller': caller, - 'sdp': answerSdp.toMap(), - }; - return await connectionHub.invoke('AnswerOfferAsync', args: [caller, jsonEncode(payload)]); - } - - // HangUpAsync(string currentUserId, string targetUserId) - Future hangupCall(String from, to) async{ - return await connectionHub.invoke('HangUpAsync', args: [from, to]); - } - - // CallAccepted(string currentUserId,string targetUserId) - Future acceptCall(String from, to) async{ - // return await connectionHub.send(methodName: 'CallAccepted', args: [from, to]); - return await connectionHub.invoke("CallAccepted", args: [ from, to]); - } - - - bool getConnectionState() { - if (connectionHub.state == HubConnectionState.connected) return true; - if (connectionHub.state == HubConnectionState.disconnected) return false; - return false; - } -} - - -class CallUser{ - String Id; - String UserName; - String Email; - String Phone; - String Title; - dynamic UserStatus; - String Image; - int UnreadMessageCount = 0; - - CallUser.from(Map map){ - Id = map['Id']; - UserName = map['UserName']; - Email = map['Email']; - Phone = map['Phone']; - Title = map['Title']; - UserStatus = map['UserStatus']; - Image = map['Image']; - UnreadMessageCount = map['UnreadMessageCount']; - } -} \ No newline at end of file +// import 'dart:convert'; +// import 'dart:io'; +// +// import 'package:flutter/cupertino.dart'; +// import 'package:flutter_webrtc/flutter_webrtc.dart'; +// import 'package:http/io_client.dart'; +// // import 'package:signalr_core/signalr_core.dart'; +// +// class SignalRUtil { +// String hubName; +// +// String sourceUser; +// String destinationUser; +// setContributors({@required String caller, @required String receiver}){ +// this.sourceUser = caller; +// this.destinationUser = receiver; +// } +// +// Function(bool) onConnected; +// SignalRUtil({@required this.hubName}); +// +// +// // HubConnection connectionHub; +// +// closeConnection() async{ +// if(connectionHub != null) { +// connectionHub.off('OnIncomingCallAsync'); +// connectionHub.off('OnCallDeclinedAsync'); +// connectionHub.off('OnCallAcceptedAsync'); +// connectionHub.off('nHangUpAsync'); +// connectionHub.off('OnIceCandidateAsync'); +// connectionHub.off('OnOfferAsync'); +// await connectionHub.stop(); +// } +// } +// +// Future openConnection() async { +// // connectionHub = HubConnectionBuilder() +// // .withUrl( +// // hubName, +// // HttpConnectionOptions( +// // logMessageContent: true, +// // client: IOClient(HttpClient()..badCertificateCallback = (x, y, z) => true), +// // logging: (level, message) => print(message), +// // )).build(); +// +// await connectionHub.start(); +// await Future.delayed(Duration(seconds: 1)); +// +// connectionHub.on('ReceiveMessage', (message) { +// handleIncomingMessage(message); +// }); +// +// return getConnectionState(); +// } +// +// void handleIncomingMessage(List message) { +// print(message.toString()); +// } +// +// void sendMessage(List args) async { +// await connectionHub.invoke('SendMessage', args: args); //['Bob', 'Says hi!'] +// } +// +// listen({Function(CallUser) onAcceptCall, Function(CallUser) onHangupCall, Function(String, CallUser) onDeclineCall, Function(String, CallUser) onOffer, Function(String) onCandidate}){ +// +// connectionHub.on('OnIncomingCallAsync', (arguments) { +// print('OnIncomingCallAsync: ${arguments.toString()}'); +// }); +// +// connectionHub.on('OnCallDeclinedAsync', (arguments) { +// print('OnCallDeclinedAsync: ${arguments.toString()}'); +// onDeclineCall(arguments.first, CallUser.from(arguments.last)); +// }); +// +// connectionHub.on('OnCallAcceptedAsync', (arguments) { +// print('OnCallAcceptedAsync: ${arguments.toString()}'); +// }); +// +// connectionHub.on('OnHangUpAsync', (arguments) { +// print('nHangUpAsync: ${arguments.toString()}'); +// onHangupCall(CallUser.from(arguments.first)); +// }); +// +// connectionHub.on('OnIceCandidateAsync', (arguments) { +// print('OnIceCandidateAsync: ${arguments.toString()}'); +// onCandidate(arguments.first); +// }); +// +// connectionHub.on('OnOfferAsync', (arguments) { +// print('OnOfferAsync: ${arguments.toString()}'); +// onOffer(arguments.first, CallUser.from(arguments.last)); +// }); +// +// } +// +// // CallUserAsync(string currentUserId, string targerUserId) +// Future callUser(String from, to) async{ +// return await connectionHub.invoke('CallUserAsync', args: [from, to]); +// } +// +// // CallDeclinedAsync(string currentUserId, string targerUserId) +// Future declineCall(String from, to) async{ +// return await connectionHub.invoke('CallDeclinedAsync', args: [from, to]); +// } +// +// // AnswerCallAsync(string currentUserId, string targetUserId) +// Future answerCall(String from, to) async{ +// return await connectionHub.invoke('AnswerCallAsync', args: [from, to]); +// } +// +// // IceCandidateAsync(string targetUserId, string candidate) +// Future addIceCandidate(String candidate) async{ +// final target = destinationUser; +// return await connectionHub.invoke('IceCandidateAsync', args: [target, candidate]); +// } +// +// // OfferAsync(string targetUserId,string currentUserId, string targetOffer) +// Future offer(String from, to, offer) async{ +// return await connectionHub.invoke('OfferAsync', args: [from, to, offer]); +// } +// +// // AnswerOfferAsync(string targetUserId, string CallerOffer) +// Future answerOffer(RTCSessionDescription answerSdp, caller, receiver) async{ +// final payload = { +// 'target': receiver, +// 'caller': caller, +// 'sdp': answerSdp.toMap(), +// }; +// return await connectionHub.invoke('AnswerOfferAsync', args: [caller, jsonEncode(payload)]); +// } +// +// // HangUpAsync(string currentUserId, string targetUserId) +// Future hangupCall(String from, to) async{ +// return await connectionHub.invoke('HangUpAsync', args: [from, to]); +// } +// +// // CallAccepted(string currentUserId,string targetUserId) +// Future acceptCall(String from, to) async{ +// // return await connectionHub.send(methodName: 'CallAccepted', args: [from, to]); +// return await connectionHub.invoke("CallAccepted", args: [ from, to]); +// } +// +// +// bool getConnectionState() { +// if (connectionHub.state == HubConnectionState.connected) return true; +// if (connectionHub.state == HubConnectionState.disconnected) return false; +// return false; +// } +// } +// +// +// class CallUser{ +// String Id; +// String UserName; +// String Email; +// String Phone; +// String Title; +// dynamic UserStatus; +// String Image; +// int UnreadMessageCount = 0; +// +// CallUser.from(Map map){ +// Id = map['Id']; +// UserName = map['UserName']; +// Email = map['Email']; +// Phone = map['Phone']; +// Title = map['Title']; +// UserStatus = map['UserStatus']; +// Image = map['Image']; +// UnreadMessageCount = map['UnreadMessageCount']; +// } +// } \ No newline at end of file