Spaces:
Sleeping
Sleeping
| import { defineStore } from 'pinia' | |
| export const useUploadStore = defineStore('upload', { | |
| state: () => ({ | |
| selectedFile: null, | |
| fileType: null, // 'image' ou 'video' | |
| filePreview: null, | |
| uploadStatus: 'idle', // 'idle', 'uploading', 'success', 'error' | |
| error: null, | |
| // Spécifique aux vidéos | |
| videoType: null, // 'static' ou 'dynamic' | |
| extractedFrame: null // Pour les vidéos statiques | |
| }), | |
| getters: { | |
| isFileSelected: (state) => state.selectedFile !== null, | |
| isImage: (state) => state.fileType === 'image', | |
| isVideo: (state) => state.fileType === 'video', | |
| isUploading: (state) => state.uploadStatus === 'uploading', | |
| // Nouveaux getters pour les vidéos | |
| isStaticVideo: (state) => state.fileType === 'video' && state.videoType === 'static', | |
| isDynamicVideo: (state) => state.fileType === 'video' && state.videoType === 'dynamic', | |
| shouldProcessDirectly: (state) => state.fileType === 'image' || state.isStaticVideo, | |
| needsParameters: (state) => state.isDynamicVideo | |
| }, | |
| actions: { | |
| setFile(file) { | |
| this.selectedFile = file | |
| this.fileType = file.type.startsWith('image/') ? 'image' : 'video' | |
| this.createPreview(file) | |
| this.uploadStatus = 'idle' | |
| this.error = null | |
| // Reset video-specific data | |
| this.videoType = null | |
| this.extractedFrame = null | |
| }, | |
| async setVideoType(type) { | |
| this.videoType = type | |
| if (type === 'static') { | |
| console.log('🔥 Starting frame extraction for static video...') | |
| await this.extractFrameFromVideo() | |
| console.log('🔥 Frame extraction completed:', { | |
| hasExtractedFrame: !!this.extractedFrame, | |
| extractedFrameType: this.extractedFrame?.type, | |
| extractedFrameName: this.extractedFrame?.name | |
| }) | |
| } | |
| }, | |
| createPreview(file) { | |
| if (file.type.startsWith('image/')) { | |
| this.filePreview = URL.createObjectURL(file) | |
| } else { | |
| this.filePreview = URL.createObjectURL(file) | |
| } | |
| }, | |
| async extractFrameFromVideo() { | |
| if (!this.selectedFile || !this.isVideo) { | |
| console.error('🔥 Cannot extract frame: no file or not a video') | |
| return null | |
| } | |
| try { | |
| const video = document.createElement('video') | |
| video.src = URL.createObjectURL(this.selectedFile) | |
| return new Promise((resolve, reject) => { | |
| video.addEventListener('loadedmetadata', () => { | |
| console.log('🔥 Video metadata loaded, seeking to frame 0') | |
| video.currentTime = 0 // Première image | |
| }) | |
| video.addEventListener('seeked', () => { | |
| try { | |
| console.log('🔥 Video seeked, drawing to canvas') | |
| const canvas = document.createElement('canvas') | |
| canvas.width = video.videoWidth | |
| canvas.height = video.videoHeight | |
| if (video.videoWidth === 0 || video.videoHeight === 0) { | |
| throw new Error('Video dimensions are 0') | |
| } | |
| const ctx = canvas.getContext('2d') | |
| ctx.drawImage(video, 0, 0) | |
| canvas.toBlob((blob) => { | |
| if (!blob) { | |
| reject(new Error('Failed to create blob from canvas')) | |
| return | |
| } | |
| // Créer un File avec un nom au lieu d'un Blob simple | |
| const file = new File([blob], 'extracted_frame.jpg', { type: 'image/jpeg' }) | |
| this.extractedFrame = file | |
| console.log('🔥 Frame extracted successfully:', { | |
| name: file.name, | |
| type: file.type, | |
| size: file.size | |
| }) | |
| URL.revokeObjectURL(video.src) | |
| resolve(file) | |
| }, 'image/jpeg', 0.9) | |
| } catch (err) { | |
| console.error('🔥 Error during canvas operations:', err) | |
| URL.revokeObjectURL(video.src) | |
| reject(err) | |
| } | |
| }) | |
| video.addEventListener('error', (err) => { | |
| console.error('🔥 Video loading error:', err) | |
| URL.revokeObjectURL(video.src) | |
| reject(err) | |
| }) | |
| // Timeout de sécurité | |
| setTimeout(() => { | |
| console.error('🔥 Frame extraction timeout') | |
| URL.revokeObjectURL(video.src) | |
| reject(new Error('Frame extraction timeout')) | |
| }, 10000) | |
| }) | |
| } catch (error) { | |
| console.error('🔥 Erreur extraction frame:', error) | |
| this.setError('Impossible d\'extraire une image de la vidéo: ' + error.message) | |
| return null | |
| } | |
| }, | |
| clearFile() { | |
| if (this.filePreview) { | |
| URL.revokeObjectURL(this.filePreview) | |
| } | |
| this.selectedFile = null | |
| this.fileType = null | |
| this.filePreview = null | |
| this.uploadStatus = 'idle' | |
| this.error = null | |
| this.videoType = null | |
| this.extractedFrame = null | |
| }, | |
| setUploadStatus(status) { | |
| this.uploadStatus = status | |
| }, | |
| setError(error) { | |
| this.error = error | |
| this.uploadStatus = 'error' | |
| } | |
| } | |
| }) |