File size: 3,060 Bytes
6425192
f470c8b
6425192
49a451b
 
 
 
 
 
 
 
2cafe3b
49a451b
513fa76
49a451b
81cc460
49a451b
 
 
 
81cc460
49a451b
 
f470c8b
49a451b
 
 
 
 
f470c8b
90d642f
49a451b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f470c8b
49a451b
 
 
 
 
 
f470c8b
49a451b
 
 
 
81cc460
49a451b
85bbc44
49a451b
 
 
 
 
 
81cc460
49a451b
 
 
 
 
 
 
 
 
 
81cc460
49a451b
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import gradio as gr
import torch
import os
from transformers import pipeline
from diffusers import StableDiffusionPipeline
from TTS.api import TTS
from moviepy.editor import *

# === SETUP ===
device = "cuda" if torch.cuda.is_available() else "cpu"
text_gen = pipeline("text-generation", model="dbmdz/german-gpt2", device=0 if device == "cuda" else -1)
tts = TTS(model_name="tts_models/de/thorsten/vits", progress_bar=False).to(device)
sd = StableDiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5").to(device)

# === HELFER ===

def generate_story(title):
    prompt = f"Titel: {title}\nSchreibe eine kurze, gruselige Horrorgeschichte in etwa 150 Wörtern."
    output = text_gen(prompt, max_length=200, do_sample=True, temperature=0.9)[0]['generated_text']
    return output.strip()

def generate_images(story, n=4):
    prompts = [story[:100]] * n
    images = []
    for i, prompt in enumerate(prompts):
        image = sd(prompt).images[0]
        path = f"bild_{i}.png"
        image.save(path)
        images.append(path)
    return images

def synthesize_audio(text, path="narration.wav"):
    tts.tts_to_file(text=text, file_path=path)
    return path

def create_subtitles(text, duration, filename="untertitel.srt"):
    lines = text.split(". ")
    per_line = duration / len(lines)
    with open(filename, "w", encoding="utf-8") as f:
        for i, line in enumerate(lines):
            start = i * per_line
            end = (i + 1) * per_line
            f.write(f"{i+1}\n")
            f.write(f"{format_time(start)} --> {format_time(end)}\n")
            f.write(line.strip() + "\n\n")
    return filename

def format_time(seconds):
    m, s = divmod(int(seconds), 60)
    ms = int((seconds - int(seconds)) * 1000)
    return f"00:{m:02}:{s:02},{ms:03}"

def generate_video(images, audio_path, story_text, out_path="output.mp4"):
    audioclip = AudioFileClip(audio_path)
    duration = audioclip.duration
    img_duration = duration / len(images)
    clips = [ImageClip(img).set_duration(img_duration).resize(height=720) for img in images]
    videoclip = concatenate_videoclips(clips, method="compose").set_audio(audioclip)

    srt_file = create_subtitles(story_text, duration)
    videoclip = videoclip.set_duration(duration)
    videoclip.write_videofile(out_path, fps=24, codec='libx264')
    return out_path

# === INTERFACE ===

def generate_horror_video(title):
    story = generate_story(title)
    images = generate_images(story)
    audio = synthesize_audio(story)
    video = generate_video(images, audio, story)
    return video, story

iface = gr.Interface(
    fn=generate_horror_video,
    inputs=gr.Textbox(label="Gib den Titel deiner deutschen Gruselgeschichte ein"),
    outputs=[
        gr.Video(label="Dein generiertes Horrorvideo"),
        gr.Textbox(label="Generierte Geschichte")
    ],
    title="Gruselige KI-Kurzgeschichten",
    description="Gib einen Titel ein – KI erstellt eine deutsche Gruselgeschichte, Bilder, Stimme und Video (ohne Musik)."
)

if __name__ == "__main__":
    iface.launch()