diff --git a/lib/components/album/album_card.dart b/lib/components/album/album_card.dart index 962673cdf..ac2fc97f0 100644 --- a/lib/components/album/album_card.dart +++ b/lib/components/album/album_card.dart @@ -42,7 +42,8 @@ class AlbumCard extends HookConsumerWidget { @override Widget build(BuildContext context, ref) { final playlist = ref.watch(PlaylistQueueNotifier.provider); - final playing = useStream(audioPlayer.playingStream).data ?? false; + final playing = + useStream(audioPlayer.playingStream).data ?? audioPlayer.isPlaying; final playlistNotifier = ref.watch(PlaylistQueueNotifier.notifier); final queryClient = useQueryClient(); final query = queryClient diff --git a/lib/components/player/player_controls.dart b/lib/components/player/player_controls.dart index b4eb32e00..3a5c3f2f2 100644 --- a/lib/components/player/player_controls.dart +++ b/lib/components/player/player_controls.dart @@ -44,7 +44,9 @@ class PlayerControls extends HookConsumerWidget { []); final playlist = ref.watch(PlaylistQueueNotifier.provider); final playlistNotifier = ref.watch(PlaylistQueueNotifier.notifier); - final playing = useStream(audioPlayer.playingStream).data ?? false; + + final playing = + useStream(audioPlayer.playingStream).data ?? audioPlayer.isPlaying; final buffering = useStream(audioPlayer.bufferingStream).data ?? true; final theme = Theme.of(context); diff --git a/lib/components/player/player_overlay.dart b/lib/components/player/player_overlay.dart index 9cfef7bed..73b052628 100644 --- a/lib/components/player/player_overlay.dart +++ b/lib/components/player/player_overlay.dart @@ -28,7 +28,8 @@ class PlayerOverlay extends HookConsumerWidget { ); final playlistNotifier = ref.watch(PlaylistQueueNotifier.notifier); final playlist = ref.watch(PlaylistQueueNotifier.provider); - final playing = useStream(audioPlayer.playingStream).data ?? false; + final playing = + useStream(audioPlayer.playingStream).data ?? audioPlayer.isPlaying; final theme = Theme.of(context); final textColor = theme.colorScheme.primary; diff --git a/lib/components/playlist/playlist_card.dart b/lib/components/playlist/playlist_card.dart index 4e971666a..1fcf88de6 100644 --- a/lib/components/playlist/playlist_card.dart +++ b/lib/components/playlist/playlist_card.dart @@ -21,7 +21,8 @@ class PlaylistCard extends HookConsumerWidget { Widget build(BuildContext context, ref) { final playlistQueue = ref.watch(PlaylistQueueNotifier.provider); final playlistNotifier = ref.watch(PlaylistQueueNotifier.notifier); - final playing = useStream(audioPlayer.playingStream).data ?? false; + final playing = + useStream(audioPlayer.playingStream).data ?? audioPlayer.isPlaying; final queryBowl = QueryClient.of(context); final query = queryBowl.getQuery, dynamic>( "playlist-tracks/${playlist.id}", diff --git a/lib/hooks/use_progress.dart b/lib/hooks/use_progress.dart index 0b1ca309c..90b256288 100644 --- a/lib/hooks/use_progress.dart +++ b/lib/hooks/use_progress.dart @@ -12,10 +12,17 @@ Tuple4 useProgress(WidgetRef ref) { useStream(audioPlayer.bufferedPositionStream).data?.inSeconds ?? 0; final playlistNotifier = ref.watch(PlaylistQueueNotifier.notifier); - final duration = useStream(audioPlayer.durationStream).data ?? Duration.zero; + // Duration future is needed for getting the duration of the song + // as stream can be null when no event occurs (Mostly needed for android) + final durationFuture = useFuture(audioPlayer.duration); + final duration = useStream(audioPlayer.durationStream).data ?? + durationFuture.data ?? + Duration.zero; + final positionFuture = useFuture(audioPlayer.position); final positionSnapshot = useStream(audioPlayer.positionStream); - final position = positionSnapshot.data ?? Duration.zero; + final position = + positionSnapshot.data ?? positionFuture.data ?? Duration.zero; final sliderMax = duration.inSeconds; final sliderValue = position.inSeconds; diff --git a/lib/main.dart b/lib/main.dart index d9d550f3d..8b5c16197 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -199,9 +199,10 @@ class SpotubeState extends ConsumerState { useInitSysTray(ref); - /// For enabling hot reload for audio player useEffect(() { return () { + /// For enabling hot reload for audio player + if (!kDebugMode) return; audioPlayer.dispose(); youtube.close(); }; diff --git a/lib/services/audio_player.dart b/lib/services/audio_player.dart index 960cb0e45..5ce8856c2 100644 --- a/lib/services/audio_player.dart +++ b/lib/services/audio_player.dart @@ -52,7 +52,7 @@ class SpotubeAudioPlayer { // stream getters Stream get durationStream { if (apSupportedPlatform) { - return _audioPlayer!.onDurationChanged; + return _audioPlayer!.onDurationChanged.asBroadcastStream(); } else { throw UnimplementedError(); } @@ -60,7 +60,7 @@ class SpotubeAudioPlayer { Stream get positionStream { if (apSupportedPlatform) { - return _audioPlayer!.onPositionChanged; + return _audioPlayer!.onPositionChanged.asBroadcastStream(); } else { throw UnimplementedError(); } @@ -69,7 +69,7 @@ class SpotubeAudioPlayer { Stream get bufferedPositionStream { if (apSupportedPlatform) { // audioplayers doesn't have the capability to get buffered position - return const Stream.empty(); + return const Stream.empty().asBroadcastStream(); } else { throw UnimplementedError(); } @@ -77,7 +77,7 @@ class SpotubeAudioPlayer { Stream get completedStream { if (apSupportedPlatform) { - return _audioPlayer!.onPlayerComplete; + return _audioPlayer!.onPlayerComplete.asBroadcastStream(); } else { throw UnimplementedError(); } @@ -87,7 +87,7 @@ class SpotubeAudioPlayer { if (apSupportedPlatform) { return _audioPlayer!.onPlayerStateChanged.map((state) { return state == ap.PlayerState.playing; - }); + }).asBroadcastStream(); } else { throw UnimplementedError(); } @@ -95,7 +95,7 @@ class SpotubeAudioPlayer { Stream get bufferingStream { if (apSupportedPlatform) { - return Stream.value(false); + return Stream.value(false).asBroadcastStream(); } else { throw UnimplementedError(); } @@ -103,7 +103,8 @@ class SpotubeAudioPlayer { Stream get playerStateStream => _audioPlayer!.onPlayerStateChanged - .map((state) => PlayerState.fromApPlayerState(state)); + .map((state) => PlayerState.fromApPlayerState(state)) + .asBroadcastStream(); // regular info getter diff --git a/macos/Runner/DebugProfile.entitlements b/macos/Runner/DebugProfile.entitlements index 42d86e9b7..6fc950efc 100644 --- a/macos/Runner/DebugProfile.entitlements +++ b/macos/Runner/DebugProfile.entitlements @@ -11,11 +11,11 @@ com.apple.security.network.client - NSAppTransportSecurity + diff --git a/macos/Runner/Release.entitlements b/macos/Runner/Release.entitlements index b26cf8bd3..4a447fde6 100644 --- a/macos/Runner/Release.entitlements +++ b/macos/Runner/Release.entitlements @@ -6,14 +6,14 @@ com.apple.security.network.server - com.apple.security.network.client - NSAppTransportSecurity + +