shigeru saito commited on
Commit
d9cbe91
·
1 Parent(s): 9a2372b

スレッドセーフに修正、動画ソート順不具合修正

Browse files
Files changed (1) hide show
  1. app.py +30 -29
app.py CHANGED
@@ -48,6 +48,7 @@ class Replicate:
48
  self.output_url = None
49
  self.response = None
50
  self.prediction_id = None
 
51
 
52
  def run_replicate(self, retries=0):
53
  try:
@@ -128,9 +129,10 @@ class Replicate:
128
  print(traceback.format_exc())
129
 
130
  def download_and_save(self, url, file_path):
131
- response = requests.get(url)
132
- with open(file_path, "wb") as f:
133
- f.write(response.content)
 
134
 
135
  def print_thread_info(self, start_time, end_time, duration):
136
  print(f"Thread {self.index} output_url: {self.output_url}")
@@ -165,7 +167,7 @@ class Video(Replicate):
165
 
166
  class Music(Replicate):
167
 
168
- def __init__(self, id, client: Client, args):
169
  super().__init__(id, client, args)
170
  self.REPLICATE_MODEL_PATH = "facebookresearch/musicgen"
171
  self.REPLICATE_MODEL_VERSION = "f8578df960c345df7bc1f85dd152c5ae0b57ce45a6fc09511c467a62ad820ba3",
@@ -174,7 +176,7 @@ class Music(Replicate):
174
 
175
  self.file_path_format = "assets/{id}/{class_name}_{index}_request_{prediction_id}.mp3"
176
  self.file_path = None
