arcanus commited on
Commit
f23841c
·
verified ·
1 Parent(s): ff58ad2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +205 -186
app.py CHANGED
@@ -23,6 +23,7 @@ PROXY_USER = "" # Změňte na vaše uživatelské jméno
23
  PROXY_PASS = "" # Změňte na vaše heslo
24
 
25
 
 
26
  # Middleware pro kontrolu přihlášení
27
  def login_required(f):
28
  @wraps(f)
@@ -216,183 +217,242 @@ def translate():
216
  return jsonify({'success': False, 'error': str(e)})
217
 
218
  def get_youtube_cookies():
 
 
 
 
 
 
 
 
 
 
219
  try:
220
- # Vytvoříme dočasný soubor pro cookies
221
- cookie_file = tempfile.mktemp()
 
 
 
 
 
 
 
 
 
222
 
223
- # Získáme cookies z prohlížečů
224
- cookies = []
 
 
 
 
 
 
 
 
225
  try:
226
- cookies.extend(list(browser_cookie3.chrome(domain_name='.youtube.com')))
227
- except:
228
- print("Nepodařilo se získat cookies z Chrome")
 
 
 
 
 
229
 
 
 
230
  try:
231
- cookies.extend(list(browser_cookie3.firefox(domain_name='.youtube.com')))
232
- except:
233
- print("Nepodařilo se získat cookies z Firefox")
234
 
235
- try:
236
- cookies.extend(list(browser_cookie3.edge(domain_name='.youtube.com')))
237
- except:
238
- print("Nepodařilo se získat cookies z Edge")
239
 
 
 
240
  if not cookies:
241
- print("Nebyly nalezeny žádné cookies")
 
242
  return None
243
 
244
- # Zapíšeme cookies do souboru ve formátu Netscape
245
- with open(cookie_file, 'w', encoding='utf-8') as f:
 
246
  f.write("# Netscape HTTP Cookie File\n")
247
  f.write("# https://curl.haxx.se/rfc/cookie_spec.html\n")
248
  f.write("# This is a generated file! Do not edit.\n\n")
249
 
250
  for cookie in cookies:
251
- secure = "TRUE" if cookie.secure else "FALSE"
252
- domain = cookie.domain if cookie.domain.startswith('.') else '.' + cookie.domain
253
- path = cookie.path or "/"
254
- expires = int(cookie.expires) if cookie.expires else 0
255
- name = cookie.name
256
- value = cookie.value
257
-
258
- # Formát: domain\tdomain_specified\tpath\tsecure\texpiry\tname\tvalue
259
- f.write(f"{domain}\tTRUE\t{path}\t{secure}\t{expires}\t{name}\t{value}\n")
260
-
261
- print(f"Cookies byly úspěšně uloženy do: {cookie_file}")
262
- return cookie_file
263
  except Exception as e:
264
- print(f"Chyba při získávání cookies: {str(e)}")
 
 
265
  return None
266
 
267
  def download_youtube_video(url, project_path, proxy=None, proxy_user=None, proxy_pass=None):
268
- if not url:
269
- raise Exception("No URL provided")
270
-
271
- if not ('youtube.com' in url or 'youtu.be' in url):
272
- raise Exception("Not a valid YouTube URL")
273
-
274
- filename = datetime.now().strftime("%Y%m%d_%H%M%S") + ".mp4"
275
- output_path = os.path.join(project_path, 'original_' + filename)
276
-
277
- print(f"Starting download for URL: {url}")
278
- print(f"Output path: {output_path}")
279
-
280
- # Cesta k souboru s cookies
281
- cookies_file = os.path.join(os.path.dirname(__file__), 'youtube.cookies')
282
- print(f"Hledám cookies v: {cookies_file}")
283
-
284
- # Základní konfigurace
285
- ydl_opts = {
286
- 'format': 'bv*[ext=mp4]+ba[ext=m4a]/b[ext=mp4] / bv*+ba/b',
287
- 'outtmpl': output_path,
288
- 'noplaylist': True,
289
- 'quiet': False,
290
- 'no_warnings': False,
291
- 'extract_flat': False,
292
- 'verbose': True,
293
- 'merge_output_format': 'mp4', # Vynutí výstup v MP4
294
- 'postprocessors': [{
295
- 'key': 'FFmpegVideoConvertor',
296
- 'preferedformat': 'mp4',
297
- }],
298
- 'http_headers': { # Add common headers
299
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36',
300
- 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
301
- 'Accept-Language': 'en-us,en;q=0.5',
302
- 'Sec-Fetch-Mode': 'navigate'
303
- }
304
- }
305
-
306
- # Přidáme cookies pokud existují
307
- if os.path.exists(cookies_file):
308
- print(f"✓ Soubor cookies nalezen: {cookies_file}")
309
- try:
310
- with open(cookies_file, 'r', encoding='utf-8') as f:
311
- first_line = f.readline().strip()
312
- print(f"První řádek cookies souboru: {first_line}")
313
- cookie_count = sum(1 for line in f if line.strip() and not line.startswith('#'))
314
- print(f"Počet načtených cookies: {cookie_count}")
315
-
316
- ydl_opts['cookiefile'] = cookies_file
317
- print("✓ Cookies byly úspěšně přidány do konfigurace")
318
- except Exception as e:
319
- print(f"⚠ Chyba při čtení cookies souboru: {str(e)}")
320
- else:
321
- print("⚠ VAROVÁNÍ: Soubor s cookies nebyl nalezen!")
322
- print(" - Zkontrolujte, že soubor youtube.cookies existuje ve správné složce")
323
- print(" - Některá videa nemusí být dostupná bez přihlášení")
324
-
325
  try:
