ishworrsubedii commited on
Commit
98173c8
·
1 Parent(s): 371c310

update: dynamic image url + music + resources

Browse files
app.py CHANGED
@@ -1,7 +1,6 @@
1
  import os
2
- import tempfile
3
 
4
- from fastapi import FastAPI, File, UploadFile
5
  from pydantic import BaseModel
6
  from starlette.responses import JSONResponse
7
  from supabase import create_client
@@ -38,40 +37,56 @@ class VideoGenerator(BaseModel):
38
  store_name: str
39
 
40
 
41
- @app.post("/create-video/")
42
- async def create_video(
43
- necklace_image: UploadFile = File(...),
44
- necklace_tryon_image: UploadFile = File(...),
45
- makeup_image: UploadFile = File(...),
46
- clothing_image_1: UploadFile = File(...),
47
- clothing_image_2: UploadFile = File(...)
48
- ):
 
 
49
  try:
50
- def save_temp_file(file: UploadFile) -> str:
51
- temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".png")
52
- temp_file.write(file.file.read())
53
- return temp_file.name
 
 
 
 
 
 
 
 
54
 
 
 
 
55
  temp_files = {
56
- 'necklace': save_temp_file(necklace_image),
57
- 'necklace_tryon': save_temp_file(necklace_tryon_image),
58
- 'makeup': save_temp_file(makeup_image),
59
- 'clothing1': save_temp_file(clothing_image_1),
60
- 'clothing2': save_temp_file(clothing_image_2)
61
  }
62
 
 
 
 
 
 
63
  intro_path = f"{RESOURCES_DIR}/intro/ChamundiJewelsMandir_intro.mp4"
64
  output_path = f"{RESOURCES_DIR}/temp_video/video_{os.urandom(8).hex()}.mp4"
65
  font_path = f"{RESOURCES_DIR}/fonts/PlayfairDisplay-VariableFont_wght.ttf"
66
- audio_path = f"{RESOURCES_DIR}/audio/background.mp3"
67
 
