feat: persistent playbackrate
Some checks are pending
Check / check (push) Waiting to run

fix: don't autoselect tracks when lang is none
This commit is contained in:
ThaUnknown 2025-07-24 18:26:31 +02:00
parent 7f84100c22
commit 715374711c
No known key found for this signature in database
6 changed files with 30 additions and 25 deletions

View file

@ -11,6 +11,7 @@ export default tseslint.config(
tsconfigRootDir: import.meta.dirname,
svelteConfig
}
}
},
ignores: ['build/', '.svelte-kit/', 'node_modules/']
}
)

View file

@ -1,6 +1,6 @@
{
"name": "ui",
"version": "6.4.85",
"version": "6.4.86",
"license": "BUSL-1.1",
"private": true,
"packageManager": "pnpm@9.15.5",

View file

@ -193,25 +193,25 @@
<Tree.Item>
<span slot='trigger'>Playback Rate</span>
<Tree.Sub>
<Tree.Item on:click={() => { playbackRate = 0.5; open = false }}>
<Tree.Item active={playbackRate === 0.5} on:click={() => { playbackRate = 0.5; open = false }}>
<span>0.5x</span>
</Tree.Item>
<Tree.Item on:click={() => { playbackRate = 0.75; open = false }}>
<Tree.Item active={playbackRate === 0.75} on:click={() => { playbackRate = 0.75; open = false }}>
<span>0.75x</span>
</Tree.Item>
<Tree.Item on:click={() => { playbackRate = 1; open = false }}>
<Tree.Item active={playbackRate === 1} on:click={() => { playbackRate = 1; open = false }}>
<span>1x</span>
</Tree.Item>
<Tree.Item on:click={() => { playbackRate = 1.25; open = false }}>
<Tree.Item active={playbackRate === 1.25} on:click={() => { playbackRate = 1.25; open = false }}>
<span>1.25x</span>
</Tree.Item>
<Tree.Item on:click={() => { playbackRate = 1.5; open = false }}>
<Tree.Item active={playbackRate === 1.5} on:click={() => { playbackRate = 1.5; open = false }}>
<span>1.5x</span>
</Tree.Item>
<Tree.Item on:click={() => { playbackRate = 1.75; open = false }}>
<Tree.Item active={playbackRate === 1.75} on:click={() => { playbackRate = 1.75; open = false }}>
<span>1.75x</span>
</Tree.Item>
<Tree.Item on:click={() => { playbackRate = 2; open = false }}>
<Tree.Item active={playbackRate === 2} on:click={() => { playbackRate = 2; open = false }}>
<span>2x</span>
</Tree.Item>
</Tree.Sub>

View file

@ -77,7 +77,7 @@
let currentTime = 0
let seekPercent = 0
let duration = 1
let playbackRate = 1
const playbackRate = persisted('playbackRate', 1)
let buffered: SvelteMediaTimeRange[] = []
let subtitleDelay = 0
$: buffer = Math.max(...buffered.map(({ end }) => end))
@ -462,7 +462,7 @@
$: if (readyState && !seekIndex) thumbnailer._paintThumbnail(video, playbackIndex)
$: native.setMediaSession(mediaInfo.session, mediaInfo.media.id, safeduration)
$: native.setPositionState({ duration: safeduration, position: Math.min(Math.max(0, currentTime), safeduration), playbackRate }, readyState === 0 ? 'none' : paused ? 'paused' : 'playing')
$: native.setPositionState({ duration: safeduration, position: Math.min(Math.max(0, currentTime), safeduration), playbackRate: $playbackRate }, readyState === 0 ? 'none' : paused ? 'paused' : 'playing')
$: native.setPlayBackState(readyState === 0 ? 'none' : paused ? 'paused' : 'playing')
native.setActionHandler('play', playPause)
native.setActionHandler('pause', playPause)
@ -657,21 +657,21 @@
desc: 'Volume Down'
},
BracketLeft: {
fn: () => { playbackRate = video.defaultPlaybackRate -= 0.1 },
fn: () => { $playbackRate -= 0.1 },
id: 'history',
icon: RotateCcw,
type: 'icon',
desc: 'Decrease Playback Rate'
},
BracketRight: {
fn: () => { playbackRate = video.defaultPlaybackRate += 0.1 },
fn: () => { $playbackRate += 0.1 },
id: 'update',
icon: RotateCw,
type: 'icon',
desc: 'Increase Playback Rate'
},
Backslash: {
fn: () => { playbackRate = video.defaultPlaybackRate = 1 },
fn: () => { $playbackRate = 1 },
icon: RefreshCcw,
id: 'schedule',
type: 'icon',
@ -700,23 +700,25 @@
function holdToFF (document: HTMLElement, type: 'key' | 'pointer') {
const ctrl = new AbortController()
let timeout = 0
let oldPlaybackRate = playbackRate
let oldPlaybackRate = $playbackRate
let wasPaused = paused
const startFF = () => {
clearTimeout(timeout)
timeout = setTimeout(() => {
if (fastForwarding) return
wasPaused = paused
paused = false
fastForwarding = true
oldPlaybackRate = playbackRate
playbackRate = 2
oldPlaybackRate = $playbackRate
$playbackRate = 2
}, 1000)
}
const endFF = () => {
clearTimeout(timeout)
if (!fastForwarding) return
fastForwarding = false
playbackRate = oldPlaybackRate
paused = true
$playbackRate = oldPlaybackRate
paused = wasPaused
}
document.addEventListener(type + 'down' as 'keydown' | 'pointerdown', event => {
if (isMiniplayer) return
@ -801,7 +803,7 @@
bind:muted
bind:readyState
bind:buffered
bind:playbackRate
bind:playbackRate={$playbackRate}
bind:volume={exponentialVolume}
bind:this={video}
on:click={() => isMiniplayer ? goto('/app/player') : playPause()}
@ -852,7 +854,7 @@
Subtitle delay: {subtitleDelay} sec
</div>
{/if}
<Options {wrapper} bind:openSubs {video} {seekTo} {selectAudio} {selectVideo} {fullscreen} {chapters} {subtitles} {videoFiles} {selectFile} {pip} bind:playbackRate bind:subtitleDelay id='player-options-button-top'
<Options {wrapper} bind:openSubs {video} {seekTo} {selectAudio} {selectVideo} {fullscreen} {chapters} {subtitles} {videoFiles} {selectFile} {pip} bind:playbackRate={$playbackRate} bind:subtitleDelay id='player-options-button-top'
class='{($settings.minimalPlayerUI || SUPPORTS.isAndroid) ? 'inline-flex' : 'mobile:inline-flex hidden'} p-3 w-12 h-12 absolute z-[1] top-4 left-4 bg-black/20 pointer-events-auto transition-opacity select:opacity-100 delay-150 {immersed && 'opacity-0'}' />
{#if fastForwarding}
<div class='absolute top-10 font-bold text-sm animate-[fade-in_.4s_ease] flex items-center leading-none bg-black/60 px-4 py-2 rounded-2xl'>x2 <FastForward class='ml-2' size='12' fill='currentColor' /></div>
@ -949,12 +951,12 @@
<Volume bind:volume={$volume} bind:muted />
</div>
<div class='flex gap-2'>
{#if playbackRate !== 1}
{#if $playbackRate !== 1}
<div class='flex justify-center items-center leading-none text-base font-bold px-1 pt-0.5'>
x{playbackRate.toFixed(1)}
x{$playbackRate.toFixed(1)}
</div>
{/if}
<Options {fullscreen} {wrapper} {seekTo} bind:openSubs {video} {selectAudio} {selectVideo} {chapters} {subtitles} {videoFiles} {selectFile} {pip} bind:playbackRate bind:subtitleDelay id='player-options-button' />
<Options {fullscreen} {wrapper} {seekTo} bind:openSubs {video} {selectAudio} {selectVideo} {chapters} {subtitles} {videoFiles} {selectFile} {pip} bind:playbackRate={$playbackRate} bind:subtitleDelay id='player-options-button' />
{#if subtitles}
<Button class='p-3 w-12 h-12' variant='ghost' on:click={openSubs} on:keydown={keywrap(openSubs)} data-up='#player-seekbar'>
<Subtitles size='24px' fill='currentColor' strokeWidth='0' />

View file

@ -138,7 +138,9 @@ export default class Subtitles {
this.initSubtitleRenderer()
const tracks = Object.entries(this._tracks.value)
if (tracks.length) {
if (!this.set.subtitleLanguage) return // if lang set to none dont autoselect
if (tracks.length === 1) {
this.selectCaptions(tracks[0]![0])
} else {

View file

@ -11,7 +11,7 @@ const dummyFiles = [
type: 'video/webm',
size: 1234567890,
path: '/Amebku.webm',
url: '/Ameku.webm',
url: '/test2.mkv',
id: 0
}
// {