File size: 2,917 Bytes
82d1e90
 
 
 
 
 
 
 
 
 
 
5443f48
82d1e90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5443f48
82d1e90
5443f48
82d1e90
 
 
5443f48
82d1e90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5443f48
82d1e90
 
 
 
5443f48
82d1e90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { useEffect, useRef } from "react"
import { useFilePicker } from "use-file-picker"
import { FileContent } from "use-file-picker/dist/interfaces"
import { ClapProject, updateClap } from "@aitube/clap"

import { useStore } from "../../app/store"
import { useProcessors } from "./useProcessors"

export function useImportClap() {

  const setError = useStore(s => s.setError)
  const setFullClap = useStore(s => s.setFullClap)
  const loadClap = useStore(s => s.loadClap)

  const {
    generateMusic,
    generateVideos,
    generateFinalVideo,
  } = useProcessors()

  const importStory = async (fileData: FileContent<ArrayBuffer>): Promise<{
    clap: ClapProject
    regenerateVideo: boolean
  }> => {
    if (!fileData?.name) { throw new Error(`invalid file (missing file name)`) }

    const {
      setParseGenerationStatus,
    } = useStore.getState()

    setParseGenerationStatus("generating")

    try {
      const blob = new Blob([fileData.content])
      const res = await loadClap(blob, fileData.name)

      if (!res?.clap) { throw new Error(`failed to load the clap file`) }

      setParseGenerationStatus("finished")
      return res
    } catch (err) {
      console.error("failed to load the Clap file:", err)
      setParseGenerationStatus("error")
      throw err
    }
  }

  const { openFilePicker: openClapFilePicker, filesContent } = useFilePicker({
    accept: '.clap',
    readAs: "ArrayBuffer"
  })
  const fileData = filesContent[0]

  useEffect(() => {
    const fn = async () => {
      if (!fileData?.name) { return }

      const { setStatus, setProgress } = useStore.getState()

      setProgress(0)
      setStatus("generating")

      try {
        let { clap, regenerateVideo } = await importStory(fileData)
        
        // clap = await generateSounds(clap)

        // setFullClap(clap)

        console.log("importClap: clap = ", clap)

        // it is important to skip regeneration if we already have a video
        if (regenerateVideo) {
          console.log(`importClap: regenerating music and videos..`)
          const claps = await Promise.all([
            generateMusic(clap),
            generateVideos(clap)
          ])

          // console.log("finished processing the 2 tasks in parallel")

          for (const newerClap of claps) {
            clap = await updateClap(clap, newerClap, {
              overwriteMeta: false,
              inlineReplace: true,
            })
          }


          setFullClap(clap)

          await generateFinalVideo(clap)

        } else {
          console.log(`importClap: skipping music and video regeneration`)
        }

        setStatus("finished")
        setProgress(100)
        setError("")
      } catch (err) {
        console.error(`failed to import: `, err)
        setStatus("error")
        setError(`${err}`)
      }
     
    }
    fn()
  }, [fileData?.name])

  return { openClapFilePicker }
}