spotube/lib/services/audio_player/audio_player.dart
Kingkor Roy Tirtho 68374efd3e
feat: LAN connect a.k.a control remote Spotube playback and local output device selection (#1355)
* feat: add connect server support

* feat: add ability discover and connect to same network Spotube(s) and sync queue

* feat(connect): add player controls, shuffle, loop, progress bar and queue support

* feat: make control page adaptive

* feat: add volume control support

* cd: upgrade macos runner version

* chore: upgrade inappwebview version to 6

* feat: customized devices button

* feat: add user icon next to devices button

* feat: add play in remote device support

* feat: show alert when new client connects

* fix: ignore the device itself from broadcast list

* fix: volume control not working

* feat: add ability to select current device's output speaker
2024-04-04 22:22:00 +06:00

157 lines
4.2 KiB
Dart

import 'package:catcher_2/catcher_2.dart';
import 'package:media_kit/media_kit.dart';
import 'package:spotube/services/audio_player/mk_state_player.dart';
// import 'package:just_audio/just_audio.dart' as ja;
import 'dart:async';
import 'package:media_kit/media_kit.dart' as mk;
import 'package:spotube/services/audio_player/loop_mode.dart';
import 'package:spotube/services/audio_player/playback_state.dart';
import 'package:spotube/services/sourced_track/sourced_track.dart';
part 'audio_players_streams_mixin.dart';
part 'audio_player_impl.dart';
abstract class AudioPlayerInterface {
final MkPlayerWithState _mkPlayer;
// final ja.AudioPlayer? _justAudxio;
AudioPlayerInterface()
: _mkPlayer = MkPlayerWithState(
configuration: const mk.PlayerConfiguration(
title: "Spotube",
),
)
// _justAudio = !_mkSupportedPlatform ? ja.AudioPlayer() : null
{
_mkPlayer.stream.error.listen((event) {
Catcher2.reportCheckedError(event, StackTrace.current);
});
}
/// Whether the current platform supports the audioplayers plugin
static const bool _mkSupportedPlatform = true;
// DesktopTools.platform.isWindows || DesktopTools.platform.isLinux;
bool get mkSupportedPlatform => _mkSupportedPlatform;
Future<Duration?> get duration async {
return _mkPlayer.state.duration;
// if (mkSupportedPlatform) {
// } else {
// return _justAudio!.duration;
// }
}
Future<Duration?> get position async {
return _mkPlayer.state.position;
// if (mkSupportedPlatform) {
// } else {
// return _justAudio!.position;
// }
}
Future<Duration?> get bufferedPosition async {
if (mkSupportedPlatform) {
// audioplayers doesn't have the capability to get buffered position
return null;
} else {
return null;
}
}
Future<AudioDevice> get selectedDevice async {
return _mkPlayer.state.audioDevice;
}
Future<List<AudioDevice>> get devices async {
return _mkPlayer.state.audioDevices;
}
bool get hasSource {
return _mkPlayer.playlist.medias.isNotEmpty;
// if (mkSupportedPlatform) {
// return _mkPlayer.playlist.medias.isNotEmpty;
// } else {
// return _justAudio!.audioSource != null;
// }
}
// states
bool get isPlaying {
return _mkPlayer.state.playing;
// if (mkSupportedPlatform) {
// return _mkPlayer.state.playing;
// } else {
// return _justAudio!.playing;
// }
}
bool get isPaused {
return !_mkPlayer.state.playing;
// if (mkSupportedPlatform) {
// return !_mkPlayer.state.playing;
// } else {
// return !isPlaying;
// }
}
bool get isStopped {
return !hasSource;
// if (mkSupportedPlatform) {
// return !hasSource;
// } else {
// return _justAudio!.processingState == ja.ProcessingState.idle;
// }
}
Future<bool> get isCompleted async {
return _mkPlayer.state.completed;
// if (mkSupportedPlatform) {
// return _mkPlayer.state.completed;
// } else {
// return _justAudio!.processingState == ja.ProcessingState.completed;
// }
}
Future<bool> get isShuffled async {
return _mkPlayer.shuffled;
// if (mkSupportedPlatform) {
// return _mkPlayer.shuffled;
// } else {
// return _justAudio!.shuffleModeEnabled;
// }
}
PlaybackLoopMode get loopMode {
return PlaybackLoopMode.fromPlaylistMode(_mkPlayer.loopMode);
// if (mkSupportedPlatform) {
// return PlaybackLoopMode.fromPlaylistMode(_mkPlayer.loopMode);
// } else {
// return PlaybackLoopMode.fromLoopMode(_justAudio!.loopMode);
// }
}
/// Returns the current volume of the player, between 0 and 1
double get volume {
return _mkPlayer.state.volume / 100;
// if (mkSupportedPlatform) {
// return _mkPlayer.state.volume / 100;
// } else {
// return _justAudio!.volume;
// }
}
bool get isBuffering {
return false;
// if (mkSupportedPlatform) {
// // audioplayers doesn't have the capability to get buffering state
// return false;
// } else {
// return _justAudio!.processingState == ja.ProcessingState.buffering ||
// _justAudio!.processingState == ja.ProcessingState.loading;
// }
}
}