[FEATURE] enhance YouTube transcript summarization with dynamic chunking and API key input
Browse files- app.py +8 -4
- requirements.txt +0 -1
- tool.py +29 -17
app.py
CHANGED
|
@@ -2,9 +2,10 @@ import gradio as gr
|
|
| 2 |
from tool import YouTubeTranscriptExtractor, TranscriptSummarizer
|
| 3 |
|
| 4 |
youtube_tool = YouTubeTranscriptExtractor()
|
| 5 |
-
summarizer_tool = TranscriptSummarizer()
|
| 6 |
|
| 7 |
-
def process_youtube_video(video_url):
|
|
|
|
| 8 |
transcript = youtube_tool.forward(video_url=video_url)
|
| 9 |
summary_and_blog = summarizer_tool.forward(transcript=transcript)
|
| 10 |
try:
|
|
@@ -16,14 +17,17 @@ def process_youtube_video(video_url):
|
|
| 16 |
|
| 17 |
iface = gr.Interface(
|
| 18 |
fn=process_youtube_video,
|
| 19 |
-
inputs=
|
|
|
|
|
|
|
|
|
|
| 20 |
outputs=[
|
| 21 |
gr.Textbox(label="Transcript"),
|
| 22 |
gr.Textbox(label="Summary and Blog Content"),
|
| 23 |
gr.Image(label="Generated Image", image_mode="RGBA")
|
| 24 |
],
|
| 25 |
title="YouTube Transcript Summarizer and Blog Content Generator",
|
| 26 |
-
description="Enter a YouTube video URL to extract the transcript, summarize it, and generate blog content with an image."
|
| 27 |
)
|
| 28 |
|
| 29 |
iface.launch()
|
|
|
|
| 2 |
from tool import YouTubeTranscriptExtractor, TranscriptSummarizer
|
| 3 |
|
| 4 |
youtube_tool = YouTubeTranscriptExtractor()
|
| 5 |
+
#summarizer_tool = TranscriptSummarizer()
|
| 6 |
|
| 7 |
+
def process_youtube_video(video_url, hf_api_key):
|
| 8 |
+
summarizer_tool = TranscriptSummarizer(hf_api_key=hf_api_key)
|
| 9 |
transcript = youtube_tool.forward(video_url=video_url)
|
| 10 |
summary_and_blog = summarizer_tool.forward(transcript=transcript)
|
| 11 |
try:
|
|
|
|
| 17 |
|
| 18 |
iface = gr.Interface(
|
| 19 |
fn=process_youtube_video,
|
| 20 |
+
inputs=[
|
| 21 |
+
gr.Textbox(label="YouTube Video URL"),
|
| 22 |
+
gr.Textbox(label="Hugging Face API Key", type="password")
|
| 23 |
+
],
|
| 24 |
outputs=[
|
| 25 |
gr.Textbox(label="Transcript"),
|
| 26 |
gr.Textbox(label="Summary and Blog Content"),
|
| 27 |
gr.Image(label="Generated Image", image_mode="RGBA")
|
| 28 |
],
|
| 29 |
title="YouTube Transcript Summarizer and Blog Content Generator",
|
| 30 |
+
description="Enter a YouTube video URL and Hugging Face API Key to extract the transcript, summarize it, and generate blog content with an image."
|
| 31 |
)
|
| 32 |
|
| 33 |
iface.launch()
|
requirements.txt
CHANGED
|
@@ -4,6 +4,5 @@ gradio
|
|
| 4 |
transformers
|
| 5 |
torch
|
| 6 |
torchvision
|
| 7 |
-
python-dotenv
|
| 8 |
requests
|
| 9 |
Pillow
|
|
|
|
| 4 |
transformers
|
| 5 |
torch
|
| 6 |
torchvision
|
|
|
|
| 7 |
requests
|
| 8 |
Pillow
|
tool.py
CHANGED
|
@@ -5,9 +5,9 @@ from transformers import pipeline
|
|
| 5 |
import requests
|
| 6 |
import io
|
| 7 |
from PIL import Image
|
| 8 |
-
from dotenv import load_dotenv
|
| 9 |
|
| 10 |
-
load_dotenv()
|
| 11 |
|
| 12 |
class TranscriptSummarizer(Tool):
|
| 13 |
description = "Summarizes a transcript and generates blog content using the transformers library and Hugging Face API for image generation."
|
|
@@ -15,11 +15,12 @@ class TranscriptSummarizer(Tool):
|
|
| 15 |
inputs = {'transcript': {'type': 'string', 'description': 'The transcript to summarize.'}}
|
| 16 |
output_type = "string"
|
| 17 |
|
| 18 |
-
def __init__(self, *args, **kwargs):
|
| 19 |
super().__init__(*args, **kwargs)
|
| 20 |
self.summarizer = pipeline("summarization", model="google/pegasus-xsum")
|
| 21 |
self.api_url = "https://api-inference.huggingface.co/models/ZB-Tech/Text-to-Image"
|
| 22 |
-
self.
|
|
|
|
| 23 |
|
| 24 |
def query(self, payload):
|
| 25 |
response = requests.post(self.api_url, headers=self.headers, json=payload)
|
|
@@ -27,23 +28,34 @@ class TranscriptSummarizer(Tool):
|
|
| 27 |
|
| 28 |
def forward(self, transcript: str) -> str:
|
| 29 |
try:
|
|
|
|
|
|
|
|
|
|
| 30 |
transcript_length = len(transcript)
|
| 31 |
|
| 32 |
def get_summary_lengths(length):
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
elif length <= 3000:
|
| 37 |
-
max_length = 750
|
| 38 |
-
min_length = 250
|
| 39 |
-
else:
|
| 40 |
-
max_length = 1500
|
| 41 |
-
min_length = 500
|
| 42 |
return max_length, min_length
|
| 43 |
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
image_prompt = f"Generate an image related to: {' '.join(key_entities)}, cartoon style"
|
| 48 |
image_bytes = self.query({"inputs": image_prompt})
|
| 49 |
image = Image.open(io.BytesIO(image_bytes))
|
|
@@ -52,7 +64,7 @@ class TranscriptSummarizer(Tool):
|
|
| 52 |
os.makedirs(image_folder)
|
| 53 |
image_url = os.path.join(image_folder, "image.jpg") # Specify the folder path
|
| 54 |
image.save(image_url) # Save the image to a file
|
| 55 |
-
return f"{
|
| 56 |
except Exception as e:
|
| 57 |
return f"An unexpected error occurred: {str(e)}"
|
| 58 |
|
|
|
|
| 5 |
import requests
|
| 6 |
import io
|
| 7 |
from PIL import Image
|
| 8 |
+
#from dotenv import load_dotenv
|
| 9 |
|
| 10 |
+
#load_dotenv()
|
| 11 |
|
| 12 |
class TranscriptSummarizer(Tool):
|
| 13 |
description = "Summarizes a transcript and generates blog content using the transformers library and Hugging Face API for image generation."
|
|
|
|
| 15 |
inputs = {'transcript': {'type': 'string', 'description': 'The transcript to summarize.'}}
|
| 16 |
output_type = "string"
|
| 17 |
|
| 18 |
+
def __init__(self, *args, hf_api_key: str = None, **kwargs):
|
| 19 |
super().__init__(*args, **kwargs)
|
| 20 |
self.summarizer = pipeline("summarization", model="google/pegasus-xsum")
|
| 21 |
self.api_url = "https://api-inference.huggingface.co/models/ZB-Tech/Text-to-Image"
|
| 22 |
+
self.hf_api_key = hf_api_key
|
| 23 |
+
self.headers = {"Authorization": f"Bearer {self.hf_api_key}"}
|
| 24 |
|
| 25 |
def query(self, payload):
|
| 26 |
response = requests.post(self.api_url, headers=self.headers, json=payload)
|
|
|
|
| 28 |
|
| 29 |
def forward(self, transcript: str) -> str:
|
| 30 |
try:
|
| 31 |
+
if not self.hf_api_key:
|
| 32 |
+
return "Hugging Face API key is required. Please provide it in the input field."
|
| 33 |
+
|
| 34 |
transcript_length = len(transcript)
|
| 35 |
|
| 36 |
def get_summary_lengths(length):
|
| 37 |
+
# set the short maths formula
|
| 38 |
+
max_length = int(length * 0.8)
|
| 39 |
+
min_length = int(length * 0.2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
return max_length, min_length
|
| 41 |
|
| 42 |
+
# Split the transcript into chunks of 500 characters make it dynamic according to the length of the transcript
|
| 43 |
+
if transcript_length < 500:
|
| 44 |
+
return "Transcript is too short to summarize."
|
| 45 |
+
chunk_size = 500
|
| 46 |
+
transcript_chunks = [transcript[i:i+chunk_size] for i in range(0, len(transcript), chunk_size)]
|
| 47 |
+
|
| 48 |
+
# Summarize each chunk of the transcript
|
| 49 |
+
summaries = []
|
| 50 |
+
for chunk in transcript_chunks:
|
| 51 |
+
max_length, min_length = get_summary_lengths(len(chunk))
|
| 52 |
+
summary = self.summarizer(chunk, max_length=max_length, min_length=min_length, do_sample=False)[0]['summary_text']
|
| 53 |
+
summaries.append(summary)
|
| 54 |
+
|
| 55 |
+
# Concatenate the summaries
|
| 56 |
+
full_summary = "\n".join(summaries)
|
| 57 |
+
|
| 58 |
+
key_entities = full_summary.split()[:15] # Extract first 3 words as key entities
|
| 59 |
image_prompt = f"Generate an image related to: {' '.join(key_entities)}, cartoon style"
|
| 60 |
image_bytes = self.query({"inputs": image_prompt})
|
| 61 |
image = Image.open(io.BytesIO(image_bytes))
|
|
|
|
| 64 |
os.makedirs(image_folder)
|
| 65 |
image_url = os.path.join(image_folder, "image.jpg") # Specify the folder path
|
| 66 |
image.save(image_url) # Save the image to a file
|
| 67 |
+
return f"{full_summary}\n\nImage URL: {image_url}" # Return the file path
|
| 68 |
except Exception as e:
|
| 69 |
return f"An unexpected error occurred: {str(e)}"
|
| 70 |
|