Spaces:
Sleeping
Sleeping
File size: 2,937 Bytes
7dd982b eec85c6 7dd982b eec85c6 7dd982b f06c20a 7dd982b eec85c6 7dd982b f06c20a 7dd982b eec85c6 7dd982b f06c20a eec85c6 2b8e4f0 eec85c6 f06c20a eec85c6 f06c20a 76e3793 eec85c6 76e3793 eec85c6 f06c20a eec85c6 2b8e4f0 f06c20a 2b8e4f0 f06c20a 2b8e4f0 f06c20a 76e3793 f06c20a eec85c6 f06c20a eec85c6 f06c20a eec85c6 f06c20a 76e3793 eec85c6 b82995c 7dd982b eec85c6 7dd982b f06c20a eec85c6 |
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 |
import gradio as gr
import tempfile, subprocess, requests
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain.chat_models import ChatOpenAI
from gtts import gTTS
from bs4 import BeautifulSoup
from PIL import Image, ImageDraw
# OpenAI LLM (fast + accurate)
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.3)
summary_prompt = PromptTemplate.from_template("""
Provide a crisp, promotional-style summary (under 50 words) of the following:
{text}
Summary:
""")
summary_chain = LLMChain(llm=llm, prompt=summary_prompt)
# Extract relevant content from article
def extract_main_content(url):
resp = requests.get(url, timeout=10)
soup = BeautifulSoup(resp.content, "html.parser")
for tag in soup(["nav", "header", "footer", "aside", "script", "style", "noscript"]): tag.decompose()
paras = [p.get_text() for p in soup.find_all("p") if len(p.get_text()) > 60]
return "\n".join(paras[:20]) or None
# Gradient background
def create_background(image_path, size=(1280,720)):
img = Image.new("RGB", size)
draw = ImageDraw.Draw(img)
for y in range(size[1]):
color = (10 + y//10, 20 + y//12, 50 + y//15)
draw.line([(0, y), (size[0], y)], fill=color)
img.save(image_path)
# AV generation logic with variable duration
def url_to_av_summary(url, duration):
content = extract_main_content(url)
if not content:
return "Failed to extract article content.", None
summary = summary_chain.run(text=content[:3000]).replace('"','')[:300]
audio_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name
gTTS(text=summary).save(audio_path)
bg_path = tempfile.NamedTemporaryFile(delete=False, suffix=".png").name
create_background(bg_path)
video_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4").name
cmd = [
'ffmpeg', '-y',
'-loop', '1', '-i', bg_path, '-i', audio_path,
'-vf', (
"drawtext=fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf:text='" + summary +
f"':fontcolor=white:fontsize=48:box=1:[email protected]:boxborderw=5:x=(w-text_w)/2:y=h-(t*(h+text_h)/{duration})"
),
'-t', str(duration),
'-c:v', 'libx264', '-c:a', 'aac', '-pix_fmt', 'yuv420p', '-shortest', video_path
]
subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
return summary, video_path
iface = gr.Interface(
fn=url_to_av_summary,
inputs=[
gr.Textbox(label="Article URL"),
gr.Radio([5, 10], label="Video Duration (sec)", value=5)
],
outputs=[
gr.Textbox(label="Summary"),
gr.Video(label="Generated AV Summary")
],
title="๐๏ธ AV Summary Generator (OpenAI Powered)",
description="Generate a short AV video (5 or 10 seconds) summarizing any article. Uses OpenAI + gTTS + FFmpeg."
)
if __name__ == '__main__':
iface.launch()
|