Omar-youssef commited on
Commit
d4e3b06
·
1 Parent(s): 9c75488
Files changed (1) hide show
  1. link_processor.py +49 -63
link_processor.py CHANGED
@@ -1,84 +1,70 @@
1
  from pathlib import Path
2
  import yt_dlp
 
 
 
 
 
3
  import os
4
- from concurrent.futures import ThreadPoolExecutor
5
- import logging
6
- import shutil
7
 
8
 
9
  class LinkDownloader:
10
- def __init__(self, output_dir, max_workers=2):
11
  self.output_dir = Path(output_dir)
12
  self.output_dir.mkdir(parents=True, exist_ok=True)
13
- self.executor = ThreadPoolExecutor(max_workers=max_workers)
14
 
15
- # Setup logging
16
- logging.basicConfig(
17
- level=logging.INFO,
18
- format='%(asctime)s - %(levelname)s - %(message)s'
19
- )
20
- self.logger = logging.getLogger(__name__)
 
 
21
 
22
  def download_from_url(self, url):
23
- """Downloads a video from the given URL using yt_dlp."""
24
- # Create a unique subdirectory to prevent file conflicts
25
- unique_download_dir = self.output_dir / "download"
26
- unique_download_dir.mkdir(parents=True, exist_ok=True)
27
-
28
- temp_filepath = str(unique_download_dir / 'downloaded_video.%(ext)s')
29
-
30
- ydl_opts = {
31
- 'format': 'best[height<=1080]',
32
- 'outtmpl': temp_filepath,
33
- 'quiet': False,
34
- 'no_warnings': True,
35
- 'extract_audio': False,
36
- 'concurrent_fragment_downloads': 3,
37
- 'file_access_retries': 3,
38
- 'retries': 3,
39
- 'socket_timeout': 30,
40
- 'nocheckcertificate': True,
41
- }
42
-
43
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  with yt_dlp.YoutubeDL(ydl_opts) as ydl:
45
- # Get video information
46
  info = ydl.extract_info(url, download=False)
 
47
  ext = info.get('ext', 'mp4')
48
 
49
- # Submit download task to executor
50
- future = self.executor.submit(ydl.download, [url])
51
- future.result() # Wait for download to complete
52
-
53
- # Find the downloaded file
54
- downloaded_files = list(unique_download_dir.glob(f'downloaded_video.{ext}'))
55
 
56
- if not downloaded_files:
57
- self.logger.error("No files found after download.")
58
- return None
59
 
60
- # Take the first file (should be the only one)
61
- actual_filepath = str(downloaded_files[0])
 
 
62
 
63
- if os.path.exists(actual_filepath):
64
- # Copy the file to the main output directory to prevent deletion
65
- final_filepath = str(self.output_dir / f"downloaded_video.{ext}")
66
- shutil.copy2(actual_filepath, final_filepath)
67
 
68
- self.logger.info(f"Download completed: {final_filepath}")
69
- return final_filepath
70
- else:
71
- self.logger.error("File not found after download.")
72
- return None
73
-
74
- except yt_dlp.DownloadError as e:
75
- self.logger.error(f"yt_dlp error: {e}")
76
  except Exception as e:
77
- self.logger.error(f"Unexpected error: {e}")
78
-
79
- return None
80
-
81
- def __del__(self):
82
- """Ensure proper shutdown of the executor."""
83
- self.executor.shutdown(wait=True)
84
- self.logger.info("ThreadPoolExecutor shut down.")
 
1
  from pathlib import Path
2
  import yt_dlp
3
+ import tempfile
4
+ import streamlit as st
5
+ from video_processor import VideoProcessor
6
+ from audio_processor import AudioProcessor
7
+ import re
8
  import os
 
 
 
9
 
10
 
11
  class LinkDownloader:
12
+ def __init__(self, output_dir):
13
  self.output_dir = Path(output_dir)
14
  self.output_dir.mkdir(parents=True, exist_ok=True)
 
15
 
16
+ def sanitize_filename(self, title):
17
+ """Sanitize filename by removing special characters and limiting length"""
18
+ # Replace special characters with underscore
19
+ clean_name = re.sub(r'[^a-zA-Z0-9.]', '_', title)
20
+ # Limit length
21
+ if len(clean_name) > 50:
22
+ clean_name = clean_name[:50]
23
+ return clean_name
24
 
25
  def download_from_url(self, url):
26
+ """Download video from URL using yt-dlp"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  try:
28
+ # Create a temporary filename template
29
+ temp_filename = 'downloaded_video.%(ext)s'
30
+ temp_filepath = str(self.output_dir / temp_filename)
31
+
32
+ # Configure yt-dlp options
33
+ ydl_opts = {
34
+ 'format': 'best',
35
+ 'outtmpl': temp_filepath,
36
+ 'quiet': False, # Enable output for debugging
37
+ 'no_warnings': False,
38
+ 'extract_audio': False,
39
+ }
40
+
41
+ st.info("Starting video download...")
42
+ print(f"Download directory: {self.output_dir}")
43
+ print(f"Download template: {temp_filepath}")
44
+
45
+ # Download the video
46
  with yt_dlp.YoutubeDL(ydl_opts) as ydl:
47
+ # Extract info first
48
  info = ydl.extract_info(url, download=False)
49
+ # Get the actual extension
50
  ext = info.get('ext', 'mp4')
51
 
52
+ # Download the video
53
+ ydl.download([url])
 
 
 
 
54
 
55
+ # Construct the actual file path
56
+ actual_filepath = str(self.output_dir / f"downloaded_video.{ext}")
57
+ print(f"Expected downloaded file: {actual_filepath}")
58
 
59
+ # Verify file exists
60
+ if not os.path.exists(actual_filepath):
61
+ print(f"Files in directory: {os.listdir(self.output_dir)}")
62
+ raise FileNotFoundError(f"Downloaded file not found at {actual_filepath}")
63
 
64
+ print(f"File size: {os.path.getsize(actual_filepath)} bytes")
65
+ return actual_filepath
 
 
66
 
 
 
 
 
 
 
 
 
67
  except Exception as e:
68
+ st.error(f"Error during download: {str(e)}")
69
+ print(f"Download error details: {str(e)}")
70
+ return None