okcan
Initial commit
1345192 unverified
Raw
History Blame Contribute Delete
5.17 kB
import gradio as gr
from youtube_transcript_api import YouTubeTranscriptApi
from transformers import pipeline
import re
# Model yükleme (ilk çalıştırmada indirir)
summarizer = pipeline("summarization", model="facebook/bart-large-cnn")
sentiment_analyzer = pipeline(
"sentiment-analysis",
model="cardiffnlp/twitter-roberta-base-sentiment-latest"
)
LABEL_MAP = {
"positive": "Olumlu",
"negative": "Olumsuz",
"neutral": "Nötr"
}
def extract_video_id(url: str) -> str:
patterns = [
r"v=([a-zA-Z0-9_-]{11})",
r"youtu\.be/([a-zA-Z0-9_-]{11})",
r"embed/([a-zA-Z0-9_-]{11})",
]
for pattern in patterns:
match = re.search(pattern, url)
if match:
return match.group(1)
raise ValueError("Geçersiz YouTube URL'si")
def get_transcript(video_id: str) -> str:
try:
transcript = YouTubeTranscriptApi.get_transcript(video_id, languages=["tr", "en"])
return " ".join([t["text"] for t in transcript])
except Exception:
try:
transcript = YouTubeTranscriptApi.get_transcript(video_id)
return " ".join([t["text"] for t in transcript])
except Exception as e:
raise ValueError(f"Transkript alınamadı: {str(e)}")
def chunk_text(text: str, max_tokens: int = 1000) -> list[str]:
words = text.split()
chunks = []
current = []
for word in words:
current.append(word)
if len(current) >= max_tokens:
chunks.append(" ".join(current))
current = []
if current:
chunks.append(" ".join(current))
return chunks
def summarize_text(text: str) -> str:
if len(text.split()) < 50:
return "Transkript çok kısa, özet oluşturulamadı."
chunks = chunk_text(text, max_tokens=900)
summaries = []
for chunk in chunks[:4]: # max 4 chunk
result = summarizer(chunk, max_length=150, min_length=40, do_sample=False)
summaries.append(result[0]["summary_text"])
return " ".join(summaries)
def analyze_sentiment(text: str) -> dict:
chunks = chunk_text(text, max_tokens=200)
scores = {"positive": 0, "negative": 0, "neutral": 0}
for chunk in chunks[:10]: # max 10 chunk
result = sentiment_analyzer(chunk[:512])[0]
label = result["label"].lower()
if label in scores:
scores[label] += result["score"]
total = sum(scores.values())
if total == 0:
return scores
return {k: round(v / total * 100, 1) for k, v in scores.items()}
def extract_keywords(text: str) -> str:
words = re.findall(r'\b[a-zA-ZğüşöçıİĞÜŞÖÇ]{4,}\b', text.lower())
freq = {}
stopwords = {"this", "that", "with", "have", "from", "they", "will", "been",
"were", "your", "what", "when", "here", "there", "more", "also",
"just", "like", "some", "than", "then", "into", "over", "after"}
for w in words:
if w not in stopwords:
freq[w] = freq.get(w, 0) + 1
top = sorted(freq.items(), key=lambda x: x[1], reverse=True)[:10]
return ", ".join([w for w, _ in top])
def analyze_youtube(url: str):
if not url.strip():
return "URL girin.", "", "", ""
try:
video_id = extract_video_id(url)
transcript = get_transcript(video_id)
summary = summarize_text(transcript)
sentiment = analyze_sentiment(transcript)
keywords = extract_keywords(transcript)
sentiment_text = (
f"Olumlu: %{sentiment['positive']}\n"
f"Olumsuz: %{sentiment['negative']}\n"
f"Nötr: %{sentiment['neutral']}"
)
dominant = max(sentiment, key=sentiment.get)
dominant_tr = LABEL_MAP.get(dominant, dominant)
return (
summary,
sentiment_text,
f"Genel Ton: {dominant_tr}",
keywords
)
except ValueError as e:
return str(e), "", "", ""
except Exception as e:
return f"Hata: {str(e)}", "", "", ""
with gr.Blocks(title="YouTube Video Analizci", theme=gr.themes.Soft()) as demo:
gr.Markdown("# YouTube Video Analizci")
gr.Markdown("YouTube video URL'si girin — transkript özetini, duygu analizini ve anahtar kelimeleri çıkarır.")
with gr.Row():
url_input = gr.Textbox(
label="YouTube URL",
placeholder="https://www.youtube.com/watch?v=...",
scale=4
)
analyze_btn = gr.Button("Analiz Et", variant="primary", scale=1)
with gr.Row():
summary_out = gr.Textbox(label="Video Özeti", lines=6, scale=3)
with gr.Column(scale=1):
sentiment_out = gr.Textbox(label="Duygu Analizi", lines=3)
tone_out = gr.Textbox(label="Genel Ton", lines=1)
keywords_out = gr.Textbox(label="Anahtar Kelimeler", lines=2)
analyze_btn.click(
fn=analyze_youtube,
inputs=[url_input],
outputs=[summary_out, sentiment_out, tone_out, keywords_out]
)
gr.Examples(
examples=[["https://www.youtube.com/watch?v=dQw4w9WgXcQ"]],
inputs=[url_input]
)
if __name__ == "__main__":
demo.launch()