Spaces:
Running
Running
File size: 5,280 Bytes
2964111 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
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'
}
}
}) |