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'
    }
  }
})