326
  print("\nZahajuji stahování videa...")
327
- with yt_dlp.YoutubeDL(ydl_opts) as ydl:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
328
  try:
329
- # First try with format selection
330
- info = ydl.extract_info(url, download=False)
331
- print("\nDostupné formáty:")
332
- if hasattr(ydl, 'list_formats'):
333
- ydl.list_formats(info)
334
-
335
- thumbnail_url = info.get('thumbnail', '')
336
- print("✓ Informace o videu úspěšně získány")
337
-
338
- # Try downloading with current format
339
- ydl.download([url])
340
- except Exception as format_error:
341
- if "Requested format is not available" in str(format_error):
342
- print("⚠ Požadovaný formát není dostupný, zkouším alternativní formát...")
343
- # Try with a more basic format
344
- ydl_opts['format'] = 'best'
345
- with yt_dlp.YoutubeDL(ydl_opts) as ydl2:
346
- ydl2.download([url])
347
- else:
348
- raise format_error
349
-
350
- print("✓ Video úspěšně staženo")
351
- return output_path, thumbnail_url
352
 
353
- except Exception as e:
354
- error_str = str(e)
355
- if "Sign in to confirm your age" in error_str or "Sign in to this account" in error_str or "Private video" in error_str:
356
- error_msg = "Video vyžaduje přihlášení. Cookies pravděpodobně vypršely nebo nefungují."
357
- print(f" {error_msg}")
358
- print(" - Zkuste se přihlásit do YouTube")
359
- print(" - Exportujte nové cookies")
360
- print(" - Nahraďte stávající youtube.cookies novým souborem")
361
- raise Exception(error_msg)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
362
  else:
363
- error_msg = f"Nepodařilo se stáhnout video. Chyba: {error_str}"
364
- print(f"⚠ {error_msg}")
365
- raise Exception(error_msg)
 
 
 
 
366
 
367
  @app.route('/download_youtube', methods=['POST'])
368
  @login_required
369
  def download_yt():
370
  try:
 
371
  url = request.form.get('url')
 
 
372
  if not url:
373
  return jsonify({'success': False, 'error': 'URL není zadána'})
374
 
375
- print(f"Received download request for URL: {url}")
376
- #print(f"Using proxy: {PROXY_URL}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
377
 
378
- if any(x in url.lower() for x in ['youtube.com', 'youtu.be']):
379
- os.makedirs('uploads', exist_ok=True)
380
- try:
381
- file_path, thumbnail_url = download_youtube_video(url, 'uploads') #, PROXY_URL, PROXY_USER, PROXY_PASS
382
- if os.path.exists(file_path):
383
- return jsonify({
384
- 'success': True,
385
- 'file_path': file_path,
386
- 'filename': os.path.basename(file_path),
387
- 'thumbnail_url': thumbnail_url
388
- })
389
- else:
390
- return jsonify({'success': False, 'error': 'Soubor nebyl vytvořen po stažení'})
391
- except Exception as e:
392
- print(f"Download error: {str(e)}")
393
- return jsonify({'success': False, 'error': f'Chyba při stahování: {str(e)}'})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
394
  else:
395
- return jsonify({'success': False, 'error': 'Není platná YouTube URL'})
396
 
397
  except Exception as e:
398
  print(f"Route error: {str(e)}")
@@ -416,6 +476,7 @@ def get_subtitles():
416
 
417
  # Handle file upload
418
  if 'video' in files and files['video'].filename:
 
