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/pages/webRTC/signaling.dart

166 lines
4.8 KiB
Dart

import 'dart:convert';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:diplomaticquarterapp/pages/webRTC/fcm/FCMSendNotification.dart';
import 'package:diplomaticquarterapp/uitl/SignalRUtil.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'call_page.dart';
typedef void StreamStateCallback(MediaStream stream);
typedef void RTCIceGatheringStateCallback(RTCIceGatheringState state);
typedef void RTCPeerConnectionStateCallback(RTCPeerConnectionState state);
typedef void RTCSignalingStateCallback(RTCSignalingState state);
class Signaling {
dispose(){
if(peerConnection != null)
peerConnection.dispose();
signalR.closeConnection();
}
init(){
// Create Peer Connection
createPeerConnection(configuration).then((value){
peerConnection = value;
registerPeerConnectionListeners();
});
}
initializeSignalR() async{
if(signalR != null)
await signalR.closeConnection();
signalR = SignalRUtil(hubName: "https://VCallApi.hmg.com/WebRTCHub?source=$My_Mobile&username=$My_ID");
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']
}
]
};
SignalRUtil signalR;
RTCPeerConnection peerConnection;
MediaStream localStream;
MediaStream remoteStream;
RTCDataChannel dataChannel;
Future<bool> call(String patientId, String mobile, {@required RTCVideoRenderer localVideo, @required RTCVideoRenderer remoteVideo}) async {
initializeSignalR();
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}) async{
await initializeSignalR();
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?.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();
})
.then((anwser) {
return peerConnection.setLocalDescription(anwser);
})
.then((value) {
return peerConnection.getLocalDescription();
})
.then((answer) {
return signalR.answerOffer(answer, caller, receiver);
});
}
Future<void> hangUp(RTCVideoRenderer localVideo) async {
}
Future<String> createSdpAnswer(String toOfferSdp) async {
final offerSdp = rtcSessionDescriptionFrom(jsonDecode(toOfferSdp));
peerConnection.setRemoteDescription(offerSdp);
final answer = await peerConnection.createAnswer();
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);
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));
}
void registerPeerConnectionListeners() {
peerConnection.onIceCandidate = (RTCIceCandidate candidate){
print(json.encode(candidate.toMap()));
signalR.addIceCandidate(json.encode(candidate.toMap()));
};
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']);
}