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 : }
|