mirror of
https://github.com/jeffvli/feishin.git
synced 2026-07-09 03:59:58 +02:00
fix reportPlayback event chain (#2131)
- properly send stopped event on song change - properly send both starting and playing evento n song change instead of only starting
This commit is contained in:
@@ -67,8 +67,9 @@ Jellyfin progress APIs still use playback position (ticks), not listen time:
|
||||
- pause / unpause
|
||||
|
||||
Other events:
|
||||
- When the song changes: sends 'start' when the new track is playing;
|
||||
clears submission flag and listen accumulator for the new track.
|
||||
- When the song changes: sends 'stop' for the previous track; sends 'start'
|
||||
when the new track is playing; clears submission flag and listen accumulator
|
||||
for the new track.
|
||||
|
||||
- When the song is restarted (near 0 after 10s+): clears submission flag
|
||||
and listen accumulator.
|
||||
@@ -129,6 +130,7 @@ export const useScrobble = () => {
|
||||
|
||||
const previousSongRef = useRef<QueueSong | undefined>(undefined);
|
||||
const previousTimestampRef = useRef<number>(0);
|
||||
const stopPositionRef = useRef<number>(0);
|
||||
const lastProgressEventRef = useRef<number>(0);
|
||||
const lastSeekEventRef = useRef<number>(0);
|
||||
const songChangeTimeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
|
||||
@@ -316,7 +318,10 @@ export const useScrobble = () => {
|
||||
) => {
|
||||
const currentSong = properties.song;
|
||||
const previousSong = previousSongRef.current;
|
||||
const previousPositionSec = stopPositionRef.current;
|
||||
const mediaType = currentSong?._itemType.includes('song') ? 'song' : 'podcast';
|
||||
const previousMediaType = previousSong?._itemType.includes('song') ? 'song' : 'podcast';
|
||||
const useTicksForPrevious = previousSong?._serverType === ServerType.JELLYFIN;
|
||||
|
||||
// Handle notifications
|
||||
if (scrobbleSettings?.notify && currentSong?.id) {
|
||||
@@ -352,6 +357,7 @@ export const useScrobble = () => {
|
||||
if (!isScrobbleEnabled || isPrivateModeEnabled) {
|
||||
previousSongRef.current = currentSong;
|
||||
previousTimestampRef.current = 0;
|
||||
stopPositionRef.current = 0;
|
||||
listenedMsRef.current = 0;
|
||||
lastListenSampleTimeRef.current = null;
|
||||
flushScrobbleDebug();
|
||||
@@ -395,10 +401,42 @@ export const useScrobble = () => {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Send stop scrobble for the track that was playing before the change
|
||||
if (previousSong?.id) {
|
||||
sendScrobble.mutate(
|
||||
{
|
||||
apiClientProps: { serverId: previousSong._serverId || '' },
|
||||
query: {
|
||||
albumId: previousSong.albumId,
|
||||
event: 'stop',
|
||||
id: previousSong.id,
|
||||
mediaType: previousMediaType,
|
||||
playbackRate: playbackRate,
|
||||
position: getPositionValue(
|
||||
previousPositionSec,
|
||||
useTicksForPrevious,
|
||||
),
|
||||
submission: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
logFn.debug(logMsg[LogCategory.SCROBBLE].scrobbledStop, {
|
||||
category: LogCategory.SCROBBLE,
|
||||
meta: {
|
||||
id: previousSong.id,
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
}, 2000);
|
||||
|
||||
previousSongRef.current = currentSong;
|
||||
previousTimestampRef.current = 0;
|
||||
stopPositionRef.current = 0;
|
||||
flushScrobbleDebug();
|
||||
},
|
||||
[
|
||||
@@ -591,6 +629,7 @@ export const useScrobble = () => {
|
||||
isCurrentSongScrobbledRef.current = false;
|
||||
lastProgressEventRef.current = 0;
|
||||
previousTimestampRef.current = 0;
|
||||
stopPositionRef.current = 0;
|
||||
listenedMsRef.current = 0;
|
||||
lastListenSampleTimeRef.current = null;
|
||||
|
||||
@@ -625,6 +664,17 @@ export const useScrobble = () => {
|
||||
// Update previous timestamp on progress for use in status change handler
|
||||
const handleProgressUpdate = useCallback(
|
||||
(properties: { timestamp: number }, prev: { timestamp: number }) => {
|
||||
// Preserve last playback position when the playhead resets to the start
|
||||
// (song change can fire after progress already reports 0 for the new track).
|
||||
if (
|
||||
properties.timestamp < SCROBBLE_TRACK_BEGIN_SEC &&
|
||||
prev.timestamp >= SCROBBLE_TRACK_BEGIN_SEC
|
||||
) {
|
||||
stopPositionRef.current = prev.timestamp;
|
||||
} else {
|
||||
stopPositionRef.current = properties.timestamp;
|
||||
}
|
||||
|
||||
previousTimestampRef.current = properties.timestamp;
|
||||
handleScrobbleFromProgress(properties, prev);
|
||||
flushScrobbleDebug();
|
||||
|
||||
Reference in New Issue
Block a user