music-mcp / tools /youtube_extract.py
frascuchon's picture
frascuchon HF Staff
avoid download the full youtube link playlist
8345790
import os
import yt_dlp
def extract_audio_from_youtube(
youtube_url: str,
audio_format: str = "wav",
quality: str = "best",
output_path: str = "output",
) -> str:
"""
Extract high-quality audio from a YouTube video URL using yt-dlp.
This function downloads the audio stream from YouTube videos and converts it to
the specified format while maintaining the best available quality.
Args:
youtube_url: YouTube video URL (full URL format: https://www.youtube.com/watch?v=...)
audio_format: Output audio format (default: 'wav')
Supported: 'wav' (uncompressed), 'mp3' (compressed), 'flac' (lossless)
quality: Audio quality selection (default: 'best')
Options: 'best' (highest available), 'worst' (lowest available)
output_path: Directory to save the extracted audio (default: 'output')
Returns:
Path to the extracted audio file in the specified format
Examples:
- Extract WAV audio: extract_audio_from_youtube('https://youtube.com/watch?v=...', 'wav')
- Extract MP3 audio: extract_audio_from_youtube('https://youtube.com/watch?v=...', 'mp3')
- High quality WAV: extract_audio_from_youtube(url, 'wav', 'best')
Note:
Requires internet connection for downloading
Respects YouTube's terms of service
Processing time depends on video length and connection speed
Output files are saved with descriptive names including video title
"""
try:
# Create temporary directory for downloads if no output path is provided
output_path = output_path or "output"
os.makedirs(output_path, exist_ok=True)
# Configure yt-dlp options
ydl_opts = {
"format": "bestaudio/best",
"outtmpl": os.path.join(output_path, "%(title)s.%(ext)s"),
"postprocessors": [
{
"key": "FFmpegExtractAudio",
"preferredcodec": audio_format,
"preferredquality": "192" if quality == "best" else "128",
}
],
"quiet": True,
"no_warnings": True,
"noplaylist": True,
}
# Download and extract audio
with yt_dlp.YoutubeDL(params=ydl_opts) as ydl:
info = ydl.extract_info(youtube_url, download=False)
video_title = info.get("title", "audio")
ydl.download([youtube_url])
# Find the downloaded file
expected_filename = f"{video_title}.{audio_format}"
audio_path = os.path.join(output_path, expected_filename)
# Handle special characters in filename
if not os.path.exists(audio_path):
# Try to find any audio file in the directory
audio_files = [
f for f in os.listdir(output_path) if f.endswith(f".{audio_format}")
]
if audio_files:
audio_path = os.path.join(output_path, audio_files[0])
else:
raise RuntimeError("Audio file not found after download")
return audio_path
except Exception as e:
raise RuntimeError(f"Error extracting audio from YouTube: {str(e)}")
def get_video_info(youtube_url: str) -> dict:
"""
Get information about a YouTube video without downloading.
Args:
youtube_url: YouTube video URL
Returns:
Dictionary with video information (title, duration, uploader, etc.)
"""
try:
ydl_opts = {
"quiet": True,
"no_warnings": True,
"skip_download": True,
"noplaylist": True,
}
with yt_dlp.YoutubeDL(params=ydl_opts) as ydl:
info = ydl.extract_info(youtube_url, download=False)
return {
"title": info.get("title"),
"duration": info.get("duration"),
"uploader": info.get("uploader"),
"upload_date": info.get("upload_date"),
"view_count": info.get("view_count"),
"description": info.get("description"),
"thumbnail": info.get("thumbnail"),
}
except Exception as e:
raise RuntimeError(f"Error getting video info: {str(e)}")
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="Extract audio from YouTube videos")
subparsers = parser.add_subparsers(dest="command", help="Available commands")
# Extract audio
extract_parser = subparsers.add_parser(
"extract", help="Extract audio from YouTube URL"
)
extract_parser.add_argument("url", help="YouTube video URL")
extract_parser.add_argument(
"--format",
default="wav",
choices=["wav", "mp3", "flac", "m4a"],
help="Output audio format (default: wav)",
)
extract_parser.add_argument(
"--quality",
default="best",
choices=["best", "worst"],
help="Audio quality (default: best)",
)
# Get video info
info_parser = subparsers.add_parser("info", help="Get video information")
info_parser.add_argument("url", help="YouTube video URL")
args = parser.parse_args()
try:
if args.command == "extract":
audio_path = extract_audio_from_youtube(args.url, args.format, args.quality)
print(f"Audio extracted to: {audio_path}")
elif args.command == "info":
info = get_video_info(args.url)
print(f"Title: {info['title']}")
print(f"Duration: {info['duration']} seconds")
print(f"Uploader: {info['uploader']}")
print(f"Upload date: {info['upload_date']}")
print(f"Views: {info['view_count']}")
else:
parser.print_help()
except Exception as e:
print(f"Error: {e}")
exit(1)