RohitCSharp commited on
Commit
eec85c6
·
verified ·
1 Parent(s): 2b8e4f0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -47
app.py CHANGED
@@ -1,21 +1,14 @@
1
  import gradio as gr
 
2
  from langchain.chains import LLMChain
3
  from langchain.prompts import PromptTemplate
4
- from langchain.llms import HuggingFacePipeline
5
- from transformers import pipeline
6
  from gtts import gTTS
7
  from bs4 import BeautifulSoup
8
- import tempfile
9
- import requests
10
- import subprocess
11
- import concurrent.futures
12
  from PIL import Image, ImageDraw
13
 
14
- # CPU-friendly summarization model
15
- summary_pipe = pipeline("text2text-generation", model="google/flan-t5-base", device=-1)
16
- llm = HuggingFacePipeline(pipeline=summary_pipe)
17
-
18
- # Prompt for <50-word promotional summary
19
  summary_prompt = PromptTemplate.from_template("""
20
  Provide a crisp, promotional-style summary (under 50 words) of the following:
21
 
@@ -25,33 +18,29 @@ Summary:
25
  """)
26
  summary_chain = LLMChain(llm=llm, prompt=summary_prompt)
27
 
28
- # Extract main article content (first 20 meaningful paragraphs)
29
  def extract_main_content(url):
30
  resp = requests.get(url, timeout=10)
31
  soup = BeautifulSoup(resp.content, "html.parser")
32
- for tag in soup(["nav","header","footer","aside","script","style","noscript"]): tag.decompose()
33
  paras = [p.get_text() for p in soup.find_all("p") if len(p.get_text()) > 60]
34
- content = "\n".join(paras[:20]) # limit to top 20 paragraphs
35
- return content or None
36
 
37
- # Create gradient background image
38
  def create_background(image_path, size=(1280,720)):
39
  img = Image.new("RGB", size)
40
  draw = ImageDraw.Draw(img)
41
- for i in range(size[1]):
42
- r = int(10 + (i/size[1])*20)
43
- g = int(20 + (i/size[1])*30)
44
- b = int(50 + (i/size[1])*50)
45
- draw.line([(0, i), (size[0], i)], fill=(r, g, b))
46
  img.save(image_path)
47
 
48
- # Generate 5s AV summary
49
- def url_to_av_summary(url):
50
- text = extract_main_content(url)
51
- if not text:
52
  return "Failed to extract article content.", None
53
- text = text[:2000] # truncate
54
- summary = summary_chain.run(text=text).replace('"','')[:250] # short summary
55
 
56
  audio_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name
57
  gTTS(text=summary).save(audio_path)
@@ -62,35 +51,31 @@ def url_to_av_summary(url):
62
  video_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4").name
63
  cmd = [
64
  'ffmpeg', '-y',
65
- '-loop', '1', '-i', bg_path,
66
- '-i', audio_path,
67
  '-vf', (
68
  "drawtext=fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf:text='" + summary +
69
- "':fontcolor=white:fontsize=48:box=1:[email protected]:boxborderw=5:"
70
- "x=(w-text_w)/2:y=h-(t*(h+text_h)/5)"
71
  ),
72
- '-t', '5',
73
  '-c:v', 'libx264', '-c:a', 'aac', '-pix_fmt', 'yuv420p', '-shortest', video_path
74
  ]
75
  subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
76
- return summary, video_path
77
 
78
- # Timeout wrapper: 60s max
79
- def safe_summary(url, timeout_secs=60):
80
- with concurrent.futures.ThreadPoolExecutor() as executor:
81
- future = executor.submit(url_to_av_summary, url)
82
- try:
83
- return future.result(timeout=timeout_secs)
84
- except concurrent.futures.TimeoutError:
85
- return "⏱️ Processing timed out.", None
86
 