177
- self.duration = args.get("")
178
  self.input = {
179
  "model_version": "large",
180
  "prompt": self.prompt,
@@ -229,9 +231,10 @@ class ThreadController:
229
  for token_index, token in enumerate(REPLICATE_API_TOKEN_LIST):
230
  client = Client()
231
  client.api_token = token
 
232
  self.replicate_client_list[token] = client
233
  if token_index == 0:
234
- self.music = Music(self.id, client, args)
235
  self.music.duration = self.duration
236
 
237
  for index, scene in enumerate(scenes):
@@ -239,7 +242,7 @@ class ThreadController:
239
  video = Video(self.id, client, args, scene, index)
240
  self.videos.append(video)
241
 
242
- # client.api_token_index = (token_index + 1) % len(REPLICATE_API_TOKEN_LIST)
243
 
244
  def run_threads(self):
245
 
@@ -265,7 +268,7 @@ class ThreadController:
265
 
266
  def merge_videos(self):
267
  clips = []
268
- for video in self.videos:
269
  video_path = Path(video.file_path)
270
  if video_path.exists():
271
  clips.append(VideoFileClip(video.file_path))
@@ -294,10 +297,12 @@ class ThreadController:
294
  # Trimming the final audio segment to match the video duration exactly
295
  final_audio_segment = final_audio_segment[:int(video_duration * 1000)]
296
 
297
- temp_audio_path = "/tmp/temp_audio.mp3"
298
 
299
  # Saving the final audio as a temporary WAV file
300
- final_audio_segment.export(temp_audio_path, format="mp3")
 
 
301
 
302
  # Loading the temporary audio file as a MoviePy AudioFileClip
303
  final_audio_clip = AudioFileClip(temp_audio_path)
@@ -305,14 +310,11 @@ class ThreadController:
305
  # Setting the audio to the video
306
  final_video_clip = video_clip.set_audio(final_audio_clip)
307
 
308
- # Path to save the final video with audio (different name to avoid confusion)
309
- output_path_with_audio_fixed = "/tmp/final_video_with_audio_fixed.mp4"
310
-
311
- # Saving the final video with audio
312
- final_video_clip.write_videofile(output_path_with_audio_fixed, codec="libx264", audio_codec="aac")
313
 
314
- # Path to the final video with audio (fixed version)
315
- output_path_with_audio_fixed
316
 
317
  os.makedirs(f"videos/{self.id}/", exist_ok=True)
318
  output_path = f"videos/{self.id}/final_concatenated_video_{self.id}.mp4"
@@ -321,6 +323,10 @@ class ThreadController:
321
 
322
  import shutil
323
  shutil.move(output_path_with_audio_fixed, output_path)
 
 
 
 
324
 
325
  return output_path
326
 
@@ -468,6 +474,11 @@ if __name__ == "__main__":
468
  NajiminoAI.generate("伝統工芸と最新技術の融合")
469
  else:
470
 
 
 
 
 
 
471
  iface = gr.Interface(
472
  fn=NajiminoAI.generate,
473
  # inputs=gr.Textbox(label=inputs_label),
@@ -477,8 +488,8 @@ if __name__ == "__main__":
477
  ],
478
  # title=title,
479
  inputs=gr.inputs.Textbox(lines=2, placeholder="Enter your prompt"),
480
- title="Video Generator",
481
- description="Generate a video based on the text prompt you enter.",
482
  examples=[
483
  ["侍たちは野を超え山を超え、敵軍大将を討ち取り、天下の大将軍となった!"],
484
  ["子どもたちが笑ったり怒ったり泣いたり楽しんだりする"],
@@ -487,13 +498,3 @@ if __name__ == "__main__":
487
  )
488
  iface.launch()
489
 
490
- # import replicate
491
- # import os
492
- # token = os.environ.get("REPLICATE_API_TOKEN")
493
- # os.environ["REPLICATE_API_TOKEN"] = token
494
- # print(f"token: {token}")
495
- # output = replicate.run(
496
- # "facebookresearch/musicgen:7a76a8258b23fae65c5a22debb8841d1d7e816b75c2f24218cd2bd8573787906",
497
- # input={"model_version": "melody"}
498
- # )
499
- # print(output)
 
48
  self.output_url = None
49
  self.response = None
50
  self.prediction_id = None
51
+ self.lock = threading.Lock()
52
 
53
  def run_replicate(self, retries=0):
54
  try:
 
129
  print(traceback.format_exc())
130
 
131
  def download_and_save(self, url, file_path):
132
+ with self.lock: # ロックを取得
133
+ response = requests.get(url)
134
+ with open(file_path, "wb") as f:
135
+ f.write(response.content)
136
 
137
  def print_thread_info(self, start_time, end_time, duration):
138
  print(f"Thread {self.index} output_url: {self.output_url}")
 
167
 
168
  class Music(Replicate):
169
 
170
+ def __init__(self, id, client: Client, args, duration):
171
  super().__init__(id, client, args)
172
  self.REPLICATE_MODEL_PATH = "facebookresearch/musicgen"
173
  self.REPLICATE_MODEL_VERSION = "f8578df960c345df7bc1f85dd152c5ae0b57ce45a6fc09511c467a62ad820ba3",
 
176
 
177
  self.file_path_format = "assets/{id}/{class_name}_{index}_request_{prediction_id}.mp3"
178
  self.file_path = None
179
+ self.duration = duration
180
  self.input = {
181
  "model_version": "large",
182
  "prompt": self.prompt,
 
231
  for token_index, token in enumerate(REPLICATE_API_TOKEN_LIST):
232
  client = Client()
233
  client.api_token = token
234
+ client.api_token_index = 0
235
  self.replicate_client_list[token] = client
236
  if token_index == 0:
237
+ self.music = Music(self.id, client, args, self.duration)
238
  self.music.duration = self.duration
239
 
240
  for index, scene in enumerate(scenes):
 
242
  video = Video(self.id, client, args, scene, index)
243
  self.videos.append(video)
244
 
245
+ client.api_token_index = (token_index + 1) % len(REPLICATE_API_TOKEN_LIST)
246
 
247
  def run_threads(self):
248
 
 
268
 
269
  def merge_videos(self):
270
  clips = []
271
+ for video in sorted(self.videos, key=lambda x: x.index):
272
  video_path = Path(video.file_path)
273
  if video_path.exists():
274
  clips.append(VideoFileClip(video.file_path))
 
297
  # Trimming the final audio segment to match the video duration exactly
298
  final_audio_segment = final_audio_segment[:int(video_duration * 1000)]
299
 
300
+ import tempfile
301
 
302
  # Saving the final audio as a temporary WAV file
303
+ with tempfile.NamedTemporaryFile(suffix='.mp3', delete=False) as f:
304
+ temp_audio_path = f.name
305
+ final_audio_segment.export(temp_audio_path, format="mp3")
306
 
307
  # Loading the temporary audio file as a MoviePy AudioFileClip
308
  final_audio_clip = AudioFileClip(temp_audio_path)
 
310
  # Setting the audio to the video
311
  final_video_clip = video_clip.set_audio(final_audio_clip)
312
 
313
+ # Saving the final video with audio to a temporary file
314
+ with tempfile.NamedTemporaryFile(suffix='.mp4', delete=False) as f:
315
+ output_path_with_audio_fixed = f.name
316
+ final_video_clip.write_videofile(output_path_with_audio_fixed, codec="libx264", audio_codec="aac")
 
317
 
 
 
318
 
319
  os.makedirs(f"videos/{self.id}/", exist_ok=True)
320
  output_path = f"videos/{self.id}/final_concatenated_video_{self.id}.mp4"
 
323
 
324
  import shutil
325
  shutil.move(output_path_with_audio_fixed, output_path)
326
+
327
+ # Delete the temporary files
328
+ os.remove(temp_audio_path)
329
+ shutil.rmtree(f"assets/{self.id}/")
330
 
331
  return output_path
332
 
 
474
  NajiminoAI.generate("伝統工芸と最新技術の融合")
475
  else:
476
 
477
+ description = """
478
+ 入力されたテキストプロンプトに基づ��てビデオを生成します。
479
+ Generate a video based on the text prompt you enter.
480
+ """
481
+
482
  iface = gr.Interface(
483
  fn=NajiminoAI.generate,
484
  # inputs=gr.Textbox(label=inputs_label),
 
488
  ],
489
  # title=title,
490
  inputs=gr.inputs.Textbox(lines=2, placeholder="Enter your prompt"),
491
+ title="najimino Video Generator (β)",
492
+ description=description,
493
  examples=[
494
  ["侍たちは野を超え山を超え、敵軍大将を討ち取り、天下の大将軍となった!"],
495
  ["子どもたちが笑ったり怒ったり泣いたり楽しんだりする"],
 
498
  )
499
  iface.launch()
500