File size: 3,424 Bytes
1d001d4 aa427d8 1b0bf97 f99a513 1d001d4 aa427d8 1d001d4 f99a513 1d001d4 f99a513 1d001d4 f99a513 1d001d4 f99a513 1d001d4 f1f04ed f99a513 f1f04ed 3206e48 f99a513 f1f04ed 1d001d4 f99a513 1d001d4 f99a513 8a4956f 1d001d4 f99a513 1d001d4 f99a513 1d001d4 8a4956f f99a513 8a4956f f99a513 8a4956f f99a513 8a4956f f99a513 8a4956f f99a513 8a4956f 1d001d4 f99a513 1d001d4 f99a513 8a4956f 1d001d4 f99a513 1d001d4 f99a513 1d001d4 f99a513 1d001d4 f99a513 1d001d4 8a4956f 1d001d4 f99a513 1d001d4 1b0bf97 f99a513 8a4956f f99a513 fd07d0a f99a513 01390f7 f99a513 9c15d35 f99a513 15f84ad 9c15d35 f99a513 9c15d35 f99a513 693f058 f99a513 1d001d4 8a4956f 1d001d4 f99a513 1d001d4 f99a513 1d001d4 f99a513 1d001d4 f99a513 1d001d4 8a4956f f99a513 8a4956f f99a513 8a4956f f99a513 1d001d4 f99a513 1b0bf97 f99a513 1d001d4 f99a513 1b0bf97 f99a513 1b0bf97 8a4956f 1b0bf97 1d001d4 | 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 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | import gradio as gr
import os
import uuid
import requests
from ultralytics import YOLO
from openai import OpenAI
from gtts import gTTS
# =========================
# YOLO
# =========================
model = YOLO("best_egypt.pt")
# =========================
# OpenRouter
# =========================
client = OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.environ["OPENROUTER_API_KEY"]
)
# =========================
# FastAPI URL
# =========================
WAV2LIP_API = "https://fatma812-wav2lip-api.hf.space/generate-video"
# =========================
# Story + Voice
# =========================
def generate(image_path, language):
results = model(image_path)
if len(results[0].boxes) == 0:
raise gr.Error("No artifact detected")
label = int(results[0].boxes.cls[0])
artifact = results[0].names[label]
if language == "Arabic":
prompt = f"""
أنت {artifact} من آثار مصر القديمة.
تحدث بصيغة المتكلم.
احك قصة قصيرة لا تزيد عن 3 جمل.
"""
tts_lang = "ar"
else:
prompt = f"""
You are {artifact}, an ancient Egyptian artifact.
Speak in first person.
Tell a short interesting story in 3 sentences.
"""
tts_lang = "en"
response = client.chat.completions.create(
model="openai/gpt-4o-mini",
messages=[
{
"role": "user",
"content": prompt
}
]
)
story = response.choices[0].message.content
audio_path = f"audio_{uuid.uuid4().hex}.mp3"
gTTS(
text=story,
lang=tts_lang
).save(audio_path)
return artifact, story, audio_path
# =========================
# Generate Talking Video
# =========================
def make_video(image_path, audio_path):
if image_path is None:
raise gr.Error("Upload image first")
if audio_path is None:
raise gr.Error("Generate audio first")
with open(image_path, "rb") as img, open(audio_path, "rb") as aud:
response = requests.post(
WAV2LIP_API,
files={
"image": img,
"audio": aud
},
timeout=600
)
if response.status_code != 200:
raise gr.Error(response.text)
video_path = f"video_{uuid.uuid4().hex}.mp4"
with open(video_path, "wb") as f:
f.write(response.content)
return video_path
# =========================
# UI
# =========================
with gr.Blocks() as demo:
gr.Markdown("# 🏛 Talking Egyptian Artifact AI")
image = gr.Image(
type="filepath",
label="Artifact Image"
)
language = gr.Radio(
["Arabic", "English"],
value="Arabic",
label="Language"
)
btn_generate = gr.Button("Generate Story + Voice")
artifact = gr.Textbox(label="Artifact")
story = gr.Textbox(
label="Story",
lines=6
)
audio = gr.Audio(
type="filepath",
label="Generated Voice"
)
btn_video = gr.Button("Generate Talking Video")
video = gr.Video(
label="Talking Video"
)
btn_generate.click(
fn=generate,
inputs=[image, language],
outputs=[artifact, story, audio]
)
btn_video.click(
fn=make_video,
inputs=[image, audio],
outputs=video
)
demo.queue()
demo.launch() |