azils3 commited on
Commit
0f1ea14
·
verified ·
2 Parent(s): 85030bf fe3d026

Merge branch #Yakova/Rectifier' into 'azils3/Tester'

Browse files
App/Generate/Schema.py CHANGED
@@ -3,11 +3,23 @@ from pydantic import BaseModel, HttpUrl
3
  from pydantic import validator
4
 
5
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  class GeneratorRequest(BaseModel):
7
  prompt: str
8
- grok: Optional[bool] = True
9
  batch_size: int = 4
10
- model: str = "llama3-70b-8192"
 
11
 
12
 
13
  class GeneratorBulkRequest(BaseModel):
 
3
  from pydantic import validator
4
 
5
 
6
+ class Scene(BaseModel):
7
+ narration: str
8
+ image_prompts: List[str]
9
+ voice: str
10
+
11
+
12
+ class Story(BaseModel):
13
+ scenes: List[Scene]
14
+ reference_image_url: Optional[str] = None
15
+ ip_adapter_weight: Optional[float] = 0.4 # Add this line
16
+
17
+
18
  class GeneratorRequest(BaseModel):
19
  prompt: str
 
20
  batch_size: int = 4
21
+ grok: bool = False
22
+ model: str = "command"
23
 
24
 
25
  class GeneratorBulkRequest(BaseModel):
App/Generate/Story/Story.py CHANGED
@@ -1,11 +1,12 @@
1
  import json
2
  from pydantic import BaseModel
3
- from typing import List
4
 
5
 
6
  class Scene(BaseModel):
7
  narration: str
8
  image_prompts: List[str]
 
9
 
10
  def num_images(self):
11
  return len(self.image_prompts)
@@ -13,6 +14,9 @@ class Scene(BaseModel):
13
 
14
  class Story(BaseModel):
15
  scenes: List[Scene]
 
 
 
16
 
17
  @classmethod
18
  def from_dict(cls, data):
 
1
  import json
2
  from pydantic import BaseModel
3
+ from typing import List, Optional
4
 
5
 
6
  class Scene(BaseModel):
7
  narration: str
8
  image_prompts: List[str]
9
+ voice: Optional[str] = None
10
 
11
  def num_images(self):
12
  return len(self.image_prompts)
 
14
 
15
  class Story(BaseModel):
16
  scenes: List[Scene]
17
+ voice: Optional[str] = None
18
+ reference_image_url: Optional[str] = None
19
+ ip_adapter_weight: Optional[float] = 0.4
20
 
21
  @classmethod
22
  def from_dict(cls, data):
App/Generate/database/CharacterAPI.py ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import aiohttp
2
+ import asyncio
3
+ import os
4
+ import uuid
5
+ import tempfile
6
+ from typing import List, Dict, Any
7
+
8
+ from pydantic import BaseModel
9
+
10
+
11
+ class AlignmentData(BaseModel):
12
+ word: str
13
+ start: float
14
+ end: float
15
+
16
+ def to_dict(self) -> dict:
17
+ return {
18
+ "word": self.word,
19
+ "alignedWord": self.word,
20
+ "startTime": self.start,
21
+ "endTime": self.end,
22
+ "hasFailedAlignment": False,
23
+ }
24
+
25
+
26
+ class CharacterAITTS:
27
+ def __init__(self):
28
+ self.api_url = "https://yakova-embedding.hf.space"
29
+ self.dir = str(tempfile.mkdtemp())
30
+ self.descript = "https://yakova-embedding.hf.space"
31
+ self.headers = {"Connection": "keep-alive", "Content-Type": "application/json"}
32
+
33
+ async def _make_transcript(self, links, text):
34
+
35
+ data = {"audio_url": links, "text": text, "file_extenstion": ".mp3"}
36
+ response_data = await self._make_request(
37
+ "post", "descript_transcript", json=data, external=self.descript
38
+ )
39
+ if not response_data:
40
+ data["audio_url"] = data["audio_url"][0]
41
+ print(data)
42
+ response_data = await self.aligner(
43
+ "post",
44
+ "align/url",
45
+ json=data,
46
+ )
47
+ print(response_data)
48
+ response_data = self.process_alignments(
49
+ data=response_data["alignment"], offset=0
50
+ )
51
+ return response_data
52
+
53
+ def process_alignments(
54
+ self, data: List[Dict[str, Any]], offset: float = 0
55
+ ) -> List[Dict[str, Any]]:
56
+ alignments = [AlignmentData(**item) for item in data]
57
+ return [alignment.to_dict() for alignment in alignments]
58
+
59
+ async def aligner(
60
+ self,
61
+ method,
62
+ endpoint,
63
+ json=None,
64
+ external="https://yakova-aligner.hf.space/align/url",
65
+ ):
66
+ async with aiohttp.ClientSession() as session:
67
+ if external:
68
+ url = f"{external}"
69
+ else:
70
+ url = f"{self.api_url}/{endpoint}"
71
+ async with getattr(session, method)(url=url, json=json) as response:
72
+ return await response.json()
73
+
74
+ async def _make_request(self, method, endpoint, json=None, external=None):
75
+ async with aiohttp.ClientSession() as session:
76
+ if external:
77
+ url = f"{external}/{endpoint}"
78
+ else:
79
+ url = f"{self.api_url}/{endpoint}"
80
+ async with getattr(session, method)(url=url, json=json) as response:
81
+ return await response.json()
82
+
83
+ async def say(self, text, speaker=None):
84
+
85
+ data = {"text": text, "voice": speaker}
86
+
87
+ response_data = await self._make_request("post", "cai_tts", json=data)
88
+ # print(response_data)
89
+ audio_url = response_data["audio"]
90
+ temp = await self.download_file(audio_url)
91
+ return audio_url, temp
92
+
93
+ async def download_file(self, url):
94
+ filename = str(uuid.uuid4()) + ".mp3"
95
+ os.makedirs(self.dir, exist_ok=True)
96
+ save_path = os.path.join(self.dir, filename)
97
+ async with aiohttp.ClientSession() as session:
98
+ async with session.get(url) as response:
99
+ if response.status == 200:
100
+ with open(save_path, "wb") as file:
101
+ while True:
102
+ chunk = await response.content.read(1024)
103
+ if not chunk:
104
+ break
105
+ file.write(chunk)
106
+
107
+ return save_path
108
+
109
+
110
+ # # Usage
111
+ # async def main():
112
+ # tts = CharacterAITTS()
113
+ # url, temp = await tts.say(
114
+ # "Did you know that you don't have the balls to talk to me"
115
+ # )
116
+ # tranny = await tts._make_transcript(
117
+ # links=[url], text="Did you know that you don't have the balls to talk to me"
118
+ # )
119
+ # print(tranny)
120
+
121
+
122
+ # # Run the main function
123
+ # asyncio.run(main())
App/Generate/database/ElevenLab.py CHANGED
@@ -3,6 +3,24 @@ import asyncio
3
  import os
4
  import uuid
5
  import tempfile
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
 
8
  class ElevenLab:
