Guest User

Untitled

a guest
Feb 10th, 2025
21
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.55 KB | None | 0 0
  1. import socket
  2. import threading
  3. import os
  4. import yt_dlp
  5. import httpx
  6. import subprocess
  7. import re
  8. import tempfile
  9. import sys
  10.  
  11. print("Server is running...")
  12. # Function to get local IP
  13. def get_local_ip():
  14. try:
  15. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  16. s.connect(("8.8.8.8", 80)) # Connect to Google's DNS server
  17. local_ip = s.getsockname()[0]
  18. s.close()
  19. return local_ip
  20. except Exception as e:
  21. return "Error: " + str(e)
  22.  
  23. # Function to handle broadcasting the IP
  24. def run_ip_broadcast():
  25. HOST = '0.0.0.0' # Listen on all interfaces
  26. PORT = 65432
  27.  
  28. with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
  29. s.bind((HOST, PORT))
  30. print(f"IP Broadcast Server running on port {PORT}...")
  31.  
  32. try:
  33. while True:
  34. data, addr = s.recvfrom(1024)
  35. if data.decode().strip() == "GET_IP":
  36. local_ip = get_local_ip()
  37. s.sendto(local_ip.encode(), addr)
  38. print(f"Sent IP to {addr[0]}")
  39. except KeyboardInterrupt:
  40. print("\nServer stopped by user.")
  41.  
  42. def check_thumbnail_exists(url):
  43. try:
  44. response = httpx.head(url)
  45. return response.status_code == 200 # Thumbnail exists if response code is 200
  46. except httpx.RequestError:
  47. return False
  48.  
  49. # Get the best thumbnail available from YouTube
  50. def get_best_thumbnail_url(youtube_url):
  51. # Extract video ID considering different URL formats
  52. video_id = None
  53. if 'youtu.be/' in youtube_url:
  54. video_id = youtube_url.split('youtu.be/')[-1].split('?')[0]
  55. elif 'v=' in youtube_url:
  56. video_id = youtube_url.split('v=')[-1].split('&')[0]
  57. elif '/watch/' in youtube_url:
  58. video_id = youtube_url.split('/watch/')[1].split('?')[0]
  59.  
  60. if not video_id:
  61. print("Invalid YouTube URL.")
  62. return None
  63.  
  64. thumbnail_urls = {
  65. "max": f"https://img.youtube.com/vi/{video_id}/sddefault.jpg", # Highest resolution
  66. "high": f"https://img.youtube.com/vi/{video_id}/hqdefault.jpg", # High quality
  67. "medium": f"https://img.youtube.com/vi/{video_id}/mqdefault.jpg", # Medium quality
  68. "default": f"https://img.youtube.com/vi/{video_id}/default.jpg" # Default quality
  69. }
  70.  
  71. for quality, url in thumbnail_urls.items():
  72. if check_thumbnail_exists(url):
  73. print(f"Found thumbnail at {quality} quality: {url}")
  74. return url
  75.  
  76. print("No thumbnail available.")
  77. return None
  78.  
  79. # Sanitize file name to remove or replace unsupported characters
  80. def sanitize_filename(filename):
  81. sanitized = re.sub(r'[\\/*?:"<>|]', '_', filename)
  82. return sanitized
  83.  
  84. # Download the video using yt-dlp
  85. def download_video_with_placeholder(youtube_url, output_path="."):
  86. placeholder_video_file = os.path.join(output_path, "VIDEO.mp4") # Temporary video file name
  87. ydl_opts = {
  88. 'format': 'bestvideo+bestaudio/best',
  89. 'outtmpl': placeholder_video_file,
  90. 'merge_output_format': 'mp4',
  91. 'quiet': True,
  92. }
  93.  
  94. with yt_dlp.YoutubeDL(ydl_opts) as ydl:
  95. print(f"Downloading video from: {youtube_url}")
  96. ydl.download([youtube_url])
  97.  
  98. # Extract info (we'll use the original title later)
  99. info = ydl.extract_info(youtube_url, download=False)
  100. return placeholder_video_file, info
  101.  
  102. # Convert the downloaded video to MP3 using FFmpeg
  103. def convert_to_mp3_with_ffmpeg(video_file_path, output_mp3_path):
  104. print(f"Converting {video_file_path} to MP3 using FFmpeg...")
  105.  
  106. command = [
  107. 'ffmpeg', '-i', video_file_path,
  108. '-vn', # Disable video output (audio only)
  109. '-acodec', 'libmp3lame', # MP3 encoding
  110. output_mp3_path
  111. ]
  112.  
  113. subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  114. print(f"Converted to MP3: {output_mp3_path}")
  115.  
  116. # Embed thumbnail into MP3 using FFmpeg
  117. def embed_thumbnail_with_ffmpeg(mp3_file_path, thumbnail_file_path, output_mp3_with_thumbnail):
  118. print(f"Embedding thumbnail {thumbnail_file_path} into MP3 using FFmpeg...")
  119.  
  120. command = [
  121. 'ffmpeg', '-i', mp3_file_path,
  122. '-i', thumbnail_file_path, # Input the thumbnail
  123. '-map', '0:a', '-map', '1:v', # Map audio from mp3, video from thumbnail
  124. '-c', 'copy', # Copy audio data without re-encoding
  125. '-id3v2_version', '3', # Use ID3v2.3 metadata standard for album art
  126. '-metadata:s:v', 'title="Album cover"', '-metadata:s:v', 'comment="Cover (front)"',
  127. output_mp3_with_thumbnail
  128. ]
  129.  
  130. subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  131. print(f"MP3 with thumbnail saved to: {output_mp3_with_thumbnail}")
  132.  
  133. # Download the thumbnail image using httpx
  134. def download_thumbnail(thumbnail_url, output_path):
  135. if thumbnail_url:
  136. print(f"Downloading thumbnail from: {thumbnail_url}")
  137. try:
  138. with httpx.stream("GET", thumbnail_url) as response:
  139. if response.status_code == 200:
  140. thumbnail_file_path = os.path.join(output_path, "thumbnail.jpg")
  141. with open(thumbnail_file_path, 'wb') as f:
  142. for chunk in response.iter_bytes():
  143. f.write(chunk)
  144. print(f"Downloaded thumbnail to: {thumbnail_file_path}")
  145. return thumbnail_file_path
  146. except httpx.RequestError:
  147. print("Failed to download thumbnail.")
  148. return None
  149.  
  150. # Cleanup the downloaded files
  151. def cleanup(files):
  152. for file in files:
  153. if os.path.exists(file):
  154. os.remove(file)
  155. print(f"Deleted: {file}")
  156. else:
  157. print(f"File not found: {file}")
  158.  
  159. def download_audio_with_thumbnail(youtube_url, output_path="."):
  160. if not os.path.exists(output_path):
  161. os.makedirs(output_path)
  162.  
  163. # Step 1: Download the video with a placeholder name
  164. video_file_path, info = download_video_with_placeholder(youtube_url, output_path)
  165.  
  166. # Step 2: Get the best available thumbnail URL
  167. thumbnail_url = get_best_thumbnail_url(youtube_url)
  168. thumbnail_file_path = download_thumbnail(thumbnail_url, output_path)
  169.  
  170. # Step 3: Convert to MP3 using FFmpeg (with a placeholder name)
  171. mp3_file_path = os.path.join(output_path, "audio.mp3")
  172. convert_to_mp3_with_ffmpeg(video_file_path, mp3_file_path)
  173.  
  174. # Step 4: Embed the thumbnail into the MP3 using FFmpeg
  175. if thumbnail_file_path:
  176. mp3_with_thumbnail_path = os.path.join(output_path, "audio_with_thumbnail.mp3")
  177. embed_thumbnail_with_ffmpeg(mp3_file_path, thumbnail_file_path, mp3_with_thumbnail_path)
  178. else:
  179. mp3_with_thumbnail_path = mp3_file_path
  180.  
  181. # Step 5: Rename the final MP3 file to the original title
  182. final_mp3_path = os.path.join(output_path, f"{sanitize_filename(info['title'])}.mp3")
  183. os.rename(mp3_with_thumbnail_path, final_mp3_path)
  184. print(f"Renamed final MP3 to: {final_mp3_path}")
  185.  
  186. # Step 6: Clean up (delete temporary files: video, thumbnail, and initial MP3)
  187. cleanup([video_file_path, thumbnail_file_path, mp3_file_path])
  188.  
  189. return final_mp3_path # Return the path of the final MP3 file
  190.  
  191. # Function to handle each client
  192. def handle_client(conn, addr):
  193. print(f"Client {addr} connected.")
  194.  
  195. # Send input prompt
  196. conn.sendall(b"Enter YouTube video URLs separated by spaces: ")
  197.  
  198. # Receive video URLs from client
  199. data = conn.recv(1024).decode().strip()
  200. if not data:
  201. print("No URLs received. Closing connection.")
  202. conn.close()
  203. return
  204.  
  205. video_urls = data.split()
  206. processed_files = []
  207.  
  208. # Specify the directory where the temporary directory should be created
  209. temp_dir_base = "C:/Users/06mosnaz/Desktop/Laboratory/temporary_files" # Replace with the desired path
  210.  
  211. # Create a temporary directory for processing
  212. with tempfile.TemporaryDirectory(dir=temp_dir_base) as temp_dir:
  213. # Process each URL
  214. for url in video_urls:
  215. try:
  216. mp3_file = download_audio_with_thumbnail(url, output_path=temp_dir)
  217. if mp3_file:
  218. processed_files.append(mp3_file)
  219. except Exception as e:
  220. print(f"Error processing {url}: {e}")
  221.  
  222. # Send file(s) to the client
  223. for mp3_file in processed_files:
  224. file_name = os.path.basename(mp3_file)
  225. file_size = os.path.getsize(mp3_file)
  226. conn.sendall(f"{file_name}\n".encode()) # Send file name
  227. conn.recv(3) # Wait for ACK
  228. conn.sendall(f"{file_size}\n".encode()) # Send file size
  229. conn.recv(3) # Wait for ACK
  230.  
  231. with open(mp3_file, "rb") as f:
  232. conn.sendall(f.read())
  233.  
  234. os.remove(mp3_file) # Cleanup after sending
  235.  
  236. print("File transfer complete.")
  237. conn.close()
  238.  
  239. # Function to run the main server
  240. def run_server():
  241. HOST = get_local_ip()
  242. PORT = 65433 # TCP port for client communication
  243.  
  244. server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  245. server_socket.bind((HOST, PORT))
  246. server_socket.listen()
  247.  
  248. print(f"Server listening on {HOST}:{PORT}...")
  249.  
  250. while True:
  251. conn, addr = server_socket.accept()
  252. client_thread = threading.Thread(target=handle_client, args=(conn, addr))
  253. client_thread.start()
  254.  
  255. # Run both IP broadcasting and the main server simultaneously
  256. if __name__ == "__main__":
  257. threading.Thread(target=run_ip_broadcast, daemon=True).start()
  258. run_server()
Advertisement
Add Comment
Please, Sign In to add comment