fakeaitext / app.py
aigorithm's picture
Upload 2 files
2dc9994 verified
raw
history blame
4.13 kB
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()