@@ -748,8 +766,41 @@ class ElevenLab:
748
  response_data = await self._make_request(
749
  "post", "descript_transcript", json=data, external=self.descript
750
  )
 
 
 
 
 
 
 
 
 
 
 
 
751
  return response_data
752
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
753
  async def _make_request(self, method, endpoint, json=None, external=None):
754
  async with aiohttp.ClientSession() as session:
755
  if external:
@@ -765,6 +816,7 @@ class ElevenLab:
765
  name = i["name"].split(" ")[0]
766
  if name.lower() == speaker.lower():
767
  voiceId = i["voice_id"]
 
768
  data = {"voiceId": voiceId, "text": text}
769
 
770
  response_data = await self._make_request("post", "convert", json=data)
 
3
  import os
4
  import uuid
5
  import tempfile
6
+ from typing import List, Dict, Any
7
+
8
+ from pydantic import BaseModel
9
+
10
+
11
+ class AlignmentData(BaseModel):
12
+ word: str
13
+ start: float
14
+ end: float
15
+
16
+ def to_dict(self) -> dict:
17
+ return {
18
+ "word": self.word,
19
+ "alignedWord": self.word,
20
+ "startTime": self.start,
21
+ "endTime": self.end,
22
+ "hasFailedAlignment": False,
23
+ }
24
 
25
 
26
  class ElevenLab:
 
766
  response_data = await self._make_request(
767
  "post", "descript_transcript", json=data, external=self.descript
768
  )
769
+ if not response_data:
770
+ data["audio_url"] = data["audio_url"][0]
771
+ print(data)
772
+ response_data = await self.aligner(
773
+ "post",
774
+ "align/url",
775
+ json=data,
776
+ )
777
+ print(response_data)
778
+ response_data = self.process_alignments(
779
+ data=response_data["alignment"], offset=0
780
+ )
781
  return response_data
782
 
783
+ def process_alignments(
784
+ self, data: List[Dict[str, Any]], offset: float = 0
785
+ ) -> List[Dict[str, Any]]:
786
+ alignments = [AlignmentData(**item) for item in data]
787
+ return [alignment.to_dict() for alignment in alignments]
788
+
789
+ async def aligner(
790
+ self,
791
+ method,
792
+ endpoint,
793
+ json=None,
794
+ external="https://yakova-aligner.hf.space/align/url",
795
+ ):
796
+ async with aiohttp.ClientSession() as session:
797
+ if external:
798
+ url = f"{external}"
799
+ else:
800
+ url = f"{self.api_url}/{endpoint}"
801
+ async with getattr(session, method)(url=url, json=json) as response:
802
+ return await response.json()
803
+
804
  async def _make_request(self, method, endpoint, json=None, external=None):
805
  async with aiohttp.ClientSession() as session:
806
  if external:
 
816
  name = i["name"].split(" ")[0]
817
  if name.lower() == speaker.lower():
818
  voiceId = i["voice_id"]
819
+ # voiceId = "yl2ZDV1MzN4HbQJbMihG"
820
  data = {"voiceId": voiceId, "text": text}
821
 
822
  response_data = await self._make_request("post", "convert", json=data)
App/Generate/database/Modal.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import aiohttp
2
+ import asyncio
3
+ import json
4
+ from typing import Dict, Any
5
+
6
+
7
+ class ModalImageGenerator:
8
+ def __init__(self, session: aiohttp.ClientSession):
9
+ self.session = session
10
+ self.base_url = (
11
+ "https://allanwatts705--kolors-app-model-web-inference.modal.run/"
12
+ )
13
+
14
+ async def generate_image(
15
+ self,
16
+ prompt: str,
17
+ reference_image_url: str = "https://image.lexica.art/full_webp/d6ddd5c5-060c-4aba-b9d0-cf0e02dc65bd",
18
+ ip_adapter_weight: float = 0.4,
19
+ ) -> Dict[str, Any]:
20
+ params = {
21
+ "ip_adapter_weight": ip_adapter_weight,
22
+ "reference_image_url": reference_image_url,
23
+ "prompt": prompt,
24
+ }
25
+
26
+ async with self.session.get(self.base_url, params=params) as response:
27
+ if response.status == 200:
28
+ return await response.json()
29
+ else:
30
+ raise Exception(f"Failed to generate image: {response.status}")
31
+
32
+ async def wait_for_image(
33
+ self, result: Dict[str, Any], max_attempts: int = 60, delay: int = 5
34
+ ) -> Dict[str, Any]:
35
+ attempts = 0
36
+ while attempts < max_attempts:
37
+ if result.get("image", {}).get("url"):
38
+ return result
39
+ await asyncio.sleep(delay)
40
+ attempts += 1
41
+
42
+ raise Exception("Image generation timed out")
43
+
44
+ async def generate_and_wait(
45
+ self, prompt: str, reference_image_url: str, ip_adapter_weight: float = 0.4
46
+ ) -> str:
47
+ result = await self.generate_image(
48
+ prompt, reference_image_url, ip_adapter_weight
49
+ )
50
+ final_result = await self.wait_for_image(result)
51
+ return final_result["image"]["url"]
App/Generate/database/Model.py CHANGED
@@ -4,13 +4,17 @@ import asyncio, os
4
  import uuid, random
5
  from pydub import AudioSegment
6
  from .DescriptAPI import Speak
7
- from .ElevenLab import ElevenLab
 
 
8
  from .Vercel import AsyncImageGenerator
 
9
  import aiohttp
10
  from typing import List
11
  from pydantic import BaseModel
12
  import tempfile
13
  import json
 
14
 
15
  SUPABASE = os.environ.get("SUPABASE", "RANDOM_STRING")
16
  database_url = SUPABASE
@@ -95,6 +99,7 @@ class Project(orm.Model):
95
 
96
  # generate transcripts
97
  temp = await scene.generate_scene_transcript(offset=self.start)
 
98
  end_word = temp[-1]
99
 
100
  # narration of the story
@@ -113,34 +118,68 @@ class Project(orm.Model):
113
  )
114
  text_stream.extend(temp[:-1])
115
 
