mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-12 23:45:18 +00:00
feat: windows OS media control panel support
This commit is contained in:
parent
06a043764d
commit
f0b426ae89
@ -11,6 +11,7 @@ import 'package:spotube/provider/user_preferences_provider.dart';
|
||||
import 'package:spotube/services/audio_player.dart';
|
||||
import 'package:spotube/services/linux_audio_service.dart';
|
||||
import 'package:spotube/services/mobile_audio_service.dart';
|
||||
import 'package:spotube/services/windows_audio_service.dart';
|
||||
import 'package:spotube/utils/persisted_state_notifier.dart';
|
||||
import 'package:spotube/utils/platform.dart';
|
||||
import 'package:spotube/utils/type_conversion_utils.dart';
|
||||
@ -137,6 +138,7 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {
|
||||
final Ref ref;
|
||||
MobileAudioService? mobileService;
|
||||
LinuxAudioService? linuxService;
|
||||
WindowsAudioService? windowsService;
|
||||
|
||||
static final provider =
|
||||
StateNotifierProvider<PlaylistQueueNotifier, PlaylistQueue?>(
|
||||
@ -166,6 +168,9 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {
|
||||
if (kIsLinux) {
|
||||
linuxService = LinuxAudioService(ref, this);
|
||||
}
|
||||
if (kIsWindows) {
|
||||
windowsService = WindowsAudioService(ref, this);
|
||||
}
|
||||
addListener((state) {
|
||||
linuxService?.player.updateProperties();
|
||||
});
|
||||
@ -363,6 +368,7 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {
|
||||
duration: state!.activeTrack.duration,
|
||||
);
|
||||
mobileService?.addItem(mediaItem);
|
||||
windowsService?.addTrack(state!.activeTrack);
|
||||
if (state!.activeTrack is LocalTrack) {
|
||||
await audioPlayer.play(
|
||||
DeviceFileSource((state!.activeTrack as LocalTrack).path),
|
||||
@ -512,6 +518,12 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {
|
||||
Map<String, dynamic> toJson() {
|
||||
return state?.toJson() ?? {};
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
windowsService?.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
class VolumeProvider extends PersistedStateNotifier<double> {
|
||||
|
99
lib/services/windows_audio_service.dart
Normal file
99
lib/services/windows_audio_service.dart
Normal file
@ -0,0 +1,99 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:audioplayers/audioplayers.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:smtc_windows/smtc_windows.dart';
|
||||
import 'package:spotify/spotify.dart';
|
||||
import 'package:spotube/provider/playlist_queue_provider.dart';
|
||||
import 'package:spotube/services/audio_player.dart';
|
||||
import 'package:spotube/utils/type_conversion_utils.dart';
|
||||
|
||||
class WindowsAudioService {
|
||||
final SMTCWindows smtc;
|
||||
final Ref ref;
|
||||
final PlaylistQueueNotifier playlistNotifier;
|
||||
|
||||
final subscriptions = <StreamSubscription>[];
|
||||
|
||||
WindowsAudioService(this.ref, this.playlistNotifier) : smtc = SMTCWindows() {
|
||||
smtc.setPlaybackStatus(PlaybackStatus.Stopped);
|
||||
final buttonStream = smtc.buttonPressStream.listen((event) {
|
||||
switch (event) {
|
||||
case PressedButton.play:
|
||||
playlistNotifier.resume();
|
||||
break;
|
||||
case PressedButton.pause:
|
||||
playlistNotifier.pause();
|
||||
break;
|
||||
case PressedButton.next:
|
||||
playlistNotifier.next();
|
||||
break;
|
||||
case PressedButton.previous:
|
||||
playlistNotifier.previous();
|
||||
break;
|
||||
case PressedButton.stop:
|
||||
playlistNotifier.stop();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
final playerStateStream =
|
||||
audioPlayer.onPlayerStateChanged.listen((state) async {
|
||||
switch (state) {
|
||||
case PlayerState.playing:
|
||||
await smtc.setPlaybackStatus(PlaybackStatus.Playing);
|
||||
break;
|
||||
case PlayerState.paused:
|
||||
await smtc.setPlaybackStatus(PlaybackStatus.Paused);
|
||||
break;
|
||||
case PlayerState.stopped:
|
||||
await smtc.setPlaybackStatus(PlaybackStatus.Stopped);
|
||||
break;
|
||||
case PlayerState.completed:
|
||||
await smtc.setPlaybackStatus(PlaybackStatus.Changing);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
final positionStream = audioPlayer.onPositionChanged.listen((pos) async {
|
||||
await smtc.setPosition(pos);
|
||||
});
|
||||
|
||||
final durationStream =
|
||||
audioPlayer.onDurationChanged.listen((duration) async {
|
||||
await smtc.setEndTime(duration);
|
||||
});
|
||||
|
||||
subscriptions.addAll([
|
||||
buttonStream,
|
||||
playerStateStream,
|
||||
positionStream,
|
||||
durationStream,
|
||||
]);
|
||||
}
|
||||
|
||||
Future<void> addTrack(Track track) async {
|
||||
await smtc.updateMetadata(MusicMetadata(
|
||||
title: track.name!,
|
||||
albumArtist: track.artists?.first.name ?? "Unknown",
|
||||
artist: TypeConversionUtils.artists_X_String<Artist>(track.artists ?? []),
|
||||
album: track.album?.name ?? "Unknown",
|
||||
trackNumber: track.trackNumber ?? 0,
|
||||
thumbnail: TypeConversionUtils.image_X_UrlString(
|
||||
track.album?.images ?? [],
|
||||
placeholder: ImagePlaceholder.albumArt,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
smtc.dispose();
|
||||
for (var element in subscriptions) {
|
||||
element.cancel();
|
||||
}
|
||||
}
|
||||
}
|
@ -1452,6 +1452,13 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.99"
|
||||
smtc_windows:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "../smtc_windows/packages/smtc_windows"
|
||||
relative: true
|
||||
source: path
|
||||
version: "0.0.1"
|
||||
source_gen:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -84,6 +84,8 @@ dependencies:
|
||||
youtube_explode_dart: ^1.12.1
|
||||
flutter_desktop_tools:
|
||||
path: ../flutter_desktop_tools
|
||||
smtc_windows:
|
||||
path: ../smtc_windows/packages/smtc_windows
|
||||
|
||||
dev_dependencies:
|
||||
build_runner: ^2.3.2
|
||||
|
@ -18,6 +18,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
||||
|
||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||
metadata_god
|
||||
smtc_windows
|
||||
)
|
||||
|
||||
set(PLUGIN_BUNDLED_LIBRARIES)
|
||||
|
Loading…
Reference in New Issue
Block a user