-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathyoutube_downloader.py
More file actions
131 lines (105 loc) · 4.41 KB
/
youtube_downloader.py
File metadata and controls
131 lines (105 loc) · 4.41 KB
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
#!/usr/bin/env python3
"""
YouTube Video Downloader with Optional Trimming
Requires: yt-dlp and ffmpeg
Install: pip install yt-dlp
"""
import subprocess
import sys
import argparse
import os
def check_dependencies():
"""Check if required dependencies are installed."""
try:
subprocess.run(['yt-dlp', '--version'], capture_output=True, check=True)
except (subprocess.CalledProcessError, FileNotFoundError):
print("Error: yt-dlp is not installed. Install it with: pip install yt-dlp")
sys.exit(1)
try:
subprocess.run(['ffmpeg', '-version'], capture_output=True, check=True)
except (subprocess.CalledProcessError, FileNotFoundError):
print("Error: ffmpeg is not installed. Please install ffmpeg from https://ffmpeg.org/")
sys.exit(1)
def download_video(url, output_path='downloads', start_time=None, end_time=None):
"""
Download YouTube video in high quality with optional trimming.
Args:
url: YouTube video URL
output_path: Directory to save the video
start_time: Start time in seconds (optional)
end_time: End time in seconds (optional)
"""
os.makedirs(output_path, exist_ok=True)
# Base command for high quality download
cmd = [
'yt-dlp',
'-f', 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',
'--merge-output-format', 'mp4',
'-o', f'{output_path}/%(title)s.%(ext)s'
]
# Add trimming with ffmpeg if timestamps provided
if start_time is not None or end_time is not None:
ffmpeg_args = []
if start_time is not None:
ffmpeg_args.extend(['-ss', str(start_time)])
if end_time is not None:
if start_time is not None:
duration = end_time - start_time
ffmpeg_args.extend(['-t', str(duration)])
else:
ffmpeg_args.extend(['-to', str(end_time)])
# Add codec copy for fast trimming
ffmpeg_args.extend(['-c', 'copy'])
cmd.extend(['--postprocessor-args', f'ffmpeg:{" ".join(ffmpeg_args)}'])
print(f"Downloading and trimming video (start: {start_time}s, end: {end_time}s)...")
else:
print("Downloading full video in high quality...")
cmd.append(url)
try:
subprocess.run(cmd, check=True)
print(f"\n✓ Download completed successfully!")
print(f"✓ Saved to: {os.path.abspath(output_path)}/")
except subprocess.CalledProcessError as e:
print(f"\n✗ Error downloading video: {e}")
sys.exit(1)
def main():
parser = argparse.ArgumentParser(
description='Download YouTube videos in high quality with optional trimming',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
# Download full video
python %(prog)s https://www.youtube.com/watch?v=VIDEO_ID
# Download video trimmed from 30s to 90s
python %(prog)s https://www.youtube.com/watch?v=VIDEO_ID -s 30 -e 90
# Download from 1 minute to end
python %(prog)s https://www.youtube.com/watch?v=VIDEO_ID -s 60
# Download first 2 minutes only
python %(prog)s https://www.youtube.com/watch?v=VIDEO_ID -e 120
# Specify custom output directory
python %(prog)s https://www.youtube.com/watch?v=VIDEO_ID -o my_videos
"""
)
parser.add_argument('url', help='YouTube video URL')
parser.add_argument('-s', '--start', type=float, metavar='SECONDS',
help='Start time in seconds')
parser.add_argument('-e', '--end', type=float, metavar='SECONDS',
help='End time in seconds')
parser.add_argument('-o', '--output', default='downloads', metavar='PATH',
help='Output directory (default: downloads)')
args = parser.parse_args()
# Validate timestamps
if args.start is not None and args.start < 0:
print("Error: Start time cannot be negative")
sys.exit(1)
if args.end is not None and args.end < 0:
print("Error: End time cannot be negative")
sys.exit(1)
if args.start is not None and args.end is not None and args.start >= args.end:
print("Error: Start time must be less than end time")
sys.exit(1)
print("Checking dependencies...")
check_dependencies()
download_video(args.url, args.output, args.start, args.end)
if __name__ == '__main__':
main()