116
- ## images and transitions
117
- for image in scene.images:
118
- file_name = str(uuid.uuid4()) + ".png"
119
- self.links.append({"file_name": file_name, "link": image})
120
- image_assets.append(
121
- {
122
- "type": "image",
123
- "name": file_name,
124
- "start": self.start,
125
- "end": self.start + scene.image_duration,
126
- }
127
- )
128
- self.start = self.start + scene.image_duration
129
-
130
- # transitions between images
131
- video_assets.append(
132
- {
133
- "type": "video",
134
- "name": "Effects/" + random.choice(transitions),
135
- "start": self.start - 1,
136
- "end": self.start + 2,
137
- "props": {
138
- "startFrom": 1 * 30,
139
- "endAt": 3 * 30,
140
- "volume": 0,
141
- },
142
- }
143
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
 
145
  self.assets.append({"type": "audio", "sequence": audio_assets})
146
  ## add the images to assets
@@ -160,12 +199,14 @@ class Project(orm.Model):
160
 
161
 
162
  class Scene(orm.Model):
163
- tts = ElevenLab()
 
164
  # eleven = ElevenLab()
165
  tablename = "scenes"
166
  registry = models
167
  fields = {
168
  "id": orm.Integer(primary_key=True),
 
169
  "project": orm.ForeignKey(Project),
170
  "images": orm.JSON(default=None),
171
  "narration": orm.String(max_length=10_000, allow_null=True, default=""),
@@ -186,9 +227,13 @@ class Scene(orm.Model):
186
  transcript = await self.tts._make_transcript(links=links, text=text)
187
  return transform_alignment_data(data=transcript, offset=offset)
188
 
189
- async def generate_scene_data(self):
 
 
190
  # Run narrate() and generate_images() concurrently
191
- await asyncio.gather(self.narrate(), self.generate_images())
 
 
192
  self.calculate_durations()
193
 
194
  async def narrate(self):
@@ -197,12 +242,11 @@ class Scene(orm.Model):
197
  self.narration_link = link
198
 
199
  async def retry_narration_generation(self):
200
- print(self.narration)
201
  retry_count = 0
202
  while retry_count < 3:
203
  try:
204
  return await self.tts.say(
205
- text=self.narration + " master"
206
  ) ### The blanks help to even stuff up.
207
  except Exception as e:
208
  print(f"Failed to generate narration: {e}")
@@ -217,14 +261,23 @@ class Scene(orm.Model):
217
  self.narration_duration = int(len(audio_file) / 1000)
218
  self.image_duration = self.narration_duration / len(self.image_prompts)
219
 
220
- async def generate_images(self):
 
 
 
 
221
  self.images = []
222
  async with aiohttp.ClientSession() as session:
223
- image_generator = AsyncImageGenerator(session)
224
- for payload in self.image_prompts:
225
- result = await image_generator.generate_image(payload)
226
- status = await image_generator.fetch_image_status(result["id"])
227
- self.images.extend(status["output"])
 
 
 
 
 
228
 
229
 
230
  class Transition(orm.Model):
@@ -262,7 +315,7 @@ class BackgroundMusic(orm.Model):
262
  # pass
263
 
264
 
265
- # # # Create the tables
266
  # async def create_tables():
267
  # datas = {
268
  # "narration": "Welcome to a journey through some of history's strangest moments! Get ready to explore the bizarre, the unusual, and the downright weird.",
 
4
  import uuid, random
5
  from pydub import AudioSegment
6
  from .DescriptAPI import Speak
7
+
8
+ # from .ElevenLab import ElevenLab
9
+ from .CharacterAPI import CharacterAITTS
10
  from .Vercel import AsyncImageGenerator
11
+ from .Video3d import VideoGenerator
12
  import aiohttp
13
  from typing import List
14
  from pydantic import BaseModel
15
  import tempfile
16
  import json
17
+ from .Modal import ModalImageGenerator
18
 
19
  SUPABASE = os.environ.get("SUPABASE", "RANDOM_STRING")
20
  database_url = SUPABASE
 
99
 
100
  # generate transcripts
101
  temp = await scene.generate_scene_transcript(offset=self.start)
102
+ await asyncio.sleep(1)
103
  end_word = temp[-1]
104
 
105
  # narration of the story
 
118
  )
119
  text_stream.extend(temp[:-1])
120
 
121
+ sample_image_extension = scene.images[0].split(".")[-1]
122
+
123
+ if sample_image_extension == "mp4":
124
+ ## moving images
125
+ for image in scene.images:
126
+ file_name = str(uuid.uuid4()) + ".mp4"
127
+ self.links.append({"file_name": file_name, "link": image})
128
+ video_assets.append(
129
+ {
130
+ "type": "video",
131
+ "name": file_name,
132
+ "start": self.start,
133
+ "loop": "true",
134
+ "end": self.start + scene.image_duration,
135
+ "props": {
136
+ "volume": 0,
137
+ "startFrom": 1 * 30,
138
+ "endAt": 2.9 * 30,
139
+ "playbackRate": 0.7,
140
+ "style": {
141
+ "transform": "translate(-50%, -50%)",
142
+ "position": "absolute",
143
+ "top": "50%",
144
+ "left": "50%",
145
+ "width": 1920,
146
+ "height": 1080,
147
+ "objectFit": "cover",
148
+ },
149
+ },
150
+ }
151
+ )
152
+ self.start = self.start + scene.image_duration
153
+
154
+ else:
155
+ ## images and transitions
156
+ for image in scene.images:
157
+ file_name = str(uuid.uuid4()) + ".png"
158
+ self.links.append({"file_name": file_name, "link": image})
159
+ image_assets.append(
160
+ {
161
+ "type": "image",
162
+ "name": file_name,
163
+ "start": self.start,
164
+ "end": self.start + scene.image_duration,
165
+ }
166
+ )
167
+ self.start = self.start + scene.image_duration
168
+
169
+ ## transitions between images
170
+ # video_assets.append(
171
+ # {
172
+ # "type": "video",
173
+ # "name": "Effects/" + random.choice(transitions),
174
+ # "start": self.start - 1,
175
+ # "end": self.start + 2,
176
+ # "props": {
177
+ # "startFrom": 1 * 30,
178
+ # "endAt": 3 * 30,
179
+ # "volume": 0,
180
+ # },
181
+ # }
182
+ # )
183
 
184
  self.assets.append({"type": "audio", "sequence": audio_assets})
185
  ## add the images to assets
 
199
 
200
 
201
  class Scene(orm.Model):
202
+ tts = CharacterAITTS()
203
+ voice = ""
204
  # eleven = ElevenLab()
205
  tablename = "scenes"
206
  registry = models
207
  fields = {
208
  "id": orm.Integer(primary_key=True),
209
+ "voice": orm.String(max_length=100, allow_null=True, default=""),
210
  "project": orm.ForeignKey(Project),
211
  "images": orm.JSON(default=None),
212
  "narration": orm.String(max_length=10_000, allow_null=True, default=""),
 
227
  transcript = await self.tts._make_transcript(links=links, text=text)
228
  return transform_alignment_data(data=transcript, offset=offset)
229
 
230
+ async def generate_scene_data(
231
+ self, reference_image_url: str = None, ip_adapter_weight: float = 0.4
232
+ ):
233
  # Run narrate() and generate_images() concurrently
234
+ await asyncio.gather(
235
+ self.narrate(), self.generate_images(reference_image_url, ip_adapter_weight)
236
+ )
237
  self.calculate_durations()
238
 
239
  async def narrate(self):
 
242
  self.narration_link = link
243
 
244
  async def retry_narration_generation(self):
 
245
  retry_count = 0
246
  while retry_count < 3:
247
  try:
248
  return await self.tts.say(
249
+ text=self.narration + " master", speaker=self.voice
250
  ) ### The blanks help to even stuff up.
251
  except Exception as e:
252
  print(f"Failed to generate narration: {e}")
 
261
  self.narration_duration = int(len(audio_file) / 1000)
262
  self.image_duration = self.narration_duration / len(self.image_prompts)
263
 
264
+ async def generate_images(
265
+ self,
266
+ reference_image_url: str = "https://image.lexica.art/full_webp/d6ddd5c5-060c-4aba-b9d0-cf0e02dc65bd",
267
+ ip_adapter_weight: float = 0.4,
268
+ ):
269
  self.images = []
270
  async with aiohttp.ClientSession() as session:
271
+ image_generator = ModalImageGenerator(session)
272
+ for prompt in self.image_prompts:
273
+ try:
274
+ image_url = await image_generator.generate_image(
275
+ prompt, reference_image_url, ip_adapter_weight
276
+ )
277
+ self.images.append(image_url)
278
+ except Exception as e:
279
+ print(f"Failed to generate image for prompt '{prompt}': {str(e)}")
280
+ await asyncio.sleep(1) # Add a small delay between requests
281
 
282
 
283
  class Transition(orm.Model):
 
315
  # pass
316
 
317
 
318
+ # # Create the tables
319
  # async def create_tables():
320
  # datas = {
321
  # "narration": "Welcome to a journey through some of history's strangest moments! Get ready to explore the bizarre, the unusual, and the downright weird.",
App/Generate/database/Vercel.py CHANGED
@@ -1,5 +1,6 @@
1
  import aiohttp, asyncio, pprint
2
  from collections import deque
 
3
 
4
 
5
  class AsyncImageGenerator:
@@ -13,35 +14,56 @@ class AsyncImageGenerator:
13
  try:
14
  url = f"{self.base}/predictions"
15
  data = {
 
 
 
 
 
 
 
 
16
  # "input": {
17
- # "prompt": payload,
18
- # "negative_prompt": "CGI, Unreal, Airbrushed, Digital",
19
  # "width": 1024,
20
- # "height": 1024,
 
 
21
  # "num_outputs": 1,
22
- # "scheduler": "DPM++SDE",
23
- # "num_inference_steps": 30,
24
- # "guidance_scale": 2,
 
25
  # },
26
- "input": {
27
- "width": 1024,
28
- "height": 1536,
29
- "prompt": payload,
30
- "scheduler": "DPMSolver++",
31
- "num_outputs": 1,
32
- "guidance_scale": 3,
33
- "negative_prompt": "doll opened mouth toy, text, sculpture pixar, cartoon, anime, low quality, plastic, 2 heads, 2 faces, poorly drawn, ugly, poorly drawn face, extra arms, extra legs, ugly, bad anatomy, bad fingers, ugly, deformed, noisy, blurry, distorted, grainy, nudity, nude",
34
- # "negative_prompt": "text, watermark, blurry, haze, low contrast, low quality, underexposed, ugly, deformed, boring, bad quality, cartoon, ((disfigured)), ((bad art)), ((deformed)), ((poorly drawn)), ((extra limbs)), ((close up)), ((b&w)), weird colors, blurry, ugly, tiling, poorly drawn hands, poorly drawn feet, poorly drawn face, out of frame, extra limbs, disfigured, body out of frame, blurry, bad anatomy, blurred, watermark, grainy, signature, cut off, draft, low detail, low quality, double face, 2 faces, cropped, ugly, low-res, tiling, grainy, cropped, ostentatious, ugly, oversaturated, grain, low resolution, disfigured, blurry, bad anatomy, disfigured, poorly drawn face, mutant, mutated, extra limb, ugly, poorly drawn hands, missing limbs, blurred, floating limbs, disjointed limbs, deformed hands, blurred, out of focus, long neck, long body, ugly, disgusting, childish, cut off cropped, distorted, imperfect, surreal, bad hands, text, error, extra digit, fewer digits, cropped , worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry, artist name, Lots of hands, extra limbs, extra fingers, conjoined fingers, deformed fingers, old, ugly eyes, imperfect eyes, skewed eyes , unnatural face, stiff face, stiff body, unbalanced body, unnatural body, lacking body, details are not clear, cluttered, details are sticky, details are low, distorted details, ugly hands, imperfect hands, (mutated hands and fingers:1.5), (long body :1.3), (mutation, poorly drawn :1.2) bad hands, fused ha nd, missing hand, disappearing arms, hands, disappearing thigh, disappearing calf, disappearing legs, ui, missing fingers",
35
- "num_inference_steps": 25,
36
- },
37
  # "input": {
38
  # "prompt": payload,
39
  # "aspect_ratio": "9:16",
40
  # "output_quality": 79,
41
  # "negative_prompt": "doll opened mouth toy, text, sculpture pixar, cartoon, anime, low quality, plastic, 2 heads, 2 faces, poorly drawn, ugly, poorly drawn face, extra arms, extra legs, ugly, bad anatomy, bad fingers, ugly, deformed, noisy, blurry, distorted, grainy, nudity, nude",
42
  # },
43
- "path": "models/playgroundai/playground-v2.5-1024px-aesthetic/versions/a45f82a1382bed5c7aeb861dac7c7d191b0fdf74d8d57c4a0e6ed7d4d0bf7d24",
44
- # "path": "models/stability-ai/stable-diffusion-3",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  # "path": "models/lucataco/proteus-v0.4/versions/34a427535a3c45552b94369280b823fcd0e5c9710e97af020bf445c033d4569e",
46
  # "path": "models/lucataco/juggernaut-xl-v9/versions/bea09cf018e513cef0841719559ea86d2299e05448633ac8fe270b5d5cd6777e",
47
  }
@@ -73,6 +95,7 @@ class AsyncImageGenerator:
73
  status["status"] = "404"
74
 
75
  while status["status"] != "succeeded":
 
76
  try:
77
  status = await self._fetch_image_status(image_id)
78
  except Exception as e:
@@ -102,7 +125,9 @@ async def process_images(payloads):
102
  result = await image_generator.generate_image(payload)
103
  status = await image_generator.fetch_image_status(result["id"])
104
  print(status["output"])
105
- results.extend(status["output"])
 
 
106
 
107
  for payload in payloads:
108
  tasks.append(payload)
@@ -118,11 +143,8 @@ async def process_images(payloads):
118
  # # # Example payloads
119
  # payloads = [
120
  # """
121
-
122
- # [Underpainting sketch] [Abstract expressive ginger arcane girl fortune teller portrait] [Detailed room with candles, vines, stars] [Mystical scene with crystal orb, herbs, potions] [Burned paper, beautiful tender elements, mannerism, jewels, detailed eyes, celestial, shadow play, rough textures, light on perfect face, focus on detailed face, smoke, dynamic movement, rim lighting, mystical, magic, complex background, by Lockwood, Kuindzhi, Rockwell] high-quality portrait photography style 8K
123
-
124
-
125
- # """
126
  # ]
127
 
128
 
 
1
  import aiohttp, asyncio, pprint
2
  from collections import deque
3
+ import json
4
 
5
 
6
  class AsyncImageGenerator:
 
14
  try:
15
  url = f"{self.base}/predictions"
16
  data = {
17
+ # "input": {
18
+ # "prompt": payload
19
+ # + """
20
+ # """,
21
+ # # "aspect_ratio": "2:3",
22
+ # "negative_prompt": "text, watermark, blurry, haze, low contrast, low quality, underexposed, ugly, deformed, boring, bad quality, cartoon, ((disfigured)), ((bad art)), ((deformed)), ((poorly drawn)), ((extra limbs)), ((close up)), ((b&w)), weird colors, blurry, ugly, tiling, poorly drawn hands, poorly drawn feet, poorly drawn face, out of frame, extra limbs, disfigured, body out of frame, blurry, bad anatomy, blurred, watermark, grainy, signature, cut off, draft, low detail, low quality, double face, 2 faces, cropped, ugly, low-res, tiling, grainy, cropped, ostentatious, ugly, oversaturated, grain, low resolution, disfigured, blurry, bad anatomy, disfigured, poorly drawn face, mutant, mutated, extra limb, ugly, poorly drawn hands, missing limbs, blurred, floating limbs, disjointed limbs, deformed hands, blurred, out of focus, long neck, long body, ugly, disgusting, childish, cut off cropped, distorted, imperfect, surreal, bad hands, text, error, extra digit, fewer digits, cropped , worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry, artist name, Lots of hands, extra limbs, extra fingers, conjoined fingers, deformed fingers, old, ugly eyes, imperfect eyes, skewed eyes , unnatural face, stiff face, stiff body, unbalanced body, unnatural body, lacking body, details are not clear, cluttered, details are sticky, details are low, distorted details, ugly hands, imperfect hands, (mutated hands and fingers:1.5), (long body :1.3), (mutation, poorly drawn :1.2) bad hands, fused ha nd, missing hand, disappearing arms, hands, disappearing thigh, disappearing calf, disappearing legs, ui, missing fingers",
23
+ # "steps": 28,
24
+ # },
25
  # "input": {
 
 
26
  # "width": 1024,
27
+ # "height": 1536,
28
+ # "prompt": payload,
29
+ # "scheduler": "DPMSolver++",
30
  # "num_outputs": 1,
31
+ # "guidance_scale": 3,
32
+ # "negative_prompt": "doll opened mouth toy, text, sculpture pixar, cartoon, anime, low quality, plastic, 2 heads, 2 faces, poorly drawn, ugly, poorly drawn face, extra arms, extra legs, ugly, bad anatomy, bad fingers, ugly, deformed, noisy, blurry, distorted, grainy, nudity, nude",
33
+ # # "negative_prompt": "text, watermark, blurry, haze, low contrast, low quality, underexposed, ugly, deformed, boring, bad quality, cartoon, ((disfigured)), ((bad art)), ((deformed)), ((poorly drawn)), ((extra limbs)), ((close up)), ((b&w)), weird colors, blurry, ugly, tiling, poorly drawn hands, poorly drawn feet, poorly drawn face, out of frame, extra limbs, disfigured, body out of frame, blurry, bad anatomy, blurred, watermark, grainy, signature, cut off, draft, low detail, low quality, double face, 2 faces, cropped, ugly, low-res, tiling, grainy, cropped, ostentatious, ugly, oversaturated, grain, low resolution, disfigured, blurry, bad anatomy, disfigured, poorly drawn face, mutant, mutated, extra limb, ugly, poorly drawn hands, missing limbs, blurred, floating limbs, disjointed limbs, deformed hands, blurred, out of focus, long neck, long body, ugly, disgusting, childish, cut off cropped, distorted, imperfect, surreal, bad hands, text, error, extra digit, fewer digits, cropped , worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry, artist name, Lots of hands, extra limbs, extra fingers, conjoined fingers, deformed fingers, old, ugly eyes, imperfect eyes, skewed eyes , unnatural face, stiff face, stiff body, unbalanced body, unnatural body, lacking body, details are not clear, cluttered, details are sticky, details are low, distorted details, ugly hands, imperfect hands, (mutated hands and fingers:1.5), (long body :1.3), (mutation, poorly drawn :1.2) bad hands, fused ha nd, missing hand, disappearing arms, hands, disappearing thigh, disappearing calf, disappearing legs, ui, missing fingers",
34
+ # "num_inference_steps": 25,
35
  # },
36
+ # "input": {"workflow_json": payload},
 
 
 
 
 
 
 
 
 
 
37
  # "input": {
38
  # "prompt": payload,
39
  # "aspect_ratio": "9:16",
40
  # "output_quality": 79,
41
  # "negative_prompt": "doll opened mouth toy, text, sculpture pixar, cartoon, anime, low quality, plastic, 2 heads, 2 faces, poorly drawn, ugly, poorly drawn face, extra arms, extra legs, ugly, bad anatomy, bad fingers, ugly, deformed, noisy, blurry, distorted, grainy, nudity, nude",
42
  # },
43
+ "input": {
44
+ "cfg": 2.5,
45
+ # "seed": 42,
46
+ # "image": "https://image.lexica.art/full_webp/e41b87fb-4cc3-43cd-a6e6-f3dbb08c2399",
47
+ # "steps": 28,
48
+ # "width": 1024,
49
+ # "height": 1536,
50
+ # "aspect_ratio": "16:9",
51
+ "prompt": payload,
52
+ # "sampler": "dpmpp_2m_sde_gpu",
53
+ # "scheduler": "karras",
54
+ # "output_format": "png",
55
+ # "output_quality": 95,
56
+ # "negative_prompt": "clouds, people, buildings",
57
+ # "number_of_images": 1,
58
+ # "ip_adapter_weight": 1,
59
+ # "ip_adapter_weight_type": "style transfer precise",
60
+ },
61
+ # "path": "models/fofr/kolors-with-ipadapter/versions/5a1a92b2c0f81813225d48ed8e411813da41aa84e7582fb705d1af46eea36eed",
62
+ # "path": "models/playgroundai/playground-v2.5-1024px-aesthetic/versions/a45f82a1382bed5c7aeb861dac7c7d191b0fdf74d8d57c4a0e6ed7d4d0bf7d24",
63
+ # "path": "models/fofr/any-comfyui-workflow/versions/cd385285ba75685a040afbded7b79814a971f3febf46c5eab7c716e200c784e1",
64
+ # "path": "models/fofr/sd3-explorer/versions/a9f4aebd943ad7db13de8e34debea359d5578d08f128e968f9a36c3e9b0148d4",
65
+ "path": "models/bingbangboom-lab/flux-new-whimscape/versions/2e8de10f217bc56da163a0204cf09f89995eaf643459014803fae79753183682",
66
+ # "path": "models/black-forest-labs/flux-schnell",
67
  # "path": "models/lucataco/proteus-v0.4/versions/34a427535a3c45552b94369280b823fcd0e5c9710e97af020bf445c033d4569e",
68
  # "path": "models/lucataco/juggernaut-xl-v9/versions/bea09cf018e513cef0841719559ea86d2299e05448633ac8fe270b5d5cd6777e",
69
  }
 
95
  status["status"] = "404"
96
 
97
  while status["status"] != "succeeded":
98
+ print(status["status"])
99
  try:
100
  status = await self._fetch_image_status(image_id)
101
  except Exception as e:
 
125
  result = await image_generator.generate_image(payload)
126
  status = await image_generator.fetch_image_status(result["id"])
127
  print(status["output"])
128
+ if type(status["output"]) == list:
129
+ results.extend(status["output"])
130
+ results.append(status["output"])
131
 
132
  for payload in payloads:
133
  tasks.append(payload)
 
143
  # # # Example payloads
144
  # payloads = [
145
  # """
146
+ # comicbook illustration artistic, beautiful Awsome cat
147
+ # """
 
 
 
148
  # ]
149
 
150
 
App/Generate/database/Video3d.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import aiohttp
2
+ import asyncio
3
+ from itertools import chain
4
+
5
+
6
+ class VideoGenerator:
7
+ def __init__(self):
8
+ self.base_urls = [f"https://yakova-depthflow-{i}.hf.space" for i in range(10)]
9
+ self.headers = {"accept": "application/json"}
10
+ self.default_params = {
11
+ "frame_rate": 30,
12
+ "duration": 3,
13
+ "quality": 1,
14
+ "ssaa": 0.8,
15
+ "raw": "false",
16
+ }
17
+
18
+ async def generate_video(self, base_url, params):
19
+ url = f"{base_url}/generate_video"
20
+
21
+ async with aiohttp.ClientSession() as session:
22
+ async with session.post(
23
+ url, params=params, headers=self.headers
24
+ ) as response:
25
+ if response.status == 200:
26
+ data = await response.json()
27
+ output_file = data.get("output_file")
28
+ return output_file
29
+ else:
30
+ print(f"Request to {url} failed with status: {response.status}")
31
+ return None
32
+
33
+ async def check_video_ready(self, base_url, output_file):
34
+ url = f"{base_url}/download/{output_file}"
35
+
36
+ async with aiohttp.ClientSession() as session:
37
+ while True:
38
+ async with session.get(url, headers=self.headers) as response:
39
+ if response.status == 200:
40
+ video_content = await response.read()
41
+ if len(video_content) > 0:
42
+ return url
43
+ else:
44
+ print(
45
+ f"Video {output_file} is ready but the file size is zero, retrying in 10 seconds..."
46
+ )
47
+ await asyncio.sleep(10)
48
+ elif response.status == 404:
49
+ data = await response.json()
50
+ if data.get("detail") == "Video not found":
51
+ print(
52
+ f"Video {output_file} not ready yet, retrying in 10 seconds..."
53
+ )
54
+ await asyncio.sleep(180)
55
+ else:
56
+ print(f"Unexpected response for {output_file}: {data}")
57
+ return None
58
+ else:
59
+ print(f"Request to {url} failed with status: {response.status}")
60
+ return None
61
+
62
+ async def process_image(self, base_url, image_link):
63
+ params = self.default_params.copy()
64
+ params["image_link"] = image_link
65
+
66
+ output_file = await self.generate_video(base_url, params)
67
+ if output_file:
68
+ print(f"Generated video file id: {output_file} for image {image_link}")
69
+ video_url = await self.check_video_ready(base_url, output_file)
70
+ if video_url:
71
+ print(
72
+ f"Video for {image_link} is ready and can be downloaded from: {video_url}"
73
+ )
74
+ return video_url
75
+ else:
76
+ print(f"Failed to get the video URL for {image_link}")
77
+ return None
78
+ else:
79
+ print(f"Failed to generate the video for {image_link}")
80
+ return None
81
+
82
+ def flatten(self, nested_list):
83
+ return list(chain.from_iterable(nested_list))
84
+
85
+ def nest(self, flat_list, nested_dims):
86
+ it = iter(flat_list)
87
+ return [[next(it) for _ in inner_list] for inner_list in nested_dims]
88
+
89
+ async def run(self, nested_image_links):
90
+ flat_image_links = self.flatten(nested_image_links)
91
+ tasks = []
92
+ base_index = 0
93
+
94
+ for image_link in flat_image_links:
95
+ base_url = self.base_urls[base_index % len(self.base_urls)]
96
+ tasks.append(self.process_image(base_url, image_link))
97
+ base_index += 1
98
+
99
+ flat_video_urls = await asyncio.gather(*tasks)
100
+ nested_video_urls = self.nest(flat_video_urls, nested_image_links)
101
+ return nested_video_urls
102
+
103
+
104
+ # # Example usage
105
+ # nested_image_links = [
106
+ # [
107
+ # "https://replicate.delivery/yhqm/mQId1rdf4Z3odCyB7cPsx1KwhHfdRc3w44eYAGNG9AQfV0dMB/out-0.png"
108
+ # ],
109
+ # [
110
+ # "https://replicate.delivery/yhqm/mQId1rdf4Z3odCyB7cPsx1KwhHfdRc3w44eYAGNG9AQfV0dMB/out-1.png",
111
+ # "https://replicate.delivery/yhqm/mQId1rdf4Z3odCyB7cPsx1KwhHfdRc3w44eYAGNG9AQfV0dMB/out-2.png",
112
+ # ],
113
+ # # Add more nested image links here
114
+ # ]
115
+
116
+ # loop = asyncio.get_event_loop()
117
+ # video_generator = VideoGenerator()
118
+ # nested_video_urls = loop.run_until_complete(video_generator.run(nested_image_links))
119
+
120
+ # print("Generated video URLs:", nested_video_urls)
App/Generate/generatorRoutes.py CHANGED
@@ -6,16 +6,29 @@ from .utils.HuggingChat import Hugging
6
  from .Story.Story import Story
7
  import asyncio, pprint, json
8
  from tqdm import tqdm
9
- from .database.Model import models, database_url, Scene, Project, database
 
 
 
 
 
 
 
10
  from .utils.RenderVideo import RenderVideo
11
  from .Prompts.StoryGen import Prompt
12
  from App.Editor.editorRoutes import celery_task, EditorRequest
13
  import uuid
14
 
15
 
16
- async def update_scene(model_scene):
17
- await model_scene.generate_scene_data()
18
- await model_scene.update(**model_scene.__dict__)
 
 
 
 
 
 
19
 
20
 
21
  async def from_dict_generate(data: Story):
@@ -23,38 +36,70 @@ async def from_dict_generate(data: Story):
23
  await generate_assets(generated_story=generated_strory)
24
 
25
 
26
- async def generate_assets(generated_story: Story, batch_size=4):
27
  x = await Project.objects.create(name=str(uuid.uuid4()))
28
 
29
  # Assuming generated_story.scenes is a list of scenes
30
- scene_updates = []
31
  with tqdm(total=len(generated_story.scenes)) as pbar:
 
 
 
32
  for i in range(0, len(generated_story.scenes), batch_size):
33
  batch = generated_story.scenes[
34
  i : i + batch_size
35
  ] # Get a batch of two story scenes
36
  batch_updates = []
37
 
 
38
  for story_scene in batch:
39
  model_scene = await Scene.objects.create(project=x)
40
  model_scene.image_prompts = story_scene.image_prompts
41
  model_scene.narration = story_scene.narration
42
- await model_scene.update(**model_scene.__dict__)
 
 
 
 
 
 
 
 
43
  batch_updates.append(
44
- update_scene(model_scene)
 
 
 
 
45
  ) # Append update coroutine to batch_updates
46
- scene_updates.extend(batch_updates) # Accumulate updates for later awaiting
47
  await asyncio.gather(
48
  *batch_updates
49
  ) # Await update coroutines for this batch
 
50
  pbar.update(len(batch)) # Increment progress bar by the size of the batch
51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  temp = await x.generate_json()
53
  # print(temp)
54
 
55
- # await renderr.render_video(temp)
 
56
  request = EditorRequest.model_validate(temp)
57
- await celery_task(video_task=request)
 
58
 
59
 
60
  async def main(request: GeneratorRequest):
@@ -98,7 +143,7 @@ async def generate_video(
98
 
99
  @generator_router.post("/generate_video_from_json")
100
  async def generate_video_from_json(jsonReq: Story, background_task: BackgroundTasks):
101
- background_task.add_task(from_dict_generate, jsonReq)
102
  return {"task_id": "started"}
103
 
104
 
 
6
  from .Story.Story import Story
7
  import asyncio, pprint, json
8
  from tqdm import tqdm
9
+ from .database.Model import (
10
+ models,
11
+ database_url,
12
+ Scene,
13
+ Project,
14
+ database,
15
+ VideoGenerator,
16
+ )
17
  from .utils.RenderVideo import RenderVideo
18
  from .Prompts.StoryGen import Prompt
19
  from App.Editor.editorRoutes import celery_task, EditorRequest
20
  import uuid
21
 
22
 
23
+ async def update_scene(model_scene, reference_image_url=None, ip_adapter_weight=0.4):
24
+ await model_scene.generate_scene_data(reference_image_url, ip_adapter_weight)
25
+ await model_scene.update(
26
+ **{
27
+ k: v
28
+ for k, v in model_scene.__dict__.items()
29
+ if k not in ["reference_image_url", "ip_adapter_weight"]
30
+ }
31
+ )
32
 
33
 
34
  async def from_dict_generate(data: Story):
 
36
  await generate_assets(generated_story=generated_strory)
37
 
38
 
39
+ async def generate_assets(generated_story: Story, batch_size=4, threeD=True):
40
  x = await Project.objects.create(name=str(uuid.uuid4()))
41
 
42
  # Assuming generated_story.scenes is a list of scenes
 
43
  with tqdm(total=len(generated_story.scenes)) as pbar:
44
+
45
+ all_scenes: list[Scene] = []
46
+ # create the batches
47
  for i in range(0, len(generated_story.scenes), batch_size):
48
  batch = generated_story.scenes[
49
  i : i + batch_size
50
  ] # Get a batch of two story scenes
51
  batch_updates = []
52
 
53
+ # generate pictures or narration per batch
54
  for story_scene in batch:
55
  model_scene = await Scene.objects.create(project=x)
56
  model_scene.image_prompts = story_scene.image_prompts
57
  model_scene.narration = story_scene.narration
58
+ model_scene.voice = story_scene.voice
59
+ await model_scene.update(
60
+ **{
61
+ k: v
62
+ for k, v in model_scene.__dict__.items()
63
+ if k not in ["reference_image_url", "ip_adapter_weight"]
64
+ }
65
+ )
66
+ all_scenes.append(model_scene)
67
  batch_updates.append(
68
+ update_scene(
69
+ model_scene,
70
+ generated_story.reference_image_url,
71
+ generated_story.ip_adapter_weight,
72
+ )
73
  ) # Append update coroutine to batch_updates
74
+ # pause per batch
75
  await asyncio.gather(
76
  *batch_updates
77
  ) # Await update coroutines for this batch
78
+
79
  pbar.update(len(batch)) # Increment progress bar by the size of the batch
80
 
81
+ ###### Here we generate the videos
82
+
83
+ if False:
84
+ vid_gen = VideoGenerator()
85
+ nested_images = []
86
+ for scene in all_scenes:
87
+ nested_images.append(scene.images)
88
+
89
+ results = await vid_gen.run(nested_image_links=nested_images)
90
+ print(results)
91
+ for result, _scene in zip(results, all_scenes):
92
+ _scene.images = result
93
+ await _scene.update(**_scene.__dict__)
94
+
95
  temp = await x.generate_json()
96
  # print(temp)
97
 
98
+ renderr = RenderVideo()
99
+ await renderr.render_video(temp)
100
  request = EditorRequest.model_validate(temp)
101
+ #
102
+ # await celery_task(video_task=request)
103
 
104
 
105
  async def main(request: GeneratorRequest):
 
143
 
144
  @generator_router.post("/generate_video_from_json")
145
  async def generate_video_from_json(jsonReq: Story, background_task: BackgroundTasks):
146
+ background_task.add_task(generate_assets, jsonReq)
147
  return {"task_id": "started"}
148
 
149
 
App/Generate/utils/Cohere.py CHANGED
@@ -22,7 +22,11 @@ class VideoOutput(BaseModel):
22
 
23
  # Patching the Cohere client with the instructor for enhanced capabilities
24
  client = instructor.from_cohere(
25
- cohere.Client(os.environ.get("COHERE_API", "RANDOM_STRING")),
 
 
 
 
26
  # max_tokens=5000,
27
  model="command-r-plus",
28
  )
@@ -36,7 +40,7 @@ def chatbot(prompt: str, model: str = "command-r-plus"):
36
 
37
  response: VideoOutput = client.chat.completions.create(
38
  model=model,
39
- max_tokens=5000,
40
  response_model=VideoOutput,
41
  messages=[
42
  {
@@ -46,3 +50,6 @@ def chatbot(prompt: str, model: str = "command-r-plus"):
46
  ],
47
  )
48
  return response.dict()
 
 
 
 
22
 
23
  # Patching the Cohere client with the instructor for enhanced capabilities
24
  client = instructor.from_cohere(
25
+ cohere.Client(
26
+ os.environ.get(
27
+ "COHERE_API",
28
+ )
29
+ ),
30
  # max_tokens=5000,
31
  model="command-r-plus",
32
  )
 
40
 
41
  response: VideoOutput = client.chat.completions.create(
42
  model=model,
43
+ # max_tokens=5000,
44
  response_model=VideoOutput,
45
  messages=[
46
  {
 
50
  ],
51
  )
52
  return response.dict()
53
+
54
+
55
+ # print(chatbot("A horror story"))
App/Generate/utils/RenderVideo.py CHANGED
@@ -2,7 +2,9 @@ import aiohttp, json
2
 
3
 
4
  class RenderVideo:
5
- def __init__(self, url="https://yakova-rectifier.hf.space/create-video"):
 
 
6
  self.url = url
7
 
8
  @staticmethod
 
2
 
3
 
4
  class RenderVideo:
5
+ def __init__(
6
+ self, url="https://mbonea-mjema--rectifier-run-rectifier.modal.run/create-video"
7
+ ):
8
  self.url = url
9
 
10
  @staticmethod
App/Worker.py CHANGED
@@ -284,7 +284,7 @@ async def cleanup_temp_directory(
284
 
285
  # @celery.task(name="All")
286
  async def celery_task(video_task: EditorRequest):
287
- remotion_app_dir = os.path.join("/srv", "Remotion-app")
288
  project_id = str(uuid.uuid4())
289
  temp_dir = f"/tmp/{project_id}"
290
  output_dir = f"/tmp/{project_id}/out/video.mp4"
 
284
 
285
  # @celery.task(name="All")
286
  async def celery_task(video_task: EditorRequest):
287
+ remotion_app_dir = os.path.join("./", "Remotion-app")
288
  project_id = str(uuid.uuid4())
289
  temp_dir = f"/tmp/{project_id}"
290
  output_dir = f"/tmp/{project_id}/out/video.mp4"
App/app.py CHANGED
@@ -15,12 +15,14 @@ manager = WorkerClient()
15
 
16
  @app.on_event("startup")
17
  async def startup_event():
 
18
  app.state.db = database
19
  app.state.models = models
20
-
21
  try:
22
  # print(type(database.url), database_url)
23
  # await models.create_all()
 
24
  await models._create_all(str(database.url))
25
  except:
26
  print("failed to create")
@@ -30,7 +32,7 @@ async def startup_event():
30
  await database.connect()
31
  # await database.execute("pragma journal_mode=wal;")
32
 
33
- await bot.start()
34
  # if SERVER_STATE.MASTER:
35
 
36
  # response = await manager.register_worker()
 
15
 
16
  @app.on_event("startup")
17
  async def startup_event():
18
+ print("StartUp running")
19
  app.state.db = database
20
  app.state.models = models
21
+
22
  try:
23
  # print(type(database.url), database_url)
24
  # await models.create_all()
25
+ print("Error registering worker")
26
  await models._create_all(str(database.url))
27
  except:
28
  print("failed to create")
 
32
  await database.connect()
33
  # await database.execute("pragma journal_mode=wal;")
34
 
35
+ # await bot.start()
36
  # if SERVER_STATE.MASTER:
37
 
38
  # response = await manager.register_worker()
Dockerfile CHANGED
@@ -71,7 +71,7 @@ COPY --chown=admin . /srv
71
  RUN chown -R admin:admin /srv
72
  RUN chmod 755 /srv
73
  USER admin
74
- CMD python -m uvicorn App.app:app --workers 1 --host 0.0.0.0 --port 7860
75
 
76
  # Expose port
77
  EXPOSE 7860
 
71
  RUN chown -R admin:admin /srv
72
  RUN chmod 755 /srv
73
  USER admin
74
+ CMD python -m uvicorn App.app:app --workers 1 --host 0.0.0.0 --port 7860 --log-level debug
75
 
76
  # Expose port
77
  EXPOSE 7860
Remotion-app/package.json CHANGED
@@ -17,8 +17,6 @@
17
  "@remotion/transitions": "4.0.147",
18
  "@remotion/zod-types": "4.0.147",
19
  "@remotion/tailwind": "4.0.147",
20
- "class-variance-authority": "^0.7.0",
21
- "clsx": "^2.1.0",
22
  "react": "^18.0.0",
23
  "react-dom": "^18.0.0",
24
  "remotion": "4.0.147",
 
17
  "@remotion/transitions": "4.0.147",
18
  "@remotion/zod-types": "4.0.147",
19
  "@remotion/tailwind": "4.0.147",
 
 
20
  "react": "^18.0.0",
21
  "react-dom": "^18.0.0",
22
  "remotion": "4.0.147",
Remotion-app/remotion.config.js CHANGED
@@ -12,4 +12,4 @@ Config.overrideWebpackConfig((currentConfiguration) => {
12
 
13
  //Config.setBrowserExecutable("/usr/bin/chrome-headless-shell");
14
  Config.setVideoImageFormat('jpeg');
15
- // Config.setConcurrency(2);
 
12
 
13
  //Config.setBrowserExecutable("/usr/bin/chrome-headless-shell");
14
  Config.setVideoImageFormat('jpeg');
15
+ Config.setConcurrency(1);
Remotion-app/src/HelloWorld/TextStream.jsx CHANGED
@@ -43,6 +43,7 @@ const TextStream = React.memo(() => {
43
  backgroundColor: 'transparent',
44
  justifyContent: 'center',
45
  alignItems: 'center',
 
46
  }}
47
  >
48
  {memoizedTranscriptData.map((entry, index) => {
 
43
  backgroundColor: 'transparent',
44
  justifyContent: 'center',
45
  alignItems: 'center',
46
+ zIndex: 2,
47
  }}
48
  >
49
  {memoizedTranscriptData.map((entry, index) => {
Remotion-app/src/HelloWorld/VideoStream.jsx CHANGED
@@ -1,4 +1,4 @@
1
- import {Series} from 'remotion';
2
  import React from 'react';
3
  import {Video, staticFile, useVideoConfig} from 'remotion';
4
  import videoSequences from './Assets/VideoSequences.json';
@@ -30,14 +30,20 @@ const VideoStream = React.memo(() => {
30
 
31
  const VideoX = React.memo(({entry}) => {
32
  const {fps} = useVideoConfig();
 
 
 
 
 
 
 
 
 
 
33
  return (
34
- <Video
35
- pauseWhenBuffering
36
- startFrom={(fps * entry.props.startFrom) / 30}
37
- endAt={(fps * entry.props.endAt) / 30}
38
- volume={(fps * entry.props.volume) / 30}
39
- src={staticFile(entry.name)}
40
- />
41
  );
42
  });
43
 
 
1
+ import {Loop} from 'remotion';
2
  import React from 'react';
3
  import {Video, staticFile, useVideoConfig} from 'remotion';
4
  import videoSequences from './Assets/VideoSequences.json';
 
30
 
31
  const VideoX = React.memo(({entry}) => {
32
  const {fps} = useVideoConfig();
33
+ const videoProps = {
34
+ pauseWhenBuffering: true,
35
+ startFrom: (fps * entry.props.startFrom) / 30,
36
+ endAt: (fps * entry.props.endAt) / 30,
37
+ volume: (fps * entry.props.volume) / 30,
38
+ src: staticFile(entry.name),
39
+ style: entry?.style ? entry.style : {},
40
+ playbackRate: entry.props.playbackRate ? entry.props.playbackRate : 1,
41
+ };
42
+
43
  return (
44
+ <>
45
+ {entry?.loop ? <Video loop {...videoProps} /> : <Video {...videoProps} />}
46
+ </>
 
 
 
 
47
  );
48
  });
49