yunuseduran commited on
Commit
91923dc
·
verified ·
1 Parent(s): d055852

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +249 -217
app.py CHANGED
@@ -1,217 +1,249 @@
1
- import gradio as gr
2
- from google import genai
3
- from youtube_transcript_api import YouTubeTranscriptApi
4
- from youtube_transcript_api._errors import TranscriptsDisabled, NoTranscriptFound, VideoUnavailable
5
- import re
6
- import time
7
- import requests
8
- from urllib.parse import urlparse, parse_qs
9
- import socket
10
-
11
- def find_free_port(start_port=7860, max_port=7960):
12
- """Boş bir port bul"""
13
- for port in range(start_port, max_port):
14
- try:
15
- with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
16
- s.bind(('', port))
17
- return port
18
- except OSError:
19
- continue
20
- return None
21
-
22
- #https://www.youtube.com/watch?v=bhR274lZNLo
23
- def is_valid_youtube_url(url):
24
- try:
25
- parsed_url = urlparse(url)
26
- if 'youtube.com' in parsed_url.netloc or 'youtu.be' in parsed_url.netloc:
27
- return True
28
- return False
29
- except:
30
- return False
31
-
32
- def extract_video_id(url):
33
- if not url:
34
- return None
35
-
36
- try:
37
- if 'youtu.be' in url:
38
- return url.split('youtu.be/')[-1].split('?')[0]
39
-
40
- parsed_url = urlparse(url)
41
- if 'youtube.com' in parsed_url.netloc:
42
- query = parse_qs(parsed_url.query)
43
- return query.get('v', [None])[0]
44
- except Exception:
45
- return None
46
-
47
- return None
48
-
49
- def get_transcript(video_url):
50
- if not video_url:
51
- return "Lütfen bir YouTube URL'si girin."
52
-
53
- if not is_valid_youtube_url(video_url):
54
- return "Geçersiz YouTube URL'si. Lütfen doğru bir URL girin."
55
-
56
- video_id = extract_video_id(video_url)
57
- if not video_id:
58
- return "Video ID çıkarılamadı. Lütfen geçerli bir YouTube URL'si girin."
59
-
60
- max_retries = 3
61
- retry_delay = 2
62
-
63
- for attempt in range(max_retries):
64
- try:
65
- # Önce video erişilebilirliğini kontrol et
66
- check_url = f"https://www.youtube.com/oembed?url=http://www.youtube.com/watch?v={video_id}"
67
- response = requests.get(check_url)
68
- if response.status_code != 200:
69
- return "Video bulunamadı veya erişilemez durumda."
70
-
71
- # Transkript almayı dene
72
- transcript = YouTubeTranscriptApi.get_transcript(video_id, languages=['en', 'tr'])
73
- if not transcript:
74
- return "Transkript bulunamadı."
75
-
76
- raw_text = " ".join([entry['text'] for entry in transcript])
77
- if not raw_text.strip():
78
- return "Transkript boş görünüyor."
79
-
80
- return raw_text
81
-
82
- except requests.exceptions.RequestException:
83
- if attempt < max_retries - 1:
84
- time.sleep(retry_delay)
85
- continue
86
- return "Bağlantı hatası oluştu. Lütfen internet bağlantınızı kontrol edin."
87
-
88
- except TranscriptsDisabled:
89
- return "Bu video için altyazılar devre dışı bırakılmış."
90
-
91
- except NoTranscriptFound:
92
- return "Bu video için transkript bulunamadı. Video başka bir dilde olabilir."
93
-
94
- except VideoUnavailable:
95
- return "Video bulunamadı veya erişilemez durumda."
96
-
97
- except Exception as e:
98
- if attempt < max_retries - 1:
99
- time.sleep(retry_delay)
100
- continue
101
- return f"Bir hata oluştu: {str(e)}"
102
-
103
- return "Maksimum deneme sayısına ulaşıldı. Lütfen daha sonra tekrar deneyin."
104
-
105
- def fn_sum_text(transkript_text, word_count, model_sel, lang_sel, action_sel, GEMINI_API_KEY):
106
- if not GEMINI_API_KEY:
107
- return "Lütfen Gemini API anahtarını girin."
108
-
109
- if not transkript_text:
110
- return "Önce transkript alınmalıdır."
111
-
112
- try:
113
- client = genai.Client(api_key=GEMINI_API_KEY)
114
- prompt = f"{transkript_text} metni {word_count} sayıda kelimeyle {lang_sel} dilinde {action_sel}"
115
-
116
- max_retries = 3
117
- retry_delay = 2
118
-
119
- for attempt in range(max_retries):
120
- try:
121
- response = client.models.generate_content(
122
- model=model_sel,
123
- contents=[prompt]
124
- )
125
- return response.text
126
- except Exception as e:
127
- if attempt < max_retries - 1:
128
- time.sleep(retry_delay)
129
- continue
130
- return f"API hatası: {str(e)}"
131
-
132
- except Exception as e:
133
- return f"Özet oluşturulurken hata: {str(e)}"
134
-
135
- with gr.Blocks() as demo:
136
- gr.Markdown("## YouTube Video Transkript ve Özet Aracı")
137
-
138
- with gr.Row():
139
- with gr.Column():
140
- video_url = gr.Textbox(
141
- label="YouTube Video URL",
142
- placeholder="https://www.youtube.com/watch?v=...",
143
- show_label=True
144
- )
145
- trs_btn = gr.Button('Transkripti Al', variant="primary")
146
-
147
- with gr.Group():
148
- GEMINI_API_KEY = gr.Textbox(
149
- label="GEMINI API KEY",
150
- placeholder="Gemini API anahtarınızı girin",
151
- type="password",
152
- show_label=True
153
- )
154
- word_count = gr.Slider(
155
- minimum=50,
156
- maximum=1000,
157
- value=200,
158
- step=10,
159
- label="Özet Kelime Sayısı"
160
- )
161
- model_sel = gr.Dropdown(
162
- choices=['gemini-2.0-flash', 'gemini-2.0-flash-lite', 'gemini-1.5-pro'],
163
- value='gemini-2.0-flash',
164
- label="Model Seçimi"
165
- )
166
- lang_sel = gr.Dropdown(
167
- choices=['Türkçe', 'İngilizce', 'Almanca'],
168
- value='Türkçe',
169
- label="Dil Seçimi"
170
- )
171
- action_sel = gr.Dropdown(
172
- choices=['Özetle', 'tam çeviri yap.'],
173
- value='Özetle',
174
- label="İşlem"
175
- )
176
- sum_btn = gr.Button('Özetle', variant="primary")
177
-
178
- with gr.Column():
179
- transkript_text = gr.Textbox(
180
- label='Transkript',
181
- lines=10,
182
- show_label=True
183
- )
184
- sum_text = gr.Textbox(
185
- label='Özet',
186
- lines=10,
187
- show_label=True
188
- )
189
-
190
- trs_btn.click(
191
- fn=get_transcript,
192
- inputs=video_url,
193
- outputs=transkript_text,
194
- api_name="get_transcript"
195
- )
196
-
197
- sum_btn.click(
198
- fn=fn_sum_text,
199
- inputs=[transkript_text, word_count, model_sel, lang_sel, action_sel, GEMINI_API_KEY],
200
- outputs=sum_text,
201
- api_name="summarize"
202
- )
203
-
204
- if __name__ == '__main__':
205
- # Boş port bul
206
- port = find_free_port()
207
- if port is None:
208
- print("Kullanılabilir port bulunamadı. Lütfen farklı bir port aralığı deneyin.")
209
- exit(1)
210
-
211
- print(f"Uygulama {port} portunda başlatılıyor...")
212
- demo.launch(
213
- server_name="127.0.0.1", # Localhost'a değiştirdik
214
- server_port=port,
215
- show_error=True,
216
- share=False
217
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from google import genai
3
+ import requests
4
+ import json
5
+ import re
6
+ import os
7
+ from urllib.parse import urlparse, parse_qs
8
+
9
+ # Video ID çıkarma fonksiyonu
10
+ def extract_video_id(url):
11
+ # YouTube URL formatları için regex
12
+ youtube_regex = r'(https?://)?(www\.)?(youtube|youtu|youtube-nocookie)\.(com|be)/(watch\?v=|embed/|v/|.+\?v=)?([^&=%\?]{11})'
13
+
14
+ match = re.match(youtube_regex, url)
15
+ if match:
16
+ return match.group(6)
17
+
18
+ # URL parametrelerinden ID çıkarma
19
+ parsed_url = urlparse(url)
20
+ if parsed_url.netloc in ['youtube.com', 'www.youtube.com']:
21
+ query_params = parse_qs(parsed_url.query)
22
+ if 'v' in query_params:
23
+ return query_params['v'][0]
24
+
25
+ # youtu.be URL'leri için
26
+ if parsed_url.netloc == 'youtu.be':
27
+ return parsed_url.path.strip('/')
28
+
29
+ return None
30
+
31
+ # RapidAPI üzerinden transkript alma fonksiyonu
32
+ def get_transcript_via_rapidapi(video_url):
33
+ try:
34
+ # Video ID'yi çıkar
35
+ video_id = extract_video_id(video_url)
36
+ if not video_id:
37
+ return "Geçersiz YouTube URL'si. Lütfen geçerli bir YouTube video URL'si girin."
38
+
39
+ # Hugging Face'de ayarladığınız secret değeri al
40
+ RAPID_API_KEY = os.environ.get("RAPID_API_KEY", "")
41
+
42
+ if not RAPID_API_KEY:
43
+ return "RapidAPI anahtarı bulunamadı. Lütfen Hugging Face Space ayarlarında RAPID_API_KEY adlı bir secret oluşturun."
44
+
45
+ # ----- RapidAPI Endpoint Seçeneği 1: YouTube Transcriptor -----
46
+ # API endpoint ve parametreleri
47
+ url = "https://youtube-transcriptor.p.rapidapi.com/transcript"
48
+ querystring = {"video_id": video_id, "lang": "tr"}
49
+ headers = {
50
+ "X-RapidAPI-Key": RAPID_API_KEY,
51
+ "X-RapidAPI-Host": "youtube-transcriptor.p.rapidapi.com"
52
+ }
53
+
54
+ # API isteği gönder
55
+ response = requests.get(url, headers=headers, params=querystring)
56
+
57
+ # ----- VEYA -----
58
+
59
+ # ----- RapidAPI Endpoint Seçeneği 2: Ultimate YouTube API -----
60
+ # url = "https://ultimate-youtube-api.p.rapidapi.com/video/transcript"
61
+ # querystring = {"id": video_id}
62
+ # headers = {
63
+ # "X-RapidAPI-Key": RAPID_API_KEY,
64
+ # "X-RapidAPI-Host": "ultimate-youtube-api.p.rapidapi.com"
65
+ # }
66
+ # response = requests.get(url, headers=headers, params=querystring)
67
+
68
+ # API yanıtını kontrol et
69
+ if response.status_code == 200:
70
+ try:
71
+ data = response.json()
72
+
73
+ # API'nin yanıt formatına göre ayarla - YouTube Transcriptor API için:
74
+ if data and 'transcript' in data:
75
+ transcript_parts = []
76
+ for item in data['transcript']:
77
+ if 'text' in item:
78
+ transcript_parts.append(item['text'])
79
+ return " ".join(transcript_parts)
80
+
81
+ # Ultimate YouTube API formatı için:
82
+ # if data and isinstance(data, list):
83
+ # transcript_parts = []
84
+ # for item in data:
85
+ # if 'text' in item:
86
+ # transcript_parts.append(item['text'])
87
+ # return " ".join(transcript_parts)
88
+
89
+ return "Transkript verileri beklenen formatta değil. Manuel olarak girmeyi deneyin."
90
+ except Exception as e:
91
+ return f"JSON verileri işlenirken hata: {str(e)}. API yanıtı: {response.text[:100]}..."
92
+ else:
93
+ return f"API yanıt vermedi (Hata kodu: {response.status_code}). Yanıt: {response.text[:100]}... Lütfen transkripti manuel olarak girin."
94
+
95
+ except Exception as e:
96
+ return f"Transkript alınırken hata oluştu: {str(e)}. Lütfen transkripti manuel olarak girin."
97
+
98
+ # Gemini API ile metni özetleme
99
+ def fn_sum_text(transkript_text, word_count, model_sel, lang_sel, action_sel):
100
+ try:
101
+ # Hugging Face'de ayarladığınız secret değeri al
102
+ GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY", "")
103
+
104
+ if not GEMINI_API_KEY:
105
+ return "Gemini API anahtarı bulunamadı. Lütfen Hugging Face Space ayarlarında GEMINI_API_KEY adlı bir secret oluşturun."
106
+
107
+ client = genai.Client(api_key=GEMINI_API_KEY)
108
+ prompt = f"{transkript_text} metni {word_count} sayıda kelimeyle {lang_sel} dilinde {action_sel}"
109
+
110
+ response = client.models.generate_content(
111
+ model=model_sel,
112
+ contents=[prompt]
113
+ )
114
+ return response.text
115
+ except Exception as e:
116
+ return f"Özet oluşturulurken hata: {str(e)}"
117
+
118
+ # Her ikisini birleştiren fonksiyon
119
+ def process_video(video_url, word_count, model_sel, lang_sel, action_sel):
120
+ # Önce transkripti al
121
+ transcript = get_transcript_via_rapidapi(video_url)
122
+
123
+ # Hata kontrolü
124
+ if transcript.startswith("Hata") or transcript.startswith("Geçersiz") or transcript.startswith("API"):
125
+ return transcript, ""
126
+
127
+ # Transkript başarıyla alındıysa, özetle
128
+ summary = fn_sum_text(transcript, word_count, model_sel, lang_sel, action_sel)
129
+ return transcript, summary
130
+
131
+ # Gradio arayüzü
132
+ with gr.Blocks(title="YouTube Transcript Özetleyici") as demo:
133
+ gr.Markdown("""
134
+ # YouTube Transcript Özetleyici
135
+
136
+ ## Nasıl Kullanılır:
137
+ 1. YouTube video URL'sini girin
138
+ 2. Özet ayarlarını yapın
139
+ 3. "Transkript Al ve Özetle" butonuna tıklayın
140
+
141
+ Not: Bu uygulama RapidAPI ve Gemini API'yi kullanır. API anahtarları Hugging Face Space'in secret bölümünde saklanmalıdır.
142
+ """)
143
+
144
+ with gr.Row():
145
+ with gr.Column():
146
+ video_url = gr.Textbox(
147
+ placeholder="https://www.youtube.com/watch?v=...",
148
+ label="YouTube Video URL'si"
149
+ )
150
+
151
+ with gr.Accordion("Özet Ayarları", open=True):
152
+ word_count = gr.Slider(
153
+ minimum=50,
154
+ maximum=1000,
155
+ value=200,
156
+ step=10,
157
+ label="Özet Kelime Sayısı"
158
+ )
159
+
160
+ model_sel = gr.Dropdown(
161
+ choices=[
162
+ 'gemini-2.0-flash',
163
+ 'gemini-2.0-flash-lite',
164
+ 'gemini-1.5-pro'
165
+ ],
166
+ value='gemini-2.0-flash',
167
+ label="Model Seçimi"
168
+ )
169
+
170
+ lang_sel = gr.Dropdown(
171
+ choices=[
172
+ 'Türkçe',
173
+ 'İngilizce',
174
+ 'Almanca',
175
+ 'Fransızca',
176
+ 'İspanyolca'
177
+ ],
178
+ value='Türkçe',
179
+ label="Dil Seçimi"
180
+ )
181
+
182
+ action_sel = gr.Dropdown(
183
+ choices=[
184
+ 'özetle',
185
+ 'tam çeviri yap',
186
+ 'madde madde özetle',
187
+ 'ana başlıkları çıkar'
188
+ ],
189
+ value='özetle',
190
+ label="İşlem Türü"
191
+ )
192
+
193
+ auto_process_btn = gr.Button("Transkript Al ve Özetle", variant="primary")
194
+
195
+ with gr.Accordion("Manuel İşlemler", open=False):
196
+ get_transcript_btn = gr.Button("Sadece Transkripti Al")
197
+ summarize_btn = gr.Button("Sadece Özetle")
198
+
199
+ with gr.Column():
200
+ transcript_text = gr.Textbox(
201
+ label="Video Transkripti",
202
+ placeholder="Transkript burada görünecek veya manuel olarak girebilirsiniz...",
203
+ lines=10
204
+ )
205
+
206
+ summary_text = gr.Textbox(
207
+ label="Özet Sonucu",
208
+ lines=10
209
+ )
210
+
211
+ # Buton işlevleri
212
+ auto_process_btn.click(
213
+ fn=process_video,
214
+ inputs=[video_url, word_count, model_sel, lang_sel, action_sel],
215
+ outputs=[transcript_text, summary_text]
216
+ )
217
+
218
+ get_transcript_btn.click(
219
+ fn=get_transcript_via_rapidapi,
220
+ inputs=[video_url],
221
+ outputs=[transcript_text]
222
+ )
223
+
224
+ summarize_btn.click(
225
+ fn=fn_sum_text,
226
+ inputs=[transcript_text, word_count, model_sel, lang_sel, action_sel],
227
+ outputs=[summary_text]
228
+ )
229
+
230
+ with gr.Accordion("Sorun Giderme", open=False):
231
+ gr.Markdown("""
232
+ ### Sık Karşılaşılan Sorunlar
233
+
234
+ **API Anahtarı Hatası Alıyorum**
235
+ - Hugging Face Space'inizin ayarlarında "Repository Secrets" bölümünde "RAPID_API_KEY" ve "GEMINI_API_KEY" adlı iki secret oluşturduğunuzdan emin olun.
236
+
237
+ **"Transkript Bulunamadı" Hatası**
238
+ - Videonun altyazıları bulunmuyor olabilir
239
+ - Seçilen RapidAPI servisi bu video için altyazı sunmuyor olabilir
240
+ - Farklı bir RapidAPI endpoint'i deneyebilirsiniz (kod içinde yorum satırlarındaki alternatif endpoint'i kullanın)
241
+
242
+ **Diğer Sorunlar**
243
+ - Hugging Face Space'in loglarını kontrol edin
244
+ - RapidAPI kullanım limitinizi aşmış olabilirsiniz
245
+ """)
246
+
247
+ # Uygulamayı başlat
248
+ if __name__ == '__main__':
249
+ demo.launch()