87
  iface = gr.Interface(
88
- fn=safe_summary,
89
- inputs=gr.Textbox(label="Article URL"),
90
- outputs=[gr.Textbox(label="Summary"), gr.Video(label="Video Preview")],
91
- title="🎥 5-Second AV Summary (CPU-only)",
92
- description="Fast, CPU-only AV summary of a URL. Video capped at 5 seconds to prevent timeouts."
 
 
 
 
 
 
93
  )
94
 
95
  if __name__ == '__main__':
96
- iface.launch()
 
1
  import gradio as gr
2
+ import tempfile, subprocess, requests
3
  from langchain.chains import LLMChain
4
  from langchain.prompts import PromptTemplate
5
+ from langchain.chat_models import ChatOpenAI
 
6
  from gtts import gTTS
7
  from bs4 import BeautifulSoup
 
 
 
 
8
  from PIL import Image, ImageDraw
9
 
10
+ # OpenAI LLM (fast + accurate)
11
+ llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.3)
 
 
 
12
  summary_prompt = PromptTemplate.from_template("""
13
  Provide a crisp, promotional-style summary (under 50 words) of the following:
14
 
 
18
  """)
19
  summary_chain = LLMChain(llm=llm, prompt=summary_prompt)
20
 
21
+ # Extract relevant content from article
22
  def extract_main_content(url):
23
  resp = requests.get(url, timeout=10)
24
  soup = BeautifulSoup(resp.content, "html.parser")
25
+ for tag in soup(["nav", "header", "footer", "aside", "script", "style", "noscript"]): tag.decompose()
26
  paras = [p.get_text() for p in soup.find_all("p") if len(p.get_text()) > 60]
27
+ return "\n".join(paras[:20]) or None
 
28
 
29
+ # Gradient background
30
  def create_background(image_path, size=(1280,720)):
31
  img = Image.new("RGB", size)
32
  draw = ImageDraw.Draw(img)
33
+ for y in range(size[1]):
34
+ color = (10 + y//10, 20 + y//12, 50 + y//15)
35
+ draw.line([(0, y), (size[0], y)], fill=color)
 
 
36
  img.save(image_path)
37
 
38
+ # AV generation logic with variable duration
39
+ def url_to_av_summary(url, duration):
40
+ content = extract_main_content(url)
41
+ if not content:
42
  return "Failed to extract article content.", None
43
+ summary = summary_chain.run(text=content[:3000]).replace('"','')[:300]
 
44
 
45
  audio_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name
46
  gTTS(text=summary).save(audio_path)
 
51
  video_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4").name
52
  cmd = [
53
  'ffmpeg', '-y',
54
+ '-loop', '1', '-i', bg_path, '-i', audio_path,
 
55
  '-vf', (
56
  "drawtext=fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf:text='" + summary +
57
+ f"':fontcolor=white:fontsize=48:box=1:[email protected]:boxborderw=5:x=(w-text_w)/2:y=h-(t*(h+text_h)/{duration})"
 
58
  ),
59
+ '-t', str(duration),
60
  '-c:v', 'libx264', '-c:a', 'aac', '-pix_fmt', 'yuv420p', '-shortest', video_path
61
  ]
62
  subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
 
63
 
64
+ return summary, video_path
 
 
 
 
 
 
 
65
 
66
  iface = gr.Interface(
67
+ fn=url_to_av_summary,
68
+ inputs=[
69
+ gr.Textbox(label="Article URL"),
70
+ gr.Radio([5, 10], label="Video Duration (sec)", value=5)
71
+ ],
72
+ outputs=[
73
+ gr.Textbox(label="Summary"),
74
+ gr.Video(label="Generated AV Summary")
75
+ ],
76
+ title="🎞️ AV Summary Generator (OpenAI Powered)",
77
+ description="Generate a short AV video (5 or 10 seconds) summarizing any article. Uses OpenAI + gTTS + FFmpeg."
78
  )
79
 
80
  if __name__ == '__main__':
81
+ iface.launch()