// import 'dart:async'; // import 'dart:typed_data'; // // import 'package:diplomaticquarterapp/pages/conference/participant_widget.dart'; // import 'package:flutter/material.dart'; // import 'package:flutter/services.dart'; // // class ConferenceRoom with ChangeNotifier { // final String name; // final String token; // final String identity; // // final StreamController _onAudioEnabledStreamController = StreamController.broadcast(); // Stream onAudioEnabled; // final StreamController _onVideoEnabledStreamController = StreamController.broadcast(); // Stream onVideoEnabled; // final StreamController _onExceptionStreamController = StreamController.broadcast(); // Stream onException; // // final Completer _completer = Completer(); // // final List _participants = []; // final List _participantBuffer = []; // final List _streamSubscriptions = []; // final List _dataTracks = []; // final List _messages = []; // // CameraCapturer _cameraCapturer; // Room _room; // Timer _timer; // // ConferenceRoom({ // @required this.name, // @required this.token, // @required this.identity, // }) { // onAudioEnabled = _onAudioEnabledStreamController.stream; // onVideoEnabled = _onVideoEnabledStreamController.stream; // onException = _onExceptionStreamController.stream; // } // // List get participants { // return [..._participants]; // } // // Future connect() async { // print('ConferenceRoom.connect()'); // try { // await TwilioProgrammableVideo.debug(dart: true, native: true); // await TwilioProgrammableVideo.setSpeakerphoneOn(true); // // _cameraCapturer = CameraCapturer(CameraSource.FRONT_CAMERA); // var connectOptions = ConnectOptions( // token, // roomName: name, // preferredAudioCodecs: [OpusCodec()], // audioTracks: [LocalAudioTrack(true)], // dataTracks: [LocalDataTrack()], // videoTracks: [LocalVideoTrack(true, _cameraCapturer)], // enableDominantSpeaker: true, // ); // // _room = await TwilioProgrammableVideo.connect(connectOptions); // // _streamSubscriptions.add(_room.onConnected.listen(_onConnected)); // _streamSubscriptions.add(_room.onConnectFailure.listen(_onConnectFailure)); // // return _completer.future; // } catch (err) { // print(err); // rethrow; // } // } // // Future disconnect() async { // print('ConferenceRoom.disconnect()'); // if (_timer != null) { // _timer.cancel(); // } // await _room.disconnect(); // } // // @override // void dispose() { // print('ConferenceRoom.dispose()'); // _disposeStreamsAndSubscriptions(); // super.dispose(); // } // // Future _disposeStreamsAndSubscriptions() async { // await _onAudioEnabledStreamController.close(); // await _onVideoEnabledStreamController.close(); // await _onExceptionStreamController.close(); // for (var streamSubscription in _streamSubscriptions) { // await streamSubscription.cancel(); // } // } // // Future sendMessage(String message) async { // final tracks = _room.localParticipant.localDataTracks; // final localDataTrack = tracks.isEmpty ? null : tracks[0].localDataTrack; // if (localDataTrack == null || _messages.isNotEmpty) { // print('ConferenceRoom.sendMessage => Track is not available yet, buffering message.'); // _messages.add(message); // return; // } // await localDataTrack.send(message); // } // // Future sendBufferMessage(ByteBuffer message) async { // final tracks = _room.localParticipant.localDataTracks; // final localDataTrack = tracks.isEmpty ? null : tracks[0].localDataTrack; // if (localDataTrack == null) { // return; // } // await localDataTrack.sendBuffer(message); // } // // Future toggleVideoEnabled() async { // final tracks = _room.localParticipant.localVideoTracks; // final localVideoTrack = tracks.isEmpty ? null : tracks[0].localVideoTrack; // if (localVideoTrack == null) { // print('ConferenceRoom.toggleVideoEnabled() => Track is not available yet!'); // return; // } // await localVideoTrack.enable(!localVideoTrack.isEnabled); // // var index = _participants.indexWhere((ParticipantWidget participant) => !participant.isRemote); // if (index < 0) { // return; // } // var participant = _participants[index]; // _participants.replaceRange( // index, // index + 1, // [ // participant.copyWith(videoEnabled: localVideoTrack.isEnabled), // ], // ); // print('ConferenceRoom.toggleVideoEnabled() => ${localVideoTrack.isEnabled}'); // _onVideoEnabledStreamController.add(localVideoTrack.isEnabled); // notifyListeners(); // } // // Future toggleAudioEnabled() async { // final tracks = _room.localParticipant.localAudioTracks; // final localAudioTrack = tracks.isEmpty ? null : tracks[0].localAudioTrack; // if (localAudioTrack == null) { // print('ConferenceRoom.toggleAudioEnabled() => Track is not available yet!'); // return; // } // await localAudioTrack.enable(!localAudioTrack.isEnabled); // // var index = _participants.indexWhere((ParticipantWidget participant) => !participant.isRemote); // if (index < 0) { // return; // } // var participant = _participants[index]; // _participants.replaceRange( // index, // index + 1, // [ // participant.copyWith(audioEnabled: localAudioTrack.isEnabled), // ], // ); // print('ConferenceRoom.toggleAudioEnabled() => ${localAudioTrack.isEnabled}'); // _onAudioEnabledStreamController.add(localAudioTrack.isEnabled); // notifyListeners(); // } // // Future switchCamera() async { // print('ConferenceRoom.switchCamera()'); // try { // await _cameraCapturer.switchCamera(); // } on FormatException catch (e) { // print( // 'ConferenceRoom.switchCamera() failed because of FormatException with message: ${e.message}', // ); // } // } // // void addDummy({Widget child}) { // print('ConferenceRoom.addDummy()'); // if (_participants.length >= 18) { // throw PlatformException( // code: 'ConferenceRoom.maximumReached', // message: 'Maximum reached', // details: 'Currently the lay-out can only render a maximum of 18 participants', // ); // } // _participants.insert( // 0, // ParticipantWidget( // id: (_participants.length + 1).toString(), // child: child, // isRemote: true, // audioEnabled: true, // videoEnabled: true, // isDummy: true, // ), // ); // notifyListeners(); // } // // void removeDummy() { // print('ConferenceRoom.removeDummy()'); // var dummy = _participants.firstWhere((participant) => participant.isDummy, orElse: () => null); // if (dummy != null) { // _participants.remove(dummy); // notifyListeners(); // } // } // // void _onConnected(Room room) { // print('ConferenceRoom._onConnected => state: ${room.state}'); // // // When connected for the first time, add remote participant listeners // _streamSubscriptions.add(_room.onParticipantConnected.listen(_onParticipantConnected)); // _streamSubscriptions.add(_room.onParticipantDisconnected.listen(_onParticipantDisconnected)); // _streamSubscriptions.add(_room.onDominantSpeakerChange.listen(_onDominantSpeakerChanged)); // // Only add ourselves when connected for the first time too. // _participants.add( // _buildParticipant( // child: room.localParticipant.localVideoTracks[0].localVideoTrack.widget(), // id: identity, // audioEnabled: true, // videoEnabled: true, // ), // ); // for (final remoteParticipant in room.remoteParticipants) { // var participant = _participants.firstWhere((participant) => participant.id == remoteParticipant.sid, orElse: () => null); // if (participant == null) { // print('Adding participant that was already present in the room ${remoteParticipant.sid}, before I connected'); // _addRemoteParticipantListeners(remoteParticipant); // } // } // // We have to listen for the [onDataTrackPublished] event on the [LocalParticipant] in // // order to be able to use the [send] method. // _streamSubscriptions.add(room.localParticipant.onDataTrackPublished.listen(_onLocalDataTrackPublished)); // notifyListeners(); // _completer.complete(room); // // _timer = Timer.periodic(const Duration(minutes: 1), (_) { // // Let's see if we can send some data over the DataTrack API // sendMessage('And another minute has passed since I connected...'); // // Also try the ByteBuffer way of sending data // final list = 'This data has been sent over the ByteBuffer channel of the DataTrack API'.codeUnits; // var bytes = Uint8List.fromList(list); // sendBufferMessage(bytes.buffer); // }); // } // // void _onLocalDataTrackPublished(LocalDataTrackPublishedEvent event) { // // Send buffered messages, if any... // while (_messages.isNotEmpty) { // var message = _messages.removeAt(0); // print('Sending buffered message: $message'); // event.localDataTrackPublication.localDataTrack.send(message); // } // } // // void _onConnectFailure(RoomConnectFailureEvent event) { // print('ConferenceRoom._onConnectFailure: ${event.exception}'); // _completer.completeError(event.exception); // } // // void _onDominantSpeakerChanged(DominantSpeakerChangedEvent event) { // print('ConferenceRoom._onDominantSpeakerChanged: ${event.remoteParticipant.identity}'); // var oldDominantParticipant = _participants.firstWhere((p) => p.isDominant, orElse: () => null); // if (oldDominantParticipant != null) { // var oldDominantParticipantIndex = _participants.indexOf(oldDominantParticipant); // _participants.replaceRange(oldDominantParticipantIndex, oldDominantParticipantIndex + 1, [oldDominantParticipant.copyWith(isDominant: false)]); // } // // var newDominantParticipant = _participants.firstWhere((p) => p.id == event.remoteParticipant.sid); // var newDominantParticipantIndex = _participants.indexOf(newDominantParticipant); // _participants.replaceRange(newDominantParticipantIndex, newDominantParticipantIndex + 1, [newDominantParticipant.copyWith(isDominant: true)]); // notifyListeners(); // } // // void _onParticipantConnected(RoomParticipantConnectedEvent event) { // print('ConferenceRoom._onParticipantConnected, ${event.remoteParticipant.sid}'); // _addRemoteParticipantListeners(event.remoteParticipant); // } // // void _onParticipantDisconnected(RoomParticipantDisconnectedEvent event) { // print('ConferenceRoom._onParticipantDisconnected: ${event.remoteParticipant.sid}'); // _participants.removeWhere((ParticipantWidget p) => p.id == event.remoteParticipant.sid); // notifyListeners(); // } // // ParticipantWidget _buildParticipant({ // @required Widget child, // @required String id, // @required bool audioEnabled, // @required bool videoEnabled, // RemoteParticipant remoteParticipant, // }) { // return ParticipantWidget( // id: remoteParticipant?.sid, // isRemote: remoteParticipant != null, // child: child, // audioEnabled: audioEnabled, // videoEnabled: videoEnabled, // ); // } // // void _addRemoteParticipantListeners(RemoteParticipant remoteParticipant) { // print('ConferenceRoom._addRemoteParticipantListeners() => Adding listeners to remoteParticipant ${remoteParticipant.sid}'); // _streamSubscriptions.add(remoteParticipant.onAudioTrackDisabled.listen(_onAudioTrackDisabled)); // _streamSubscriptions.add(remoteParticipant.onAudioTrackEnabled.listen(_onAudioTrackEnabled)); // _streamSubscriptions.add(remoteParticipant.onAudioTrackPublished.listen(_onAudioTrackPublished)); // _streamSubscriptions.add(remoteParticipant.onAudioTrackSubscribed.listen(_onAudioTrackSubscribed)); // _streamSubscriptions.add(remoteParticipant.onAudioTrackSubscriptionFailed.listen(_onAudioTrackSubscriptionFailed)); // _streamSubscriptions.add(remoteParticipant.onAudioTrackUnpublished.listen(_onAudioTrackUnpublished)); // _streamSubscriptions.add(remoteParticipant.onAudioTrackUnsubscribed.listen(_onAudioTrackUnsubscribed)); // // _streamSubscriptions.add(remoteParticipant.onDataTrackPublished.listen(_onDataTrackPublished)); // _streamSubscriptions.add(remoteParticipant.onDataTrackSubscribed.listen(_onDataTrackSubscribed)); // _streamSubscriptions.add(remoteParticipant.onDataTrackSubscriptionFailed.listen(_onDataTrackSubscriptionFailed)); // _streamSubscriptions.add(remoteParticipant.onDataTrackUnpublished.listen(_onDataTrackUnpublished)); // _streamSubscriptions.add(remoteParticipant.onDataTrackUnsubscribed.listen(_onDataTrackUnsubscribed)); // // _streamSubscriptions.add(remoteParticipant.onVideoTrackDisabled.listen(_onVideoTrackDisabled)); // _streamSubscriptions.add(remoteParticipant.onVideoTrackEnabled.listen(_onVideoTrackEnabled)); // _streamSubscriptions.add(remoteParticipant.onVideoTrackPublished.listen(_onVideoTrackPublished)); // _streamSubscriptions.add(remoteParticipant.onVideoTrackSubscribed.listen(_onVideoTrackSubscribed)); // _streamSubscriptions.add(remoteParticipant.onVideoTrackSubscriptionFailed.listen(_onVideoTrackSubscriptionFailed)); // _streamSubscriptions.add(remoteParticipant.onVideoTrackUnpublished.listen(_onVideoTrackUnpublished)); // _streamSubscriptions.add(remoteParticipant.onVideoTrackUnsubscribed.listen(_onVideoTrackUnsubscribed)); // } // // void _onAudioTrackDisabled(RemoteAudioTrackEvent event) { // print('ConferenceRoom._onAudioTrackDisabled(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}, isEnabled: ${event.remoteAudioTrackPublication.isTrackEnabled}'); // _setRemoteAudioEnabled(event); // } // // void _onAudioTrackEnabled(RemoteAudioTrackEvent event) { // print('ConferenceRoom._onAudioTrackEnabled(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}, isEnabled: ${event.remoteAudioTrackPublication.isTrackEnabled}'); // _setRemoteAudioEnabled(event); // } // // void _onAudioTrackPublished(RemoteAudioTrackEvent event) { // print('ConferenceRoom._onAudioTrackPublished(), ${event.remoteParticipant.sid}}'); // } // // void _onAudioTrackSubscribed(RemoteAudioTrackSubscriptionEvent event) { // print('ConferenceRoom._onAudioTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}'); // _addOrUpdateParticipant(event); // } // // void _onAudioTrackSubscriptionFailed(RemoteAudioTrackSubscriptionFailedEvent event) { // print('ConferenceRoom._onAudioTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}'); // _onExceptionStreamController.add( // PlatformException( // code: 'ConferenceRoom.audioTrackSubscriptionFailed', // message: 'AudioTrack Subscription Failed', // details: event.exception.toString(), // ), // ); // } // // void _onAudioTrackUnpublished(RemoteAudioTrackEvent event) { // print('ConferenceRoom._onAudioTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrackPublication.trackSid}'); // } // // void _onAudioTrackUnsubscribed(RemoteAudioTrackSubscriptionEvent event) { // print('ConferenceRoom._onAudioTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteAudioTrack.sid}'); // } // // void _onDataTrackPublished(RemoteDataTrackEvent event) { // print('ConferenceRoom._onDataTrackPublished(), ${event.remoteParticipant.sid}}'); // } // // void _onDataTrackSubscribed(RemoteDataTrackSubscriptionEvent event) { // print('ConferenceRoom._onDataTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}'); // final dataTrack = event.remoteDataTrackPublication.remoteDataTrack; // _dataTracks.add(dataTrack); // _streamSubscriptions.add(dataTrack.onMessage.listen(_onMessage)); // _streamSubscriptions.add(dataTrack.onBufferMessage.listen(_onBufferMessage)); // } // // void _onDataTrackSubscriptionFailed(RemoteDataTrackSubscriptionFailedEvent event) { // print('ConferenceRoom._onDataTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}'); // _onExceptionStreamController.add( // PlatformException( // code: 'ConferenceRoom.dataTrackSubscriptionFailed', // message: 'DataTrack Subscription Failed', // details: event.exception.toString(), // ), // ); // } // // void _onDataTrackUnpublished(RemoteDataTrackEvent event) { // print('ConferenceRoom._onDataTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteDataTrackPublication.trackSid}'); // } // // void _onDataTrackUnsubscribed(RemoteDataTrackSubscriptionEvent event) { // print('ConferenceRoom._onDataTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteDataTrack.sid}'); // } // // void _onVideoTrackDisabled(RemoteVideoTrackEvent event) { // print('ConferenceRoom._onVideoTrackDisabled(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}, isEnabled: ${event.remoteVideoTrackPublication.isTrackEnabled}'); // _setRemoteVideoEnabled(event); // } // // void _onVideoTrackEnabled(RemoteVideoTrackEvent event) { // print('ConferenceRoom._onVideoTrackEnabled(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}, isEnabled: ${event.remoteVideoTrackPublication.isTrackEnabled}'); // _setRemoteVideoEnabled(event); // } // // void _onVideoTrackPublished(RemoteVideoTrackEvent event) { // print('ConferenceRoom._onVideoTrackPublished(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}'); // } // // void _onVideoTrackSubscribed(RemoteVideoTrackSubscriptionEvent event) { // print('ConferenceRoom._onVideoTrackSubscribed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrack.sid}'); // _addOrUpdateParticipant(event); // } // // void _onVideoTrackSubscriptionFailed(RemoteVideoTrackSubscriptionFailedEvent event) { // print('ConferenceRoom._onVideoTrackSubscriptionFailed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}'); // _onExceptionStreamController.add( // PlatformException( // code: 'ConferenceRoom.videoTrackSubscriptionFailed', // message: 'VideoTrack Subscription Failed', // details: event.exception.toString(), // ), // ); // } // // void _onVideoTrackUnpublished(RemoteVideoTrackEvent event) { // print('ConferenceRoom._onVideoTrackUnpublished(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrackPublication.trackSid}'); // } // // void _onVideoTrackUnsubscribed(RemoteVideoTrackSubscriptionEvent event) { // print('ConferenceRoom._onVideoTrackUnsubscribed(), ${event.remoteParticipant.sid}, ${event.remoteVideoTrack.sid}'); // } // // void _onMessage(RemoteDataTrackStringMessageEvent event) { // print('onMessage => ${event.remoteDataTrack.sid}, ${event.message}'); // } // // void _onBufferMessage(RemoteDataTrackBufferMessageEvent event) { // print('onBufferMessage => ${event.remoteDataTrack.sid}, ${String.fromCharCodes(event.message.asUint8List())}'); // } // // void _setRemoteAudioEnabled(RemoteAudioTrackEvent event) { // if (event.remoteAudioTrackPublication == null) { // return; // } // var index = _participants.indexWhere((ParticipantWidget participant) => participant.id == event.remoteParticipant.sid); // if (index < 0) { // return; // } // var participant = _participants[index]; // _participants.replaceRange( // index, // index + 1, // [ // participant.copyWith(audioEnabled: event.remoteAudioTrackPublication.isTrackEnabled), // ], // ); // notifyListeners(); // } // // void _setRemoteVideoEnabled(RemoteVideoTrackEvent event) { // if (event.remoteVideoTrackPublication == null) { // return; // } // var index = _participants.indexWhere((ParticipantWidget participant) => participant.id == event.remoteParticipant.sid); // if (index < 0) { // return; // } // var participant = _participants[index]; // _participants.replaceRange( // index, // index + 1, // [ // participant.copyWith(videoEnabled: event.remoteVideoTrackPublication.isTrackEnabled), // ], // ); // notifyListeners(); // } // // void _addOrUpdateParticipant(RemoteParticipantEvent event) { // print('ConferenceRoom._addOrUpdateParticipant(), ${event.remoteParticipant.sid}'); // final participant = _participants.firstWhere( // (ParticipantWidget participant) => participant.id == event.remoteParticipant.sid, // orElse: () => null, // ); // if (participant != null) { // print('Participant found: ${participant.id}, updating A/V enabled values'); // _setRemoteVideoEnabled(event); // _setRemoteAudioEnabled(event); // } else { // final bufferedParticipant = _participantBuffer.firstWhere( // (ParticipantBuffer participant) => participant.id == event.remoteParticipant.sid, // orElse: () => null, // ); // if (bufferedParticipant != null) { // _participantBuffer.remove(bufferedParticipant); // } else if (event is RemoteAudioTrackEvent) { // print('Audio subscription came first, waiting for the video subscription...'); // _participantBuffer.add( // ParticipantBuffer( // id: event.remoteParticipant.sid, // audioEnabled: event.remoteAudioTrackPublication?.remoteAudioTrack?.isEnabled ?? true, // ), // ); // return; // } // if (event is RemoteVideoTrackSubscriptionEvent) { // print('New participant, adding: ${event.remoteParticipant.sid}'); // _participants.insert( // 0, // _buildParticipant( // child: event.remoteVideoTrack.widget(), // id: event.remoteParticipant.sid, // remoteParticipant: event.remoteParticipant, // audioEnabled: bufferedParticipant?.audioEnabled ?? true, // videoEnabled: event.remoteVideoTrackPublication?.remoteVideoTrack?.isEnabled ?? true, // ), // ); // } // notifyListeners(); // } // } // }