use direct stream for resume

This commit is contained in:
2026-06-06 22:21:48 +03:00
parent c9f6d92a7f
commit 253af91f46
2 changed files with 18 additions and 1 deletions
+17 -1
View File
@@ -622,6 +622,15 @@ export function useSimilarItems(itemId?: string, limit = 12) {
* has to load first so the first PlaybackInfo request includes the
* saved StartTimeTicks - otherwise the video streams from 0 and
* reloads mid-playback when the second query returns.
*
* `requireDirectStream` is used for resume: the direct-play
* /Videos/{id}/stream endpoint with `static=true` returns the file
* from byte 0 even when StartTimeTicks is passed, because Chromium
* / WebView2 don't send a Range header for the initial GET. The
* direct-stream path has the server read the file from the start
* position itself and stream the bytes, so the response naturally
* starts at the saved offset. Direct-stream is not transcoding -
* it's just server-side file I/O with no encoding work.
*/
export function usePlaybackInfo(
itemId?: string,
@@ -629,6 +638,7 @@ export function usePlaybackInfo(
audioStreamIndex?: number,
maxStreamingBitrate?: number,
enabled: boolean = true,
requireDirectStream: boolean = false,
) {
const api = useApi()
const audioPassthrough = usePreferencesStore(s => s.audioPassthrough)
@@ -640,6 +650,7 @@ export function usePlaybackInfo(
startTimeTicks,
audioStreamIndex,
maxStreamingBitrate,
requireDirectStream,
],
queryFn: async () => {
if (!api || !itemId) return null
@@ -657,7 +668,12 @@ export function usePlaybackInfo(
AudioStreamIndex: audioStreamIndex,
DeviceProfile: await browserDeviceProfile(audioPassthrough) as any,
AutoOpenLiveStream: true,
EnableDirectPlay: true,
// For resume, prefer direct-stream so the server starts the
// read at StartTimeTicks. Direct-play can't honour start
// time on the initial GET. Otherwise let the server pick
// direct-play for the no-resume case so the browser plays
// the file as-is.
EnableDirectPlay: !requireDirectStream,
EnableDirectStream: true,
EnableTranscoding: true,
AllowVideoStreamCopy: true,
+1
View File
@@ -331,6 +331,7 @@ export default function PlayerPage() {
streamAudioIndex ?? undefined,
maxBitrate,
playbackInfoReady,
startTimeTicks !== undefined,
)
const resolvedSource = playbackInfo?.MediaSources?.[0]
const streamUrl = (() => {