handle player stop on queue clear

This commit is contained in:
jeffvli
2025-12-13 00:15:20 -08:00
parent 1ac267fa99
commit a546a4d57b
5 changed files with 38 additions and 0 deletions
@@ -249,6 +249,9 @@ export const MpvPlayerEngine = (props: MpvPlayerEngineProps) => {
onPlayerPlay: () => { onPlayerPlay: () => {
replaceMpvQueue(transcode); replaceMpvQueue(transcode);
}, },
onQueueCleared: () => {
console.log('queue cleared');
},
}, },
[transcode], [transcode],
); );
@@ -13,6 +13,7 @@ import {
subscribePlayerSpeed, subscribePlayerSpeed,
subscribePlayerStatus, subscribePlayerStatus,
subscribePlayerVolume, subscribePlayerVolume,
subscribeQueueCleared,
} from '/@/renderer/store'; } from '/@/renderer/store';
import { LibraryItem, QueueData, QueueSong, Song } from '/@/shared/types/domain-types'; import { LibraryItem, QueueData, QueueSong, Song } from '/@/shared/types/domain-types';
import { PlayerRepeat, PlayerShuffle, PlayerStatus } from '/@/shared/types/types'; import { PlayerRepeat, PlayerShuffle, PlayerStatus } from '/@/shared/types/types';
@@ -46,6 +47,7 @@ interface PlayerEventsCallbacks {
onPlayerSpeed?: (properties: { speed: number }, prev: { speed: number }) => void; onPlayerSpeed?: (properties: { speed: number }, prev: { speed: number }) => void;
onPlayerStatus?: (properties: { status: PlayerStatus }, prev: { status: PlayerStatus }) => void; onPlayerStatus?: (properties: { status: PlayerStatus }, prev: { status: PlayerStatus }) => void;
onPlayerVolume?: (properties: { volume: number }, prev: { volume: number }) => void; onPlayerVolume?: (properties: { volume: number }, prev: { volume: number }) => void;
onQueueCleared?: () => void;
onQueueRestored?: (properties: { data: Song[]; index: number; position: number }) => void; onQueueRestored?: (properties: { data: Song[]; index: number; position: number }) => void;
onUserFavorite?: (properties: { onUserFavorite?: (properties: {
favorite: boolean; favorite: boolean;
@@ -99,6 +101,12 @@ function createPlayerEvents(callbacks: PlayerEventsCallbacks): PlayerEvents {
unsubscribers.push(unsubscribe); unsubscribers.push(unsubscribe);
} }
// Subscribe to queue cleared events
if (callbacks.onQueueCleared) {
const unsubscribe = subscribeQueueCleared(callbacks.onQueueCleared);
unsubscribers.push(unsubscribe);
}
// Subscribe to seek events // Subscribe to seek events
if (callbacks.onPlayerSeekToTimestamp) { if (callbacks.onPlayerSeekToTimestamp) {
const unsubscribe = subscribePlayerSeekToTimestamp(callbacks.onPlayerSeekToTimestamp); const unsubscribe = subscribePlayerSeekToTimestamp(callbacks.onPlayerSeekToTimestamp);
@@ -4,6 +4,7 @@ import { useCallback, useEffect, useRef, useState } from 'react';
import { MpvPlayerEngine, MpvPlayerEngineHandle } from './engine/mpv-player-engine'; import { MpvPlayerEngine, MpvPlayerEngineHandle } from './engine/mpv-player-engine';
import { usePlayerEvents } from '/@/renderer/features/player/audio-player/hooks/use-player-events'; import { usePlayerEvents } from '/@/renderer/features/player/audio-player/hooks/use-player-events';
import { usePlayer } from '/@/renderer/features/player/context/player-context';
import { import {
usePlaybackSettings, usePlaybackSettings,
usePlayerActions, usePlayerActions,
@@ -97,6 +98,8 @@ export function MpvPlayer() {
return playerData; return playerData;
}, [mediaAutoNext, volume, setIsTransitioning]); }, [mediaAutoNext, volume, setIsTransitioning]);
const player = usePlayer();
usePlayerEvents( usePlayerEvents(
{ {
onPlayerSeekToTimestamp: (properties) => { onPlayerSeekToTimestamp: (properties) => {
@@ -125,6 +128,9 @@ export function MpvPlayer() {
const volume = properties.volume; const volume = properties.volume;
playerRef.current?.setVolume(volume); playerRef.current?.setVolume(volume);
}, },
onQueueCleared: () => {
player.mediaStop();
},
}, },
[volume, fadeAndSetStatus, audioFadeOnStatusChange], [volume, fadeAndSetStatus, audioFadeOnStatusChange],
); );
@@ -10,6 +10,7 @@ import {
import { usePlayerEvents } from '/@/renderer/features/player/audio-player/hooks/use-player-events'; import { usePlayerEvents } from '/@/renderer/features/player/audio-player/hooks/use-player-events';
import { useSongUrl } from '/@/renderer/features/player/audio-player/hooks/use-stream-url'; import { useSongUrl } from '/@/renderer/features/player/audio-player/hooks/use-stream-url';
import { PlayerOnProgressProps } from '/@/renderer/features/player/audio-player/types'; import { PlayerOnProgressProps } from '/@/renderer/features/player/audio-player/types';
import { usePlayer } from '/@/renderer/features/player/context/player-context';
import { useWebAudio } from '/@/renderer/features/player/hooks/use-webaudio'; import { useWebAudio } from '/@/renderer/features/player/hooks/use-webaudio';
import { import {
useMpvSettings, useMpvSettings,
@@ -193,6 +194,8 @@ export function WebPlayer() {
}); });
}, [mediaAutoNext, volume]); }, [mediaAutoNext, volume]);
const player = usePlayer();
usePlayerEvents( usePlayerEvents(
{ {
onCurrentSongChange: () => { onCurrentSongChange: () => {
@@ -266,6 +269,9 @@ export function WebPlayer() {
const volume = properties.volume; const volume = properties.volume;
playerRef.current?.setVolume(volume); playerRef.current?.setVolume(volume);
}, },
onQueueCleared: () => {
player.mediaStop();
},
}, },
[volume, num, isTransitioning, transitionType, audioFadeOnStatusChange], [volume, num, isTransitioning, transitionType, audioFadeOnStatusChange],
); );
+15
View File
@@ -2538,6 +2538,21 @@ export const subscribePlayerShuffle = (
); );
}; };
export const subscribeQueueCleared = (onChange: () => void) => {
return usePlayerStoreBase.subscribe(
(state) => state.queue,
(queue, prevQueue) => {
// Detect if queue became empty
const wasNotEmpty = prevQueue.default.length > 0 || prevQueue.priority.length > 0;
const isEmpty = queue.default.length === 0 && queue.priority.length === 0;
if (wasNotEmpty && isEmpty) {
onChange();
}
},
);
};
export const usePlayerProperties = () => { export const usePlayerProperties = () => {
return usePlayerStoreBase( return usePlayerStoreBase(
useShallow((state) => ({ useShallow((state) => ({