RohitCSharp's picture
Update app.py
556278e verified
raw
history blame
3.51 kB
import gradio as gr
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain.llms import HuggingFacePipeline
from transformers import pipeline
from bs4 import BeautifulSoup
import requests
from TTS.api import TTS
import tempfile
import os
import shutil
# Setup summarization LLM
summary_pipe = pipeline("text2text-generation", model="google/flan-t5-base", device=-1)
llm = HuggingFacePipeline(pipeline=summary_pipe)
# Prompt for more engaging summary
summary_prompt = PromptTemplate.from_template("""
Summarize the following article content in a clear, warm, and motivational tone like a preacher speaking to an audience:
{text}
Summary:
""")
summary_chain = LLMChain(llm=llm, prompt=summary_prompt)
# TTS model setup
tts_model = TTS(model_name="tts_models/multilingual/multi-dataset/your_tts", progress_bar=False, gpu=False)
def extract_main_content(url):
try:
response = requests.get(url, timeout=10)
soup = BeautifulSoup(response.content, "html.parser")
for tag in soup(["nav", "header", "footer", "aside", "script", "style", "noscript"]):
tag.decompose()
paragraphs = soup.find_all("p")
content = "\n".join([p.get_text() for p in paragraphs if len(p.get_text()) > 60])
return content.strip()
except Exception as e:
return f"Error extracting article content: {str(e)}"
def generate_human_like_audio(text):
try:
temp_dir = tempfile.mkdtemp()
wav_path = os.path.join(temp_dir, "summary.wav")
mp3_path = os.path.join(temp_dir, "summary.mp3")
tts_model.tts_to_file(text=text, file_path=wav_path)
# Convert to mp3 for download link (requires ffmpeg in Hugging Face Spaces)
os.system(f"ffmpeg -y -i {wav_path} -codec:a libmp3lame -qscale:a 4 {mp3_path}")
if os.path.exists(mp3_path):
return wav_path, mp3_path
else:
return wav_path, None
except Exception as e:
print(f"TTS ERROR: {e}")
return None, None
def url_to_audio_summary(url):
try:
article_text = extract_main_content(url)
if article_text.startswith("Error"):
return article_text, None, None
if len(article_text) > 1500:
article_text = article_text[:1500] + "..."
summary = summary_chain.invoke({"text": article_text})
summary = summary["text"] if isinstance(summary, dict) and "text" in summary else summary
wav_path, mp3_path = generate_human_like_audio(summary)
return summary, wav_path, mp3_path
except Exception as e:
return f"Error: {str(e)}", None, None
def interface_wrapper(url):
summary, wav_path, mp3_path = url_to_audio_summary(url)
download_html = ""
if mp3_path and os.path.exists(mp3_path):
download_html = f'<a href="file/{os.path.basename(mp3_path)}" download target="_blank">Click to download MP3</a>'
return summary, wav_path, download_html
iface = gr.Interface(
fn=interface_wrapper,
inputs=gr.Textbox(label="Article URL", placeholder="Paste a news/blog URL here..."),
outputs=[
gr.Textbox(label="Summary"),
gr.Audio(label="Preacher-style Audio Summary", type="filepath"),
gr.HTML(label="Download MP3")
],
title="Preaching-Style URL to Audio Agent",
description="Summarizes article content and reads it aloud in a warm, preacher-style voice using YourTTS. CPU-only."
)
if __name__ == "__main__":
iface.launch()