Spaces:
Runtime error
Runtime error
| import os | |
| import subprocess | |
| import yt_dlp | |
| def download_audio_from_youtube(url_or_query: str, output_dir: str = "temp_audio") -> str: | |
| """ | |
| Downloads audio from YouTube using yt-dlp and converts it to a mono WAV file at 16kHz. | |
| Accepts a YouTube URL or a search query (e.g., "ytsearch1:Hillsong Hosanna"). | |
| Returns: Path to the downloaded .wav file, or None if extraction fails. | |
| """ | |
| if not os.path.exists(output_dir): | |
| os.makedirs(output_dir) | |
| # Output file template (using a unique identifier) | |
| # We will generate a unique filename | |
| output_filename = os.path.join(output_dir, "%(id)s.%(ext)s") | |
| ydl_opts = { | |
| 'format': 'bestaudio/best', | |
| 'outtmpl': output_filename, | |
| # Convert to WAV | |
| 'postprocessors': [{ | |
| 'key': 'FFmpegExtractAudio', | |
| 'preferredcodec': 'wav', | |
| 'preferredquality': '192', | |
| }], | |
| # Limit search results to 1 if it is a query | |
| 'noplaylist': True, | |
| 'quiet': True, | |
| 'no_warnings': True, | |
| } | |
| # Check if the input is a YouTube URL, if not, treat it as a search query | |
| is_url = url_or_query.startswith("http://") or url_or_query.startswith("https://") | |
| if not is_url: | |
| search_query = f"ytsearch1:{url_or_query} audio" | |
| else: | |
| search_query = url_or_query | |
| try: | |
| with yt_dlp.YoutubeDL(ydl_opts) as ydl: | |
| info = ydl.extract_info(search_query, download=True) | |
| if 'entries' in info: | |
| # Search query returns a list under entries | |
| video_info = info['entries'][0] | |
| else: | |
| video_info = info | |
| video_id = video_info['id'] | |
| downloaded_file = os.path.join(output_dir, f"{video_id}.wav") | |
| # Postprocess to 16kHz mono WAV for optimal Whisper / Librosa usage | |
| resampled_file = os.path.join(output_dir, f"{video_id}_16k.wav") | |
| # We use ffmpeg to convert to 16kHz mono | |
| ffmpeg_cmd = [ | |
| 'ffmpeg', '-y', | |
| '-i', downloaded_file, | |
| '-ar', '16000', | |
| '-ac', '1', | |
| resampled_file | |
| ] | |
| # Run ffmpeg | |
| subprocess.run(ffmpeg_cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) | |
| # Delete original WAV file to save space | |
| if os.path.exists(downloaded_file): | |
| os.remove(downloaded_file) | |
| return resampled_file | |
| except Exception as e: | |
| print(f"Error downloading audio from YouTube: {e}") | |
| return None | |
| if __name__ == "__main__": | |
| # Test query | |
| path = download_audio_from_youtube("Hosanna Hillsong") | |
| print(f"Downloaded to: {path}") | |