vidload 0.1.11 → 0.2.1
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 +4 -4
- data/lib/vidload/cli.rb +26 -28
- data/lib/vidload/mp2t/api.rb +206 -185
- data/lib/vidload/mp2t.rb +6 -2
- data/lib/vidload/version.rb +3 -1
- data/lib/vidload.rb +5 -3
- metadata +30 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e25ffa5a4bdbfdadd4ee261da31fab7f78e15f6865196bec9ed6824d827918cc
|
|
4
|
+
data.tar.gz: 85cbad777cffda334cf26c8992fe42b8a209eaed2b6210cea733e1f54f7cadcb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 898294dbb222d1d84f31cde9b4b30f7689de6cd18bacf2dd452496346be24f83245d24f52c1125291256020533e5b759091f4c67a7d7a9b47ed7457416a29633
|
|
7
|
+
data.tar.gz: 6bfae7fb0047df91c7aecfc6cc0f6302f895b6872e52dedad7751a2fbb39f97ee29966a437a5f1ba8b1dfd8324c34704e846cd930e1768324e8a2f0d64343bde
|
data/lib/vidload/cli.rb
CHANGED
|
@@ -1,34 +1,32 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
desc "mp2t VIDEO_URL", "download a mp2t containerized video"
|
|
5
|
-
method_option :video_name, type: :string, required: false
|
|
6
|
-
method_option :author_name, type: :string, required: false
|
|
7
|
-
method_option :hls_url, type: :string, required: true
|
|
8
|
-
method_option :master_playlist_name, type: :string, required: true
|
|
9
|
-
method_option :playwright_cli_path, type: :string, required: true
|
|
10
|
-
method_option :video_referer, type: :string, required: true
|
|
11
|
-
method_option :ts_seg_pattern, type: :string, required: true
|
|
12
|
-
method_option :hls_index_pattern, type: :string, required: true
|
|
13
|
-
def mp2t(video_url)
|
|
14
|
-
params = {
|
|
15
|
-
video_url: video_url,
|
|
16
|
-
video_name: options[:video_name],
|
|
17
|
-
hls_url: options[:hls_url],
|
|
18
|
-
master_playlist_name: options[:master_playlist_name],
|
|
19
|
-
playwright_cli_path: options[:playwright_cli_path],
|
|
20
|
-
video_referer: options[:video_referer],
|
|
21
|
-
ts_seg_pattern: options[:ts_seg_pattern],
|
|
22
|
-
hls_index_pattern: options[:hls_index_pattern],
|
|
23
|
-
author_name: options[:author_name]
|
|
24
|
-
}
|
|
3
|
+
require 'thor'
|
|
25
4
|
|
|
26
|
-
|
|
27
|
-
|
|
5
|
+
module Vidload
|
|
6
|
+
class Cli < Thor
|
|
7
|
+
desc 'mp2t VIDEO_URL', 'download a mp2t containerized video'
|
|
8
|
+
method_option :video_name, type: :string, required: false
|
|
9
|
+
method_option :author_name, type: :string, required: false
|
|
10
|
+
method_option :output_dir, type: :string, required: false
|
|
11
|
+
method_option :hls_url, type: :string, required: true
|
|
12
|
+
method_option :master_playlist_name, type: :string, required: true
|
|
13
|
+
method_option :playwright_cli_path, type: :string, required: true
|
|
14
|
+
method_option :video_referer, type: :string, required: true
|
|
15
|
+
method_option :ts_seg_pattern, type: :string, required: true
|
|
16
|
+
method_option :hls_index_pattern, type: :string, required: true
|
|
17
|
+
def mp2t(video_url)
|
|
18
|
+
params = {
|
|
19
|
+
video_url: video_url,
|
|
20
|
+
**options
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
process_mp2t(params)
|
|
24
|
+
end
|
|
28
25
|
|
|
29
|
-
|
|
26
|
+
private
|
|
30
27
|
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
def process_mp2t(params)
|
|
29
|
+
raise NotImplementedError
|
|
30
|
+
end
|
|
33
31
|
end
|
|
34
32
|
end
|
data/lib/vidload/mp2t/api.rb
CHANGED
|
@@ -1,218 +1,239 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
ts_seg_pattern:,
|
|
27
|
-
hls_index_pattern:,
|
|
28
|
-
author_name:
|
|
29
|
-
)
|
|
30
|
-
raise ArgumentError, "video_url must be provided" unless video_url
|
|
31
|
-
raise ArgumentError, "hls_url must be provided" unless hls_url
|
|
32
|
-
raise ArgumentError, "master_playlist_name must be provided" unless master_playlist_name
|
|
33
|
-
raise ArgumentError, "playwright_cli_path must be provided" unless playwright_cli_path
|
|
34
|
-
raise ArgumentError, "video_referer must be provided" unless video_referer
|
|
35
|
-
raise ArgumentError, "ts_seg_pattern must be provided" unless ts_seg_pattern
|
|
36
|
-
raise ArgumentError, "hls_index_pattern must be provided" unless hls_index_pattern
|
|
37
|
-
|
|
38
|
-
@video_url = video_url
|
|
39
|
-
@hls_url = hls_url
|
|
40
|
-
@master_playlist_name = master_playlist_name
|
|
41
|
-
@playwright_cli_path = playwright_cli_path
|
|
42
|
-
@video_referer = video_referer
|
|
43
|
-
@ts_seg_pattern = ts_seg_pattern
|
|
44
|
-
@hls_index_pattern = hls_index_pattern
|
|
45
|
-
@max_lines = IO.console.winsize[0]
|
|
46
|
-
@author_name = author_name
|
|
47
|
-
@video_name = if @author_name then "#{@author_name}_#{video_name}" else nil end
|
|
48
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'playwright'
|
|
4
|
+
require 'tty-spinner'
|
|
5
|
+
require 'open3'
|
|
6
|
+
require 'm3u8'
|
|
7
|
+
require 'io/console'
|
|
8
|
+
|
|
9
|
+
module Vidload
|
|
10
|
+
module Mp2t
|
|
11
|
+
module Api
|
|
12
|
+
DEMUXER_PATH = "#{__dir__}/remuxer.sh"
|
|
13
|
+
VIDEO_DOWNLOADED_EVENT_QUEUE = Queue.new
|
|
14
|
+
VIDEO_INDEX_EVENT_QUEUE = Queue.new
|
|
15
|
+
ANSI_BOLD_WHITE = "\033[1;97m"
|
|
16
|
+
ANSI_LIGHT_GREY = "\033[37m"
|
|
17
|
+
ANSI_RESET = "\033[0m"
|
|
18
|
+
|
|
19
|
+
class DownloaderBuilder
|
|
20
|
+
REQUIRED_ARGS = %i[video_url hls_url master_playlist_name playwright_cli_path video_referer
|
|
21
|
+
ts_seg_pattern hls_index_pattern].freeze
|
|
22
|
+
|
|
23
|
+
def initialize
|
|
24
|
+
@kwargs = {}
|
|
25
|
+
end
|
|
49
26
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
hls_url: ARGV[2],
|
|
55
|
-
master_playlist_name: ARGV[3],
|
|
56
|
-
playwright_cli_path: ARGV[4],
|
|
57
|
-
video_referer: ARGV[5],
|
|
58
|
-
ts_seg_pattern: ARGV[6],
|
|
59
|
-
hls_index_pattern: ARGV[7],
|
|
60
|
-
author_name: ARGV[8],
|
|
61
|
-
)
|
|
62
|
-
end
|
|
27
|
+
def with_kwargs(**kwargs)
|
|
28
|
+
@kwargs = kwargs
|
|
29
|
+
self
|
|
30
|
+
end
|
|
63
31
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
video_name: hash[:video_name],
|
|
69
|
-
hls_url: hash[:hls_url],
|
|
70
|
-
master_playlist_name: hash[:master_playlist_name],
|
|
71
|
-
playwright_cli_path: hash[:playwright_cli_path],
|
|
72
|
-
video_referer: hash[:video_referer],
|
|
73
|
-
ts_seg_pattern: hash[:ts_seg_pattern],
|
|
74
|
-
hls_index_pattern: hash[:hls_index_pattern],
|
|
75
|
-
)
|
|
76
|
-
end
|
|
32
|
+
def with_video_url(video_url)
|
|
33
|
+
@kwargs[:video_url] = video_url
|
|
34
|
+
self
|
|
35
|
+
end
|
|
77
36
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
page = browser.new_page
|
|
37
|
+
def with_video_name(video_name)
|
|
38
|
+
@kwargs[:video_name] = video_name
|
|
39
|
+
self
|
|
40
|
+
end
|
|
83
41
|
|
|
84
|
-
|
|
85
|
-
|
|
42
|
+
def with_author_name(author_name)
|
|
43
|
+
@kwargs[:author_name] = author_name
|
|
44
|
+
self
|
|
45
|
+
end
|
|
86
46
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
47
|
+
def with_hls_url(hls_url)
|
|
48
|
+
@kwargs[:hls_url] = hls_url
|
|
49
|
+
self
|
|
50
|
+
end
|
|
90
51
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
puts "\tvideo_url=#{@video_url}"
|
|
96
|
-
puts "\tvideo_name=#{@video_name}"
|
|
97
|
-
puts "\thls_url=#{@hls_url}"
|
|
98
|
-
puts "\tmaster_playlist_name=#{@master_playlist_name}"
|
|
99
|
-
puts "\tplaywright_cli_path=#{@playwright_cli_path}"
|
|
100
|
-
puts "\tvideo_referer=#{@video_referer}"
|
|
101
|
-
puts "\tts_seg_pattern=#{@ts_seg_pattern}"
|
|
102
|
-
puts "\thls_index_pattern=#{@hls_index_pattern}"
|
|
103
|
-
puts "\tauthor_name=#{@author_name}"
|
|
104
|
-
end
|
|
52
|
+
def with_master_playlist_name(master_playlist_name)
|
|
53
|
+
@kwargs[:master_playlist_name] = master_playlist_name
|
|
54
|
+
self
|
|
55
|
+
end
|
|
105
56
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
spinner.success("(done)")
|
|
111
|
-
end
|
|
57
|
+
def with_playwright_cli_path(playwright_cli_path)
|
|
58
|
+
@kwargs[:playwright_cli_path] = playwright_cli_path
|
|
59
|
+
self
|
|
60
|
+
end
|
|
112
61
|
|
|
113
|
-
|
|
62
|
+
def with_video_referer(video_referer)
|
|
63
|
+
@kwargs[:video_referer] = video_referer
|
|
64
|
+
self
|
|
65
|
+
end
|
|
114
66
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
@lines = [""] * @max_lines
|
|
119
|
-
page.on("response", -> (resp) { listen_to_video_starts(resp) })
|
|
120
|
-
navigate_to_url(@video_url, page)
|
|
121
|
-
video_starter_callbacks.each do |callback|
|
|
122
|
-
res = callback.call(page)
|
|
123
|
-
if !@video_name && res[:video_name]
|
|
124
|
-
@video_name = res[:video_name]
|
|
67
|
+
def with_ts_seg_pattern(ts_seg_pattern)
|
|
68
|
+
@kwargs[:ts_seg_pattern] = ts_seg_pattern
|
|
69
|
+
self
|
|
125
70
|
end
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
@
|
|
71
|
+
|
|
72
|
+
def with_hls_index_pattern(hls_index_pattern)
|
|
73
|
+
@kwargs[:hls_index_pattern] = hls_index_pattern
|
|
74
|
+
self
|
|
129
75
|
end
|
|
130
|
-
end
|
|
131
|
-
end
|
|
132
76
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
77
|
+
def with_output_dir(output_dir)
|
|
78
|
+
@kwargs[:output_dir] = output_dir
|
|
79
|
+
self
|
|
80
|
+
end
|
|
136
81
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
82
|
+
def build
|
|
83
|
+
REQUIRED_ARGS.each do |required_arg|
|
|
84
|
+
raise ArgumentError, "#{required_arg} must be provided" unless @kwargs[required_arg]
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
@kwargs[:output_dir] = './' unless @kwargs[:output_dir]
|
|
88
|
+
@kwargs[:video_name] = "#{@kwargs[:author_name]}_#{@kwargs[:video_name]}" if @kwargs[:author_name]
|
|
89
|
+
|
|
90
|
+
Downloader.new(**@kwargs)
|
|
144
91
|
end
|
|
145
92
|
end
|
|
146
|
-
print "\r\e[2K"
|
|
147
|
-
puts "✔ Video downloaded successfully! Available in ./#{@video_name}.mp4"
|
|
148
|
-
VIDEO_DOWNLOADED_EVENT_QUEUE << true
|
|
149
|
-
end
|
|
150
93
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
match = last_item.match(/#{@ts_seg_pattern}/i)
|
|
157
|
-
@seg_qty = match[:seg_nb].to_i
|
|
94
|
+
class Downloader
|
|
95
|
+
def initialize(**kwargs)
|
|
96
|
+
@max_lines = IO.console.winsize[0]
|
|
97
|
+
@kwargs = kwargs
|
|
98
|
+
end
|
|
158
99
|
|
|
159
|
-
|
|
160
|
-
|
|
100
|
+
def self.builder
|
|
101
|
+
DownloaderBuilder.new
|
|
161
102
|
end
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
else
|
|
166
|
-
@pending_hls_response = response
|
|
103
|
+
|
|
104
|
+
def self.from_hash(hash)
|
|
105
|
+
builder.with_kwargs(**hash).build
|
|
167
106
|
end
|
|
168
|
-
end
|
|
169
|
-
end
|
|
170
107
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
108
|
+
# main func to be called in your own scripts defined under web/
|
|
109
|
+
def download_video(video_starter_callbacks: [])
|
|
110
|
+
Playwright.create(playwright_cli_executable_path: @kwargs[:playwright_cli_path]) do |playwright|
|
|
111
|
+
browser = playwright.chromium.launch
|
|
112
|
+
page = browser.new_page
|
|
176
113
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
114
|
+
manage_video_download(page, *video_starter_callbacks)
|
|
115
|
+
wait_until_video_downloaded
|
|
116
|
+
|
|
117
|
+
browser.close
|
|
118
|
+
end
|
|
181
119
|
end
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
120
|
|
|
185
|
-
|
|
186
|
-
|
|
121
|
+
def display_calling_args
|
|
122
|
+
puts 'Constants:'
|
|
123
|
+
puts "\tDEMUXER_PATH=#{DEMUXER_PATH}"
|
|
124
|
+
puts 'Called with:'
|
|
125
|
+
@kwargs.each do |key, value|
|
|
126
|
+
puts "\t#{key}=#{value}"
|
|
127
|
+
end
|
|
128
|
+
end
|
|
187
129
|
|
|
188
|
-
|
|
189
|
-
|
|
130
|
+
def self.display_with_spinner(loading_msg = 'Loading...')
|
|
131
|
+
spinner = TTY::Spinner.new("[:spinner] #{loading_msg}")
|
|
132
|
+
spinner.auto_spin
|
|
133
|
+
yield
|
|
134
|
+
spinner.success('(done)')
|
|
135
|
+
end
|
|
190
136
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
137
|
+
private
|
|
138
|
+
|
|
139
|
+
def manage_video_download(page, *video_starter_callbacks)
|
|
140
|
+
@seg_qty = nil
|
|
141
|
+
@pending_hls_response = nil
|
|
142
|
+
@lines = [''] * @max_lines
|
|
143
|
+
page.on('response', ->(resp) { listen_to_video_starts(resp) })
|
|
144
|
+
navigate_to_url(@kwargs[:video_url], page)
|
|
145
|
+
video_starter_callbacks.each do |callback|
|
|
146
|
+
res = callback.call(page)
|
|
147
|
+
@kwargs[:video_name] = res[:video_name] if !@kwargs[:video_name] && res[:video_name]
|
|
148
|
+
if !@kwargs[:author_name] && res[:author_name]
|
|
149
|
+
@kwargs[:author_name] = res[:author_name]
|
|
150
|
+
@kwargs[:video_name] = "#{@kwargs[:author_name]}_#{@kwargs[:video_name]}"
|
|
151
|
+
end
|
|
152
|
+
end
|
|
197
153
|
end
|
|
198
|
-
end
|
|
199
|
-
end
|
|
200
154
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
redraw_lines()
|
|
205
|
-
end
|
|
155
|
+
def wait_until_video_downloaded
|
|
156
|
+
VIDEO_DOWNLOADED_EVENT_QUEUE.pop
|
|
157
|
+
end
|
|
206
158
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
159
|
+
def trigger_video_download(video_url, seg_qty)
|
|
160
|
+
puts 'Video starts. Starting download...'
|
|
161
|
+
run_cmd(DEMUXER_PATH, video_url, "#{@kwargs[:output_dir]}#{@kwargs[:video_name]}",
|
|
162
|
+
@kwargs[:video_referer]) do |line|
|
|
163
|
+
if (line.include?('hls @') || line.include?('https @')) && line.match?(/#{@kwargs[:ts_seg_pattern]}/i)
|
|
164
|
+
seg_nb = line.match(/#{@kwargs[:ts_seg_pattern]}/i)[:seg_nb]
|
|
165
|
+
add_line(line)
|
|
166
|
+
progress_bar(seg_nb, seg_qty)
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
print "\r\e[2K"
|
|
170
|
+
puts "✔ Video downloaded successfully! Available in #{@kwargs[:output_dir]}#{@kwargs[:video_name]}.mp4"
|
|
171
|
+
VIDEO_DOWNLOADED_EVENT_QUEUE << true
|
|
172
|
+
end
|
|
211
173
|
|
|
212
|
-
|
|
213
|
-
|
|
174
|
+
def listen_to_video_starts(response)
|
|
175
|
+
if response.url.start_with?(@kwargs[:hls_url]) && response.url.match?(/#{@kwargs[:hls_index_pattern]}/i)
|
|
176
|
+
body = response.text
|
|
177
|
+
playlist = M3u8::Playlist.read(body)
|
|
178
|
+
last_item = playlist.items.last.segment
|
|
179
|
+
match = last_item.match(/#{@kwargs[:ts_seg_pattern]}/i)
|
|
180
|
+
@seg_qty = match[:seg_nb].to_i
|
|
181
|
+
|
|
182
|
+
trigger_video_download(@pending_hls_response.url, @seg_qty) if @pending_hls_response
|
|
183
|
+
elsif response.url.start_with?(@kwargs[:hls_url]) && response.url.include?(@kwargs[:master_playlist_name])
|
|
184
|
+
if @seg_qty
|
|
185
|
+
trigger_video_download(response.url, @seg_qty)
|
|
186
|
+
else
|
|
187
|
+
@pending_hls_response = response
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
214
191
|
|
|
215
|
-
|
|
192
|
+
def navigate_to_url(url, page)
|
|
193
|
+
Downloader.display_with_spinner("Page #{url} loading...") do
|
|
194
|
+
page.goto(url)
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def run_cmd(*cmd, &block)
|
|
199
|
+
Open3.popen2e(*cmd) do |_stdin, stdout_and_stderr, _wait_thr|
|
|
200
|
+
stdout_and_stderr.each_line(&block)
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def redraw_lines
|
|
205
|
+
return if @lines.empty?
|
|
206
|
+
|
|
207
|
+
printf "\e[H"
|
|
208
|
+
printf "\e[0J"
|
|
209
|
+
|
|
210
|
+
_rows, cols = IO.console.winsize
|
|
211
|
+
@lines.each do |line|
|
|
212
|
+
if line.length > cols
|
|
213
|
+
puts "#{line.slice(0, cols - 3)}..."
|
|
214
|
+
else
|
|
215
|
+
puts line
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def add_line(line)
|
|
221
|
+
@lines << line
|
|
222
|
+
@lines.shift if @lines.size > @max_lines
|
|
223
|
+
redraw_lines
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def progress_bar(current, total, width: 40)
|
|
227
|
+
ratio = current.to_f / total
|
|
228
|
+
filled = (ratio * width).round
|
|
229
|
+
empty = width - filled
|
|
230
|
+
|
|
231
|
+
bar = '█' * filled + '░' * empty
|
|
232
|
+
percent = (ratio * 100).round(1)
|
|
233
|
+
|
|
234
|
+
print "\r[#{bar}] #{percent}% (#{current}/#{total})"
|
|
235
|
+
end
|
|
236
|
+
end
|
|
216
237
|
end
|
|
217
238
|
end
|
|
218
239
|
end
|
data/lib/vidload/mp2t.rb
CHANGED
data/lib/vidload/version.rb
CHANGED
data/lib/vidload.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Vidload
|
|
2
|
-
require_relative
|
|
3
|
-
require_relative
|
|
4
|
-
require_relative
|
|
4
|
+
require_relative 'vidload/version'
|
|
5
|
+
require_relative 'vidload/mp2t'
|
|
6
|
+
require_relative 'vidload/cli'
|
|
5
7
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: vidload
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1
|
|
4
|
+
version: 0.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Patacode <pata.codegineer@gmail.com>
|
|
@@ -10,6 +10,20 @@ bindir: bin
|
|
|
10
10
|
cert_chain: []
|
|
11
11
|
date: 2026-03-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: m3u8
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.8'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.8'
|
|
13
27
|
- !ruby/object:Gem::Dependency
|
|
14
28
|
name: playwright-ruby-client
|
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -25,61 +39,61 @@ dependencies:
|
|
|
25
39
|
- !ruby/object:Gem::Version
|
|
26
40
|
version: '1.58'
|
|
27
41
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
42
|
+
name: thor
|
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
|
30
44
|
requirements:
|
|
31
45
|
- - "~>"
|
|
32
46
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
47
|
+
version: '1.5'
|
|
34
48
|
type: :runtime
|
|
35
49
|
prerelease: false
|
|
36
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
51
|
requirements:
|
|
38
52
|
- - "~>"
|
|
39
53
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
54
|
+
version: '1.5'
|
|
41
55
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
56
|
+
name: tty-spinner
|
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
|
44
58
|
requirements:
|
|
45
59
|
- - "~>"
|
|
46
60
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: '
|
|
61
|
+
version: '0.9'
|
|
48
62
|
type: :runtime
|
|
49
63
|
prerelease: false
|
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
65
|
requirements:
|
|
52
66
|
- - "~>"
|
|
53
67
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: '
|
|
68
|
+
version: '0.9'
|
|
55
69
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name:
|
|
70
|
+
name: rake
|
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
|
58
72
|
requirements:
|
|
59
73
|
- - "~>"
|
|
60
74
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
62
|
-
type: :
|
|
75
|
+
version: '13.3'
|
|
76
|
+
type: :development
|
|
63
77
|
prerelease: false
|
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
79
|
requirements:
|
|
66
80
|
- - "~>"
|
|
67
81
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
82
|
+
version: '13.3'
|
|
69
83
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
84
|
+
name: rubocop
|
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
|
72
86
|
requirements:
|
|
73
|
-
- - "
|
|
87
|
+
- - "~>"
|
|
74
88
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '
|
|
89
|
+
version: '1.85'
|
|
76
90
|
type: :development
|
|
77
91
|
prerelease: false
|
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
93
|
requirements:
|
|
80
|
-
- - "
|
|
94
|
+
- - "~>"
|
|
81
95
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '
|
|
96
|
+
version: '1.85'
|
|
83
97
|
description:
|
|
84
98
|
email:
|
|
85
99
|
executables: []
|