Line data Source code
1 : import 'package:webrtc_interface/webrtc_interface.dart'; 2 : 3 : import 'package:matrix/matrix.dart'; 4 : import 'package:matrix/src/utils/cached_stream_controller.dart'; 5 : import 'package:matrix/src/voip/utils/stream_helper.dart'; 6 : 7 : /// Wrapped MediaStream, used to adapt Widget to display 8 : class WrappedMediaStream { 9 : MediaStream? stream; 10 : final CallParticipant participant; 11 : final Room room; 12 : final VoIP voip; 13 : 14 : /// Current stream type, usermedia or screen-sharing 15 : String purpose; 16 : bool audioMuted; 17 : bool videoMuted; 18 : final Client client; 19 : final bool isGroupCall; 20 : final RTCPeerConnection? pc; 21 : 22 : /// for debug 23 0 : String get title => 24 0 : '${client.userID!}:${client.deviceID!} $displayName:$purpose:a[$audioMuted]:v[$videoMuted]'; 25 : bool stopped = false; 26 : 27 : final CachedStreamController<WrappedMediaStream> onMuteStateChanged = 28 : CachedStreamController(); 29 : 30 : final CachedStreamController<MediaStream> onStreamChanged = 31 : CachedStreamController(); 32 : 33 2 : WrappedMediaStream({ 34 : this.stream, 35 : this.pc, 36 : required this.room, 37 : required this.participant, 38 : required this.purpose, 39 : required this.client, 40 : required this.audioMuted, 41 : required this.videoMuted, 42 : required this.isGroupCall, 43 : required this.voip, 44 : }); 45 : 46 0 : String get id => '${stream?.id}: $title'; 47 : 48 2 : Future<void> dispose() async { 49 : // AOT it 50 : const isWeb = bool.fromEnvironment('dart.library.js_util'); 51 : 52 : // libwebrtc does not provide a way to clone MediaStreams. So stopping the 53 : // local stream here would break calls with all other participants if anyone 54 : // leaves. The local stream is manually disposed when user leaves. On web 55 : // streams are actually cloned. 56 2 : if (!isGroupCall || isWeb) { 57 4 : await stopMediaStream(stream); 58 : } 59 : 60 2 : stream = null; 61 : } 62 : 63 0 : Uri? get avatarUrl => getUser().avatarUrl; 64 : 65 0 : String get avatarName => 66 0 : getUser().calcDisplayname(mxidLocalPartFallback: false); 67 : 68 0 : String? get displayName => getUser().displayName; 69 : 70 0 : User getUser() { 71 0 : return room.unsafeGetUserFromMemoryOrFallback(participant.userId); 72 : } 73 : 74 2 : bool isLocal() { 75 8 : return participant == voip.localParticipant; 76 : } 77 : 78 0 : bool isAudioMuted() { 79 0 : return (stream != null && stream!.getAudioTracks().isEmpty) || audioMuted; 80 : } 81 : 82 0 : bool isVideoMuted() { 83 0 : return (stream != null && stream!.getVideoTracks().isEmpty) || videoMuted; 84 : } 85 : 86 0 : void setNewStream(MediaStream newStream) { 87 0 : stream = newStream; 88 0 : onStreamChanged.add(stream!); 89 : } 90 : 91 0 : void setAudioMuted(bool muted) { 92 0 : audioMuted = muted; 93 0 : onMuteStateChanged.add(this); 94 : } 95 : 96 0 : void setVideoMuted(bool muted) { 97 0 : videoMuted = muted; 98 0 : onMuteStateChanged.add(this); 99 : } 100 : }