Update app.py
Browse files
app.py
CHANGED
|
@@ -398,7 +398,7 @@ def edit_video_raw(video_path: str) -> str:
|
|
| 398 |
.set_duration(clip.duration) \
|
| 399 |
.set_position((0, 0)) # Positioned at the top
|
| 400 |
|
| 401 |
-
# Laugh meme (2s + freeze + 2s)
|
| 402 |
laugh_files = ["laugh/laugh_one.mp4", "laugh/laugh_two.mp4"]
|
| 403 |
laugh_path = random.choice(laugh_files)
|
| 404 |
if not os.path.exists(laugh_path):
|
|
@@ -410,29 +410,27 @@ def edit_video_raw(video_path: str) -> str:
|
|
| 410 |
if laugh_raw.duration < 4:
|
| 411 |
raise ValueError("Laugh meme must be at least 4 seconds.")
|
| 412 |
|
| 413 |
-
|
| 414 |
-
|
| 415 |
-
|
| 416 |
-
|
| 417 |
-
0,
|
| 418 |
-
CAPTION_H # Positioned below the top caption
|
| 419 |
-
))
|
| 420 |
-
)
|
| 421 |
|
| 422 |
-
|
| 423 |
-
|
| 424 |
-
|
| 425 |
-
|
| 426 |
-
|
| 427 |
-
)
|
| 428 |
-
|
| 429 |
-
|
| 430 |
-
|
| 431 |
-
|
| 432 |
-
|
| 433 |
-
|
| 434 |
-
|
| 435 |
-
|
|
|
|
|
|
|
| 436 |
|
| 437 |
# Mid caption
|
| 438 |
mid_text = random.choice([
|
|
@@ -452,9 +450,16 @@ def edit_video_raw(video_path: str) -> str:
|
|
| 452 |
.set_start(0) \
|
| 453 |
.set_position((0, CAPTION_H + LAUGH_H)) # Positioned below laugh meme
|
| 454 |
|
| 455 |
-
# Main video
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 456 |
main_video_y = CAPTION_H + LAUGH_H + MID_H
|
| 457 |
-
resized_main = clip.resize(height=MAIN_H) # Scale to fit the remaining height
|
| 458 |
main_video_x = (vw - resized_main.w) // 2 if resized_main.w > vw else 0 # Center horizontally if wider than vw
|
| 459 |
main_video = resized_main.set_start(0).set_position((
|
| 460 |
main_video_x,
|
|
@@ -469,7 +474,8 @@ def edit_video_raw(video_path: str) -> str:
|
|
| 469 |
# Final composition
|
| 470 |
final = CompositeVideoClip([
|
| 471 |
caption_clip,
|
| 472 |
-
|
|
|
|
| 473 |
mid_caption_clip,
|
| 474 |
main_video,
|
| 475 |
overlay
|
|
@@ -488,7 +494,6 @@ def edit_video_raw(video_path: str) -> str:
|
|
| 488 |
threads=4,
|
| 489 |
fps=clip.fps
|
| 490 |
)
|
| 491 |
-
|
| 492 |
# Clean up resources
|
| 493 |
clip.close()
|
| 494 |
laugh_raw.close()
|
|
|
|
| 398 |
.set_duration(clip.duration) \
|
| 399 |
.set_position((0, 0)) # Positioned at the top
|
| 400 |
|
| 401 |
+
# Laugh meme (2s + freeze + 2s) between caption and mid caption
|
| 402 |
laugh_files = ["laugh/laugh_one.mp4", "laugh/laugh_two.mp4"]
|
| 403 |
laugh_path = random.choice(laugh_files)
|
| 404 |
if not os.path.exists(laugh_path):
|
|
|
|
| 410 |
if laugh_raw.duration < 4:
|
| 411 |
raise ValueError("Laugh meme must be at least 4 seconds.")
|
| 412 |
|
| 413 |
+
# Make the first 2 seconds of the laugh video silent
|
| 414 |
+
laugh_start = resized_laugh.subclip(0, 2).without_audio().set_position((
|
| 415 |
+
0, CAPTION_H # Positioned below the top caption
|
| 416 |
+
))
|
|
|
|
|
|
|
|
|
|
|
|
|
| 417 |
|
| 418 |
+
# Get the rest of the laugh video with sound
|
| 419 |
+
laugh_with_audio = resized_laugh.subclip(2).set_position((
|
| 420 |
+
0, CAPTION_H # Positioned below the top caption
|
| 421 |
+
))
|
| 422 |
+
|
| 423 |
+
# Freeze frame for laugh (just after 2s of silence)
|
| 424 |
+
freeze_frame = laugh_start.to_ImageClip().set_start(2).set_duration(
|
| 425 |
+
max(0, clip.duration - 4)).set_position((0, CAPTION_H))
|
| 426 |
+
|
| 427 |
+
# Adjust laugh_end to stop before mid caption
|
| 428 |
+
laugh_end = resized_laugh.subclip(laugh_raw.duration - 2).set_position((
|
| 429 |
+
0, CAPTION_H + LAUGH_H # Positioned below the caption and laugh meme
|
| 430 |
+
))
|
| 431 |
+
|
| 432 |
+
# Combine the silent and audible parts of the laugh meme
|
| 433 |
+
laugh_full = concatenate_videoclips([laugh_start, laugh_with_audio])
|
| 434 |
|
| 435 |
# Mid caption
|
| 436 |
mid_text = random.choice([
|
|
|
|
| 450 |
.set_start(0) \
|
| 451 |
.set_position((0, CAPTION_H + LAUGH_H)) # Positioned below laugh meme
|
| 452 |
|
| 453 |
+
# Main video (resize width to 1080px and crop top and bottom)
|
| 454 |
+
resized_main = clip.resize(width=1080)
|
| 455 |
+
if resized_main.h > MAIN_H:
|
| 456 |
+
top_crop = (resized_main.h - MAIN_H) // 2
|
| 457 |
+
bottom_crop = resized_main.h - MAIN_H - top_crop
|
| 458 |
+
resized_main = resized_main.crop(
|
| 459 |
+
y1=top_crop, y2=bottom_crop
|
| 460 |
+
)
|
| 461 |
+
|
| 462 |
main_video_y = CAPTION_H + LAUGH_H + MID_H
|
|
|
|
| 463 |
main_video_x = (vw - resized_main.w) // 2 if resized_main.w > vw else 0 # Center horizontally if wider than vw
|
| 464 |
main_video = resized_main.set_start(0).set_position((
|
| 465 |
main_video_x,
|
|
|
|
| 474 |
# Final composition
|
| 475 |
final = CompositeVideoClip([
|
| 476 |
caption_clip,
|
| 477 |
+
laugh_full, # Replace laugh_start with laugh_full to include both parts
|
| 478 |
+
freeze_frame, laugh_end,
|
| 479 |
mid_caption_clip,
|
| 480 |
main_video,
|
| 481 |
overlay
|
|
|
|
| 494 |
threads=4,
|
| 495 |
fps=clip.fps
|
| 496 |
)
|
|
|
|
| 497 |
# Clean up resources
|
| 498 |
clip.close()
|
| 499 |
laugh_raw.close()
|