saq1b commited on
Commit
e1c9abe
·
verified ·
1 Parent(s): 5f93144

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +51 -73
main.py CHANGED
@@ -88,77 +88,61 @@ async def create_slideshow(image_paths, audio_path, output_path, duration, zoom=
88
  output_path
89
  ]
90
  else:
91
- # Implementation with zoom effect
92
- temp_dir = os.path.dirname(output_path) + "/temp"
93
- os.makedirs(temp_dir, exist_ok=True)
94
-
95
- # Generate a video clip for each image with zoom effect
96
- video_parts = []
97
- try:
98
- for i, img_path in enumerate(image_paths):
99
- out_clip = f"{temp_dir}/clip_{i:03d}.mp4"
100
- video_parts.append(out_clip)
101
-
102
- # Calculate zoompan parameters
103
- fps = 30
104
- frames = duration * fps
105
-
106
- # Start at zoom=1 and gradually increase over time
107
- zoom_expr = f"'1+{zoom_ratio}*t/{duration}'"
108
-
109
- # Center the zoom effect
110
- x_expr = "'iw/2-(iw/zoom/2)'"
111
- y_expr = "'ih/2-(ih/zoom/2)'"
112
-
113
- cmd = [
114
- "ffmpeg",
115
- "-loop", "1",
116
- "-i", img_path,
117
- "-t", str(duration),
118
- "-filter_complex", f"zoompan=z={zoom_expr}:x={x_expr}:y={y_expr}:d={frames}:s='iw:ih':fps={fps}",
119
- "-c:v", "libx264",
120
- "-pix_fmt", "yuv420p",
121
- "-y",
122
- out_clip
123
- ]
124
-
125
- process = await asyncio.create_subprocess_exec(
126
- *cmd,
127
- stdout=asyncio.subprocess.PIPE,
128
- stderr=asyncio.subprocess.PIPE
129
- )
130
- _, stderr = await process.communicate()
131
-
132
- if process.returncode != 0:
133
- print(f"FFmpeg error on clip {i}: {stderr.decode()}")
134
- raise Exception(f"Failed to create zoomed clip {i}")
135
-
136
- # Create a concat file for all the video parts
137
- async with aiofiles.open(concat_file, "w") as f:
138
- for video in video_parts:
139
- await f.write(f"file '{video}'\n")
140
 
141
- # Combine all clips with audio
142
- cmd = [
143
  "ffmpeg",
144
- "-f", "concat",
145
- "-safe", "0",
146
- "-i", concat_file,
147
- "-i", audio_path,
148
- "-c:v", "copy",
149
- "-c:a", "aac",
150
- "-shortest",
151
  "-y",
152
- output_path
153
  ]
154
- except Exception as e:
155
- # Clean up on error
156
- if os.path.exists(temp_dir):
157
- shutil.rmtree(temp_dir)
158
- if os.path.exists(concat_file):
159
- os.remove(concat_file)
160
- raise e
161
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  try:
163
  process = await asyncio.create_subprocess_exec(
164
  *cmd,
@@ -169,10 +153,6 @@ async def create_slideshow(image_paths, audio_path, output_path, duration, zoom=
169
 
170
  if os.path.exists(concat_file):
171
  os.remove(concat_file)
172
-
173
- # Clean up temporary directory if zoom was used
174
- if zoom and os.path.exists(temp_dir):
175
- shutil.rmtree(temp_dir)
176
 
177
  if process.returncode != 0:
178
  print(f"FFmpeg error: {stderr.decode()}")
@@ -182,8 +162,6 @@ async def create_slideshow(image_paths, audio_path, output_path, duration, zoom=
182
  print(f"FFmpeg error: {str(e)}")
183
  if os.path.exists(concat_file):
184
  os.remove(concat_file)
185
- if zoom and os.path.exists(temp_dir):
186
- shutil.rmtree(temp_dir)
187
  return False
188
 
189
  @app.post("/make_slideshow")
 
88
  output_path
89
  ]
90
  else:
91
+ # ffmpeg -loop 1 -framerate 60 -i image.jpg -vf "scale=8000:-1,zoompan=z='zoom+0.001':x=iw/2-(iw/zoom/2):y=ih/2-(ih/zoom/2):d=5*60:s=1920x1280:fps=60" -t 5 -c:v libx264 -pix_fmt yuv420p output.mp4
92
+ # For zoom effect, process each image separately and then concatenate
93
+ temp_videos = []
94
+ zoom_filter = f"zoompan=z='min(zoom+{zoom_ratio},1.5)':x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)':d={duration*60}:s=1920x1080:fps=24"
95
+
96
+ # First create individual video clips with zoom effect for each image
97
+ for i, img_path in enumerate(image_paths):
98
+ temp_video = os.path.join(os.path.dirname(output_path), f"temp_{i:03d}.mp4")
99
+ temp_videos.append(temp_video)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
+ img_cmd = [
 
102
  "ffmpeg",
103
+ "-loop", "1",
104
+ "-i", img_path,
105
+ "-vf", zoom_filter,
106
+ "-t", str(duration),
107
+ "-c:v", "libx264",
108
+ "-pix_fmt", "yuv420p",
 
109
  "-y",
110
+ temp_video
111
  ]
112
+
113
+ img_process = await asyncio.create_subprocess_exec(
114
+ *img_cmd,
115
+ stdout=asyncio.subprocess.PIPE,
116
+ stderr=asyncio.subprocess.PIPE
117
+ )
118
+ img_stdout, img_stderr = await img_process.communicate()
119
+
120
+ if img_process.returncode != 0:
121
+ print(f"FFmpeg error processing image {i}: {img_stderr.decode()}")
122
+ # Clean up already created temp videos
123
+ for vid in temp_videos:
124
+ if os.path.exists(vid):
125
+ os.remove(vid)
126
+ return False
127
+
128
+ # Create a concat file for the temporary videos
129
+ async with aiofiles.open(concat_file, "w") as f:
130
+ for video in temp_videos:
131
+ await f.write(f"file '{video}'\n")
132
+
133
+ # Combine videos with audio
134
+ cmd = [
135
+ "ffmpeg",
136
+ "-f", "concat",
137
+ "-safe", "0",
138
+ "-i", concat_file,
139
+ "-i", audio_path,
140
+ "-c:v", "libx264",
141
+ "-c:a", "aac",
142
+ "-shortest",
143
+ "-y",
144
+ output_path
145
+ ]
146
  try:
147
  process = await asyncio.create_subprocess_exec(
148
  *cmd,
 
153
 
154
  if os.path.exists(concat_file):
155
  os.remove(concat_file)
 
 
 
 
156
 
157
  if process.returncode != 0:
158
  print(f"FFmpeg error: {stderr.decode()}")
 
162
  print(f"FFmpeg error: {str(e)}")
163
  if os.path.exists(concat_file):
164
  os.remove(concat_file)
 
 
165
  return False
166
 
167
  @app.post("/make_slideshow")