419
  media_filer = files['video']
420
  custom_filename = "video.mp4"
421
  upload_paths = os.path.join(project_path, custom_filename)
@@ -645,49 +706,7 @@ def get_current_video_path():
645
  })
646
  return jsonify({'success': False, 'error': 'No video path in session'})
647
 
648
- def export_youtube_cookies():
649
- try:
650
- cookies_file = os.path.join(os.path.dirname(__file__), 'youtube.cookies')
651
- print(f"Exportuji cookies do: {cookies_file}")
652
-
653
- # Seznam prohlížečů běžně dostupných na Windows
654
- browsers = ['chrome', 'firefox', 'edge']
655
-
656
- for browser in browsers:
657
- try:
658
- print(f"Zkouším získat cookies z prohlížeče: {browser}")
659
- ydl_opts = {
660
- 'cookiesfrombrowser': (browser,),
661
- 'quiet': True,
662
- }
663
-
664
- with yt_dlp.YoutubeDL(ydl_opts) as ydl:
665
- print(f"Zkouším získat cookies z prohlížeče: {browser}")
666
- # Vytvoříme dočasný soubor pro cookies
667
- cookie_file = tempfile.mktemp()
668
- ydl_opts['cookiefile'] = cookie_file
669
-
670
- # Pokusíme se získat cookies
671
- try:
672
- ydl.extract_info("https://www.youtube.com", download=False)
673
- except:
674
- pass
675
-
676
- # Pokud se soubor vytvořil, zkopírujeme ho
677
- if os.path.exists(cookie_file):
678
- shutil.copy2(cookie_file, cookies_file)
679
- print(f"Cookies úspěšně exportovány z {browser} do {cookies_file}")
680
- return cookies_file
681
- except Exception as e:
682
- print(f"Nepodařilo se exportovat cookies z {browser}: {str(e)}")
683
- continue
684
-
685
- print("Nepodařilo se exportovat cookies z žádného prohlížeče")
686
- return None
687
- except Exception as e:
688
- print(f"Chyba při exportu cookies: {str(e)}")
689
- return None
690
-
691
  # Pokud je skript spuštěn přímo, exportujeme cookies
692
  if __name__ == "__main__":
693
- export_youtube_cookies()
 
 
23
  PROXY_PASS = "" # Změňte na vaše heslo
24
 
25
 
26
+
27
  # Middleware pro kontrolu přihlášení
28
  def login_required(f):
29
  @wraps(f)
 
217
  return jsonify({'success': False, 'error': str(e)})
218
 
219
  def get_youtube_cookies():
220
+ print("Získávám cookies pomocí automatického přihlášení...")
221
+ options = webdriver.ChromeOptions()
222
+ # Removed headless mode as it often causes issues with Google login
223
+ options.add_argument('--no-sandbox')
224
+ options.add_argument('--disable-dev-shm-usage')
225
+ options.add_argument('--disable-blink-features=AutomationControlled')
226
+ options.add_argument('--disable-notifications')
227
+ options.add_experimental_option('excludeSwitches', ['enable-automation'])
228
+ options.add_experimental_option('useAutomationExtension', False)
229
+
230
  try:
231
+ driver_manager = ChromeDriverManager()
232
+ driver_path = driver_manager.install()
233
+ service = Service(driver_path)
234
+
235
+ print(f"Používám ChromeDriver z: {driver_path}")
236
+ driver = webdriver.Chrome(service=service, options=options)
237
+
238
+ # Add undetected characteristics
239
+ driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
240
+
241
+ wait = WebDriverWait(driver, 30) # Increased timeout
242
 
243
+ print("Přihlašuji se do Google účtu...")
244
+ driver.get('https://accounts.google.com/signin/v2/identifier?service=youtube')
245
+
246
+ # Wait for and interact with email field
247
+ email_input = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'input[type="email"]')))
248
+ email_input.clear()
249
+ email_input.send_keys("[email protected]")
250
+ email_input.send_keys(Keys.RETURN)
251
+
252
+ # Wait for and interact with password field
253
  try:
254
+ password_input = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'input[type="password"]')))
255
+ password_input.clear()
256
+ password_input.send_keys("Guildwars1!")
257
+ password_input.send_keys(Keys.RETURN)
258
+ except TimeoutException:
259
+ print("⚠ Timeout při čekání na pole pro heslo. Možná je vyžadováno ruční ověření.")
260
+ driver.quit()
261
+ return None
262
 
263
+ # Wait for successful login and redirect to YouTube
264
+ print("Přecházím na YouTube...")
265
  try:
