File size: 6,849 Bytes
80aa632 3af83fc 80aa632 3af83fc 80aa632 1ba4b6a de997dc 80aa632 cdac1d6 80aa632 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
import os
import yt_dlp
import requests
from bs4 import BeautifulSoup
import re
import subprocess
import shutil
# Set the path to your FFmpeg executable - prioritize system ffmpeg for Docker
def get_ffmpeg_path():
"""Get FFmpeg path with fallback options"""
ffmpeg_path = shutil.which("ffmpeg")
if ffmpeg_path:
return ffmpeg_path
possible_paths = [
"ffmpeg", # System ffmpeg (Docker/Linux)
r"C:\Users\abhiv\OneDrive\Desktop\agentic ai\SoundFeet\ffmpeg-7.1-essentials_build\bin\ffmpeg.exe",
"./ffmpeg/ffmpeg.exe",
"./ffmpeg-7.1-essentials_build/bin/ffmpeg.exe"
]
for path in possible_paths:
try:
if path == "ffmpeg" or not path.endswith('.exe'):
result = subprocess.run([path, '-version'], capture_output=True, timeout=5)
if result.returncode == 0:
return path
elif os.path.exists(path):
return path
except:
continue
return "ffmpeg"
FFMPEG_PATH = get_ffmpeg_path()
def create_audio_folder():
"""Create audio folder if it doesn't exist"""
if not os.path.exists("./audio"):
os.makedirs("./audio")
return "./audio"
def check_ffmpeg():
"""Check if FFmpeg is available at the specified path"""
if not os.path.exists(FFMPEG_PATH):
print(f"β FFmpeg not found at: {FFMPEG_PATH}")
print("Please check the path and make sure FFmpeg is installed.")
return False
print(f"β
FFmpeg found at: {FFMPEG_PATH}")
return True
def search_and_download_audio(audio_name):
"""Search and download audio using yt-dlp's built-in search"""
audio_folder = create_audio_folder()
sanitized_name = sanitize_filename(audio_name)
# Configure yt-dlp with FFmpeg path
ydl_opts = {
'format': 'bestaudio/best',
'outtmpl': f'{audio_folder}/{sanitized_name}.%(ext)s',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
'ffmpeg_location': os.path.dirname(FFMPEG_PATH),
'default_search': 'ytsearch', # Use YouTube search
'noplaylist': True, # Download only single video, not playlist
}
try:
print(f"π Searching for '{audio_name}' on YouTube...")
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
# Search and download the first result
search_query = f"{audio_name} audio"
ydl.download([search_query])
# Check if file was created
mp3_file = os.path.join(audio_folder, f"{sanitized_name}.mp3")
if os.path.exists(mp3_file):
file_size = os.path.getsize(mp3_file) / (1024 * 1024) # Size in MB
print(f"β
Audio '{sanitized_name}' downloaded successfully! ({file_size:.2f} MB)")
return ydl_opts['outtmpl']
else:
print("β Downloaded file not found.")
return False
except yt_dlp.utils.DownloadError as e:
print(f"β Download error: {e}")
return False
except Exception as e:
print(f"β Unexpected error: {e}")
return False
def search_youtube_improved(audio_name):
"""Alternative search method with better headers"""
search_query = f"{audio_name} audio"
url = f"https://www.youtube.com/results?search_query={search_query.replace(' ', '+')}"
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.5',
'Accept-Encoding': 'gzip, deflate',
'Connection': 'keep-alive',
}
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
# Extract video IDs using regex from the page source
video_ids = re.findall(r'watch\?v=([a-zA-Z0-9_-]{11})', response.text)
# Remove duplicates and create full URLs
video_links = []
for video_id in video_ids:
url = f"https://www.youtube.com/watch?v={video_id}"
if url not in video_links:
video_links.append(url)
return video_links[:5] # Return top 5 results
except Exception as e:
print(f"β Error searching YouTube: {e}")
return []
def sanitize_filename(name):
"""Remove invalid characters from filename"""
invalid_chars = '<>:"/\\|?*'
for char in invalid_chars:
name = name.replace(char, '')
return name.strip()
def main_sound(audio_name):
print("π΅ Audio Downloader")
print("=" * 40)
# Check FFmpeg availability first
if not check_ffmpeg():
return None
if not audio_name:
print("β Please enter a valid audio name.")
return None
# Try the direct download method first (more reliable)
print("\nπ Trying direct download method...")
file_path = search_and_download_audio(audio_name)
if file_path:
print(f"π Success! Audio saved as '{sanitize_filename(audio_name)}.mp3'")
return file_path
else:
print("\nπ Direct method failed, trying alternative search...")
# Try alternative search method
video_urls = search_youtube_improved(audio_name)
if not video_urls:
print("β No audio found. Please try a different name.")
print(
"π‘ Try more specific terms like: 'city street sounds', 'footsteps on pavement', 'urban ambient noise'")
return None
print(f"π₯ Found {len(video_urls)} results. Downloading the first one...")
# Download using the traditional method
file_path = download_audio_direct(audio_name, video_urls[0])
if file_path:
print(f"π Audio saved in 'audio' folder!")
return file_path
else:
print("β All download methods failed.")
return None
def download_audio_direct(audio_name, url):
"""Direct download method for specific URLs"""
audio_folder = create_audio_folder()
sanitized_name = sanitize_filename(audio_name)
ydl_opts = {
'format': 'bestaudio/best',
'outtmpl': f'{audio_folder}/{sanitized_name}.%(ext)s',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
'ffmpeg_location': os.path.dirname(FFMPEG_PATH),
}
try:
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
ydl.download([url])
return ydl_opts['outtmpl']
except Exception as e:
print(f"β Error: {e}")
return False
|