diff --git a/backend/plugins/jellyfin.plugin/src/index.ts b/backend/plugins/jellyfin.plugin/src/index.ts index 46e8918..d256d5f 100644 --- a/backend/plugins/jellyfin.plugin/src/index.ts +++ b/backend/plugins/jellyfin.plugin/src/index.ts @@ -599,6 +599,11 @@ export default class JellyfinPlugin implements SourcePlugin { if (!proxyRes) return; + proxyRes.headers.forEach((value, name) => { + console.log('jellyfin proxy header', name, value); + res.setHeader(name, value); + }); + res.status(proxyRes.status); Readable.from(proxyRes.body).pipe(res); }; diff --git a/src/lib/components/VideoPlayer/ProgressBar.svelte b/src/lib/components/VideoPlayer/ProgressBar.svelte index da600bd..f856f8e 100644 --- a/src/lib/components/VideoPlayer/ProgressBar.svelte +++ b/src/lib/components/VideoPlayer/ProgressBar.svelte @@ -35,13 +35,32 @@ dispatch('jumpTo', progressTime); } + let pauseTime = 0; + const handlePause = (paused: boolean) => { + if (paused) { + pauseTime = progressTime; + } else if (pauseTime > 0) { + dispatch('jumpTo', pauseTime); + pauseTime = 0; + } + }; + $: handlePause(paused); + function handleNavigateEvent({ detail }: CustomEvent) { if (detail.direction === 'left') { - dispatch('jumpTo', progressTime - 10); - detail.preventNavigation(); + if (paused) { + pauseTime = pauseTime - 10; + } else { + dispatch('jumpTo', progressTime - 10); + detail.preventNavigation(); + } } else if (detail.direction === 'right') { - dispatch('jumpTo', progressTime + 30); - detail.preventNavigation(); + if (paused) { + pauseTime = pauseTime + 30; + } else { + dispatch('jumpTo', progressTime + 30); + detail.preventNavigation(); + } } } @@ -67,9 +86,9 @@
0 ? pauseTime : progressTime) / totalTime) * 100 + }% - 0.5rem + ${(pauseTime > 0 ? pauseTime : progressTime) / totalTime}rem);`} />
0 ? pauseTime : progressTime) / totalTime) * 100}% - ${ + (pauseTime > 0 ? pauseTime : progressTime) / totalTime + }rem); box-shadow: 0 0 0.25rem 2px #00000033; `} /> @@ -98,7 +119,7 @@ />
- {formatSecondsToTime(progressTime)} - -{formatSecondsToTime(totalTime - progressTime)} + {formatSecondsToTime(pauseTime || progressTime)} + -{formatSecondsToTime(totalTime - (pauseTime || progressTime))}
diff --git a/src/lib/components/VideoPlayer/VideoPlayer.svelte b/src/lib/components/VideoPlayer/VideoPlayer.svelte index 3721820..2ea13ca 100644 --- a/src/lib/components/VideoPlayer/VideoPlayer.svelte +++ b/src/lib/components/VideoPlayer/VideoPlayer.svelte @@ -8,10 +8,11 @@ import type { Selectable } from '../../selectable'; import { modalStack } from '../Modal/modal.store'; import SelectSubtitlesModal from './SelectSubtitlesModal.svelte'; - import { ChatBubble, TextAlignLeft } from 'radix-icons-svelte'; + import { ChatBubble, Pause, TextAlignLeft } from 'radix-icons-svelte'; import IconButton from './IconButton.svelte'; import SelectAudioModal from './SelectAudioModal.svelte'; import Spinner from '../Utils/Spinner.svelte'; + import { createInfoNotification } from '../Notifications/notification.store'; export let playbackInfo: PlaybackInfo | undefined; export let subtitleInfo: SubtitleInfo | undefined; @@ -41,13 +42,14 @@ $: if (modalHidden) video?.pause(); else video?.play(); $: if (!seeking && !modalHidden) handleShowInterface(); + $: if (paused) handleShowInterface(); function handleShowInterface() { showInterface = true; clearTimeout(showInterfaceTimeout); showInterfaceTimeout = setTimeout(() => { if (!seeking && !modalHidden) handleHideInterface(); - }, 4000); + }, 5000); } function handleHideInterface() { @@ -141,9 +143,17 @@ {#if buffering || !videoDidLoad} -
+
+ {:else if paused && showInterface} +
+ +
{/if} Promise; @@ -68,7 +69,11 @@ Loading... {:then streams} {#each streams ?? [] as stream} - selectStream(s, stream)} let:hasFocus> + selectStream(s, stream)} + on:enter={scrollIntoView({ vertical: 64 })} + let:hasFocus + >