merge-update-with-lab-changes
haroon amjad 3 years ago
parent ff23f3a8cb
commit 3353c93de9

@ -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<CallHomePage> {
bool showNoise = true;
RTCVideoRenderer _localRenderer = RTCVideoRenderer();
RTCVideoRenderer _remoteRenderer = RTCVideoRenderer();
final StreamController<bool> _audioButton = StreamController<bool>.broadcast();
final StreamController<bool> _videoButton = StreamController<bool>.broadcast();
final StreamController<bool> _onButtonBarVisibleStreamController = StreamController<bool>.broadcast();
final StreamController<double> _onButtonBarHeightStreamController = StreamController<double>.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<bool> 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<void> _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<void> _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<CallHomePage> {
// bool showNoise = true;
// RTCVideoRenderer _localRenderer = RTCVideoRenderer();
// RTCVideoRenderer _remoteRenderer = RTCVideoRenderer();
//
// final StreamController<bool> _audioButton = StreamController<bool>.broadcast();
// final StreamController<bool> _videoButton = StreamController<bool>.broadcast();
// final StreamController<bool> _onButtonBarVisibleStreamController = StreamController<bool>.broadcast();
// final StreamController<double> _onButtonBarHeightStreamController = StreamController<double>.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<bool> 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<void> _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<void> _onHangup() async {
// signaling.hangupCall(widget.callerId, widget.receiverId);
// print('onHangup');
// Navigator.of(context).pop();
// }
// }

@ -81,7 +81,7 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
var themeNotifier;
DateTime currentBackPressTime;
SignalRUtil signalRUtil;
// SignalRUtil signalRUtil;
ToDoCountProviderModel toDoProvider;

@ -34,7 +34,7 @@ class _IncomingCallState extends State<IncomingCall> with SingleTickerProviderSt
CameraController _controller;
Future<void> _initializeControllerFuture;
bool isCameraReady = false;
Signaling signaling = Signaling()..init();
// Signaling signaling = Signaling()..init();
@override
void initState() {

@ -14,7 +14,7 @@ class CallPage extends StatefulWidget {
}
class _CallPageState extends State<CallPage> {
Signaling signaling = Signaling();
// Signaling signaling = Signaling();
RTCVideoRenderer _localRenderer = RTCVideoRenderer();
RTCVideoRenderer _remoteRenderer = RTCVideoRenderer();
String roomId;
@ -73,7 +73,7 @@ class _CallPageState extends State<CallPage> {
),
ElevatedButton(
onPressed: () {
signaling.hangUp(_localRenderer);
// signaling.hangUp(_localRenderer);
},
child: Text("Hangup"),
)

@ -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<String, dynamic> constraints = {
'mandatory': {},
'optional': [
{'DtlsSrtpKeyAgreement': true},
]
};
Map<String, dynamic> 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<String, dynamic> 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<String, dynamic> 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<String, dynamic> 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<String, dynamic> 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<bool> 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<bool> 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<bool> 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<void> hangUp(RTCVideoRenderer localVideo) async {}
Future<String> 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<String> 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<String, dynamic> constraints = {
// 'mandatory': {},
// 'optional': [
// {'DtlsSrtpKeyAgreement': true},
// ]
// };
//
// Map<String, dynamic> 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<String, dynamic> 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<String, dynamic> 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<String, dynamic> 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<String, dynamic> 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<bool> 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<bool> 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<bool> 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<void> hangUp(RTCVideoRenderer localVideo) async {}
//
// Future<String> 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<String> 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']);
// }

@ -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<bool> 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<dynamic> message) {
print(message.toString());
}
void sendMessage(List<dynamic> 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<dynamic> callUser(String from, to) async{
return await connectionHub.invoke('CallUserAsync', args: [from, to]);
}
// CallDeclinedAsync(string currentUserId, string targerUserId)
Future<dynamic> declineCall(String from, to) async{
return await connectionHub.invoke('CallDeclinedAsync', args: [from, to]);
}
// AnswerCallAsync(string currentUserId, string targetUserId)
Future<dynamic> answerCall(String from, to) async{
return await connectionHub.invoke('AnswerCallAsync', args: [from, to]);
}
// IceCandidateAsync(string targetUserId, string candidate)
Future<dynamic> addIceCandidate(String candidate) async{
final target = destinationUser;
return await connectionHub.invoke('IceCandidateAsync', args: [target, candidate]);
}
// OfferAsync(string targetUserId,string currentUserId, string targetOffer)
Future<dynamic> offer(String from, to, offer) async{
return await connectionHub.invoke('OfferAsync', args: [from, to, offer]);
}
// AnswerOfferAsync(string targetUserId, string CallerOffer)
Future<dynamic> 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<dynamic> hangupCall(String from, to) async{
return await connectionHub.invoke('HangUpAsync', args: [from, to]);
}
// CallAccepted(string currentUserId,string targetUserId)
Future<dynamic> 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'];
}
}
// 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<bool> 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<dynamic> message) {
// print(message.toString());
// }
//
// void sendMessage(List<dynamic> 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<dynamic> callUser(String from, to) async{
// return await connectionHub.invoke('CallUserAsync', args: [from, to]);
// }
//
// // CallDeclinedAsync(string currentUserId, string targerUserId)
// Future<dynamic> declineCall(String from, to) async{
// return await connectionHub.invoke('CallDeclinedAsync', args: [from, to]);
// }
//
// // AnswerCallAsync(string currentUserId, string targetUserId)
// Future<dynamic> answerCall(String from, to) async{
// return await connectionHub.invoke('AnswerCallAsync', args: [from, to]);
// }
//
// // IceCandidateAsync(string targetUserId, string candidate)
// Future<dynamic> addIceCandidate(String candidate) async{
// final target = destinationUser;
// return await connectionHub.invoke('IceCandidateAsync', args: [target, candidate]);
// }
//
// // OfferAsync(string targetUserId,string currentUserId, string targetOffer)
// Future<dynamic> offer(String from, to, offer) async{
// return await connectionHub.invoke('OfferAsync', args: [from, to, offer]);
// }
//
// // AnswerOfferAsync(string targetUserId, string CallerOffer)
// Future<dynamic> 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<dynamic> hangupCall(String from, to) async{
// return await connectionHub.invoke('HangUpAsync', args: [from, to]);
// }
//
// // CallAccepted(string currentUserId,string targetUserId)
// Future<dynamic> 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'];
// }
// }
Loading…
Cancel
Save