mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 07:55:18 +00:00

* 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
157 lines
4.2 KiB
Dart
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;
|
|
// }
|
|
}
|
|
}
|