seek via underlying media element for resume
This commit is contained in:
@@ -348,6 +348,19 @@ export default function PlayerPage() {
|
|||||||
}
|
}
|
||||||
return ''
|
return ''
|
||||||
})()
|
})()
|
||||||
|
if (typeof window !== 'undefined' && playbackInfo) {
|
||||||
|
const transcodingUrl = resolvedSource?.TranscodingUrl
|
||||||
|
const supportsDirectPlay = resolvedSource?.SupportsDirectPlay
|
||||||
|
const hasRuntimeTicks = transcodingUrl ? transcodingUrl.includes('runtimeTicks=') : null
|
||||||
|
console.log('[player] stream resolved', {
|
||||||
|
id,
|
||||||
|
startTimeTicks,
|
||||||
|
supportsDirectPlay,
|
||||||
|
transcodingUrlPresent: !!transcodingUrl,
|
||||||
|
transcodingUrlHasRuntimeTicks: hasRuntimeTicks,
|
||||||
|
streamUrl: streamUrl.replace(/api_key=[^&]+/, 'api_key=***'),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/* Reset transient flags on item change */
|
/* Reset transient flags on item change */
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -1164,8 +1177,13 @@ export default function PlayerPage() {
|
|||||||
if (p && pendingSeekRef.current != null) {
|
if (p && pendingSeekRef.current != null) {
|
||||||
const target = pendingSeekRef.current
|
const target = pendingSeekRef.current
|
||||||
pendingSeekRef.current = null
|
pendingSeekRef.current = null
|
||||||
if (p.currentTime < target - 0.5 || p.currentTime > target + 0.5) {
|
const mediaEl = (p as any).media as HTMLMediaElement | undefined
|
||||||
try { p.currentTime = target } catch { /* ignore */ }
|
const before = mediaEl ? mediaEl.currentTime : p.currentTime
|
||||||
|
if (before < target - 0.5 || before > target + 0.5) {
|
||||||
|
try {
|
||||||
|
if (mediaEl) mediaEl.currentTime = target
|
||||||
|
else p.currentTime = target
|
||||||
|
} catch { /* ignore */ }
|
||||||
}
|
}
|
||||||
p.play().catch(() => {})
|
p.play().catch(() => {})
|
||||||
}
|
}
|
||||||
@@ -1403,13 +1421,29 @@ export default function PlayerPage() {
|
|||||||
setResumePromptOpen(false)
|
setResumePromptOpen(false)
|
||||||
const p = playerRef.current
|
const p = playerRef.current
|
||||||
const pos = Number(item?.UserData?.PlaybackPositionTicks ?? 0)
|
const pos = Number(item?.UserData?.PlaybackPositionTicks ?? 0)
|
||||||
|
const target = pos > 0 ? pos / 10_000_000 : 0
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
console.log('[player] resume prompt clicked', {
|
||||||
|
id,
|
||||||
|
pos,
|
||||||
|
target,
|
||||||
|
mediaElementCurrentTime: (p as any)?.media?.currentTime,
|
||||||
|
streamUrlStart: streamUrl.includes('StartTimeTicks=') || streamUrl.includes('runtimeTicks='),
|
||||||
|
})
|
||||||
|
}
|
||||||
if (p) {
|
if (p) {
|
||||||
// Queue the seek: if the video isn't ready yet, onCanPlay
|
// Vidstack has a known issue (GH #941) where setting
|
||||||
// picks it up. The setter works on a paused player in
|
// currentTime on the MediaPlayerInstance for a direct-play
|
||||||
// vidstack, but buffering the seek target can race the
|
// MP4 source restarts the video from the beginning. The
|
||||||
// canPlay event for the initial source.
|
// workaround is to set currentTime on the underlying
|
||||||
pendingSeekRef.current = pos > 0 ? pos / 10_000_000 : 0
|
// HTMLMediaElement. For HLS it works either way; we use
|
||||||
try { p.currentTime = pendingSeekRef.current } catch { /* ignore */ }
|
// the underlying element for consistency.
|
||||||
|
pendingSeekRef.current = target
|
||||||
|
const mediaEl = (p as any).media as HTMLMediaElement | undefined
|
||||||
|
try {
|
||||||
|
if (mediaEl) mediaEl.currentTime = target
|
||||||
|
else p.currentTime = target
|
||||||
|
} catch { /* ignore */ }
|
||||||
p.play().catch(() => {})
|
p.play().catch(() => {})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1418,7 +1452,11 @@ export default function PlayerPage() {
|
|||||||
const p = playerRef.current
|
const p = playerRef.current
|
||||||
if (p) {
|
if (p) {
|
||||||
pendingSeekRef.current = 0
|
pendingSeekRef.current = 0
|
||||||
try { p.currentTime = 0 } catch { /* ignore */ }
|
const mediaEl = (p as any).media as HTMLMediaElement | undefined
|
||||||
|
try {
|
||||||
|
if (mediaEl) mediaEl.currentTime = 0
|
||||||
|
else p.currentTime = 0
|
||||||
|
} catch { /* ignore */ }
|
||||||
p.play().catch(() => {})
|
p.play().catch(() => {})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user