From d25c729bebf0718986e277139b64517a9b4a168f Mon Sep 17 00:00:00 2001 From: Arturo Manzoli Date: Thu, 25 Apr 2024 17:28:57 -0300 Subject: [PATCH] Stores: Video: Fix thumbnail generation method Signed-off-by: Arturo Manzoli --- src/stores/video.ts | 101 +++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 53 deletions(-) diff --git a/src/stores/video.ts b/src/stores/video.ts index 6ff4713b3..599ba61db 100644 --- a/src/stores/video.ts +++ b/src/stores/video.ts @@ -144,54 +144,47 @@ export const useVideoStore = defineStore('video', () => { /** * Extracts a thumbnail from the first frame of a video. - * @param {string} videoUrl - The URL of the video from which to extract the thumbnail. + * @param {Blob} firstChunkBlob * @returns {Promise} A promise that resolves with the base64-encoded image data of the thumbnail. */ - const extractThumbnailFromVideo = async (videoUrl: string): Promise => { + const extractThumbnailFromVideo = async (firstChunkBlob: Blob): Promise => { return new Promise((resolve, reject) => { - fetch(videoUrl) - .then((response) => response.blob()) - .then((videoBlob) => { - const videoObjectUrl = URL.createObjectURL(videoBlob) - const video = document.createElement('video') - - let seekResolve: (() => void) | null = null - video.addEventListener('seeked', function () { - if (seekResolve) seekResolve() - }) - - video.addEventListener('error', () => { - URL.revokeObjectURL(videoObjectUrl) - reject('Error loading video') - }) - - video.src = videoObjectUrl - - video.addEventListener('loadedmetadata', () => { - const canvas = document.createElement('canvas') - const context = canvas.getContext('2d') - if (!context) { - URL.revokeObjectURL(videoObjectUrl) - reject('2D context not available.') - return - } - - const [width, height] = [660, 370] - canvas.width = width - canvas.height = height - - video.currentTime = 0 - seekResolve = () => { - context.drawImage(video, 0, 0, width, height) - const base64ImageData = canvas.toDataURL('image/jpeg', 0.6) - resolve(base64ImageData) - URL.revokeObjectURL(videoObjectUrl) - } - }) - }) - .catch((error) => { - reject('Failed to fetch video: ' + error) - }) + const videoObjectUrl = URL.createObjectURL(firstChunkBlob) + const video = document.createElement('video') + + let seekResolve: (() => void) | null = null + video.addEventListener('seeked', function () { + if (seekResolve) seekResolve() + }) + + video.addEventListener('error', () => { + URL.revokeObjectURL(videoObjectUrl) + reject('Error loading video') + }) + + video.src = videoObjectUrl + + video.addEventListener('loadedmetadata', () => { + const canvas = document.createElement('canvas') + const context = canvas.getContext('2d') + if (!context) { + URL.revokeObjectURL(videoObjectUrl) + reject('2D context not available.') + return + } + + const [width, height] = [660, 370] + canvas.width = width + canvas.height = height + + video.currentTime = 0 + seekResolve = () => { + context.drawImage(video, 0, 0, width, height) + const base64ImageData = canvas.toDataURL('image/jpeg', 0.6) + resolve(base64ImageData) + URL.revokeObjectURL(videoObjectUrl) + } + }) }) } @@ -267,14 +260,16 @@ export const useVideoStore = defineStore('video', () => { // Gets the thumbnail from the first chunk if (chunksCount === 0) { - const videoChunk = await tempVideoChunksDB.getItem(chunkName) - if (videoChunk) { - const blob = videoChunk as Blob - const thumbnailBlob = new Blob([blob], { type: 'video/webm;codecs=vp9' }) - const thumbnailUrl = URL.createObjectURL(thumbnailBlob) - const thumbnail = await extractThumbnailFromVideo(thumbnailUrl) - updatedInfo.thumbnail = thumbnail - unprocessedVideos.value = { ...unprocessedVideos.value, ...{ [recordingHash]: updatedInfo } } + try { + const videoChunk = await tempVideoChunksDB.getItem(chunkName) + if (videoChunk) { + const firstChunkBlob = new Blob([videoChunk as Blob], { type: 'video/webm;codecs=vp9' }) + const thumbnail = await extractThumbnailFromVideo(firstChunkBlob) + updatedInfo.thumbnail = thumbnail + unprocessedVideos.value = { ...unprocessedVideos.value, ...{ [recordingHash]: updatedInfo } } + } + } catch (error) { + console.error('Failed to extract thumbnail:', error) } } }