Mbonea commited on
Commit
6d59db4
·
1 Parent(s): 768cf04

CharacterAI improvements

Browse files
App/Generate/Story/Story.py CHANGED
@@ -1,6 +1,6 @@
1
  import json
2
  from pydantic import BaseModel
3
- from typing import List
4
 
5
 
6
  class Scene(BaseModel):
@@ -13,6 +13,7 @@ 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):
 
13
 
14
  class Story(BaseModel):
15
  scenes: List[Scene]
16
+ voice: Optional[str] = None
17
 
18
  @classmethod
19
  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/Model.py CHANGED
@@ -4,7 +4,9 @@ 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
  from .Video3d import VideoGenerator
10
  import aiohttp
@@ -196,12 +198,13 @@ class Project(orm.Model):
196
 
197
 
198
  class Scene(orm.Model):
199
- tts = ElevenLab()
200
  # eleven = ElevenLab()
201
  tablename = "scenes"
202
  registry = models
203
  fields = {
204
  "id": orm.Integer(primary_key=True),
 
205
  "project": orm.ForeignKey(Project),
206
  "images": orm.JSON(default=None),
207
  "narration": orm.String(max_length=10_000, allow_null=True, default=""),
@@ -237,7 +240,7 @@ class Scene(orm.Model):
237
  while retry_count < 3:
238
  try:
239
  return await self.tts.say(
240
- text=self.narration + " master"
241
  ) ### The blanks help to even stuff up.
242
  except Exception as e:
243
  print(f"Failed to generate narration: {e}")
 
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
 
198
 
199
 
200
  class Scene(orm.Model):
201
+ tts = CharacterAITTS()
202
  # eleven = ElevenLab()
203
  tablename = "scenes"
204
  registry = models
205
  fields = {
206
  "id": orm.Integer(primary_key=True),
207
+ "voice": orm.String(max_length=100, allow_null=True, default=""),
208
  "project": orm.ForeignKey(Project),
209
  "images": orm.JSON(default=None),
210
  "narration": orm.String(max_length=10_000, allow_null=True, default=""),
 
240
  while retry_count < 3:
241
  try:
242
  return await self.tts.say(
243
+ text=self.narration + " master", speaker=self.voice
244
  ) ### The blanks help to even stuff up.
245
  except Exception as e:
246
  print(f"Failed to generate narration: {e}")
App/Generate/database/Vercel.py CHANGED
@@ -44,15 +44,15 @@ class AsyncImageGenerator:
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,
@@ -62,8 +62,8 @@ class AsyncImageGenerator:
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/stability-ai/stable-diffusion-3",
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
  }
@@ -140,18 +140,18 @@ async def process_images(payloads):
140
  return results
141
 
142
 
143
- # # # Example payloads
144
- # payloads = [
145
- # """
146
- # comicbook illustration artistic, beautiful Awsome cat
147
- # """
148
- # ]
149
 
150
 
151
- # # # Run the asyncio event loop
152
- # async def main():
153
- # results = await process_images(payloads)
154
- # pprint.pprint(results)
155
 
156
 
157
- # asyncio.run(main())
 
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,
 
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
  }
 
140
  return results
141
 
142
 
143
+ # # Example payloads
144
+ payloads = [
145
+ """
146
+ comicbook illustration artistic, beautiful Awsome cat
147
+ """
148
+ ]
149
 
150
 
151
+ # # Run the asyncio event loop
152
+ async def main():
153
+ results = await process_images(payloads)
154
+ pprint.pprint(results)
155
 
156
 
157
+ asyncio.run(main())
App/Generate/generatorRoutes.py CHANGED
@@ -49,6 +49,7 @@ async def generate_assets(generated_story: Story, batch_size=4, threeD=True):
49
  model_scene = await Scene.objects.create(project=x)
50
  model_scene.image_prompts = story_scene.image_prompts
51
  model_scene.narration = story_scene.narration
 
52
  await model_scene.update(**model_scene.__dict__)
53
  all_scenes.append(model_scene)
54
  batch_updates.append(
 
49
  model_scene = await Scene.objects.create(project=x)
50
  model_scene.image_prompts = story_scene.image_prompts
51
  model_scene.narration = story_scene.narration
52
+ model_scene.voice = story_scene.voice
53
  await model_scene.update(**model_scene.__dict__)
54
  all_scenes.append(model_scene)
55
  batch_updates.append(