fix: ice restart mechanism
This commit is contained in:
parent
9cc7c0e581
commit
59703aef75
|
|
@ -519,14 +519,6 @@ class CallSession {
|
||||||
_remoteCandidates.add(candidate);
|
_remoteCandidates.add(candidate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pc != null &&
|
|
||||||
{
|
|
||||||
RTCIceConnectionState.RTCIceConnectionStateDisconnected,
|
|
||||||
RTCIceConnectionState.RTCIceConnectionStateFailed
|
|
||||||
}.contains(pc!.iceConnectionState)) {
|
|
||||||
await restartIce();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void onAssertedIdentityReceived(AssertedIdentity identity) {
|
void onAssertedIdentityReceived(AssertedIdentity identity) {
|
||||||
|
|
@ -566,7 +558,6 @@ class CallSession {
|
||||||
return true;
|
return true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
fireCallEvent(CallStateChange.kError);
|
fireCallEvent(CallStateChange.kError);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1087,7 +1078,7 @@ class CallSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> onNegotiationNeeded() async {
|
Future<void> onNegotiationNeeded() async {
|
||||||
Logs().i('Negotiation is needed!');
|
Logs().d('Negotiation is needed!');
|
||||||
_makingOffer = true;
|
_makingOffer = true;
|
||||||
try {
|
try {
|
||||||
// The first addTrack(audio track) on iOS will trigger
|
// The first addTrack(audio track) on iOS will trigger
|
||||||
|
|
@ -1106,13 +1097,14 @@ class CallSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _preparePeerConnection() async {
|
Future<void> _preparePeerConnection() async {
|
||||||
|
int iceRestartedCount = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
pc = await _createPeerConnection();
|
pc = await _createPeerConnection();
|
||||||
pc!.onRenegotiationNeeded = onNegotiationNeeded;
|
pc!.onRenegotiationNeeded = onNegotiationNeeded;
|
||||||
|
|
||||||
pc!.onIceCandidate = (RTCIceCandidate candidate) async {
|
pc!.onIceCandidate = (RTCIceCandidate candidate) async {
|
||||||
if (callHasEnded) return;
|
if (callHasEnded) return;
|
||||||
//Logs().v('[VOIP] onIceCandidate => ${candidate.toMap().toString()}');
|
|
||||||
_localCandidates.add(candidate);
|
_localCandidates.add(candidate);
|
||||||
|
|
||||||
if (state == CallState.kRinging || !_inviteOrAnswerSent) return;
|
if (state == CallState.kRinging || !_inviteOrAnswerSent) return;
|
||||||
|
|
@ -1149,12 +1141,21 @@ class CallSession {
|
||||||
if (state == RTCIceConnectionState.RTCIceConnectionStateConnected) {
|
if (state == RTCIceConnectionState.RTCIceConnectionStateConnected) {
|
||||||
_localCandidates.clear();
|
_localCandidates.clear();
|
||||||
_remoteCandidates.clear();
|
_remoteCandidates.clear();
|
||||||
|
iceRestartedCount = 0;
|
||||||
setCallState(CallState.kConnected);
|
setCallState(CallState.kConnected);
|
||||||
// fix any state/race issues we had with sdp packets and cloned streams
|
// fix any state/race issues we had with sdp packets and cloned streams
|
||||||
await updateMuteStatus();
|
await updateMuteStatus();
|
||||||
_missedCall = false;
|
_missedCall = false;
|
||||||
} else if (state == RTCIceConnectionState.RTCIceConnectionStateFailed) {
|
} else if ({
|
||||||
await hangup(reason: CallErrorCode.iceFailed);
|
RTCIceConnectionState.RTCIceConnectionStateFailed,
|
||||||
|
RTCIceConnectionState.RTCIceConnectionStateDisconnected
|
||||||
|
}.contains(state)) {
|
||||||
|
if (iceRestartedCount < 3) {
|
||||||
|
await restartIce();
|
||||||
|
iceRestartedCount++;
|
||||||
|
} else {
|
||||||
|
await hangup(reason: CallErrorCode.iceFailed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -1234,10 +1235,8 @@ class CallSession {
|
||||||
Logs().v('[VOIP] iceRestart.');
|
Logs().v('[VOIP] iceRestart.');
|
||||||
// Needs restart ice on session.pc and renegotiation.
|
// Needs restart ice on session.pc and renegotiation.
|
||||||
_iceGatheringFinished = false;
|
_iceGatheringFinished = false;
|
||||||
final desc =
|
|
||||||
await pc!.createOffer(_getOfferAnswerConstraints(iceRestart: true));
|
|
||||||
await pc!.setLocalDescription(desc);
|
|
||||||
_localCandidates.clear();
|
_localCandidates.clear();
|
||||||
|
await pc!.restartIce();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<MediaStream?> _getUserMedia(CallType type) async {
|
Future<MediaStream?> _getUserMedia(CallType type) async {
|
||||||
|
|
@ -1272,8 +1271,7 @@ class CallSession {
|
||||||
};
|
};
|
||||||
final pc = await voip.delegate.createPeerConnection(configuration);
|
final pc = await voip.delegate.createPeerConnection(configuration);
|
||||||
pc.onTrack = (RTCTrackEvent event) async {
|
pc.onTrack = (RTCTrackEvent event) async {
|
||||||
if (event.streams.isNotEmpty) {
|
for (final stream in event.streams) {
|
||||||
final stream = event.streams[0];
|
|
||||||
await _addRemoteStream(stream);
|
await _addRemoteStream(stream);
|
||||||
for (final track in stream.getTracks()) {
|
for (final track in stream.getTracks()) {
|
||||||
track.onEnded = () async {
|
track.onEnded = () async {
|
||||||
|
|
@ -1322,13 +1320,6 @@ class CallSession {
|
||||||
await wpstream.dispose();
|
await wpstream.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> _getOfferAnswerConstraints({bool iceRestart = false}) {
|
|
||||||
return {
|
|
||||||
'mandatory': {if (iceRestart) 'IceRestart': true},
|
|
||||||
'optional': [],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _sendCandidateQueue() async {
|
Future<void> _sendCandidateQueue() async {
|
||||||
if (callHasEnded) return;
|
if (callHasEnded) return;
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue