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()