youtube-rb 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +703 -0
- data/Rakefile +6 -0
- data/bin/console +10 -0
- data/bin/setup +8 -0
- data/lib/youtube-rb/client.rb +160 -0
- data/lib/youtube-rb/downloader.rb +632 -0
- data/lib/youtube-rb/extractor.rb +425 -0
- data/lib/youtube-rb/options.rb +186 -0
- data/lib/youtube-rb/version.rb +3 -0
- data/lib/youtube-rb/video_info.rb +179 -0
- data/lib/youtube-rb/ytdlp_wrapper.rb +269 -0
- data/lib/youtube-rb.rb +69 -0
- data/spec/client_spec.rb +514 -0
- data/spec/download_with_mocks_spec.rb +216 -0
- data/spec/downloader_spec.rb +774 -0
- data/spec/fixtures/first_video_info.json +19 -0
- data/spec/fixtures/rickroll_full_info.json +73 -0
- data/spec/fixtures/rickroll_info.json +73 -0
- data/spec/fixtures/rickroll_segment_info.json +9 -0
- data/spec/integration/ytdlp_integration_spec.rb +109 -0
- data/spec/real_download_spec.rb +175 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/support/fixtures_helper.rb +109 -0
- data/spec/support/mocking_helper.rb +21 -0
- data/spec/support/webmock_helper.rb +132 -0
- data/spec/youtube_rb_spec.rb +200 -0
- data/spec/ytdlp_wrapper_spec.rb +178 -0
- data/youtube-rb.gemspec +39 -0
- metadata +229 -0
data/bin/console
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "youtube-rb"
|
|
5
|
+
|
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
8
|
+
|
|
9
|
+
require "irb"
|
|
10
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
module YoutubeRb
|
|
2
|
+
class Client
|
|
3
|
+
attr_reader :options
|
|
4
|
+
|
|
5
|
+
def initialize(**options)
|
|
6
|
+
@options = Options.new(**options)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Get video information without downloading
|
|
10
|
+
# @param url [String] Video URL
|
|
11
|
+
# @return [VideoInfo] Video information object
|
|
12
|
+
def info(url)
|
|
13
|
+
extractor = Extractor.new(url, @options.to_h)
|
|
14
|
+
extractor.extract_info
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Download full video
|
|
18
|
+
# @param url [String] Video URL
|
|
19
|
+
# @param options [Hash] Additional options for this download
|
|
20
|
+
# @return [String] Path to downloaded file
|
|
21
|
+
def download(url, **options)
|
|
22
|
+
merged_options = @options.dup.merge(options)
|
|
23
|
+
downloader = Downloader.new(url, merged_options)
|
|
24
|
+
downloader.download
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Download video segment
|
|
28
|
+
# @param url [String] Video URL
|
|
29
|
+
# @param start_time [Integer] Start time in seconds
|
|
30
|
+
# @param end_time [Integer] End time in seconds
|
|
31
|
+
# @param output_file [String, nil] Optional output file path
|
|
32
|
+
# @param options [Hash] Additional options for this download
|
|
33
|
+
# @return [String] Path to downloaded segment file
|
|
34
|
+
def download_segment(url, start_time, end_time, output_file: nil, **options)
|
|
35
|
+
merged_options = @options.dup.merge(options)
|
|
36
|
+
downloader = Downloader.new(url, merged_options)
|
|
37
|
+
downloader.download_segment(start_time, end_time, output_file)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Download multiple video segments (batch processing)
|
|
41
|
+
# @param url [String] Video URL
|
|
42
|
+
# @param segments [Array<Hash>] Array of segment definitions: [{start: 0, end: 30, output_file: 'seg1.mp4'}, ...]
|
|
43
|
+
# Each segment hash should contain:
|
|
44
|
+
# - :start (required) - Start time in seconds
|
|
45
|
+
# - :end (required) - End time in seconds
|
|
46
|
+
# - :output_file (optional) - Custom output file path
|
|
47
|
+
# @param options [Hash] Additional options for this download
|
|
48
|
+
# @return [Array<String>] Paths to downloaded segment files
|
|
49
|
+
# @example Download multiple segments from one video
|
|
50
|
+
# client.download_segments(url, [
|
|
51
|
+
# { start: 0, end: 30 },
|
|
52
|
+
# { start: 60, end: 90 },
|
|
53
|
+
# { start: 120, end: 150, output_file: './custom_name.mp4' }
|
|
54
|
+
# ])
|
|
55
|
+
def download_segments(url, segments, **options)
|
|
56
|
+
# Enable caching by default for batch downloads (can be overridden)
|
|
57
|
+
merged_options = @options.dup.merge({ cache_full_video: true }.merge(options))
|
|
58
|
+
downloader = Downloader.new(url, merged_options)
|
|
59
|
+
downloader.download_segments(segments)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Download only subtitles
|
|
63
|
+
# @param url [String] Video URL
|
|
64
|
+
# @param langs [Array<String>, nil] Subtitle languages to download
|
|
65
|
+
# @param options [Hash] Additional options for this download
|
|
66
|
+
# @return [void]
|
|
67
|
+
def download_subtitles(url, langs: nil, **options)
|
|
68
|
+
merged_options = @options.dup.merge(options)
|
|
69
|
+
merged_options.write_subtitles = true
|
|
70
|
+
downloader = Downloader.new(url, merged_options)
|
|
71
|
+
downloader.download_subtitles_only(langs)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Download video with subtitles and metadata
|
|
75
|
+
# @param url [String] Video URL
|
|
76
|
+
# @param options [Hash] Additional options for this download
|
|
77
|
+
# @return [String] Path to downloaded file
|
|
78
|
+
def download_with_metadata(url, **options)
|
|
79
|
+
merged_options = @options.dup.merge(
|
|
80
|
+
write_subtitles: true,
|
|
81
|
+
write_info_json: true,
|
|
82
|
+
write_thumbnail: true,
|
|
83
|
+
**options
|
|
84
|
+
)
|
|
85
|
+
downloader = Downloader.new(url, merged_options)
|
|
86
|
+
downloader.download
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Extract audio from video
|
|
90
|
+
# @param url [String] Video URL
|
|
91
|
+
# @param format [String] Audio format (mp3, aac, opus, etc.)
|
|
92
|
+
# @param quality [String] Audio quality (e.g., '192')
|
|
93
|
+
# @param options [Hash] Additional options for this download
|
|
94
|
+
# @return [String] Path to downloaded audio file
|
|
95
|
+
def extract_audio(url, format: 'mp3', quality: '192', **options)
|
|
96
|
+
merged_options = @options.dup.merge(
|
|
97
|
+
extract_audio: true,
|
|
98
|
+
audio_format: format,
|
|
99
|
+
audio_quality: quality,
|
|
100
|
+
**options
|
|
101
|
+
)
|
|
102
|
+
downloader = Downloader.new(url, merged_options)
|
|
103
|
+
downloader.download
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Check if video URL is valid and extractable
|
|
107
|
+
# @param url [String] Video URL
|
|
108
|
+
# @return [Boolean] True if URL is valid
|
|
109
|
+
def valid_url?(url)
|
|
110
|
+
return false if url.nil? || url.empty?
|
|
111
|
+
|
|
112
|
+
begin
|
|
113
|
+
info(url)
|
|
114
|
+
true
|
|
115
|
+
rescue => e
|
|
116
|
+
false
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Get available formats for video
|
|
121
|
+
# @param url [String] Video URL
|
|
122
|
+
# @return [Array<Hash>] Available formats
|
|
123
|
+
def formats(url)
|
|
124
|
+
video_info = info(url)
|
|
125
|
+
video_info.formats
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Get available subtitles for video
|
|
129
|
+
# @param url [String] Video URL
|
|
130
|
+
# @return [Hash] Available subtitles by language
|
|
131
|
+
def subtitles(url)
|
|
132
|
+
video_info = info(url)
|
|
133
|
+
video_info.subtitles
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Update default options
|
|
137
|
+
# @param options [Hash] Options to update
|
|
138
|
+
# @return [self]
|
|
139
|
+
def configure(**options)
|
|
140
|
+
@options.merge(options)
|
|
141
|
+
self
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Check if optional tools are available
|
|
145
|
+
# @return [Hash] Status of optional tools
|
|
146
|
+
def check_dependencies
|
|
147
|
+
{
|
|
148
|
+
ffmpeg: system('which ffmpeg > /dev/null 2>&1'),
|
|
149
|
+
ytdlp: YtdlpWrapper.available?,
|
|
150
|
+
ytdlp_version: YtdlpWrapper.version
|
|
151
|
+
}
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Get version information
|
|
155
|
+
# @return [String] Version string
|
|
156
|
+
def version
|
|
157
|
+
YoutubeRb::VERSION
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|