fix: cleaner deband code

This commit is contained in:
ThaUnknown 2025-05-11 18:55:27 +02:00
parent c9a0a98fee
commit 8ff16ace6d
No known key found for this signature in database
4 changed files with 43 additions and 26 deletions

View file

@ -1,6 +1,6 @@
{
"name": "ui",
"version": "6.3.6",
"version": "6.3.7",
"license": "BUSL-1.1",
"private": true,
"packageManager": "pnpm@9.14.4",

View file

@ -71,8 +71,13 @@
$: pip._setElements(video, subtitles, deband)
const pipElementStore = pip.element
$: pictureInPictureElement = $pipElementStore
const thumbnailer = new Thumbnailer(mediaInfo.file.url)
onMount(() => thumbnailer.setVideo(video))
onDestroy(() => {
pip.destroy()
thumbnailer.destroy()
})
// state
@ -133,15 +138,14 @@
}
}
function seek (time: number) {
// this cant be called, because it will cause the video to mutate and update all video mutation listeners
// video.currentTime = currentTime = currentTime + time
// WARN: this causes all subscriptions to video to re-run!!!
video.currentTime = currentTime = currentTime + time
currentTime = currentTime + time
playAnimation(time > 0 ? 'seekforw' : 'seekback')
}
function seekTo (time: number) {
playAnimation(time > currentTime ? 'seekforw' : 'seekback')
// video.currentTime = currentTime = time
currentTime = time
video.currentTime = currentTime = time
}
let wasPaused = false
function startSeek () {
@ -195,9 +199,6 @@
}
let animations: Animation[] = []
const thumbnailer = new Thumbnailer(mediaInfo.file.url)
onMount(() => thumbnailer.setVideo(video))
let chapters: Chapter[] = []
const chaptersPromise = native.chapters(mediaInfo.file.hash, mediaInfo.file.id)
async function loadChapters (pr: typeof chaptersPromise, safeduration: number) {
@ -224,23 +225,33 @@
}
}
function cleanupDeband () {
deband?.destroy()
deband?.canvas.remove()
deband = undefined
pip._setElements(video, subtitles, deband)
}
function createDeband (video: HTMLVideoElement, playerDeband: boolean) {
const create = () => {
destroy()
deband = new VideoDeband(video)
deband.canvas.classList.add('deband-canvas', 'w-full', 'h-full', 'pointer-events-none', 'object-contain')
video.before(deband.canvas)
}
function createDeband (video: HTMLVideoElement | undefined, playerDeband: boolean) {
if (!playerDeband || !video) return cleanupDeband()
if (deband) cleanupDeband()
deband = new VideoDeband(video)
pip._setElements(video, subtitles, deband)
deband.canvas.classList.add('deband-canvas', 'w-full', 'h-full', 'pointer-events-none', 'object-contain')
video.before(deband.canvas)
}
const destroy = () => {
deband?.destroy()
deband?.canvas.remove()
deband = undefined
}
$: createDeband(video, $settings.playerDeband)
if (playerDeband) create()
return {
destroy,
update: (playerDeband: boolean) => {
if (playerDeband) {
create()
} else {
destroy()
}
}
}
}
let completed = false
function checkCompletion () {
@ -323,7 +334,7 @@
} else {
currentTime = currentTime + 85
}
// video.currentTime = currentTime
video.currentTime = currentTime
}
let stats: {
@ -622,6 +633,7 @@
<div class='w-full h-full relative content-center bg-black overflow-clip text-left' class:fitWidth class:seeking bind:this={wrapper}>
<video class='w-full h-full' preload='auto' class:cursor-none={immersed} class:cursor-pointer={isMiniplayer} class:object-cover={fitWidth} class:opacity-0={$settings.playerDeband || seeking} class:absolute={$settings.playerDeband} class:top-0={$settings.playerDeband}
use:createSubtitles
use:createDeband={$settings.playerDeband}
use:holdToFF={'pointer'}
crossorigin='anonymous'
src={mediaInfo.file.url}

View file

@ -27,12 +27,16 @@ export default class Thumbnailer {
}
}
timeUpdateCtrl = new AbortController()
setVideo (currentVideo: HTMLVideoElement) {
this.timeUpdateCtrl.abort()
this.timeUpdateCtrl = new AbortController()
currentVideo.addEventListener('timeupdate', () => {
const index = Math.floor(currentVideo.currentTime / this.interval)
const thumbnail = this.thumbnails[index]
if (!thumbnail) this._paintThumbnail(currentVideo, index)
})
}, { signal: this.timeUpdateCtrl.signal })
}
_createTask (index: number): RenderItem {
@ -106,6 +110,7 @@ export default class Thumbnailer {
destroy () {
this.video.remove()
this.timeUpdateCtrl.abort()
this.thumbnails = []
}
}

View file

@ -37,7 +37,7 @@
}
</script>
<div class='h-full w-full flex flex-row gap-2 group/volume'>
<div class='h-full w-full hidden sm:flex flex-row gap-2 group/volume'>
<Button class='p-3 w-12 h-12' variant='ghost' on:click={mute}>
{#if muted}
<VolumeOff size='24px' fill='currentColor' />