rget 4.9.0 → 4.11.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 +4 -4
- data/.devcontainer/Dockerfile +14 -0
- data/.devcontainer/devcontainer.json +30 -0
- data/.travis.yml +1 -1
- data/README.md +9 -7
- data/bin/hls-dl +11 -96
- data/lib/hibiki.rb +3 -1
- data/lib/hls.rb +10 -28
- data/lib/nicovideo.rb +1 -1
- data/lib/onsen.rb +9 -25
- data/lib/standfm.rb +62 -0
- data/lib/webradio.rb +7 -1
- data/lib/youtube.rb +40 -0
- data/rget.gemspec +3 -3
- data/rget.yaml +8 -0
- metadata +9 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 399f9407dcfa7a2c99884c4c7c1cac60fabaae386622bac006896d877e2f1c71
|
4
|
+
data.tar.gz: 5ba2047c907946753452437b51ecf3a55f3e7fa97e247c6ffab04f10badda4fc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0d57aff2683b09e53fbd663a11db02e862430d51ed97588c317e1432aa0b5d13625fc6747a8c83b210b1b394a726c48662af5c2b22ba24bbd08d8ddebf08487
|
7
|
+
data.tar.gz: de34fca3119bbb1a78704131e0a825fe3f2d0b77d1426dbe08bb0cf94eed751f6961b1c34e37a55f2907dfafed803877f692aeafffe780f9513b1b239270ba03
|
@@ -0,0 +1,14 @@
|
|
1
|
+
FROM ruby:2
|
2
|
+
ENV USER vscode
|
3
|
+
LABEL maintainer "@tdtds <t@tdtds.jp>"
|
4
|
+
RUN apt-get -y update && apt-get -y install ffmpeg && \
|
5
|
+
curl -sLo /usr/local/bin/youtube-dl http://www.yt-dl.org/downloads/latest/youtube-dl && \
|
6
|
+
chmod +x /usr/local/bin/youtube-dl && \
|
7
|
+
useradd -u 1000 -m $USER && chsh -s /bin/bash $USER
|
8
|
+
USER $USER
|
9
|
+
RUN bundle config set path vendor/bundle && \
|
10
|
+
bundle config set with development:test && \
|
11
|
+
echo 'git config --global --unset core.editor' >> /home/$USER/.bashrc && \
|
12
|
+
echo 'git config --global --unset core.sshCommand' >> /home/$USER/.bashrc && \
|
13
|
+
echo 'git ls-remote -q > /dev/null' >> /home/$USER/.bashrc
|
14
|
+
CMD [ "sleep", "infinity" ]
|
@@ -0,0 +1,30 @@
|
|
1
|
+
// For format details, see https://aka.ms/vscode-remote/devcontainer.json or this file's README at:
|
2
|
+
// https://github.com/microsoft/vscode-dev-containers/tree/v0.122.1/containers/docker-from-docker-compose
|
3
|
+
// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml.
|
4
|
+
{
|
5
|
+
"name": "rget",
|
6
|
+
"context": "..",
|
7
|
+
"dockerFile": "Dockerfile",
|
8
|
+
|
9
|
+
// Set *default* container specific settings.json values on container create.
|
10
|
+
"settings": {
|
11
|
+
"terminal.integrated.shell.linux": "/bin/bash"
|
12
|
+
},
|
13
|
+
|
14
|
+
// Add the IDs of extensions you want installed when the container is created.
|
15
|
+
"extensions": [
|
16
|
+
"rebornix.ruby"
|
17
|
+
],
|
18
|
+
|
19
|
+
// Uncomment the next line if you want start specific services in your Docker Compose config.
|
20
|
+
// "runServices": [],
|
21
|
+
|
22
|
+
// Uncomment the next line if you want to keep your containers running after VS Code shuts down.
|
23
|
+
// "shutdownAction": "none",
|
24
|
+
|
25
|
+
// Use 'postCreateCommand' to run commands after the container is created.
|
26
|
+
// "postCreateCommand": "docker --version",
|
27
|
+
|
28
|
+
// Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root.
|
29
|
+
// "remoteUser": "vscode"
|
30
|
+
}
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -5,12 +5,13 @@ Downloading newest radio programs on the web. Supported radio stations are:
|
|
5
5
|
* hibiki
|
6
6
|
* onsen
|
7
7
|
* niconico
|
8
|
-
* freshlive.tv
|
9
8
|
* himalaya.fm
|
10
9
|
* Asobi Store
|
10
|
+
* stand.fm
|
11
|
+
* YouTube (playlist only)
|
11
12
|
|
12
13
|
If you want to save files as MP3, needs `ffmpeg` command.
|
13
|
-
To download niconico video, also needs latest `youtube-dl` command (you can get it from `https://yt-dl.org/`), then specify
|
14
|
+
To download niconico video or YouTube, also needs latest `youtube-dl` command (you can get it from `https://yt-dl.org/`), then specify user ID and password to `~/.netrc` for niconico as:
|
14
15
|
|
15
16
|
```
|
16
17
|
machine niconico
|
@@ -25,9 +26,10 @@ For customize radio programs, copy `rget.yaml` to `~/.rget` or current work dire
|
|
25
26
|
* `~/.rget`
|
26
27
|
* `<command path>/../rget.yaml` (for gem)
|
27
28
|
|
28
|
-
## Installation
|
29
|
+
## Installation and Setup
|
29
30
|
```
|
30
31
|
$ gem install rget
|
32
|
+
$ rget init > ~/.rget # or your local rget.yaml
|
31
33
|
```
|
32
34
|
|
33
35
|
## Usage
|
@@ -41,14 +43,14 @@ rget yaml http://example.com/radio >> ~/.rget
|
|
41
43
|
# download and convert to mp3 THE iDOLM@STER Cinderella Girls Radio
|
42
44
|
rget imas_cg
|
43
45
|
|
44
|
-
# download
|
45
|
-
rget
|
46
|
+
# download suzakinishi only (saving movie file as .MP4)
|
47
|
+
rget suzakinishi --no-mp3
|
46
48
|
|
47
49
|
# srore mp3 file to specified directory
|
48
|
-
rget
|
50
|
+
rget matsui --path=/home/hoge/radio
|
49
51
|
|
50
52
|
# store mp3 file to radio folder of Dropbox
|
51
|
-
rget
|
53
|
+
rget shiny_radio --path=dropbpx://radio
|
52
54
|
```
|
53
55
|
|
54
56
|
### add\_mp3info command
|
data/bin/hls-dl
CHANGED
@@ -1,103 +1,18 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
require "
|
3
|
-
require "mechanize"
|
4
|
-
require 'open-uri'
|
5
|
-
require 'thread'
|
2
|
+
require "open3"
|
6
3
|
|
7
4
|
if ARGV.size != 2
|
8
|
-
$stderr.puts "
|
9
|
-
$stderr.puts "hls-dl <playlist.m3u8> <output(.
|
5
|
+
$stderr.puts "HLS downloader wrapping ffmpeg"
|
6
|
+
$stderr.puts "hls-dl <playlist.m3u8> <output(.mp4,mp3,...)>"
|
10
7
|
exit 1
|
11
8
|
end
|
12
9
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
agent.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
21
|
-
agent.get(m3u8)
|
22
|
-
body = agent.page.body
|
23
|
-
rescue ArgumentError
|
24
|
-
body = URI.open(m3u8, &:read)
|
25
|
-
end
|
26
|
-
tses = body.scan(/.*\.ts.*/)
|
27
|
-
key_url = body.scan(/URI="(.*)"/).flatten.first
|
28
|
-
|
29
|
-
if key_url
|
30
|
-
key = agent.get_file(key_url)
|
31
|
-
decoder = OpenSSL::Cipher.new('aes-128-cbc')
|
32
|
-
decoder.key = key
|
33
|
-
decoder.decrypt
|
34
|
-
else
|
35
|
-
decoder = ''
|
36
|
-
def decoder.update(s); return s; end
|
37
|
-
def decoder.final(); return ''; end
|
38
|
-
end
|
39
|
-
|
40
|
-
q = Queue.new
|
41
|
-
tses.each_with_index{|ts_url, block_no| q.push([ts_url, block_no])}
|
42
|
-
q.close
|
43
|
-
results = [nil] * q.size
|
44
|
-
|
45
|
-
msgs = Queue.new
|
46
|
-
stats = [0] * 3
|
47
|
-
stats.size.times do |thread_no|
|
48
|
-
Thread.start(thread_no) do |thread_no|
|
49
|
-
while (ts_url, block_no = q.pop)
|
50
|
-
begin
|
51
|
-
sleep(rand(0.1) * 3)
|
52
|
-
results[block_no] = agent.get_file(ts_url)
|
53
|
-
stats[thread_no] = block_no
|
54
|
-
rescue Mechanize::ResponseCodeError => e
|
55
|
-
case e.response_code
|
56
|
-
when "403" # Forbidden
|
57
|
-
msgs.push "T#{thread_no}: 403 Forbidden"
|
58
|
-
retry
|
59
|
-
when "429" # TooManyRequests
|
60
|
-
msgs.push "T#{thread_no}: 429 TooManyRequests"
|
61
|
-
retry
|
62
|
-
else
|
63
|
-
msgs.push "T#{thread_no}: #{e}"
|
64
|
-
retry # TODO: catch other status code
|
65
|
-
end
|
66
|
-
rescue
|
67
|
-
msgs.push "T#{thread_no}: #{e.class} #{e}"
|
68
|
-
break
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def print_status(block, tses, stats, msgs)
|
75
|
-
$stderr.puts msgs.pop while !msgs.empty?
|
76
|
-
$stderr.print "#{block+1}/#{tses.size} saved --"
|
77
|
-
stats.each_with_index{|block_no, thread_no| $stderr.print " T#{thread_no+1}:#{block_no+1}"}
|
78
|
-
$stderr.print "\r"
|
79
|
-
end
|
80
|
-
|
81
|
-
def save(fd, results, tses, stats, msgs, decoder)
|
82
|
-
results.each_with_index do |data, i|
|
83
|
-
print_status(i, tses, stats, msgs)
|
84
|
-
loop do
|
85
|
-
if data
|
86
|
-
fd.write(decoder.update(data))
|
87
|
-
results[i] = nil # be saved data want to GC
|
88
|
-
break
|
89
|
-
else
|
90
|
-
sleep(1.0) # wait for complete of chunk download finished
|
91
|
-
data = results[i]
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
fd.write(decoder.final)
|
96
|
-
puts
|
97
|
-
end
|
98
|
-
|
99
|
-
if ts_file
|
100
|
-
open(ts_file, 'wb:ASCII-8BIT'){|f|save(f, results, tses, stats, msgs, decoder)}
|
101
|
-
else
|
102
|
-
save($stdout, results, tses, stats, msgs, decoder)
|
10
|
+
ffmpeg = %Q[ffmpeg -loglevel error -protocol_whitelist file,http,https,tcp,tls,crypto -n -i "#{ARGV[0]}" #{ARGV[1]}]
|
11
|
+
result = Open3.capture3(ffmpeg)
|
12
|
+
unless result[2].to_i == 0
|
13
|
+
p result
|
14
|
+
File.delete(ARGV[1]) if File.exist?(ARGV[1])
|
15
|
+
$stderr.puts result[1]
|
16
|
+
exit(1)
|
103
17
|
end
|
18
|
+
exit(0)
|
data/lib/hibiki.rb
CHANGED
@@ -57,7 +57,9 @@ private
|
|
57
57
|
playlist_url = video_info[:playlist_url]
|
58
58
|
m3u8_url = URI(agent.get(playlist_url).body.scan(/http.*/).flatten.first)
|
59
59
|
|
60
|
-
|
60
|
+
# choice the max size element from multi-part m3u8 file
|
61
|
+
m3u8 = agent.get(m3u8_url).body.split("EXT-X-KEY").sort{|m,n|m.size <=> n.size}.last
|
62
|
+
|
61
63
|
key_url = m3u8.scan(/URI="(.*)"/).flatten.first
|
62
64
|
|
63
65
|
tses = m3u8.scan(/^.*ts_.*\.ts/)
|
data/lib/hls.rb
CHANGED
@@ -1,35 +1,17 @@
|
|
1
1
|
require 'webradio'
|
2
|
+
require 'open3'
|
2
3
|
|
3
4
|
class HLS < WebRadio
|
4
5
|
private
|
5
|
-
def hls_download(name,
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
m3u_meta1 = URI.open(m3u_meta2, &:read)
|
15
|
-
m3u = m3u_meta1.scan(/^[^#].*/).first
|
16
|
-
save_m4a(URI(m3u), @m4a_file)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def get_m4a(uri_playlist)
|
21
|
-
URI.open(uri_playlist).each_line do |l|
|
22
|
-
next if /^#/ =~ l
|
23
|
-
l.chomp!
|
24
|
-
print "."
|
25
|
-
yield URI.open(uri_playlist + l, 'r:ASCII-8BIT', &:read)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def save_m4a(uri_playlist, m4a_file)
|
30
|
-
open(m4a_file, 'wb:ASCII-8BIT') do |m4a|
|
31
|
-
get_m4a(uri_playlist) do |part|
|
32
|
-
m4a.write part
|
6
|
+
def hls_download(name, serial, m3u_meta)
|
7
|
+
mp4_file = "#{name}##{serial}.mp4"
|
8
|
+
mp3_file = "#{name}##{serial}.mp3"
|
9
|
+
m3u = URI.open(m3u_meta, &:read).scan(/^[^#].*/).first
|
10
|
+
m3u = Pathname(m3u_meta).dirname.join(m3u) if Pathname(m3u).relative?
|
11
|
+
mp3nize(mp4_file, mp3_file) do
|
12
|
+
result = Open3.capture3(%Q[ffmpeg -loglevel error -protocol_whitelist file,http,https,tcp,tls,crypto -i "#{m3u}" "#{mp4_file}"])
|
13
|
+
unless result[2].to_i == 0
|
14
|
+
raise WebRadio::DownloadError.new("failed download the radio program (#{@label}).")
|
33
15
|
end
|
34
16
|
end
|
35
17
|
end
|
data/lib/nicovideo.rb
CHANGED
@@ -39,7 +39,7 @@ class Nicovideo < WebRadio
|
|
39
39
|
_, err, status = Open3.capture3("youtube-dl -f mp4 -o #{@file} --netrc #{video.url}")
|
40
40
|
break if status == 0
|
41
41
|
next if err =~ /403: Forbidden/
|
42
|
-
raise ForbiddenError.new("Could not access to #{video.url}") if err =~ /TypeError/
|
42
|
+
raise ForbiddenError.new("Could not access to #{video.url}") if err =~ /TypeError|AssertionError/
|
43
43
|
raise DownloadError.new(err)
|
44
44
|
end
|
45
45
|
end
|
data/lib/onsen.rb
CHANGED
@@ -1,22 +1,26 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'hls'
|
4
4
|
require 'nokogiri'
|
5
|
+
require 'json'
|
5
6
|
|
6
|
-
class Onsen <
|
7
|
+
class Onsen < HLS
|
7
8
|
def initialize(params, options)
|
8
9
|
super
|
9
|
-
@cover = "//*[@
|
10
|
+
@cover = "//*[@class='newest-content--left']//img[1]/@src" unless @cover
|
10
11
|
end
|
11
12
|
|
12
13
|
def download
|
13
|
-
|
14
|
+
html = URI.open(@url, &:read)
|
15
|
+
serial = Nokogiri(html).css('.play-video-info td')[0].text.scan(/\d+/)[0].to_i
|
16
|
+
m3u8 = JSON.parse(html.scan(%r|streaming_url:("https:.*?.m3u8")|).flatten.sort.last)
|
17
|
+
hls_download(@label, serial, m3u8)
|
14
18
|
end
|
15
19
|
|
16
20
|
def dump
|
17
21
|
tag = Pathname(@url).basename.to_s.gsub(%r|[-/]|, '_')
|
18
22
|
html = Nokogiri(URI.open(@url, &:read))
|
19
|
-
title = html.css('
|
23
|
+
title = html.css('h3')[0].text
|
20
24
|
return {
|
21
25
|
tag => {
|
22
26
|
'desc' => title,
|
@@ -25,24 +29,4 @@ class Onsen < WebRadio
|
|
25
29
|
}
|
26
30
|
}
|
27
31
|
end
|
28
|
-
|
29
|
-
private
|
30
|
-
def onsen_download(name, program_id)
|
31
|
-
html = Nokogiri(URI.open('http://onsen.ag/', 'User-Agent' => 'iPhone', &:read))
|
32
|
-
begin
|
33
|
-
serial = html.css("##{program_id}").text.scan(/#(\d+)/).flatten.first
|
34
|
-
mp3_url = html.css('form[target=_self]').select {|form|
|
35
|
-
form.attr('action') =~ %r|/#{program_id}\w+\.mp[34]|
|
36
|
-
}.first.attr('action')
|
37
|
-
rescue NoMethodError
|
38
|
-
raise NotFoundError.new("no radio program in #{program_id}.")
|
39
|
-
end
|
40
|
-
src_file = "#{name}##{serial}#{mp3_url.scan(/\.mp[34]$/).first}"
|
41
|
-
mp3_file = "#{name}##{serial}.mp3"
|
42
|
-
mp3nize(src_file, mp3_file, false) do
|
43
|
-
open(src_file, 'wb:ASCII-8BIT') do |mp3|
|
44
|
-
mp3.write URI.open(mp3_url, 'rb:ASCII-8BIT', &:read)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
32
|
end
|
data/lib/standfm.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'nokogiri'
|
3
|
+
require 'mechanize'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
class StandFm < WebRadio
|
7
|
+
def initialize(params, options)
|
8
|
+
super
|
9
|
+
@offset = 0
|
10
|
+
end
|
11
|
+
|
12
|
+
def download
|
13
|
+
uri = URI(@url)
|
14
|
+
html = Nokogiri(uri.open.read)
|
15
|
+
episode = uri + html.css('#root a[href^="/episodes/"]').map{|e|e.attr('href')}.uniq[@offset]
|
16
|
+
|
17
|
+
html = episode.open.read
|
18
|
+
json = JSON.parse(html.scan(%r[<script>window.__SERVER_STATE__=(.*)</script>]).flatten[0])
|
19
|
+
m4a = json['topics'].find{|k,v|v['episodeId'] == File.basename(episode.path)}.last['downloadUrl']
|
20
|
+
|
21
|
+
doc = Nokogiri(html)
|
22
|
+
serial = doc.title.scan(/#(\d+)/).flatten.first.to_i
|
23
|
+
@cover = doc.css('meta[property="og:image"]').attr('content').text unless @cover
|
24
|
+
m4a_file = "#{@label}##{serial}.m4a"
|
25
|
+
mp3_file = "#{@label}##{serial}.mp3"
|
26
|
+
|
27
|
+
mp3nize(m4a_file, mp3_file) do
|
28
|
+
open(m4a_file, 'wb:ASCII-8BIT') do |w|
|
29
|
+
w.write(URI(m4a).open.read)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def dump
|
35
|
+
uri = URI(@url)
|
36
|
+
tag = File.basename(uri.path)
|
37
|
+
html = Nokogiri(uri.open.read)
|
38
|
+
label, = html.css('title').text.split(/ \| /)
|
39
|
+
cover = html.css('meta[property="og:image"]').attr('content').text
|
40
|
+
return {
|
41
|
+
tag => {
|
42
|
+
'desc' => label,
|
43
|
+
'url' => @url,
|
44
|
+
'label' => label,
|
45
|
+
'cover' => cover
|
46
|
+
}
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
def find_player(url)
|
52
|
+
programs = Nokogiri(URI.open(url).read)
|
53
|
+
programs.css('.list-main-product a.wrap').each do |program|
|
54
|
+
begin
|
55
|
+
return Nokogiri(URI.open("https://asobistore.jp#{program.attr('href')}").read).css('iframe').last.attr('src')
|
56
|
+
rescue # access denied because only access by premium members
|
57
|
+
next
|
58
|
+
end
|
59
|
+
end
|
60
|
+
raise StandardError.new('movie not found.')
|
61
|
+
end
|
62
|
+
end
|
data/lib/webradio.rb
CHANGED
@@ -14,7 +14,7 @@ class WebRadio
|
|
14
14
|
when %r[^https?://hibiki-radio\.jp/]
|
15
15
|
require 'hibiki'
|
16
16
|
Hibiki.new(params, options)
|
17
|
-
when %r[^
|
17
|
+
when %r[^https?://(www\.)?onsen\.ag/program/]
|
18
18
|
require 'onsen'
|
19
19
|
Onsen.new(params, options)
|
20
20
|
when %r[nicovideo\.jp]
|
@@ -29,6 +29,12 @@ class WebRadio
|
|
29
29
|
when %r[^https://asobistore\.jp/]
|
30
30
|
require 'asobistore'
|
31
31
|
AsobiStore.new(params, options)
|
32
|
+
when %r[^https://stand\.fm/channels/]
|
33
|
+
require 'standfm'
|
34
|
+
StandFm.new(params, options)
|
35
|
+
when %r[^https://www\.youtube\.com/playlist]
|
36
|
+
require 'youtube'
|
37
|
+
Youtube.new(params, options)
|
32
38
|
else
|
33
39
|
raise UnsupportError, "unsupported url: #{params['url']}"
|
34
40
|
end
|
data/lib/youtube.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
class Youtube < WebRadio
|
5
|
+
def initialize(params, options)
|
6
|
+
super
|
7
|
+
@offset = 0
|
8
|
+
end
|
9
|
+
|
10
|
+
def download
|
11
|
+
html = URI.open(@url).read
|
12
|
+
json_str = html.scan(/ytInitialData = (.*);<\/script>/).flatten.first
|
13
|
+
json = JSON.parse(json_str)
|
14
|
+
title = json["contents"]["twoColumnBrowseResultsRenderer"]["tabs"][0]["tabRenderer"]["content"]["sectionListRenderer"]["contents"][0]["itemSectionRenderer"]["contents"][0]["playlistVideoListRenderer"]["contents"][0]["playlistVideoRenderer"]["title"]["runs"][0]["text"]
|
15
|
+
@cover = json["contents"]["twoColumnBrowseResultsRenderer"]["tabs"][0]["tabRenderer"]["content"]["sectionListRenderer"]["contents"][0]["itemSectionRenderer"]["contents"][0]["playlistVideoListRenderer"]["contents"][0]["playlistVideoRenderer"]["thumbnail"]["thumbnails"].last["url"]
|
16
|
+
mp4_url = "https://www.youtube.com#{json["contents"]["twoColumnBrowseResultsRenderer"]["tabs"][0]["tabRenderer"]["content"]["sectionListRenderer"]["contents"][0]["itemSectionRenderer"]["contents"][0]["playlistVideoListRenderer"]["contents"][0]["playlistVideoRenderer"]["navigationEndpoint"]["commandMetadata"]["webCommandMetadata"]["url"]}"
|
17
|
+
serial = title.scan(/[0-9]+/).first
|
18
|
+
|
19
|
+
mp4_file = "#{@label}##{serial}.mp4"
|
20
|
+
mp3_file = "#{@label}##{serial}.mp3"
|
21
|
+
begin
|
22
|
+
mp3nize(mp4_file, mp3_file) do
|
23
|
+
loop do
|
24
|
+
print '.'
|
25
|
+
_, err, status = Open3.capture3("youtube-dl -f mp4 -o #{mp4_file} --netrc '#{mp4_url}'")
|
26
|
+
break if status == 0
|
27
|
+
next if err =~ /403: Forbidden/
|
28
|
+
raise ForbiddenError.new("Could not access to #{mp4_url}") if err =~ /TypeError|AssertionError/
|
29
|
+
raise DownloadError.new(err)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
rescue ForbiddenError
|
33
|
+
puts "#{$!.message}, try next."
|
34
|
+
@offset += 1
|
35
|
+
retry
|
36
|
+
rescue NotFoundError
|
37
|
+
raise DownloadError.new('video not found')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/rget.gemspec
CHANGED
@@ -4,10 +4,10 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "rget"
|
7
|
-
spec.version = "4.
|
8
|
-
spec.authors = ["
|
7
|
+
spec.version = "4.11.0"
|
8
|
+
spec.authors = ["Tada, Tadashi"]
|
9
9
|
spec.email = ["t@tdtds.jp"]
|
10
|
-
spec.description = %q{Downloading newest radio programs on the web. Supported radio stations are hibiki, onsen, niconico,
|
10
|
+
spec.description = %q{Downloading newest radio programs on the web. Supported radio stations are hibiki, onsen, niconico, himalaya, asobi store, stand.fm and youtube playlist.}
|
11
11
|
spec.summary = %q{Downloading newest radio programs on the web.}
|
12
12
|
spec.homepage = "https://github.com/wasamas/rget"
|
13
13
|
spec.license = "GPL"
|
data/rget.yaml
CHANGED
@@ -23,3 +23,11 @@ programs:
|
|
23
23
|
desc: ル美子さん
|
24
24
|
url: https://ch.nicovideo.jp/luminesan/video?rss=2.0
|
25
25
|
label: ル美子さん
|
26
|
+
ranacha:
|
27
|
+
desc: らなちゃのひとりごと
|
28
|
+
url: https://stand.fm/channels/5f7d9011f04555115d2170ef
|
29
|
+
label: らなちゃのひとりごと
|
30
|
+
active:
|
31
|
+
desc: 愛美とはるかの2年A組青春アクティ部!
|
32
|
+
url: https://www.youtube.com/playlist?list=PLI5zma0g_n8_y5Xk5eFwX8osz4Q2a3cqU
|
33
|
+
label: アクティ部
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rget
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Tada, Tadashi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -151,7 +151,7 @@ dependencies:
|
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
153
|
description: Downloading newest radio programs on the web. Supported radio stations
|
154
|
-
are hibiki, onsen, niconico,
|
154
|
+
are hibiki, onsen, niconico, himalaya, asobi store, stand.fm and youtube playlist.
|
155
155
|
email:
|
156
156
|
- t@tdtds.jp
|
157
157
|
executables:
|
@@ -161,6 +161,8 @@ executables:
|
|
161
161
|
extensions: []
|
162
162
|
extra_rdoc_files: []
|
163
163
|
files:
|
164
|
+
- ".devcontainer/Dockerfile"
|
165
|
+
- ".devcontainer/devcontainer.json"
|
164
166
|
- ".gitignore"
|
165
167
|
- ".travis.yml"
|
166
168
|
- Gemfile
|
@@ -179,7 +181,9 @@ files:
|
|
179
181
|
- lib/nicovideo.rb
|
180
182
|
- lib/onsen.rb
|
181
183
|
- lib/podcast.rb
|
184
|
+
- lib/standfm.rb
|
182
185
|
- lib/webradio.rb
|
186
|
+
- lib/youtube.rb
|
183
187
|
- rget.gemspec
|
184
188
|
- rget.yaml
|
185
189
|
homepage: https://github.com/wasamas/rget
|
@@ -201,8 +205,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
201
205
|
- !ruby/object:Gem::Version
|
202
206
|
version: '0'
|
203
207
|
requirements: []
|
204
|
-
|
205
|
-
rubygems_version: 2.7.7
|
208
|
+
rubygems_version: 3.0.8
|
206
209
|
signing_key:
|
207
210
|
specification_version: 4
|
208
211
|
summary: Downloading newest radio programs on the web.
|