68
  video_creator = VideoCreator(
69
  intro_video_path=intro_path,
70
  necklace_image=temp_files['necklace'],
71
- nto_image1=temp_files['necklace_tryon'],
72
- nto_cto_1=temp_files['clothing1'],
73
- nto_cto_2=temp_files['clothing2'],
74
- makeup_1=temp_files['makeup'],
75
  font_path=font_path,
76
  output_path=output_path,
77
  audio_path=audio_path
@@ -80,23 +95,37 @@ async def create_video(
80
  # Generate video
81
  video_creator.create_final_video()
82
 
83
- # Clean up temp files
84
- for temp_file in temp_files.values():
85
- if os.path.exists(temp_file):
86
- os.unlink(temp_file)
87
-
88
  url = upload_to_supabase(video_path=output_path)
89
- response = {"status": "success",
90
- "message": "Video created successfully",
91
- "public_url": url
92
- }
93
- os.remove(output_path)
 
 
 
 
 
 
 
 
94
 
 
95
  return JSONResponse(content=response, status_code=200)
96
 
97
  except Exception as e:
98
- return JSONResponse(content={"status": "error", "message": "Please try again", "error": str(e)},
99
- status_code=500)
 
 
 
 
 
 
 
 
 
100
 
101
 
102
  if __name__ == "__main__":
 
1
  import os
 
2
 
3
+ from fastapi import FastAPI
4
  from pydantic import BaseModel
5
  from starlette.responses import JSONResponse
6
  from supabase import create_client
 
37
  store_name: str
38
 
39
 
40
+ import requests
41
+ import tempfile
42
+
43
+
44
+ def download_image(url):
45
+ """
46
+ Download an image from the web and save it as a temporary file.
47
+ :param url: URL of the image.
48
+ :return: Path to the temporary file.
49
+ """
50
  try:
51
+ response = requests.get(url, stream=True)
52
+ response.raise_for_status()
53
+
54
+ temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".png")
55
+ with open(temp_file.name, 'wb') as f:
56
+ for chunk in response.iter_content(chunk_size=8192):
57
+ f.write(chunk)
58
+ return temp_file.name
59
+ except Exception as e:
60
+ print(f"Error downloading image from {url}: {str(e)}")
61
+ return None
62
+
63
 
64
+ @app.post("/create-video/")
65
+ async def create_video(request: VideoGenerator):
66
+ try:
67
  temp_files = {
68
+ 'necklace': download_image(request.necklace_image),
69
+ 'necklace_tryon': [download_image(url) for url in request.necklace_try_on_output_images],
70
+ 'clothing': [download_image(url) for url in request.clothing_output_images],
71
+ 'makeup': [download_image(url) for url in request.makeup_output_images]
 
72
  }
73
 
74
+ if any(file is None for files in temp_files.values() for file in
75
+ (files if isinstance(files, list) else [files])):
76
+ return JSONResponse(content={"status": "error", "message": "Failed to download all required images."},
77
+ status_code=400)
78
+
79
  intro_path = f"{RESOURCES_DIR}/intro/ChamundiJewelsMandir_intro.mp4"
80
  output_path = f"{RESOURCES_DIR}/temp_video/video_{os.urandom(8).hex()}.mp4"
81
  font_path = f"{RESOURCES_DIR}/fonts/PlayfairDisplay-VariableFont_wght.ttf"
82
+ audio_path = f"{RESOURCES_DIR}/audio/TraditionalIndianVlogMusic.mp3"
83
 
84
  video_creator = VideoCreator(
85
  intro_video_path=intro_path,
86
  necklace_image=temp_files['necklace'],
87
+ nto_outputs=temp_files['necklace_tryon'],
88
+ nto_cto_outputs=temp_files['clothing'],
89
+ makeup_outputs=temp_files['makeup'],
 
90
  font_path=font_path,
91
  output_path=output_path,
92
  audio_path=audio_path
 
95
  # Generate video
96
  video_creator.create_final_video()
97
 
98
+ # Upload to Supabase
 
 
 
 
99
  url = upload_to_supabase(video_path=output_path)
100
+ response = {
101
+ "status": "success",
102
+ "message": "Video created successfully",
103
+ "public_url": url
104
+ }
105
+
106
+ for files in temp_files.values():
107
+ if isinstance(files, list):
108
+ for file in files:
109
+ if os.path.exists(file):
110
+ os.unlink(file)
111
+ elif os.path.exists(files):
112
+ os.unlink(files)
113
 
114
+ os.remove(output_path)
115
  return JSONResponse(content=response, status_code=200)
116
 
117
  except Exception as e:
118
+ raise e
119
+
120
+
121
+ @app.get("/resources")
122
+ async def get_infromation():
123
+ music = os.listdir(RESOURCES_DIR + "/audio")
124
+ fonts = os.listdir(RESOURCES_DIR + "/fonts")
125
+ intro = os.listdir(RESOURCES_DIR + "/intro")
126
+
127
+ json = {"music": music, "fonts": fonts, "intro": intro}
128
+ return JSONResponse(content=json, status_code=200)
129
 
130
 
131
  if __name__ == "__main__":
resources/audio/TraditionalIndianVlogMusic.mp3 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b290e209d37cdcff0dfeda53d4c7b6fcda1d286f924c47ad68d82ae433b296e2
3
+ size 3133367
src/components/imgs_video.py CHANGED
@@ -27,7 +27,7 @@
27
  # "output_video_path": f"/home/ishwor/Desktop/TCP/Virtual_Makeup/images_to_video/resourcesssss/02_medium_long_haram/output/{self.current_date}_jewelmirror_cjm.mp4",
28
  # "font_path": "/home/ishwor/Desktop/TCP/Virtual_Makeup/images_to_video/resourcesssss/font/PlayfairDisplay-VariableFont_wght.ttf",
29
  # "necklace_image": "/home/ishwor/Desktop/TCP/Virtual_Makeup/images_to_video/resourcesssss/01_lean_short_necklace/necklace_image/KAR2201CR001.png",
30
- # "audio_path": "/home/ishwor/Desktop/TCP/Virtual_Makeup/images_to_video/resourcesssss/audio/Traditional Indian Vlog Music.mp3",
31
  # "transition_duration": 1.0,
32
  # "image_display_duration": 2.5,
33
  # "text_color": "white",
 
27
  # "output_video_path": f"/home/ishwor/Desktop/TCP/Virtual_Makeup/images_to_video/resourcesssss/02_medium_long_haram/output/{self.current_date}_jewelmirror_cjm.mp4",
28
  # "font_path": "/home/ishwor/Desktop/TCP/Virtual_Makeup/images_to_video/resourcesssss/font/PlayfairDisplay-VariableFont_wght.ttf",
29
  # "necklace_image": "/home/ishwor/Desktop/TCP/Virtual_Makeup/images_to_video/resourcesssss/01_lean_short_necklace/necklace_image/KAR2201CR001.png",
30
+ # "audio_path": "/home/ishwor/Desktop/TCP/Virtual_Makeup/images_to_video/resourcesssss/audio/TraditionalIndianVlogMusic.mp3",
31
  # "transition_duration": 1.0,
32
  # "image_display_duration": 2.5,
33
  # "text_color": "white",
src/components/vidgen.py CHANGED
@@ -12,27 +12,31 @@ from moviepy.video.compositing.concatenate import concatenate_videoclips
12
  from moviepy.video.fx.all import resize
13
  from moviepy.video.io.VideoFileClip import VideoFileClip
14
 
 
 
15
 
16
  class VideoCreator:
17
  def __init__(self, intro_video_path, necklace_image, nto_outputs: list, nto_cto_outputs: list, makeup_outputs: list,
18
  font_path,
19
- output_path, audio_path):
 
20
  self.intro_video_path = intro_video_path
21
  self.nto_images_dir = nto_outputs
22
  self.nto_cto_images_dir = nto_cto_outputs
23
- self.makeup_images_dir = [makeup_outputs]
24
  self.output_video_path = output_path
25
  self.font_path = font_path
26
  self.necklace_image = necklace_image
27
  self.audio_path = audio_path
28
- self.transition_duration = 1.0
29
- self.image_display_duration = 2.5
30
- self.text_color = 'white'
31
- self.box_color = (131, 42, 48)
32
- self.box_opacity = 0.8
33
- self.font_size = 28
34
- self.category_font_size = 70
35
- self.necklace_display_duration = 2.0
 
36
 
37
  def create_necklace_clips(self, necklace_image_path, backgrounds=None):
38
  if backgrounds is None:
@@ -84,6 +88,7 @@ class VideoCreator:
84
  # Create background box
85
  w, h = 1080, 120 if is_category else 80
86
  box = ColorClip((w, h), col=self.box_color, duration=duration)
 
87
  box = box.set_opacity(self.box_opacity)
88
 
89
  # Create text using TextClip with method='label' instead of default
@@ -127,6 +132,7 @@ class VideoCreator:
127
 
128
  def process_images_in_directory(self, directory, font_path, duration, category_name):
129
  clips = []
 
130
 
131
  for image_file in sorted(directory):
132
  if image_file.lower().endswith((".png", ".jpg", ".jpeg", ".webp")):
@@ -186,7 +192,7 @@ class VideoCreator:
186
  print("Rendering final temp_video...")
187
  final_video.write_videofile(
188
  self.output_video_path,
189
- fps=1,
190
  codec="libx264",
191
  audio_codec="aac",
192
  bitrate="8000k",
 
12
  from moviepy.video.fx.all import resize
13
  from moviepy.video.io.VideoFileClip import VideoFileClip
14
 
15
+ from resourcesssss.vid_gen import transition_duration
16
+
17
 
18
  class VideoCreator:
19
  def __init__(self, intro_video_path, necklace_image, nto_outputs: list, nto_cto_outputs: list, makeup_outputs: list,
20
  font_path,
21
+ output_path, audio_path, image_display_duration=2.5, box_color: tuple = (131, 42, 48), box_opacity=0.8,
22
+ font_size=28, necklace_display_duration=2.0, text_color="white", fps=1):
23
  self.intro_video_path = intro_video_path
24
  self.nto_images_dir = nto_outputs
25
  self.nto_cto_images_dir = nto_cto_outputs
26
+ self.makeup_images_dir = makeup_outputs
27
  self.output_video_path = output_path
28
  self.font_path = font_path
29
  self.necklace_image = necklace_image
30
  self.audio_path = audio_path
31
+ self.transition_duration = transition_duration
32
+ self.image_display_duration = image_display_duration
33
+ self.text_color = text_color
34
+ self.box_color = box_color
35
+ self.box_opacity = box_opacity
36
+ self.font_size = font_size
37
+ self.category_font_size = font_size
38
+ self.necklace_display_duration = necklace_display_duration
39
+ self.fps = fps
40
 
41
  def create_necklace_clips(self, necklace_image_path, backgrounds=None):
42
  if backgrounds is None:
 
88
  # Create background box
89
  w, h = 1080, 120 if is_category else 80
90
  box = ColorClip((w, h), col=self.box_color, duration=duration)
91
+ print("box_opacity", self.box_opacity)
92
  box = box.set_opacity(self.box_opacity)
93
 
94
  # Create text using TextClip with method='label' instead of default
 
132
 
133
  def process_images_in_directory(self, directory, font_path, duration, category_name):
134
  clips = []
135
+ print(directory)
136
 
137
  for image_file in sorted(directory):
138
  if image_file.lower().endswith((".png", ".jpg", ".jpeg", ".webp")):
 
192
  print("Rendering final temp_video...")
193
  final_video.write_videofile(
194
  self.output_video_path,
195
+ fps=self.fps,
196
  codec="libx264",
197
  audio_codec="aac",
198
  bitrate="8000k",