File size: 4,134 Bytes
672e79a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import gradio as gr
from transformers import pipeline
import requests
import os
import html
import base64
import random
import json
from datetime import datetime

chat_gen = pipeline("text-generation", model="tiiuae/falcon-rw-1b")

voice_options = {
    "Rachel": "EXAVITQu4vr4xnSDxMaL",
    "Adam": "21m00Tcm4TlvDq8ikWAM",
    "Elli": "AZnzlk1XvdvUeBnXmlld",
    "Josh": "VR6AewLTigWG4xSOukaG"
}

DEFAULT_ELEVEN_API_KEY = "sk_4e67c39c0e9cbc87462cd2643e1f4d1d9959d7d81203adc2"
library_file = "/tmp/library.json"

def generate_chat_bundle(prompt, *character_inputs):
    characters = [c.split(":")[0].strip() for c in character_inputs if ":" in c]
    voices = {c.split(":")[0].strip(): c.split(":")[1].strip() for c in character_inputs if ":" in c}

    system_prompt = (
        f"Group chat between {', '.join(characters)}. Prompt: {prompt}. "
        "Use casual texting style: Name: message"
    )
    response = chat_gen(system_prompt, max_new_tokens=300)[0]["generated_text"]
    chat_lines = [(line.split(':', 1)[0].strip(), line.split(':', 1)[1].strip()) for line in response.splitlines() if ':' in line]

    html_chat = ""
    file_paths = []
    api_key = os.getenv("ELEVEN_API_KEY", DEFAULT_ELEVEN_API_KEY)

    for i, (name, msg) in enumerate(chat_lines):
        color = random.choice(["#DCF8C6", "#FEE2E2", "#EDEDED", "#C7E2FF"])
        html_chat += f"""<div style='margin: 10px; text-align: {'left' if i % 2 == 0 else 'right'}'>
        <div style='display:inline-block; padding: 10px 15px; background: {color}; border-radius: 15px; max-width: 70%;'>
        <strong>{html.escape(name)}:</strong> {html.escape(msg)}
        </div></div>"""

        voice_id = voices.get(name, list(voice_options.values())[0])
        eleven_response = requests.post(
            f"https://api.elevenlabs.io/v1/text-to-speech/{voice_id}",
            headers={
                "xi-api-key": api_key,
                "Content-Type": "application/json"
            },
            json={"text": msg, "model_id": "eleven_monolingual_v1"}
        )

        if eleven_response.status_code == 200:
            file_path = f"/tmp/audio_{i}_{name}.mp3"
            with open(file_path, 'wb') as f:
                f.write(eleven_response.content)
            file_paths.append(file_path)

    timestamp = datetime.now().strftime('%Y%m%d-%H%M%S')
    html_path = f"/tmp/fakechat_{timestamp}.html"
    with open(html_path, "w") as f:
        f.write(f"<html><body>{html_chat}</body></html>")
    file_paths.append(html_path)

    if os.path.exists(library_file):
        with open(library_file, "r") as f:
            lib = json.load(f)
    else:
        lib = []

    lib.insert(0, {
        "timestamp": timestamp,
        "characters": characters,
        "prompt": prompt,
        "html": html_path,
        "audio_files": file_paths[:-1]
    })

    with open(library_file, "w") as f:
        json.dump(lib, f, indent=2)

    return file_paths

def get_library():
    if not os.path.exists(library_file):
        return "No stories saved yet."
    with open(library_file, "r") as f:
        lib = json.load(f)
    html_links = [f"<li><b>{item['timestamp']}</b>: {', '.join(item['characters'])} β€” <a href='file={item['html']}' target='_blank'>Chat</a></li>" for item in lib]
    return "<ul>" + "".join(html_links) + "</ul>"

def build_character_inputs():
    return [gr.Textbox(label=f"Character {i+1} (Format: Name:Voice)", placeholder="e.g. Anna:Rachel") for i in range(4)]

with gr.Blocks() as app:
    with gr.Row():
        with gr.Column(scale=3):
            characters = build_character_inputs()
            prompt = gr.Textbox(label="Scene Prompt")
            generate_btn = gr.Button("🎀 Generate Chat + Audio")
            file_output = gr.File(file_types=[".html", ".mp3"], label="Download Files")
        with gr.Column(scale=1):
            lib_html = gr.HTML(label="πŸ“ My Saved Stories")
            refresh_btn = gr.Button("πŸ” Refresh Library")

    generate_btn.click(fn=generate_chat_bundle, inputs=[prompt] + characters, outputs=file_output)
    refresh_btn.click(fn=get_library, outputs=lib_html)

app.launch()