import requests import os import re def clean_filename(title): # Remove quotes and illegal characters title = title.strip("'").strip('"') return re.sub(r'[\\/*?:"<>|]', "", title) def download_mp3(url, quality='320'): print(f"\nšŸ” Processing: {url}") try: # Use Cobalt v9 API to download print("🌐 Requesting download from Cobalt API v9...") response = requests.post( 'https://api.cobalt.tools/api/v9/process', headers={ 'Accept': 'application/json', 'Content-Type': 'application/json' }, json={ 'url': url, 'downloadMode': 'audio', 'audioFormat': 'mp3' }, timeout=30 ) print(f"šŸ“” API Response Status: {response.status_code}") if response.status_code != 200: try: error_data = response.json() print(f"āŒ Cobalt API error: {error_data}") except: print(f"āŒ Cobalt API error: {response.text}") return {"success": False, "error": f"API returned {response.status_code}"} data = response.json() print(f"šŸ“¦ API Response: {data}") # Check for errors in response if data.get('status') == 'error': error_msg = data.get('text', 'Unknown error') print(f"āŒ Cobalt error: {error_msg}") return {"success": False, "error": error_msg} # Get download URL download_url = data.get('url') if not download_url: print(f"āŒ No download URL in response: {data}") return {"success": False, "error": "No download URL received"} print(f"šŸ“„ Downloading audio...") # Download the audio file audio_response = requests.get(download_url, stream=True, timeout=60) if audio_response.status_code != 200: print(f"āŒ Download failed: {audio_response.status_code}") return {"success": False, "error": f"Download failed with status {audio_response.status_code}"} # Try to get filename from Content-Disposition header content_disposition = audio_response.headers.get('Content-Disposition', '') if 'filename=' in content_disposition: filename = content_disposition.split('filename=')[1].strip('"') filename = clean_filename(os.path.splitext(filename)[0]) else: # Fallback: extract video ID and use it video_id = url.split('v=')[-1].split('&')[0] filename = f"youtube_{video_id}" # Ensure .mp3 extension output_path = f"music/{filename}.mp3" # Save the file with open(output_path, 'wb') as f: for chunk in audio_response.iter_content(chunk_size=8192): f.write(chunk) print(f"āœ… Success! Saved as: {filename}.mp3") print(" (Hit Refresh in the App)") return {"success": True, "title": filename} except requests.exceptions.Timeout: print("āŒ Request timed out") return {"success": False, "error": "Request timed out"} except requests.exceptions.RequestException as e: print(f"āŒ Network error: {e}") return {"success": False, "error": str(e)} except Exception as e: print(f"āŒ Error: {e}") return {"success": False, "error": str(e)} if __name__ == "__main__": if not os.path.exists("music"): os.makedirs("music") print("--- TECHDJ DOWNLOADER (via Cobalt API) ---") while True: url = input("\nšŸ”— URL (q to quit): ").strip() if url.lower() == 'q': break if url: download_mp3(url)