Spaces:
Sleeping
Sleeping
File size: 2,988 Bytes
7dd982b 6ac3507 7dd982b 6ac3507 7dd982b f06c20a 6ac3507 7dd982b 6ac3507 7dd982b f06c20a 7dd982b 6ac3507 7dd982b f06c20a 6ac3507 2b8e4f0 eec85c6 f06c20a eec85c6 6ac3507 f06c20a 76e3793 eec85c6 6ac3507 76e3793 6ac3507 eec85c6 6ac3507 eec85c6 2b8e4f0 6ac3507 2b8e4f0 6ac3507 2b8e4f0 6ac3507 76e3793 6ac3507 b82995c 7dd982b eec85c6 6ac3507 7dd982b 6ac3507 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 83 84 85 86 87 88 89 90 |
import gradio as gr
import tempfile, requests
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from gtts import gTTS
from bs4 import BeautifulSoup
from PIL import Image, ImageDraw
import ffmpeg
import textwrap
# Initialize OpenAI LLM
llm = ChatOpenAI(model_name="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 top article paragraphs
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(path, size=(1280,720)):
img = Image.new("RGB", size)
draw = ImageDraw.Draw(img)
for y in range(size[1]):
draw.line([(0,y),(size[0],y)], fill=(10+y//10,20+y//12,50+y//15))
img.save(path)
# Generate AV summary
def url_to_av_summary(url, duration):
content = extract_main_content(url)
if not content:
return "Failed to extract content.", None
summary = summary_chain.run(text=content[:3000]).replace('"','')[:300]
# Wrap long summary to multiline
wrapped_summary = textwrap.fill(summary, width=50).replace("\n", "\\n")
# TTS
audio = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name
gTTS(text=summary).save(audio)
# Background image
bg = tempfile.NamedTemporaryFile(delete=False, suffix=".png").name
create_background(bg)
# Build video stream
video_stream = ffmpeg.input(bg, loop=1, framerate=1)
text_opts = dict(
fontfile="/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf",
text=wrapped_summary,
fontcolor="white",
fontsize=48,
box=1,
boxcolor="[email protected]",
boxborderw=5,
x="(w-text_w)/2",
y=f"h-(t*(h+text_h)/{duration})"
)
video = video_stream.drawtext(**text_opts).setpts('PTS')
audio_stream = ffmpeg.input(audio)
out_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4").name
out = ffmpeg.output(video, audio_stream, out_path,
vcodec="libx264", acodec="aac", pix_fmt="yuv420p", t=duration)
out.run(quiet=True)
return summary, out_path
iface = gr.Interface(
fn=url_to_av_summary,
inputs=[gr.Textbox(label="Article URL"), gr.Radio([5,10], label="Duration (sec)", value=5)],
outputs=[gr.Textbox(label="Summary"), gr.Video(label="AV Summary")],
title="AV Summary Generator",
description="Generate a promo-style AV summary (5 or 10s) using OpenAI + gTTS + ffmpeg-python."
)
if __name__=='__main__':
iface.launch()
|