|
|
@ -74,6 +74,7 @@ class ThumnbnailWorker { |
|
|
|
this.canvasEl.height |
|
|
|
this.canvasEl.height |
|
|
|
); |
|
|
|
); |
|
|
|
const imgUrl = this.canvasEl.toDataURL(); |
|
|
|
const imgUrl = this.canvasEl.toDataURL(); |
|
|
|
|
|
|
|
if (this.interrupted) return; |
|
|
|
this.cb({ |
|
|
|
this.cb({ |
|
|
|
at, |
|
|
|
at, |
|
|
|
data: imgUrl, |
|
|
|
data: imgUrl, |
|
|
@ -84,13 +85,20 @@ class ThumnbnailWorker { |
|
|
|
const vid = this.videoEl; |
|
|
|
const vid = this.videoEl; |
|
|
|
if (!vid) return; |
|
|
|
if (!vid) return; |
|
|
|
await this.initVideo(); |
|
|
|
await this.initVideo(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO make a queue based on refinement algorithm
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const queue = [0.5, 0.25, 0.75]; |
|
|
|
|
|
|
|
for (let i = 0; i < queue.length; i += 1) { |
|
|
|
if (this.interrupted) return; |
|
|
|
if (this.interrupted) return; |
|
|
|
await this.takeSnapshot(vid.duration / 2); |
|
|
|
await this.takeSnapshot(vid.duration * queue[i]); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
export function ThumbnailScraper() { |
|
|
|
export function ThumbnailScraper() { |
|
|
|
const addImage = usePlayerStore((s) => s.thumbnails.addImage); |
|
|
|
const addImage = usePlayerStore((s) => s.thumbnails.addImage); |
|
|
|
|
|
|
|
const meta = usePlayerStore((s) => s.meta); |
|
|
|
const source = usePlayerStore((s) => s.source); |
|
|
|
const source = usePlayerStore((s) => s.source); |
|
|
|
const workerRef = useRef<ThumnbnailWorker | null>(null); |
|
|
|
const workerRef = useRef<ThumnbnailWorker | null>(null); |
|
|
|
|
|
|
|
|
|
|
@ -102,8 +110,6 @@ export function ThumbnailScraper() { |
|
|
|
}); |
|
|
|
}); |
|
|
|
}, [source]); |
|
|
|
}, [source]); |
|
|
|
|
|
|
|
|
|
|
|
// TODO stop worker on meta change
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// start worker with the stream
|
|
|
|
// start worker with the stream
|
|
|
|
useEffect(() => { |
|
|
|
useEffect(() => { |
|
|
|
// dont interrupt existing working
|
|
|
|
// dont interrupt existing working
|
|
|
@ -119,9 +125,25 @@ export function ThumbnailScraper() { |
|
|
|
// destroy worker on unmount
|
|
|
|
// destroy worker on unmount
|
|
|
|
useEffect(() => { |
|
|
|
useEffect(() => { |
|
|
|
return () => { |
|
|
|
return () => { |
|
|
|
if (workerRef.current) workerRef.current.destroy(); |
|
|
|
if (workerRef.current) { |
|
|
|
|
|
|
|
workerRef.current.destroy(); |
|
|
|
|
|
|
|
workerRef.current = null; |
|
|
|
|
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
}, []); |
|
|
|
}, []); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if targeted meta changes, abort the scraper
|
|
|
|
|
|
|
|
const serializedMeta = JSON.stringify({ |
|
|
|
|
|
|
|
id: meta?.tmdbId, |
|
|
|
|
|
|
|
ep: meta?.episode?.tmdbId, |
|
|
|
|
|
|
|
se: meta?.season?.tmdbId, |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
|
|
|
if (workerRef.current) { |
|
|
|
|
|
|
|
workerRef.current.destroy(); |
|
|
|
|
|
|
|
workerRef.current = null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, [serializedMeta]); |
|
|
|
|
|
|
|
|
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|