File size: 5,953 Bytes
801ea60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8345790
801ea60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8345790
801ea60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
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)