[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 |
|