show resume prompt for ?resume=true and reset on item change
This commit is contained in:
+16
-39
@@ -361,35 +361,21 @@ export default function PlayerPage() {
|
||||
transcodingUrlHasRuntimeTicks: hasRuntimeTicks,
|
||||
streamUrl: streamUrl.replace(/api_key=[^&]+/, 'api_key=***'),
|
||||
})
|
||||
if (transcodingUrl && !hasRuntimeTicks) {
|
||||
const fullUrl = `${serverUrl}${transcodingUrl}`
|
||||
fetch(fullUrl, { headers: { Authorization: `MediaBrowser Token=${token}` } })
|
||||
.then(r => r.text())
|
||||
.then(text => {
|
||||
const lines = text.split(/\r?\n/)
|
||||
const variantLine = lines.find(l => l.endsWith('.m3u8') && !l.startsWith('#'))
|
||||
console.log('[player] hls master playlist', text)
|
||||
if (variantLine) {
|
||||
const variantUrl = variantLine.startsWith('http')
|
||||
? variantLine
|
||||
: new URL(variantLine, fullUrl).toString()
|
||||
return fetch(variantUrl, { headers: { Authorization: `MediaBrowser Token=${token}` } }).then(r => r.text())
|
||||
}
|
||||
return null
|
||||
})
|
||||
.then(variantText => {
|
||||
if (!variantText) return
|
||||
const lines = variantText.split(/\r?\n/)
|
||||
const segmentLines = lines.filter(l => /\.(ts|m4s|mp4)(\?|$)/.test(l))
|
||||
console.log('[player] hls variant playlist (first 20 lines)', lines.slice(0, 20))
|
||||
console.log('[player] hls variant first 6 segment lines', segmentLines.slice(0, 6))
|
||||
console.log('[player] hls variant segments have runtimeTicks', segmentLines.some(l => l.includes('runtimeTicks=')))
|
||||
console.log('[player] hls variant segments have StartTimeTicks', segmentLines.some(l => l.includes('StartTimeTicks=')))
|
||||
})
|
||||
.catch(e => console.warn('[player] hls playlist fetch failed', e))
|
||||
}
|
||||
}
|
||||
|
||||
/* Resume prompt: show on first mount when there's a saved position
|
||||
* past the threshold AND the user wants the prompt. The prompt auto-
|
||||
* confirms after a few seconds, which queues the deferred seek via
|
||||
* pendingSeekRef and seeks the underlying HTMLMediaElement directly
|
||||
* (vidstack's MediaPlayerInstance.currentTime has a known bug on
|
||||
* direct-play MP4 sources that restarts the video from 0).
|
||||
* Intentionally scoped to item?.Id only - we only want to evaluate
|
||||
* the resume condition once per item, not re-trigger when item data
|
||||
* refreshes or prefs change mid-playback. */
|
||||
const resumePromptShownRef = useRef<string | null>(null)
|
||||
const resumeItemId = item?.Id
|
||||
const resumePositionTicks = item?.UserData?.PlaybackPositionTicks
|
||||
|
||||
/* Reset transient flags on item change */
|
||||
useEffect(() => {
|
||||
setUpNextDismissed(false)
|
||||
@@ -398,29 +384,20 @@ export default function PlayerPage() {
|
||||
setStreamAudioIndex(null)
|
||||
setEndCardOpen(false)
|
||||
pendingSeekRef.current = null
|
||||
resumePromptShownRef.current = null
|
||||
usePlayerRuntimeStore.getState().resetForNewItem()
|
||||
}, [id, setPanel])
|
||||
|
||||
/* Resume prompt: show on first mount when there's a saved position
|
||||
* past the threshold AND the user wants the prompt AND the URL didn't
|
||||
* already specify ?resume=true (queue navigation path).
|
||||
* Intentionally scoped to item?.Id only - we only want to evaluate
|
||||
* the resume condition once per item, not re-trigger when item data
|
||||
* refreshes or prefs change mid-playback. */
|
||||
const resumePromptShownRef = useRef<string | null>(null)
|
||||
const resumeItemId = item?.Id
|
||||
const resumePositionTicks = item?.UserData?.PlaybackPositionTicks
|
||||
useEffect(() => {
|
||||
if (!resumeItemId || resumePromptShownRef.current === resumeItemId) return
|
||||
const pos = Number(resumePositionTicks ?? 0)
|
||||
const thresholdSec = usePreferencesStore.getState().resumeThresholdSec ?? 5
|
||||
const threshold = thresholdSec * 10_000_000
|
||||
const fromQueue = searchParams.get('resume') === 'true'
|
||||
if (showResumePromptPref && !fromQueue && pos > threshold) {
|
||||
if (showResumePromptPref && pos > threshold) {
|
||||
setResumePromptOpen(true)
|
||||
resumePromptShownRef.current = resumeItemId
|
||||
}
|
||||
}, [resumeItemId, resumePositionTicks, searchParams, showResumePromptPref])
|
||||
}, [resumeItemId, resumePositionTicks, showResumePromptPref])
|
||||
|
||||
/* Auto-rewatch counter: when an already-played item starts playing
|
||||
* again, record the rewatch. We trip it at most once per item-mount
|
||||
|
||||
Reference in New Issue
Block a user