266
+ wait.until(lambda driver: "youtube.com" in driver.current_url)
267
+ except TimeoutException:
268
+ driver.get('https://www.youtube.com')
269
 
270
+ wait.until(EC.presence_of_element_located((By.ID, "logo")))
 
 
 
271
 
272
+ # Get and save cookies
273
+ cookies = driver.get_cookies()
274
  if not cookies:
275
+ print(" Nepodařilo se získat cookies. Přihlášení možná selhalo.")
276
+ driver.quit()
277
  return None
278
 
279
+ cookies_file = os.path.join(os.path.dirname(__file__), 'youtube.cookies')
280
+
281
+ with open(cookies_file, 'w', encoding='utf-8') as f:
282
  f.write("# Netscape HTTP Cookie File\n")
283
  f.write("# https://curl.haxx.se/rfc/cookie_spec.html\n")
284
  f.write("# This is a generated file! Do not edit.\n\n")
285
 
286
  for cookie in cookies:
287
+ secure = "TRUE" if cookie.get('secure', False) else "FALSE"
288
+ domain = cookie['domain'] if cookie['domain'].startswith('.') else '.' + cookie['domain']
289
+ path = cookie.get('path', '/')
290
+ expires = str(int(cookie.get('expiry', 0)) if cookie.get('expiry') else 0)
291
+ f.write(f"{domain}\tTRUE\t{path}\t{secure}\t{expires}\t{cookie['name']}\t{cookie['value']}\n")
292
+
293
+ print(f"✓ Cookies úspěšně uloženy do: {cookies_file}")
294
+ driver.quit()
295
+ return cookies_file
296
+
 
 
297
  except Exception as e:
298
+ print(f"Chyba při získávání cookies: {str(e)}")
299
+ if 'driver' in locals():
300
+ driver.quit()
301
  return None
302
 
303
  def download_youtube_video(url, project_path, proxy=None, proxy_user=None, proxy_pass=None):
