You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
2.7 KiB
111 lines
2.7 KiB
2 years ago
|
part of '../neon_spreed.dart';
|
||
|
|
||
|
abstract class SpreedCallParticipant {
|
||
|
SpreedCallParticipant(
|
||
|
this.userID,
|
||
|
this.sessionID,
|
||
|
this.renderer,
|
||
|
this.stream,
|
||
|
);
|
||
|
|
||
|
final String userID;
|
||
|
final String sessionID;
|
||
|
RTCVideoRenderer? renderer;
|
||
|
MediaStream? stream;
|
||
|
|
||
|
void dispose() {
|
||
|
stream?.getTracks().forEach((final track) => unawaited(track.stop()));
|
||
|
unawaited(stream?.dispose());
|
||
|
renderer?.srcObject = null;
|
||
|
unawaited(renderer?.dispose());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class SpreedLocalCallParticipant extends SpreedCallParticipant {
|
||
|
SpreedLocalCallParticipant(
|
||
|
super.userID,
|
||
|
super.sessionID,
|
||
|
super.renderer,
|
||
|
super.stream,
|
||
|
);
|
||
|
}
|
||
|
|
||
|
class SpreedRemoteCallParticipant extends SpreedCallParticipant {
|
||
|
SpreedRemoteCallParticipant(
|
||
|
super.userID,
|
||
|
super.sessionID,
|
||
|
super.renderer,
|
||
|
super.stream,
|
||
|
this._connection,
|
||
|
this._senders, {
|
||
|
this.audioEnabled = false,
|
||
|
this.videoEnabled = false,
|
||
|
});
|
||
|
|
||
|
RTCPeerConnection? _connection;
|
||
|
List<RTCRtpSender>? _senders;
|
||
|
final List<RTCIceCandidate> _candidates = [];
|
||
|
bool audioEnabled;
|
||
|
bool videoEnabled;
|
||
|
|
||
|
RTCPeerConnection? get connection => _connection;
|
||
|
List<RTCRtpSender>? get senders => _senders;
|
||
|
|
||
|
Future<void> _clearSenders() async {
|
||
|
if (_senders != null && _connection != null) {
|
||
|
for (final sender in _senders!) {
|
||
|
await _connection!.removeTrack(sender);
|
||
|
}
|
||
|
}
|
||
|
if (_senders != null) {
|
||
|
for (final sender in _senders!) {
|
||
|
try {
|
||
|
await sender.dispose();
|
||
|
} catch (_) {
|
||
|
// TODO: Somehow peerConnection is null when calling this on disposing the participant
|
||
|
}
|
||
|
}
|
||
|
_senders = null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Future<void> acceptNewConnection(final RTCPeerConnection? connection) async {
|
||
|
await _clearSenders();
|
||
|
await _connection?.close();
|
||
|
_connection = connection;
|
||
|
if (_connection != null) {
|
||
|
for (final candidate in _candidates) {
|
||
|
debugPrint('Loading candidate');
|
||
|
await _connection!.addCandidate(candidate);
|
||
|
}
|
||
|
_candidates.clear();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Future<void> acceptNewLocalStream(final MediaStream? stream) async {
|
||
|
await _clearSenders();
|
||
|
if (_connection != null && stream != null) {
|
||
|
_senders = [];
|
||
|
for (final track in stream.getTracks()) {
|
||
|
_senders!.add(await _connection!.addTrack(track, stream));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Future<void> addCandidate(final RTCIceCandidate candidate) async {
|
||
|
if (connection != null) {
|
||
|
await connection!.addCandidate(candidate);
|
||
|
} else {
|
||
|
_candidates.add(candidate);
|
||
|
debugPrint('Storing candidate for later use');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@override
|
||
|
void dispose() {
|
||
|
unawaited(_clearSenders());
|
||
|
unawaited(_connection?.close());
|
||
|
super.dispose();
|
||
|
}
|
||
|
}
|