Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,22 +1,20 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
import subprocess
|
| 3 |
-
import tempfile
|
| 4 |
from pathlib import Path
|
|
|
|
| 5 |
import uuid
|
|
|
|
| 6 |
|
| 7 |
allowed_medias = [".png", ".jpg", ".jpeg", ".bmp", ".gif", ".tiff"]
|
| 8 |
|
| 9 |
-
def
|
| 10 |
-
"""
|
| 11 |
-
Erzeugt ein Video aus mehreren Bildern mit Fade-Übergang zwischen allen Bildern.
|
| 12 |
-
"""
|
| 13 |
if not images:
|
| 14 |
return None, "❌ Keine Bilder ausgewählt"
|
| 15 |
|
| 16 |
temp_dir = tempfile.mkdtemp()
|
| 17 |
clips = []
|
| 18 |
|
| 19 |
-
#
|
| 20 |
for idx, img_path in enumerate(images):
|
| 21 |
clip_file = Path(temp_dir) / f"clip_{idx}.mp4"
|
| 22 |
cmd = [
|
|
@@ -31,28 +29,31 @@ def generate_slideshow_with_fade(images, duration):
|
|
| 31 |
subprocess.run(cmd, check=True)
|
| 32 |
clips.append(clip_file)
|
| 33 |
|
| 34 |
-
#
|
| 35 |
if len(clips) == 1:
|
| 36 |
-
# Nur ein Clip, kein Übergang
|
| 37 |
return str(clips[0]), f"✅ Video erstellt ({len(clips)} Bild)"
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
|
| 57 |
# Gradio UI
|
| 58 |
with gr.Blocks() as demo:
|
|
@@ -68,7 +69,7 @@ with gr.Blocks() as demo:
|
|
| 68 |
|
| 69 |
btn = gr.Button("Video erstellen")
|
| 70 |
btn.click(
|
| 71 |
-
fn=
|
| 72 |
inputs=[img_input, duration_input],
|
| 73 |
outputs=[out_video, status]
|
| 74 |
)
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
import subprocess
|
|
|
|
| 3 |
from pathlib import Path
|
| 4 |
+
import tempfile
|
| 5 |
import uuid
|
| 6 |
+
import shutil
|
| 7 |
|
| 8 |
allowed_medias = [".png", ".jpg", ".jpeg", ".bmp", ".gif", ".tiff"]
|
| 9 |
|
| 10 |
+
def generate_slideshow_with_simple_fade(images, duration):
|
|
|
|
|
|
|
|
|
|
| 11 |
if not images:
|
| 12 |
return None, "❌ Keine Bilder ausgewählt"
|
| 13 |
|
| 14 |
temp_dir = tempfile.mkdtemp()
|
| 15 |
clips = []
|
| 16 |
|
| 17 |
+
# 1️⃣ Bilder in Clips umwandeln
|
| 18 |
for idx, img_path in enumerate(images):
|
| 19 |
clip_file = Path(temp_dir) / f"clip_{idx}.mp4"
|
| 20 |
cmd = [
|
|
|
|
| 29 |
subprocess.run(cmd, check=True)
|
| 30 |
clips.append(clip_file)
|
| 31 |
|
| 32 |
+
# 2️⃣ Übergänge erstellen
|
| 33 |
if len(clips) == 1:
|
|
|
|
| 34 |
return str(clips[0]), f"✅ Video erstellt ({len(clips)} Bild)"
|
| 35 |
+
|
| 36 |
+
current_clip = clips[0]
|
| 37 |
+
for next_clip in clips[1:]:
|
| 38 |
+
output_file = Path(temp_dir) / f"fade_{uuid.uuid4().hex}.mp4"
|
| 39 |
+
cmd = [
|
| 40 |
+
"ffmpeg",
|
| 41 |
+
"-y",
|
| 42 |
+
"-i", str(current_clip),
|
| 43 |
+
"-i", str(next_clip),
|
| 44 |
+
"-filter_complex",
|
| 45 |
+
f"[0:v][1:v]xfade=transition=fade:duration=1:offset={duration-1}[v]",
|
| 46 |
+
"-map", "[v]",
|
| 47 |
+
"-pix_fmt", "yuv420p",
|
| 48 |
+
str(output_file)
|
| 49 |
+
]
|
| 50 |
+
subprocess.run(cmd, check=True)
|
| 51 |
+
current_clip = output_file # der neue Clip wird zum aktuellen
|
| 52 |
|
| 53 |
+
if current_clip.exists():
|
| 54 |
+
return str(current_clip), f"✅ Slideshow Video erstellt mit Fade ({len(clips)} Bilder)"
|
| 55 |
+
else:
|
| 56 |
+
return None, "❌ Video konnte nicht erstellt werden"
|
| 57 |
|
| 58 |
# Gradio UI
|
| 59 |
with gr.Blocks() as demo:
|
|
|
|
| 69 |
|
| 70 |
btn = gr.Button("Video erstellen")
|
| 71 |
btn.click(
|
| 72 |
+
fn=generate_slideshow_with_simple_fade,
|
| 73 |
inputs=[img_input, duration_input],
|
| 74 |
outputs=[out_video, status]
|
| 75 |
)
|