304
+ """Stáhne video z YouTube"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
305
  try:
306
  print("\nZahajuji stahování videa...")
307
+
308
+ # Prepare the API request
309
+ api_url = 'https://7701-185-68-219-242.ngrok-free.app/download-video'
310
+ headers = {
311
+ 'Accept': '*/*', # Accept any content type
312
+ 'Content-Type': 'application/json'
313
+ }
314
+ payload = {
315
+ 'url': url,
316
+ 'api_key': '5as4d4f12sxdf45sfg46vawd74879ad5sd5AF4g6d8f4hfgb5'
317
+ }
318
+
319
+ print(f"Odesílám požadavek na API: {api_url}")
320
+ print(f"Payload: {payload}")
321
+
322
+ # Make the API request with proper JSON encoding
323
+ response = requests.post(
324
+ api_url,
325
+ headers=headers,
326
+ json=payload,
327
+ stream=True
328
+ )
329
+
330
+ print(f"Status code: {response.status_code}")
331
+ print(f"Response headers: {dict(response.headers)}")
332
+
333
+ if response.status_code != 200:
334
+ error_message = f"API request failed with status code {response.status_code}"
335
  try:
336
+ error_message += f": {response.text[:200]}"
337
+ except Exception as e:
338
+ error_message += f" (Error reading response: {str(e)})"
339
+ raise Exception(error_message)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
340
 
341
+ # Get content type and suggested filename from headers
342
+ content_type = response.headers.get('Content-Type', '').lower()
343
+ content_disp = response.headers.get('Content-Disposition', '')
344
+
345
+ print(f"Content-Type: {content_type}")
346
+ print(f"Content-Disposition: {content_disp}")
347
+
348
+ video_path = os.path.join(project_path, "video.mp4")
349
+ total_size = 0
350
+
351
+ print("Začínám stahovat video po částech...")
352
+ with open(video_path, 'wb') as f:
353
+ for chunk in response.iter_content(chunk_size=8192):
354
+ if chunk:
355
+ chunk_size = len(chunk)
356
+ total_size += chunk_size
357
+ f.write(chunk)
358
+ print(f"\rStaženo: {total_size / (1024*1024):.2f} MB", end='', flush=True)
359
+
360
+ print("\nKontroluji stažený soubor...")
361
+ if os.path.exists(video_path):
362
+ final_size = os.path.getsize(video_path)
363
+ print(f"Velikost souboru: {final_size / (1024*1024):.2f} MB")
364
+
365
+ if final_size > 0:
366
+ print(f"✓ Video bylo úspěšně staženo do: {video_path}")
367
+ return video_path
368
+ else:
369
+ os.remove(video_path)
370
+ raise Exception("Stažený soubor je prázdný")
371
  else:
372
+ raise Exception("Soubor nebyl vytvořen")
373
+
374
+ except Exception as e:
375
+ print(f"Chyba při stahování videa: {str(e)}")
376
+ if 'video_path' in locals() and os.path.exists(video_path):
377
+ os.remove(video_path)
378
+ return None
379
 
380
  @app.route('/download_youtube', methods=['POST'])
381
  @login_required
382
  def download_yt():
383
  try:
384
+ # Get data from form submission
385
  url = request.form.get('url')
386
+ project_name = request.form.get('project_name', '')
387
+
388
  if not url:
389
  return jsonify({'success': False, 'error': 'URL není zadána'})
390
 
391
+ if not any(x in url.lower() for x in ['youtube.com', 'youtu.be']):
392
+ return jsonify({'success': False, 'error': 'Není platná YouTube URL'})
393
+
394
+ project_path = create_project_folder(project_name)
395
+ if not project_path:
396
+ return jsonify({'success': False, 'error': 'Nepodařilo se vytvořit složku projektu'})
397
+
398
+ # Get thumbnail from API
399
+ api_url = 'https://7701-185-68-219-242.ngrok-free.app/download-thumbnail'
400
+ headers = {
401
+ 'accept': 'application/json',
402
+ 'Content-Type': 'application/json'
403
+ }
404
+ payload = {
405
+ 'url': url,
406
+ 'api_key': '5as4d4f12sxdf45sfg46vawd74879ad5sd5AF4g6d8f4hfgb5'
407
+ }
408
 
409
+ # Get thumbnail URL with error handling
410
+ thumbnail_url = None # Initialize as None
411
+ try:
412
+ print(f"Sending request to thumbnail API with payload: {payload}")
413
+ thumbnail_response = requests.post(api_url, headers=headers, json=payload)
414
+ print(f"Thumbnail API response status: {thumbnail_response.status_code}")
415
+ print(f"Thumbnail API response content: {thumbnail_response.text}")
416
+
417
+ if thumbnail_response.status_code == 200:
418
+ try:
419
+ thumbnail_data = thumbnail_response.json()
420
+ if isinstance(thumbnail_data, dict):
421
+ thumbnail_url = thumbnail_data.get('thumbnail_url')
422
+ if not thumbnail_url:
423
+ # Extract video ID and use YouTube thumbnail URL directly
424
+ video_id = None
425
+ if 'youtube.com/watch?v=' in url:
426
+ video_id = url.split('watch?v=')[1].split('&')[0]
427
+ elif 'youtu.be/' in url:
428
+ video_id = url.split('youtu.be/')[1].split('?')[0]
429
+
430
+ if video_id:
431
+ thumbnail_url = f'https://img.youtube.com/vi/{video_id}/maxresdefault.jpg'
432
+
433
+ print(f"Final thumbnail URL: {thumbnail_url}")
434
+ except ValueError as e:
435
+ print(f"Error parsing thumbnail JSON: {str(e)}")
436
+ # Fallback to direct YouTube thumbnail
437
+ if 'youtube.com/watch?v=' in url:
438
+ video_id = url.split('watch?v=')[1].split('&')[0]
439
+ thumbnail_url = f'https://img.youtube.com/vi/{video_id}/maxresdefault.jpg'
440
+ except Exception as e:
441
+ print(f"Error getting thumbnail: {str(e)}")
442
+
443
+ video_path = download_youtube_video(url, project_path)
444
+
445
+ if video_path and os.path.exists(video_path):
446
+ session['video_path'] = video_path
447
+ session['project_path'] = project_path
448
+ return jsonify({
449
+ 'success': True,
450
+ 'file_path': video_path,
451
+ 'filename': os.path.basename(video_path),
452
+ 'thumbnail_url': thumbnail_url
453
+ })
454
  else:
455
+ return jsonify({'success': False, 'error': 'Nepodařilo se stáhnout video'})
456
 
457
  except Exception as e:
458
  print(f"Route error: {str(e)}")
 
476
 
477
  # Handle file upload
478
  if 'video' in files and files['video'].filename:
479
+ # Handle file upload
480
  media_filer = files['video']
481
  custom_filename = "video.mp4"
482
  upload_paths = os.path.join(project_path, custom_filename)
 
706
  })
707
  return jsonify({'success': False, 'error': 'No video path in session'})
708
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
709
  # Pokud je skript spuštěn přímo, exportujeme cookies
710
  if __name__ == "__main__":
711
+ get_youtube_cookies()
712
+