You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
PatientApp-KKUMC/lib/voipcall/provider/chat_call_provider.dart

1201 lines
46 KiB
Dart

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:diplomaticquarterapp/locator.dart';
import 'package:diplomaticquarterapp/models/LiveCare/IncomingCallData.dart';
import 'package:diplomaticquarterapp/routes.dart';
import 'package:diplomaticquarterapp/uitl/navigation_service.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/voipcall/call/chat_incoming_call_screen.dart';
import 'package:diplomaticquarterapp/voipcall/model/call.dart';
import 'package:diplomaticquarterapp/voipcall/model/webrtc_payloads.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:http/http.dart';
import 'package:just_audio/just_audio.dart';
import 'package:logger/logger.dart' as log;
import 'package:logging/logging.dart';
import 'package:signalr_netcore/signalr_client.dart';
class ChatCallProvider with ChangeNotifier, DiagnosticableTreeMixin {
///////////////////// Web RTC Video Calling //////////////////////
// Video Call
HubConnection? chatHubConnection;
RTCPeerConnection? _pc;
//late ChatProviderModel chatProvModel;
RTCVideoRenderer? localVideoRenderer;
RTCVideoRenderer? remoteRenderer;
final AudioPlayer player = AudioPlayer();
MediaStream? _localStream;
CallDataModel? outGoingCallData;
bool isMicOff = false;
bool isLoudSpeaker = false;
bool isCamOff = false;
bool isCallEnded = false;
// This need to Be Changed to dynamic
bool isVideoCall = true;
bool isAudioCall = false;
bool isCallStarted = false;
bool isFrontCamera = true;
//SingleUserChatModel? incomingCallData;
/// WebRTC Connection Variables
bool isIncomingCallLoader = true;
bool isIncomingCall = false;
bool isOutGoingCall = false;
bool isUserOnline = false;
List<MediaDeviceInfo> devices = [];
log.Logger debuglogger = log.Logger();
IncomingCallData? _incomingCallData;
IncomingCallData? get incomingCallData => _incomingCallData;
set incomingCallData(IncomingCallData? value) {
_incomingCallData = value;
}
//
// // If you want only to log out the message for the higer level hub protocol:
// final hubProtLogger = Logger("SignalR - hub");
// final transportProtLogger = Logger("SignalR - transport");
// late Logger _logger;
// late StreamSubscription<LogRecord> _logMessagesSub;
//
// void _handleLogMessage(LogRecord msg) {
// print(msg.message);
// }
//
// Future<void> buildHubConnection() async {
// try {
// Logger.root.level = Level.ALL;
// _logMessagesSub = Logger.root.onRecord.listen(_handleLogMessage);
// _logger = Logger("ChatPageViewModel");
//
// // chatHubConnection = await getHubConnection();
// String to = "ytvF4zQfUrJHOUfpE7UE1Q";
// HttpConnectionOptions httpOp = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true, logger: transportProtLogger);
// // hub = HubConnectionBuilder()
// // .withUrl(ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Desktop&access_token=${AppState().chatDetails!.response!.token}", options: httpOp)
// // .withAutomaticReconnect(retryDelays: <int>[2000, 5000, 10000, 20000]).build();
// var urlWithParams = "https://ms.hmg.com/livecare/liveCareHub?UserID=4767770&ProjectId=12&IsAdmin=false&To=$to";
// print("ChatHubURL:::: " + urlWithParams);
// chatHubConnection = await HubConnectionBuilder().withUrl(urlWithParams, options: httpOp).build();
// await chatHubConnection!.start();
// print(chatHubConnection!.state);
// chatHubConnection!.onclose(({error}) {
// print("Connection Closed");
// });
// // if (chatHubConnection!.state == HubConnectionState.Connected) {
// // print("Success Chat Con ID::: " + chatHubConnection!.connectionId.toString());
// // if (kDebugMode) {
// // print("Hub Conn: Startedddddddd");
// // }
// // //registerCallListners();
// // }
// } catch (e) {
// print(e.toString());
// Utils.showErrorToast(e.toString());
// }
// }
//{"id":341682,"userName":"Aamir.Muhammad","email":"Aamir.Muhammad@cloudsolutions.com.sa","phone":null,"title":"Aamir Saleem Ahmad Dost Muhammad","token":"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIzNDE2ODIiLCJlbWFpbCI6IkFhbWlyLk11aGFtbWFkQGNsb3Vkc29sdXRpb25zLmNvbS5zYSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvdXNlcmRhdGEiOiJBYW1pci5NdWhhbW1hZCIsIm5iZiI6MTcwNzIwNTAyMywiZXhwIjoxNzA3MjkxNDIzLCJpYXQiOjE3MDcyMDUwMjN9.Zz2bcsMwiLAAWGZh2E_p5Qs6ItMt0JHhDFI_0DLdggCQtt6HHcT4n8nvqMZx-uYr3jLwqhA_IAjTuaCeSE15sw","isDomainUser":true,"isActiveCode":false,"encryptedUserId":"nn7RkYzbnQc=","encryptedUserName":"/QruOyp4QMcmNXKZlljUgg=="}
// Future<HubConnection> getHubConnection() async {
// AppState().chatDetails = getUserToken.UserAutoLoginModel(
// response: getUserToken.Response.fromJson({
// "id": 341682,
// "userName": "Aamir.Muhammad",
// "email": "Aamir.Muhammad@cloudsolutions.com.sa",
// "phone": null,
// "title": "Aamir Saleem Ahmad Dost Muhammad",
// "token":
// "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIzNDE2ODIiLCJlbWFpbCI6IkFhbWlyLk11aGFtbWFkQGNsb3Vkc29sdXRpb25zLmNvbS5zYSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvdXNlcmRhdGEiOiJBYW1pci5NdWhhbW1hZCIsIm5iZiI6MTcwODI1NjI5NywiZXhwIjoxNzA4MzQyNjk3LCJpYXQiOjE3MDgyNTYyOTd9.Y-QDVbSbPzcMVkHyIT06WgM0EsKH183hASZrIsXGkFOR_XZcqCJS-CrgdN0nOtxCWV6wd01dgfhMTNTZhybwiQ",
// "isDomainUser": true,
// "isActiveCode": false,
// "encryptedUserId": "nn7RkYzbnQc=",
// "encryptedUserName": "/QruOyp4QMcmNXKZlljUgg=="
// }),
// );
// String to = "dfK3ZqFD-BTlJLnuf1F5Cw";
// HubConnection hub;
// HttpConnectionOptions httpOp = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true);
// // hub = HubConnectionBuilder()
// // .withUrl(ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Desktop&access_token=${AppState().chatDetails!.response!.token}", options: httpOp)
// // .withAutomaticReconnect(retryDelays: <int>[2000, 5000, 10000, 20000]).build();
// var urlWithParams = "https://ms.hmg.com/livecare/liveCareHub?UserID=4767770&ProjectId=15&IsAdmin=false&To=$to";
// print("ChatHubURL:::: " + urlWithParams);
// hub = await HubConnectionBuilder().withUrl(urlWithParams, options: httpOp).withAutomaticReconnect(retryDelays: <int>[2000, 5000, 10000, 20000]).build();
// return hub;
// }
// Future<CallDataModel> makeCall({required String callType}) async {
// Map<String, dynamic> json = {
// "callerID": AppState().chatDetails!.response!.id,
// "callerName": AppState().chatDetails!.response!.userName,
// "callerEmail": AppState().chatDetails!.response!.email,
// "callerTitle": AppState().chatDetails!.response!.title,
// "callerPhone": AppState().chatDetails!.response!.phone,
// "receiverID": 266642,
// "receiverName": "Muhammad Alam",
// "receiverEmail": "Muhamad.Alam@cloudsolutions.com.sa",
// "receiverTitle": "Muhammad Alam",
// "receiverPhone": "123456789",
// "title": "Muhammad Alam",
// "callType": callType == "VIDEO" ? "Video" : "Audio",
// };
// CallDataModel res = CallDataModel.fromJson(json);
// return res;
// }
// void registerCallListners() {
// if (kDebugMode) {
// print("=================== Call Listeners Registered =======================");
// }
// chatHubConnection!.on("OnCallAcceptedAsync", onCallAcceptedAsync);
// chatHubConnection!.on("OnIceCandidateAsync", onIceCandidateAsync);
// chatHubConnection!.on("OnOfferAsync", onOfferAsync);
// chatHubConnection!.on("OnAnswerOffer", onAnswerOffer);
// chatHubConnection!.on("OnHangUpAsync", onHangUpAsync);
// // chatHubConnection!.on("OnCallDeclinedAsync", onCallDeclinedAsync);
// // chatHubConnection!.on("OnIncomingCallAsync", OnIncomingCallAsync);
// }
// Audio Constraints
Map<String, Object> audioConstraints = {
"sampleRate": 8000,
"sampleSize": 16,
"channelCount": 2,
"echoCancellation": true,
"audio": true,
};
// Future<void> init() async {
// _pc = await creatOfferWithCon();
// Future.delayed(const Duration(seconds: 2), () {
// connectIncomingCall();
// });
// }
///////////////////////////////////////////////OutGoing Call////////////////////////////////////////////////////
//
// Future<void> initLocalCamera({callData, bool isIncomingCall = false}) async {
// isCallEnded = false;
// outGoingCallData = callData;
// await initStreams();
// await startCall();
// _pc = await creatOfferWithCon();
// connectOutgoing();
// notifyListeners();
// }
//
// void connectOutgoing() {
// isOutGoingCall = true;
// // notifyListeners();
// }
//
// Future<void> startCall() async {
// // chatProvModel.isTextMsg = true;
// // chatProvModel.isAttachmentMsg = false;
// // chatProvModel.isVoiceMsg = false;
// // chatProvModel.isReplyMsg = false;
// // chatProvModel.isCall = true;
// // chatProvModel.message.text = "Start $callType call ${outGoingCallData.receiverName.toString().replaceAll(".", " ")}";
// // chatProvModel.sendChatMessage(
// // context,
// // targetUserId: outGoingCallData.receiverId,
// // userStatus: 1,
// // userEmail: outGoingCallData.receiverEmail,
// // targetUserName: outGoingCallData.receiverName,
// // );
// await invoke(
// invokeMethod: "CallUserAsync",
// currentUserID: outGoingCallData!.callerId!,
// targetUserID: outGoingCallData!.receiverId!,
// );
// await invoke(invokeMethod: "UpdateUserStatusAsync", currentUserID: outGoingCallData!.callerId!, targetUserID: outGoingCallData!.receiverId!, userStatus: 4);
// }
// // OutGoing Listeners
// void onCallAcceptedAsync(List<Object?>? params) async {
// dynamic items = params!.toList();
// RTCSessionDescription description = await _createOffer();
// await _pc!.setLocalDescription(description);
// dynamic payload = {"target": items[0]["id"], "caller": outGoingCallData!.callerId, "sdp": description.toMap()};
// invoke(invokeMethod: "OfferAsync", currentUserID: outGoingCallData!.callerId!, targetUserID: items[0]["id"], data: jsonEncode(payload));
// }
//
// Future<void> onIceCandidateAsync(List<Object?>? params) async {
// dynamic items = params!.toList();
// if (isIncomingCall) {
// RemoteIceCandidatePayLoad data = RemoteIceCandidatePayLoad.fromJson(jsonDecode(items.first.toString()));
// if (_pc != null) {
// await _pc!.addCandidate(RTCIceCandidate(data.candidate!.candidate, data.candidate!.sdpMid, data.candidate!.sdpMLineIndex));
// }
// } else {
// if (kDebugMode) {
// print("res: " + items.toString());
// }
// RemoteIceCandidatePayLoad data = RemoteIceCandidatePayLoad.fromJson(jsonDecode(items.first.toString()));
// if (_pc != null) {
// await _pc!.addCandidate(RTCIceCandidate(data.candidate!.candidate, data.candidate!.sdpMid, data.candidate!.sdpMLineIndex));
// if (!isCallStarted) {
// isCallStarted = true;
// notifyListeners();
// if (isCallStarted) {
// isIncomingCallLoader = false;
// isOutGoingCall = true;
// if (Platform.isIOS) {
// Future.delayed(Duration(seconds: 2), () {
// Navigator.pushReplacement(
// locator<NavigationService>().navigatorKey.currentContext!,
// MaterialPageRoute(
// builder: (BuildContext context) => StartCallPage(),
// ));
// });
// } else {
// Navigator.pushReplacement(
// locator<NavigationService>().navigatorKey.currentContext!,
// MaterialPageRoute(
// builder: (BuildContext context) => StartCallPage(),
// ));
// }
// }
// }
// }
// notifyListeners();
// }
// }
//
// Future<void> onOfferAsync(List<Object?>? params) async {
// dynamic items = params!.toList();
// var data = jsonDecode(items.toString());
// if (isIncomingCall) {
// _pc!.setRemoteDescription(RTCSessionDescription(data[0]["sdp"]["sdp"], data[0]["sdp"]["type"]));
// RTCSessionDescription description = await _createAnswer();
// await _pc!.setLocalDescription(description);
// dynamic payload = {"target": data[0]["caller"], "caller": AppState().chatDetails!.response!.id!, "sdp": description.toMap()};
// invoke(invokeMethod: "AnswerOfferAsync", currentUserID: AppState().chatDetails!.response!.id!, targetUserID: incomingCallData!.targetUserId!, data: jsonEncode(payload));
// }
// // else {
// // RTCSessionDescription description = await _createAnswer();
// // await _pc.setLocalDescription(description);
// // var payload = {"target": items[0]["id"], "caller": outGoingCallData.callerId, "sdp": description.toMap()};
// // invoke(invokeMethod: "AnswerOffer", currentUserID: outGoingCallData.callerId!, targetUserID: items[0]["id"], data: jsonEncode(payload));
// // }
// notifyListeners();
// }
//////////////////////////// OutGoing Call End ///////////////////////////////////////
// Future<bool> endCall({bool? isUserOnline}) async {
// if (isIncomingCall) {
// print("-----------------------Endeddddd By Me---------------------------");
// if (chatHubConnection!.state == HubConnectionState.Connected) {
// await invoke(invokeMethod: "HangUpAsync", currentUserID: AppState().chatDetails!.response!.id!, targetUserID: incomingCallData!.targetUserId!, userStatus: 0);
// await invoke(invokeMethod: "UpdateUserStatusAsync", currentUserID: AppState().chatDetails!.response!.id!, targetUserID: incomingCallData!.targetUserId!, userStatus: 1);
// }
// isCallStarted = false;
// isVideoCall = false;
// isCamOff = false;
// isMicOff = false;
// isLoudSpeaker = false;
// isIncomingCall = false;
// isOutGoingCall = false;
// isAudioCall = false;
//
// if (isCallConnected) {
// if (_pc!.connectionState == RTCPeerConnectionState.RTCPeerConnectionStateConnected) {
// if (kDebugMode) {
// print("------------------ PC Stopped ----------------------------");
// }
// _pc!.close();
// _pc!.dispose();
// }
// }
// if (remoteRenderer != null) {
// remoteRenderer!.dispose();
// remoteRenderer = null;
// }
// if (localVideoRenderer != null) {
// localVideoRenderer!.dispose();
// localVideoRenderer = null;
// }
//
// if (_localStream != null) {
// _localStream!.dispose();
// _localStream = null;
// }
// if (chatHubConnection != null && !isUserOnline!) {
// chatHubConnection!.stop();
// }
// await FlutterCallkitIncoming.endAllCalls();
// return true;
// } else {
// if (isOutGoingCall) {
// await invoke(invokeMethod: "HangUpAsync", currentUserID: outGoingCallData!.callerId!, targetUserID: outGoingCallData!.receiverId!, userStatus: 1);
// await invoke(invokeMethod: "UpdateUserStatusAsync", currentUserID: outGoingCallData!.callerId!, targetUserID: outGoingCallData!.receiverId!, userStatus: 1);
// } else if (isIncomingCall) {
// await invoke(invokeMethod: "UpdateUserStatusAsync", currentUserID: AppState().chatDetails!.response!.id!, targetUserID: incomingCallData!.targetUserId!, userStatus: 1);
// }
// isCallStarted = false;
// isVideoCall = false;
// isCamOff = false;
// isMicOff = false;
// isLoudSpeaker = false;
// if (isCallConnected) {
// if (_pc!.connectionState == RTCPeerConnectionState.RTCPeerConnectionStateConnected) {
// _pc!.close();
// _pc!.dispose();
// }
// }
// if (remoteRenderer != null) {
// remoteRenderer!.dispose();
// remoteRenderer = null;
// }
// if (localVideoRenderer != null) {
// localVideoRenderer!.dispose();
// localVideoRenderer = null;
// }
//
// if (_localStream != null) {
// _localStream!.dispose();
// _localStream = null;
// }
// isOutGoingCall = false;
// isIncomingCall = false;
// isAudioCall = false;
// return true;
// }
// }
// Incoming Listeners
// void onAnswerOffer(List<Object?>? payload) async {
// // if (isIncomingCall) {
// // // print("--------------------- On Answer Offer Async ---------------------------------------");
// // //await invoke(invokeMethod: "InvokeMobile", currentUserID: AppState().getchatUserDetails!.response!.id!, targetUserID: incomingCallData.targetUserId!, debugData: {"On Answer Offer Async"});
// // } else {
// var items = payload!.toList();
// if (kDebugMode) {
// print("res: " + items.toString());
// }
// CallSessionPayLoad data = CallSessionPayLoad.fromJson(jsonDecode(items.first.toString()));
// RTCSessionDescription description = RTCSessionDescription(data.sdp!.sdp, 'answer');
// _pc!.setRemoteDescription(description);
// // }
// }
// void onHangUpAsync(List<Object?>? params) {
// print("--------------------- onHangUp ASYNC ---------------------------------");
//
// dynamic items = params!.toList();
// // if (kDebugMode) {
// // logger.i("res: " + items.toString());
// // }
// if (items[0]["id"] != AppState().chatDetails!.response!.id!) {
// if (kDebugMode) {
// print("Call Ended By Other User");
// }
// if (isIncomingCall) {
// endCall(isUserOnline: isUserOnline).then((bool value) {
// if (isCallConnected && isUserOnline) {
// isCallConnected = false;
// if (!AppState().isLogged) {
// Navigator.of(locator<NavigationService>().navigatorKey.currentContext!).pop();
// } else {
// Navigator.of(locator<NavigationService>().navigatorKey.currentContext!).popUntil(ModalRoute.withName(HOME));
// }
// } else {
// Navigator.of(locator<NavigationService>().navigatorKey.currentContext!).pop();
// }
// });
// } else {
// if (isOutGoingCall) {
// endCall(isUserOnline: isUserOnline).then((bool value) {
// if (isCallConnected && isUserOnline) {
// isCallConnected = false;
// Navigator.of(locator<NavigationService>().navigatorKey.currentContext!).popUntil(ModalRoute.withName(HOME));
// } else {
// Navigator.of(locator<NavigationService>().navigatorKey.currentContext!).pop();
// }
// });
// }
// }
// } else {
// if (kDebugMode) {
// print("Call Ended By Me");
// }
// if (isOutGoingCall) {
// if (isCallConnected && isUserOnline) {
// isCallConnected = false;
// Navigator.of(locator<NavigationService>().navigatorKey.currentContext!).popUntil(ModalRoute.withName(HOME));
// } else {
// Navigator.of(locator<NavigationService>().navigatorKey.currentContext!).pop();
// }
// }
// }
// // endCall(isUserOnline: isUserOnline).then((bool value) {
// // if (isCallConnected && isUserOnline) {
// // Navigator.of(AppRoutes.navigatorKey.currentContext!).popUntil(ModalRoute.withName(AppRoutes.chatDetailed));
// // isCallConnected = false;
// // }
// // if (items[0]["id"] != AppState().chatDetails!!.response!.id && !AppState().isBackgroundCall) {
// // if (kDebugMode) {
// // print("Popped Due to Another User");
// // }
// // if (AppState().isBackgroundCall) {
// // Navigator.of(AppRoutes.navigatorKey.currentContext!).pop();
// // // Navigator.of(AppRoutes.navigatorKey.currentContext!).popUntil(ModalRoute.withName(AppRoutes.login));
// // } else {
// // Navigator.of(AppRoutes.navigatorKey.currentContext!).popUntil(ModalRoute.withName(AppRoutes.chat));
// // }
// // }
// // if (AppState().isBackgroundCall) {
// // Navigator.of(AppRoutes.navigatorKey.currentContext!).pop();
// // }
// //
// notifyListeners();
// isCallEnded = true;
// // });
// }
// Future<void> OnIncomingCallAsync(List<Object?>? params) async {
// print("--------------------- On Incoming Call ---------------------------------------");
// dynamic items = params!.toList();
// logger.d(items);
// // Map<String, dynamic> json = {
// // "callerID": items[0]["id"],
// // "callerName": items[0]["userName"],
// // "callerEmail": items[0]["email"],
// // "callerTitle": items[0]["title"],
// // "callerPhone": null,
// // "receiverID": AppState().chatDetails!!.response!.id,
// // "receiverName": AppState().chatDetails!!.response!.userName,
// // "receiverEmail": AppState().chatDetails!!.response!.email,
// // "receiverTitle": AppState().chatDetails!!.response!.title,
// // "receiverPhone": AppState().chatDetails!!.response!.phone,
// // "title": AppState().chatDetails!!.response!.userName!.replaceAll(".", " "),
// // "callType": items[1] ? "Video" : "Audio",
// // };
// // CallDataModel callData = CallDataModel.fromJson(json);
// // ChatVoipCall().showCallkitIncoming(uuid: const Uuid().v4(), isOnline: true, incomingCallData: callData);
// //
// // if (!isOnIncomingCallPage) {
// // Map<String, dynamic> json = {
// // "callerID": items[0]["id"],
// // "callerName": items[0]["userName"],
// // "callerEmail": items[0]["email"],
// // "callerTitle": items[0]["title"],
// // "callerPhone": null,
// // "receiverID": AppState().chatDetails!!.response!.id,
// // "receiverName": AppState().chatDetails!!.response!.userName,
// // "receiverEmail": AppState().chatDetails!!.response!.email,
// // "receiverTitle": AppState().chatDetails!!.response!.title,
// // "receiverPhone": AppState().chatDetails!!.response!.phone,
// // "title": AppState().chatDetails!!.response!.userName!.replaceAll(".", " "),
// // "callType": items[1] ? "Video" : "Audio",
// // };
// // CallDataModel callData = CallDataModel.fromJson(json);
// // await Navigator.push(
// // providerContext,
// // MaterialPageRoute(
// // builder: (BuildContext context) => IncomingCall(
// // isVideoCall: items[1] ? true : false,
// // outGoingCallData: callData,
// // ),
// // ),
// // );
// // isOnIncomingCallPage = true;
// // }
// }
void onCallDeclinedAsync(List<Object> params) {
print("================= On Declained ========================");
print(params);
// endCall().then((bool value) {
// if (value) {
// isCallEnded = true;
// notifyListeners();
// }
// });
// if (params != null) {
// endCall(isUserOnline: isUserOnline).then((bool value) {
// if (isCallConnected) {
// // Navigator.of(AppRoutes.navigatorKey.currentContext!).pop();
// isCallConnected = false;
// }
// isCallEnded = true;
// });
// }
}
//// Invoke Methods
// Future<void> invoke({required String invokeMethod, required int currentUserID, required int targetUserID, var data, int userStatus = 1, var debugData}) async {
// List<Object> args = [];
// if (invokeMethod == "CallUserAsync") {
// args = [currentUserID, targetUserID, isVideoCall];
// } else if (invokeMethod == "answerCallAsync") {
// args = [currentUserID, targetUserID];
// } else if (invokeMethod == "IceCandidateAsync") {
// args = [targetUserID, data];
// } else if (invokeMethod == "OfferAsync") {
// args = [targetUserID, data];
// } else if (invokeMethod == "AnswerOfferAsync") {
// args = [targetUserID, data];
// // json In Data
// } else if (invokeMethod == "UpdateUserStatusAsync") {
// args = [currentUserID, userStatus];
// } else if (invokeMethod == "HangUpAsync") {
// args = [currentUserID, targetUserID];
// } else if (invokeMethod == "InvokeMobile") {
// args = [debugData];
// }
// try {
// await chatHubConnection!.invoke("$invokeMethod", args: args);
// } catch (e) {
// print(e);
// }
// }
void stopListeners() async {
chatHubConnection!.off('OnCallDeclinedAsync');
chatHubConnection!.off('OnCallAcceptedAsync');
chatHubConnection!.off('OnIceCandidateAsync');
chatHubConnection!.off('OnAnswerOffer');
}
void playRingtone() async {
player.stop();
await player.setVolume(1.0);
String audioAsset = "";
if (Platform.isAndroid) {
audioAsset = "assets/audio/ring_60Sec.mp3";
} else {
audioAsset = "assets/audio/ring_30Sec.caf";
}
try {
await player.setAsset(audioAsset);
await player.load();
player.play();
} catch (e) {
print("Error: $e");
}
}
//////////////////// Web RTC Offers & Connections ////////////////////////
// Future<RTCPeerConnection> creatOfferWithCon() async {
// Map<String, dynamic> configuration = {
// "sdpSemantics": "plan-b",
// 'iceServers': [
// {
// 'urls': 'stun:15.185.116.59:3478',
// },
// {
// 'urls': 'turn:15.185.116.59:3479',
// 'username': 'admin',
// 'credential': 'admin',
// },
// ]
// };
// Map<String, dynamic> offerSdpConstraints = {
// 'mandatory': {
// 'OfferToReceiveAudio': true,
// 'OfferToReceiveVideo': true,
// },
// 'optional': []
// };
// RTCPeerConnection pc = await createPeerConnection(configuration, offerSdpConstraints);
// // await pc.addStream(_localStream!);
// //Changed By Aamir
// _localStream?.getTracks().forEach((track) {
// pc.addTrack(track, _localStream!);
// });
// pc.onConnectionState = (RTCPeerConnectionState state) {};
// pc.onAddStream = (MediaStream stream) {
// remoteRenderer!.srcObject = stream;
// notifyListeners();
// };
// pc.onIceCandidate = (RTCIceCandidate e) async {
// if (isIncomingCall) {
// if (e.candidate != null) {
// var payload = {"target": incomingCallData!.targetUserId, "candidate": e.toMap()};
// invoke(invokeMethod: "IceCandidateAsync", currentUserID: AppState().chatDetails!.response!.id!, targetUserID: incomingCallData!.targetUserId!, data: jsonEncode(payload));
// notifyListeners();
// }
// } else {
// if (e.candidate != null) {
// var payload = {"target": outGoingCallData!.callerId, "candidate": e.toMap()};
// invoke(invokeMethod: "IceCandidateAsync", currentUserID: outGoingCallData!.callerId!, targetUserID: outGoingCallData!.receiverId!, data: jsonEncode(payload));
// }
// }
// };
// // pc!.onTrack = (RTCTrackEvent event) async {
// //
// // String streamId = const Uuid().toString();
// // MediaStream remoteStream = await createLocalMediaStream(streamId);
// // event.streams[0].getTracks().forEach((MediaStreamTrack element) {
// // logger.i("Stream Track: " + element.id.toString());
// // // remoteRenderer.srcObject = element;
// // remoteStream.addTrack(element);
// // });
// // };
// pc.onSignalingState = (RTCSignalingState state) {
// print("signaling state: " + state.name);
// // invoke(
// // invokeMethod: "InvokeMobile",
// // currentUserID: AppState().getchatUserDetails!.response!.id!,
// // targetUserID: incomingCallData.targetUserId!,
// // debugData: {"location": "Signaling", "parms": state.name});
// };
// pc.onIceGatheringState = (RTCIceGatheringState state) {
// print("rtc ice gathering state: " + state.name);
// };
// pc.onIceConnectionState = (RTCIceConnectionState state) {
// if (RTCIceConnectionState.RTCIceConnectionStateFailed == state ||
// RTCIceConnectionState.RTCIceConnectionStateDisconnected == state ||
// RTCIceConnectionState.RTCIceConnectionStateClosed == state) {
// print("Ice Connection State:" + state.name);
//
// // endCall().then((value) {
// // notifyListeners();
// // });
// }
// };
// // pc!.onRenegotiationNeeded = _onRenegotiate;
// return pc;
// }
// void _onRenegotiate() async {
// try {
// print('onRenegotiationNeeded start');
// // makingOffer = true;
// await _pc.setLocalDescription(await _pc.createOffer(videoConstraints));
// print('onRenegotiationNeeded state after setLocalDescription: ' + _pc.signalingState.toString());
// // send offer via callManager
// var localDesc = await _pc.getLocalDescription();
// // callManager.sendCallMessage(MsgType.rtc_offer, RtcOfferAnswer(localDesc.sdp, localDesc.type));
// print('onRenegotiationNeeded; offer sent');
// } catch (e) {
// print("onRenegotiationNeeded error: " + e.toString());
// } finally {
// // makingOffer = false;
// print('onRenegotiationNeeded done');
// }
// }
// Future<RTCSessionDescription> _createOffer() async {
// RTCSessionDescription description = await _pc!.createOffer();
// // _offer = true;
// return description;
// }
//
// Future<RTCSessionDescription> _createAnswer() async {
// RTCSessionDescription description = await _pc!.createAnswer();
// // _offer = false;
// return description;
// }
//////////////////// Web RTC End Offers ////////////////////
//////////////////// CallPage Buttons //////////////////////
void micOff() {
isMicOff = !isMicOff;
_localStream!.getAudioTracks().forEach((track) {
track.enabled = !track.enabled;
});
notifyListeners();
}
void camOff() {
isCamOff = !isCamOff;
_localStream!.getVideoTracks().forEach((track) {
track.enabled = !track.enabled;
});
// if (isCamOff) {
// isVideoCall = false;
// } else {
// isVideoCall = true;
// }
notifyListeners();
}
void loudOn() {
isLoudSpeaker = !isLoudSpeaker;
remoteRenderer!.srcObject?.getAudioTracks().forEach((track) {
if (isLoudSpeaker) {
track.enableSpeakerphone(true);
} else {
track.enableSpeakerphone(false);
}
});
notifyListeners();
}
void switchCamera() {
isFrontCamera = !isFrontCamera;
Helper.switchCamera(_localStream!.getVideoTracks()[0]);
notifyListeners();
}
///////////////// Incoming Call ///////////////////////////////
Future<void> initStreams() async {
List<MediaDeviceInfo> devices = await navigator.mediaDevices.enumerateDevices();
remoteRenderer = RTCVideoRenderer();
localVideoRenderer ??= RTCVideoRenderer();
await localVideoRenderer!.initialize();
try {
_localStream = await navigator.mediaDevices.getUserMedia({
'audio': true,
'video': {
'mandatory': {
'minWidth': '640', // Provide your own width, height and frame rate here
'minHeight': '480',
'minFrameRate': '25',
},
'facingMode': 'user',
'optional': [],
"audio": true,
}
});
_localStream!.getAudioTracks().first.enableSpeakerphone(true);
localVideoRenderer!.srcObject = _localStream;
localVideoRenderer!.value = (const RTCVideoValue(
width: 200,
height: 200,
renderVideo: true,
));
print("Working localStream");
} catch (e) {
print("Failed to get user media: $e");
}
await remoteRenderer!.initialize();
notifyListeners();
}
// Future<void> startIncomingCallViaKit({bool isVCall = true, var inCallData}) async {
// AppSharedPrefs().setStringFromPrefs("isIncomingCall", "false");
// if (isVCall) {
// isVideoCall = isVCall;
// } else {
// isAudioCall = true;
// }
// await initStreams();
// isIncomingCall = true;
// incomingCallData = SingleUserChatModel.fromJson(inCallData);
// loudOn();
// // notifyListeners();
// }
// void connectIncomingCall() {
// invoke(invokeMethod: "answerCallAsync", currentUserID: AppState().getchatUserDetails.response!.id!, targetUserID: incomingCallData!.targetUserId!);
// isIncomingCallLoader = false;
// isIncomingCall = true;
// // isVideoCall = true;
//
// notifyListeners();
// }
// void startRecording() async {
// print("=-=-=-=-=-=-= Call Recoding Started -=-=-=-=-=-=-=-=-==-=");
// if (_localStream == null) throw Exception('Stream is not initialized');
// if (Platform.isIOS) {
// print('Recording is not available on iOS');
// return;
// }
// Directory appDirectory = await getApplicationDocumentsDirectory();
// String dirPath = '${appDirectory.path}/webrtc_sample';
// if (!await Directory(dirPath).exists()) {
// await Directory(dirPath).create();
// await File('$dirPath/.nomedia').create();
// }
// if (appDirectory == null) throw Exception('Can\'t find storagePath');
// String filePath = dirPath + '/mobile.mp4';
// mobileRecoder = MediaRecorder();
// notifyListeners();
// MediaStreamTrack videoTrack = _localStream!.getVideoTracks().firstWhere((track) => track.kind == 'video');
// await mobileRecoder!.start(filePath, videoTrack: videoTrack);
//
// Future.delayed(Duration(minutes: 1), () {
// stopRecording();
// });
// }
//
// void stopRecording() async {
// print("=-=-=-=-=-=-= Call Recoding Stopped -=-=-=-=-=-=-=-=-==-=");
// await mobileRecoder!.stop();
// mobileRecoder = null;
// notifyListeners();
// }
// WebRtc
final transportProtLogger = Logger("SignalR - transport");
late Logger _logger;
RTCPeerConnection? pCon;
String? _doctorID;
String? _patientID;
String? get doctorID => _doctorID;
set doctorID(String? value) {
_doctorID = value;
}
String? get patientID => _patientID;
set patientID(String? value) {
_patientID = value;
}
bool _isAccepted = false;
bool get isAccepted => _isAccepted;
set isAccepted(bool value) {
_isAccepted = value;
}
// int _secondsRemaining = 30;
// late Timer _timer;
// void startCountTimer() {
// _timer = Timer.periodic(Duration(seconds: 1), (timer) async {
// if (_secondsRemaining > 0) {
// _secondsRemaining--;
// if (isAccepted) {
// _timer.cancel(); // Stop the timer if isAccepted becomes true
// }
// } else {
// _timer.cancel();
// if (chatHubConnection != null) {
// chatHubConnection!.stop();
// chatHubConnection = null;
// }
// chatHubConnection = await createHub();
// NoAnswer();
// }
// });
// // notifyListeners();
// }
NoAnswer() {
handleCallComplete([{}]);
}
void httpCallback(Client httpClient) {
HttpOverrides.global = HttpOverrideCertificateVerificationInDev();
}
Future<HubConnection> createHub() async {
doctorID = incomingCallData!.sessionId!.split("**").last;
String path = incomingCallData!.sessionId!.split("**").first;
patientID = incomingCallData!.receiverID;
_logger = Logger("ChatPageViewModel");
final httpConnectionOptions = HttpConnectionOptions(logMessageContent: true, httpClient: WebSupportingHttpClient(_logger, httpClientCreateCallback: httpCallback));
var urlWithParams = path + "UserID=$patientID&ProjectId=15&IsAdmin=false&To=$doctorID";
HubConnection hubCon =
await HubConnectionBuilder().withUrl(urlWithParams, options: httpConnectionOptions).withAutomaticReconnect(retryDelays: [2000, 5000, 10000, 20000]).configureLogging(_logger).build();
return hubCon;
}
Future<void> initCall({required bool isConnectCall}) async {
if (chatHubConnection != null) {
chatHubConnection!.stop();
chatHubConnection = null;
}
chatHubConnection = await createHub();
if (doctorID != null) {
try {
chatHubConnection!.onclose(({error}) {
Utils.showErrorToast(error.toString());
});
register();
if (chatHubConnection!.state == HubConnectionState.Disconnected) {
await chatHubConnection!.start();
}
if (chatHubConnection!.state == HubConnectionState.Connected) {
if (chatHubConnection != null) {
patientID = chatHubConnection!.connectionId;
print("DOC: " + doctorID.toString());
print("PAT " + patientID.toString());
try {
isConnectCall ? ping("Call_Accept") : ping("Call_Decline");
} catch (e) {
print(e);
}
}
}
} catch (e) {
print(e.toString());
Utils.showErrorToast(e.toString());
}
} else {
Utils.showErrorToast("Doctor ID is not correct");
}
}
ping(String eventName) async {
print("============ $eventName =====================");
if (chatHubConnection != null) if (chatHubConnection!.state == HubConnectionState.Connected) {
print("============ CONNECTED ==============");
dynamic payload = {"UserID": int.parse(incomingCallData!.receiverID!)};
if (eventName == "Call_Complete") payload = {"from": patientID, "to": doctorID};
await chatHubConnection!.invoke(eventName, args: [payload]).onError((error, stackTrace) {}).whenComplete(() {
if (eventName == "Call_Decline" || eventName == "Call_Complete" || eventName == "Call_NoAnswer") {
if (chatHubConnection != null) {
chatHubConnection!.stop();
}
}
});
} else {
print("============ ELSE RECONNECT ==============");
chatHubConnection = await createHub();
chatHubConnection!.start();
ping(eventName);
}
}
void register() async {
chatHubConnection!.on("pre_offer", handlePreOffer);
chatHubConnection!.on("on_offer", handleOnOffer);
chatHubConnection!.on("on_ice_candidate", handleIceCandidate);
// New Events
chatHubConnection!.on("Call_Decline", handleCallDecline);
chatHubConnection!.on("call_completed", handleCallComplete);
if (kDebugMode) debugPrint("Listners Initiated");
}
// genericCheckEvent(List<Object?>? params) async {
// print("------------- Generic Event Triggered ---------------");
// print("------------- Generic Event Triggered ---------------");
// print(params);
// print("------------- Generic Event Triggered ---------------");
// print("------------- Generic Event Triggered ---------------");
// }
handlePreOffer(List<Object?>? params) async {
print("----------Event Pre Offer Received ----------");
dynamic items = params!.toList();
if (kDebugMode) {
print("Doctor ID : " + items[0]['from'].toString());
print("Patient ID: " + items[0]['to'].toString());
}
doctorID = items[0]['from'];
patientID = items[0]['to'];
initStreams();
createPConnection();
sendPreAnswerOffer();
}
handleOnOffer(List<Object?>? params) async {
print("----------Event On Offer Received ----------");
dynamic items = params!.toList();
var data = jsonDecode(items[0]["offer"]);
_localStream?.getTracks().forEach((track) {
pCon!.addTrack(track, _localStream!);
});
await pCon!.setRemoteDescription(RTCSessionDescription(data["sdp"], data["type"]));
RTCSessionDescription description = await pCon!.createAnswer();
await pCon!.setLocalDescription(description);
var payload = {
"to": doctorID,
"callerSocketId": patientID,
"answer": "${json.encode(description.toMap())}",
};
if (chatHubConnection!.state == HubConnectionState.Connected) {
print("---------Answer Offer Invoke --------");
await chatHubConnection!.invoke("OnAnswerOffer", args: [payload]).onError((error, stackTrace) {
print("error sending offer answer");
Utils.showErrorToast(error.toString());
});
}
startCallByRTC();
Future.delayed(Duration(seconds: 2), () {
Navigator.pushReplacement(
locator<NavigationService>().navigatorKey.currentContext!,
MaterialPageRoute(
builder: (BuildContext context) => StartCallPage(),
));
});
}
handleIceCandidate(List<Object?>? params) async {
print("----------Event Ice Candidate Received ----------");
dynamic items = params!.toList();
var val = jsonDecode(items[0]["candidate"]);
RemoteIceCandidatePayLoad data = await RemoteIceCandidatePayLoad(
target: 00000, candidate: Candidate(candidate: val["candidate"], sdpMid: val["sdpMid"], sdpMLineIndex: val["sdpMLineIndex"], usernameFragment: val["usernameFragment"]));
if (pCon != null) {
pCon!.addCandidate(RTCIceCandidate(data.candidate!.candidate, data.candidate!.sdpMid, data.candidate!.sdpMLineIndex));
}
}
handleCallDecline(List<Object?>? params) {
print("----------handle Call Decline Received ----------");
dynamic items = params!.toList();
debuglogger.d(items);
}
handleCallComplete(List<Object?>? params) {
print("----------handle Call Complete Received ----------");
dynamic items = params!.toList();
debuglogger.d(items);
if (isCallConnected) ping("Call_Complete");
if (!isCallConnected && !isAccepted) {
ping("Call_NoAnswer");
} else {
if (!isCallConnected) ping("Call_Decline");
}
isCallConnected = false;
isCallStarted = false;
isVideoCall = false;
isCamOff = false;
isMicOff = false;
isLoudSpeaker = false;
isIncomingCall = false;
isOutGoingCall = false;
isAudioCall = false;
isAccepted = false;
if (pCon != null) if (pCon!.connectionState == RTCPeerConnectionState.RTCPeerConnectionStateConnected) {
if (_localStream != null) pCon!.removeStream(_localStream!);
pCon!.close();
pCon!.dispose();
}
if (remoteRenderer != null) {
remoteRenderer!.dispose();
remoteRenderer = null;
}
if (localVideoRenderer != null) {
localVideoRenderer!.dispose();
localVideoRenderer = null;
}
if (_localStream != null) {
_localStream!.dispose();
_localStream = null;
}
// if (chatHubConnection != null && !isUserOnline) {
// chatHubConnection!.stop();
// }
Navigator.of(locator<NavigationService>().navigatorKey.currentContext!).popAndPushNamed(HOME);
}
void createPConnection() async {
Map<String, dynamic> configuration = {
"sdpSemantics": "plan-b",
'iceServers': [
{
'urls': 'stun:15.185.116.59:3478',
},
{
'urls': 'turn:15.185.116.59:3479',
'username': 'admin',
'credential': 'admin',
}
],
"iceCandidatePoolSize": 10
};
Map<String, dynamic> offerSdpConstraints = {
'mandatory': {
'OfferToReceiveAudio': true,
'OfferToReceiveVideo': true,
},
'optional': []
};
pCon = await createPeerConnection(configuration, offerSdpConstraints);
pCon!.onConnectionState = (RTCPeerConnectionState state) {};
pCon!.onAddStream = (MediaStream stream) {
remoteRenderer!.srcObject = stream;
notifyListeners();
};
pCon!.onIceCandidate = (RTCIceCandidate e) async {
if (e.candidate != null) {
await pCon!.addCandidate(e);
var data = {"target": doctorID, "callerSocketId": doctorID, "from": patientID, "calleePersonalCode": patientID, "to": doctorID, "candidate": "${json.encode(e.toMap())}"};
if (chatHubConnection!.state == HubConnectionState.Connected) {
await chatHubConnection!.invoke('IceCandidate', args: [data]).onError((error, stackTrace) {
Utils.showErrorToast(error.toString());
});
}
}
};
pCon!.onSignalingState = (RTCSignalingState state) {
print("signaling state: " + state.name);
};
pCon!.onIceGatheringState = (RTCIceGatheringState state) {
print("rtc ice gathering state: " + state.name);
};
pCon!.onIceConnectionState = (RTCIceConnectionState state) {
if (RTCIceConnectionState.RTCIceConnectionStateFailed == state ||
RTCIceConnectionState.RTCIceConnectionStateDisconnected == state ||
RTCIceConnectionState.RTCIceConnectionStateClosed == state) {
print("Ice Connection State:" + state.name);
}
};
}
sendPreAnswerOffer() async {
var data = {
"to": doctorID,
"calleePersonalCode": patientID,
"preOfferAnswer": "",
};
print(data);
if (chatHubConnection!.state == HubConnectionState.Connected) {
await chatHubConnection!.invoke("SendPreOfferAnswer", args: [data]).onError((error, stackTrace) {
print("error sending pre offer answer");
Utils.showErrorToast(error.toString());
});
}
}
startCallByRTC() {
isVideoCall = true;
isIncomingCallLoader = false;
isIncomingCall = true;
isCallConnected = true;
}
}
class HttpOverrideCertificateVerificationInDev extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return super.createHttpClient(context)..badCertificateCallback = (X509Certificate cert, String host, int port) => true;
}
}
// class ChatService extends BaseService {
// Future<getUserToken.UserAutoLoginModel> getUserCallToken({required String userid}) async {
// getUserToken.UserAutoLoginModel userLoginResponse = getUserToken.UserAutoLoginModel();
// http.post(Uri.parse("${ApiConsts.chatLoginTokenUrl}externaluserlogin"), body: {
// "employeeNumber": userid,
// "password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG",
// }).then((response) {
// userLoginResponse = getUserToken.userAutoLoginModelFromJson(response.body);
// }).onError((error, stackTrace) {
// hasError = true;
// print(error);
// super.error = error.toString();
// });
//
// return userLoginResponse;
// }
// }