feat: Video load indicator, keyboard shortcuts

This commit is contained in:
Aleksi Lassila
2024-05-08 19:12:22 +03:00
parent 11575f49eb
commit 1e9675dc72
3 changed files with 67 additions and 1 deletions

View File

@@ -14,13 +14,19 @@
export let muted = false;
export let volume = 1;
export let videoDidLoad = false;
export let buffering = false;
export let video: HTMLVideoElement;
// let hls: Hls | undefined;
$: playbackInfo && loadPlaybackInfo(playbackInfo);
function loadPlaybackInfo(playbackInfo: PlaybackInfo) {
videoDidLoad = false;
// video.src = '';
// video.srcObject = null;
// hls?.destroy();
const { playbackUrl, directPlay, backdrop, startTime } = playbackInfo;
@@ -30,6 +36,7 @@
if (!directPlay) {
if (Hls.isSupported()) {
console.log('HLS is supported, loading HLS.js');
const hls = new Hls();
hls.loadSource(playbackUrl);
@@ -94,6 +101,8 @@
videoDidLoad = true;
console.log('Video loaded');
}}
on:waiting={() => (buffering = true)}
on:playing={() => (buffering = false)}
on:dblclick
on:click={togglePlay}
autoplay

View File

@@ -8,9 +8,10 @@
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, TextAlignLeft, Update } from 'radix-icons-svelte';
import IconButton from './IconButton.svelte';
import SelectAudioModal from './SelectAudioModal.svelte';
import Spinner from '../Utils/Spinner.svelte';
export let playbackInfo: PlaybackInfo | undefined;
export let subtitleInfo: SubtitleInfo | undefined;
@@ -26,6 +27,7 @@
export let muted = false;
export let volume = 1;
export let videoDidLoad = false;
let buffering = false;
export let video: HTMLVideoElement;
@@ -76,6 +78,27 @@
else console.error('No playback info when selecting audio stream');
}
function handleShortcuts(e: KeyboardEvent) {
if (e.key === ' ' || e.key === 'k') {
e.preventDefault();
if (paused) video.play();
else video.pause();
} else if (e.key === 'm') {
e.preventDefault();
video.muted = !video.muted;
} else if (e.key === 'f') {
e.preventDefault();
if (document.fullscreenElement) document.exitFullscreen();
else video.requestFullscreen();
} else if (e.key === 'ArrowUp') {
e.preventDefault();
video.volume = Math.min(video.volume + 0.1, 1);
} else if (e.key === 'ArrowDown') {
e.preventDefault();
video.volume = Math.max(video.volume - 0.1, 0);
}
}
onDestroy(() => {
clearTimeout(showInterfaceTimeout);
clearTimeout(hideInterfaceTimeout);
@@ -105,6 +128,7 @@
bind:volume
bind:videoDidLoad
bind:video
bind:buffering
/>
<Container
class={classNames('absolute inset-x-12 top-8 transition-opacity', {
@@ -113,6 +137,11 @@
>
Title
</Container>
{#if buffering || !videoDidLoad}
<div class="absolute left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2">
<Spinner class="w-12 h-12" />
</div>
{/if}
<Container
class={classNames('absolute inset-x-12 bottom-8 transition-opacity flex flex-col', {
'opacity-0': !showInterface
@@ -170,3 +199,5 @@
/>
</Container>
</Container>
<svelte:window on:keypress={handleShortcuts} />