sleeproom 0.4.0 → 0.9.0.beta3
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/.gitignore +2 -0
- data/Gemfile +3 -2
- data/README.md +0 -1
- data/Rakefile +3 -1
- data/bin/sleeproom +1 -2
- data/lib/sleeproom/async/websocket.rb +8 -6
- data/lib/sleeproom/cli.rb +32 -20
- data/lib/sleeproom/record.rb +8 -6
- data/lib/sleeproom/record/api/api.rb +3 -7
- data/lib/sleeproom/record/api/room.rb +2 -1
- data/lib/sleeproom/record/api/room_api.rb +2 -1
- data/lib/sleeproom/record/api/streaming_api.rb +4 -3
- data/lib/sleeproom/record/plugins.rb +9 -0
- data/lib/sleeproom/record/plugins/youtube/upload.rb +1 -0
- data/lib/sleeproom/record/record.rb +165 -193
- data/lib/sleeproom/record/tasks.rb +63 -56
- data/lib/sleeproom/record/websocket.rb +75 -69
- data/lib/sleeproom/record/write_status.rb +32 -2
- data/lib/sleeproom/utils.rb +72 -24
- data/lib/sleeproom/version.rb +1 -1
- data/sleeproom.gemspec +11 -8
- metadata +65 -22
- data/Gemfile.lock +0 -126
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3845e3c4fe71e788a6a58fdccdeafdf54df9a076970e603d255221f9a9eb485d
|
4
|
+
data.tar.gz: 5bb98e697e5b39f8d2a7c77e8b383dfcc68c76d342f9aa9a062cdb1908567bc4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 10225f5c2f860a9c0862962f0e0e35ed8bd3ceb4d630d7cfc72dd98d388643dea785bab30448b2003c1019dbc3bcb708615ce63cd296fbff549c2d7c2a76d5d6
|
7
|
+
data.tar.gz: 638388a6ab62c5db454155bdf8d21aebd6f1fdd562ea0b807add10c4759008ab2f09e96f535990ca506ffa5ccfdbcccdde7509ef22434b94d660ee0d584322cd
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source "https://rubygems.org"
|
2
4
|
|
3
5
|
# Specify your gem's dependencies in sleeproom.gemspec
|
4
6
|
gemspec
|
5
7
|
|
6
|
-
gem "rake", "~>
|
8
|
+
gem "rake", "~> 13.0"
|
7
9
|
gem "rspec", "~> 3.0"
|
8
|
-
gem "rubocop", "~> 0.79.0"
|
9
10
|
gem "rubocop-github"
|
10
11
|
gem "rubocop-performance", require: false
|
data/README.md
CHANGED
data/Rakefile
CHANGED
data/bin/sleeproom
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "async/websocket/connection"
|
2
4
|
class WebSocketConnection < Async::WebSocket::Connection
|
3
5
|
def read
|
@@ -5,16 +7,16 @@ class WebSocketConnection < Async::WebSocket::Connection
|
|
5
7
|
parse(buffer)
|
6
8
|
end
|
7
9
|
end
|
8
|
-
|
10
|
+
|
9
11
|
def write(object)
|
10
12
|
super(dump(object))
|
11
13
|
end
|
12
|
-
|
14
|
+
|
13
15
|
def parse(buffer)
|
14
|
-
|
16
|
+
buffer
|
15
17
|
end
|
16
|
-
|
18
|
+
|
17
19
|
def dump(object)
|
18
|
-
|
20
|
+
object
|
19
21
|
end
|
20
|
-
end
|
22
|
+
end
|
data/lib/sleeproom/cli.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "ruby-next"
|
3
4
|
require "optparse"
|
4
5
|
require "yaml"
|
5
6
|
require "sleeproom/record"
|
@@ -8,17 +9,25 @@ module SleepRoom
|
|
8
9
|
class CLI
|
9
10
|
# @param argv [Array]
|
10
11
|
def initialize(argv)
|
12
|
+
SleepRoom.reload_config
|
11
13
|
@options = {}
|
14
|
+
begin
|
15
|
+
minyami = `minyami --version`
|
16
|
+
status = $?
|
17
|
+
rescue => e
|
18
|
+
SleepRoom.warning("无法调用 Minyami: #{e.message}")
|
19
|
+
end
|
12
20
|
build
|
13
|
-
|
21
|
+
if argv.empty? == false
|
14
22
|
@parser.parse!(argv)
|
15
23
|
action = argv.shift
|
16
|
-
|
24
|
+
case action
|
25
|
+
when "status"
|
17
26
|
SleepRoom::Record::Tasks.status
|
18
|
-
|
19
|
-
SleepRoom::Record::Tasks.start
|
20
|
-
|
21
|
-
SleepRoom::Record::Tasks.
|
27
|
+
when "start"
|
28
|
+
SleepRoom::Record::Tasks.start(**@options)
|
29
|
+
when "lists"
|
30
|
+
SleepRoom::Record::Tasks.lists
|
22
31
|
end
|
23
32
|
exit(0)
|
24
33
|
else
|
@@ -27,46 +36,49 @@ module SleepRoom
|
|
27
36
|
end
|
28
37
|
end
|
29
38
|
|
30
|
-
# @return [void]
|
31
|
-
def run
|
32
|
-
SleepRoom::Record::Tasks.start
|
33
|
-
end
|
34
|
-
|
35
39
|
# @return [void]
|
36
40
|
def build
|
37
41
|
@parser = OptionParser.new do |opt|
|
38
42
|
opt.version = "SleepRoom / #{SleepRoom::VERSION}"
|
39
|
-
opt.banner =
|
43
|
+
opt.banner = opt.version.to_s
|
40
44
|
opt.banner += "\nUsage: sleeproom [Options]\n\n"
|
41
45
|
|
42
46
|
opt.banner += "Action:\n"
|
43
47
|
opt.banner += "status".rjust(10)
|
44
48
|
opt.banner += "显示任务状态".rjust(33)
|
45
49
|
opt.banner += "\n"
|
50
|
+
opt.banner += "lists".rjust(9)
|
51
|
+
opt.banner += "显示录制列表".rjust(34)
|
52
|
+
opt.banner += "\n"
|
46
53
|
opt.banner += "exit".rjust(8)
|
47
54
|
opt.banner += "关闭任务队列".rjust(35)
|
48
55
|
opt.banner += "\n\nCommands:\n"
|
49
56
|
|
50
|
-
opt.on("-a ROOM, NAME", "--add ROOM, GROUP", Array, "
|
57
|
+
opt.on("-a ROOM, NAME", "--add ROOM, GROUP", Array, "添加房间到监视列表") do |room|
|
51
58
|
SleepRoom::Record::Tasks.add(room[0].to_s, room[1].to_s)
|
52
59
|
end
|
53
60
|
|
54
|
-
opt.on("-r", "--remove [ROOM]", "
|
61
|
+
opt.on("-r", "--remove [ROOM]", "从监视列表移除房间") do |room|
|
55
62
|
SleepRoom::Record::Tasks.remove(room)
|
56
63
|
end
|
57
64
|
|
58
65
|
opt.on("-d", "--download [ROOM]", "录制指定房间") do |room|
|
59
|
-
raise Error
|
66
|
+
raise Error, "房间名不能为空" if room.nil?
|
67
|
+
|
68
|
+
room = room.match(%r{https://www.showroom-live.com/(.*)})[1] if room.match?("https://www.showroom-live.com/")
|
60
69
|
write_status = SleepRoom::Record::WriteStatus.new
|
61
|
-
|
62
|
-
|
70
|
+
Async do
|
71
|
+
record = SleepRoom::Record::Showroom.new(room: room, group: "download", queue: write_status)
|
72
|
+
record.record
|
73
|
+
end
|
63
74
|
end
|
64
75
|
|
65
|
-
opt.on("
|
76
|
+
opt.on("--verbose", "DEBUG") do
|
77
|
+
ENV["SR_DEBUG"] = "DEBUG"
|
66
78
|
@options[:verbose] = true
|
67
79
|
end
|
68
|
-
|
69
|
-
opt.on_tail("--version", "Print version") do
|
80
|
+
|
81
|
+
opt.on_tail("-v", "--version", "Print version") do
|
70
82
|
STDOUT.puts(opt.version)
|
71
83
|
end
|
72
84
|
|
data/lib/sleeproom/record.rb
CHANGED
@@ -8,39 +8,41 @@ require "sleeproom/record/record"
|
|
8
8
|
require "sleeproom/record/tasks"
|
9
9
|
require "sleeproom/record/websocket"
|
10
10
|
require "sleeproom/record/api/api"
|
11
|
+
require "sleeproom/record/plugins"
|
11
12
|
require "async"
|
12
13
|
require "shellwords"
|
13
14
|
module SleepRoom
|
14
15
|
module Record
|
15
16
|
# Okite!!!
|
16
17
|
# @param url [String]
|
17
|
-
# @return [
|
18
|
-
def self.call_minyami(url:, is_live: true, threads: configatron.minyami.threads, output:, retries: configatron.minyami.retries)
|
18
|
+
# @return [Integer]
|
19
|
+
def self.call_minyami(url:, is_live: true, threads: configatron.minyami.threads, output:, retries: configatron.minyami.retries, no_merge: configatron.minyami.no_merge)
|
19
20
|
command = "minyami -d #{Shellwords.escape(url)}"
|
20
21
|
command += " --retries #{retries.to_i}" if retries
|
21
22
|
command += " --threads #{threads.to_i}" if threads
|
22
23
|
command += " --live" if is_live
|
24
|
+
command += " --nomerge" if no_merge
|
23
25
|
output = File.join(configatron.save_path, output)
|
24
26
|
command += " --output #{Shellwords.escape(output)}" if output
|
25
27
|
download_dir_check(output)
|
26
28
|
pid = exec_command(command, output)
|
27
|
-
|
29
|
+
pid
|
28
30
|
end
|
29
31
|
|
30
32
|
# @param command [String]
|
31
|
-
# @return [
|
33
|
+
# @return [Integer]
|
32
34
|
def self.exec_command(command, output)
|
33
35
|
SleepRoom.info("Call command: #{command}")
|
34
36
|
SleepRoom.info("STDOUT: #{output}.out , STDERR: #{output}.err")
|
35
37
|
pid = spawn(command, out: "#{output}.out", err: "#{output}.err")
|
36
38
|
SleepRoom.info("PID: #{pid}")
|
37
39
|
Process.detach(pid)
|
38
|
-
|
40
|
+
pid
|
39
41
|
end
|
40
42
|
|
41
43
|
def self.download_dir_check(output)
|
42
44
|
dir = File.dirname(output)
|
43
|
-
|
45
|
+
unless Dir.exist?(dir)
|
44
46
|
SleepRoom.info("#{dir} does not exist, creating...")
|
45
47
|
SleepRoom.mkdir(dir)
|
46
48
|
end
|
@@ -11,15 +11,11 @@ module SleepRoom
|
|
11
11
|
module API
|
12
12
|
class Error < StandardError; end
|
13
13
|
class NotFoundError < Error; end
|
14
|
-
ROOM_URL = "https://www.showroom-live.com"
|
15
|
-
ROOM_API = "https://www.showroom-live.com/api/room/status"
|
16
|
-
STREAMING_API = "https://www.showroom-live.com/api/live/streaming_url"
|
17
|
-
|
18
14
|
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"
|
19
15
|
|
20
|
-
def self.get(url)
|
21
|
-
|
22
|
-
http = Faraday.get(url, nil, {"User-Agent": USER_AGENT})
|
16
|
+
def self.get(url, task: Async::Task.current)
|
17
|
+
task.async do
|
18
|
+
http = Faraday.get(url, nil, { "User-Agent": USER_AGENT })
|
23
19
|
if http.status == 200
|
24
20
|
@json = JSON.parse(http.body)
|
25
21
|
elsif http.status == 404
|
@@ -4,11 +4,12 @@ module SleepRoom
|
|
4
4
|
module Record
|
5
5
|
module API
|
6
6
|
class Room
|
7
|
+
ROOM_URL = "https://www.showroom-live.com"
|
7
8
|
def initialize(room_name)
|
8
9
|
@url = ROOM_URL + "/" + room_name
|
9
10
|
end
|
10
11
|
|
11
|
-
def get
|
12
|
+
def get
|
12
13
|
@json = API.get(@url).wait
|
13
14
|
end
|
14
15
|
end
|
@@ -4,13 +4,14 @@ module SleepRoom
|
|
4
4
|
module Record
|
5
5
|
module API
|
6
6
|
class RoomAPI
|
7
|
+
ROOM_API = "https://www.showroom-live.com/api/room/status"
|
7
8
|
def initialize(room_url_key)
|
8
9
|
@url = ROOM_API + "?room_url_key=" + room_url_key
|
9
10
|
@json = nil
|
10
11
|
get
|
11
12
|
end
|
12
13
|
|
13
|
-
def get
|
14
|
+
def get
|
14
15
|
@json = API.get(@url).wait
|
15
16
|
end
|
16
17
|
|
@@ -4,21 +4,22 @@ module SleepRoom
|
|
4
4
|
module Record
|
5
5
|
module API
|
6
6
|
class StreamingAPI
|
7
|
+
STREAMING_API = "https://www.showroom-live.com/api/live/streaming_url"
|
7
8
|
def initialize(room_id)
|
8
9
|
@url = STREAMING_API + "?room_id=" + room_id.to_s + "&ignore_low_stream=1"
|
9
10
|
@json = nil
|
10
11
|
get
|
11
12
|
end
|
12
13
|
|
13
|
-
def get
|
14
|
+
def get
|
14
15
|
@json = API.get(@url).wait
|
15
16
|
end
|
16
17
|
|
17
18
|
def streaming_url
|
18
19
|
if @json["streaming_url_list"].nil?
|
19
|
-
raise Error
|
20
|
+
raise Error, "streaming url is null."
|
20
21
|
else
|
21
|
-
@json["streaming_url_list"].
|
22
|
+
@json["streaming_url_list"].min_by { |hash| -hash["quality"] }["url"]
|
22
23
|
end
|
23
24
|
end
|
24
25
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
# Youtube Uploader
|
@@ -1,148 +1,111 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "sleeproom/record/write_status"
|
3
4
|
|
4
5
|
module SleepRoom
|
5
6
|
module Record
|
7
|
+
# showroom-live.com
|
6
8
|
class Showroom
|
7
|
-
|
9
|
+
# Showroom Downloader
|
10
|
+
# @param room [String]
|
11
|
+
# @param group [String]
|
12
|
+
# @param queue [WriteStatus]
|
8
13
|
def initialize(room:, group: "default", queue:)
|
9
14
|
@room = room
|
10
15
|
@group = group
|
11
|
-
@
|
16
|
+
@status = queue
|
12
17
|
@running = false
|
13
|
-
@
|
14
|
-
|
18
|
+
@downloading = false
|
19
|
+
set_room_info
|
15
20
|
end
|
16
21
|
|
17
|
-
#
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
if status = SleepRoom.load_config(:status).find{|hash| hash[:room] == room}
|
26
|
-
if !status[:pid].nil?
|
27
|
-
break if SleepRoom.running?(status[:pid]) == false
|
28
|
-
else
|
29
|
-
break
|
30
|
-
end
|
31
|
-
else
|
32
|
-
break
|
33
|
-
end
|
34
|
-
t.sleep 60
|
35
|
-
end
|
36
|
-
end.wait
|
37
|
-
if @is_live
|
38
|
-
start_time = Time.now
|
39
|
-
log("Live broadcast.")
|
40
|
-
streaming_url = parse_streaming_url
|
41
|
-
output = build_output
|
42
|
-
pid = SleepRoom::Record.call_minyami(url: streaming_url, output: output)
|
43
|
-
downloading(streaming_url, pid, start_time)
|
44
|
-
record
|
45
|
-
else
|
46
|
-
log("Status: Stop.")
|
47
|
-
waiting_live(ws: :init)
|
48
|
-
Async do |task|
|
49
|
-
while true
|
50
|
-
if @running == false && @reconnection == false
|
51
|
-
start_websocket
|
52
|
-
elsif @reconnection == true
|
53
|
-
set_room_info
|
54
|
-
start_websocket
|
55
|
-
@reconnection = false
|
56
|
-
end
|
57
|
-
task.sleep 10
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
rescue => e
|
62
|
-
add_error(e)
|
63
|
-
SleepRoom.error(e.full_message)
|
64
|
-
log("Retry...")
|
65
|
-
task.sleep 5
|
66
|
-
retry
|
22
|
+
# Record Room
|
23
|
+
def record
|
24
|
+
if @is_live
|
25
|
+
log("Status: broadcast.")
|
26
|
+
download_process if @downloading == false
|
27
|
+
else
|
28
|
+
update_status
|
29
|
+
log("Status: Stop.")
|
67
30
|
end
|
31
|
+
start_websocket
|
32
|
+
rescue => e
|
33
|
+
error(e.full_message)
|
34
|
+
Async::Task.current.sleep 5
|
35
|
+
set_room_info
|
36
|
+
retry
|
68
37
|
end
|
69
38
|
|
39
|
+
# Print log
|
40
|
+
# @param str [String]
|
70
41
|
def log(str)
|
71
42
|
SleepRoom.info("[#{@room}] #{str}")
|
72
43
|
end
|
73
|
-
|
44
|
+
|
45
|
+
def debug(str)
|
46
|
+
SleepRoom.debug("[#{@room}] #{str}")
|
47
|
+
end
|
48
|
+
|
49
|
+
# Print log
|
50
|
+
# @param str [String]
|
51
|
+
def error(str)
|
52
|
+
SleepRoom.error("[#{@room}] #{str}")
|
53
|
+
end
|
54
|
+
|
74
55
|
private
|
75
|
-
def start_websocket()
|
76
|
-
Async do |task|
|
77
|
-
@running = true
|
78
|
-
log("Broadcast Key: #{@broadcast_key}")
|
79
|
-
waiting_live(ws: :init)
|
80
|
-
ws = WebSocket.new(room: @room, broadcast_key: @broadcast_key, url: @broadcast_host)
|
81
|
-
@ws = ws
|
82
|
-
# ws status
|
83
|
-
ws_task = task.async do |sub|
|
84
|
-
ws.running = true
|
85
|
-
ws.connect(task: sub) do |message|
|
86
|
-
case message["t"].to_i
|
87
|
-
when 101
|
88
|
-
log("Live stop.")
|
89
|
-
ws.running = false
|
90
|
-
@running = false
|
91
|
-
record
|
92
|
-
when 104
|
93
|
-
log("Live start.")
|
94
|
-
start_time = Time.now
|
95
|
-
streaming_url = parse_streaming_url
|
96
|
-
output = build_output
|
97
|
-
pid = SleepRoom::Record.call_minyami(url: streaming_url, output: output)
|
98
|
-
downloading(streaming_url, pid, start_time)
|
99
|
-
ws.running = false
|
100
|
-
@running = false
|
101
|
-
@reconnection = true
|
102
|
-
else
|
103
|
-
# other
|
104
|
-
end
|
105
|
-
end
|
106
|
-
rescue => e
|
107
|
-
SleepRoom.error("WS Stop.")
|
108
|
-
SleepRoom.error(e.full_message)
|
109
|
-
ws.running = false
|
110
|
-
@running = false
|
111
|
-
add_error(e)
|
112
|
-
end
|
113
56
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
57
|
+
def open_handler
|
58
|
+
end
|
59
|
+
|
60
|
+
def message_handler(data)
|
61
|
+
case data["t"].to_i
|
62
|
+
when 101
|
63
|
+
log("Live stop.")
|
64
|
+
@is_live = false
|
65
|
+
set_room_info
|
66
|
+
when 104
|
67
|
+
log("Live start.")
|
68
|
+
download_process
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def close_handler(error)
|
73
|
+
@running = false
|
74
|
+
end
|
75
|
+
|
76
|
+
def error_handler(error)
|
77
|
+
@running = false
|
78
|
+
end
|
79
|
+
|
80
|
+
def ping_handler
|
81
|
+
end
|
82
|
+
|
83
|
+
# Websocket connect
|
84
|
+
def start_websocket(task: Async::Task.current)
|
85
|
+
connection = task.async do |task|
|
86
|
+
while @running == false
|
87
|
+
log("Broadcast Key: #{@broadcast_key}")
|
88
|
+
@ws = WebSocket.new(
|
89
|
+
room: @room,
|
90
|
+
broadcast_key: @broadcast_key,
|
91
|
+
url: @broadcast_host,
|
92
|
+
open_handler: method(:open_handler),
|
93
|
+
message_handler: method(:message_handler),
|
94
|
+
close_handler: method(:close_handler),
|
95
|
+
error_handler: method(:error_handler),
|
96
|
+
ping_handler: method(:ping_handler)
|
97
|
+
)
|
98
|
+
@ws.connect
|
137
99
|
end
|
138
|
-
task.children.each(&:wait)
|
139
|
-
ensure
|
140
|
-
ws.running = false
|
141
|
-
@running = false
|
142
100
|
end
|
101
|
+
task.children.each(&:wait)
|
102
|
+
ensure
|
103
|
+
log("Websocket task stop.")
|
104
|
+
connection&.stop
|
105
|
+
@running = false
|
143
106
|
end
|
144
|
-
|
145
|
-
def set_room_info
|
107
|
+
|
108
|
+
def set_room_info(task: Async::Task.current)
|
146
109
|
api = API::RoomAPI.new(@room)
|
147
110
|
@room_id = api.room_id
|
148
111
|
@room_name = api.room_name
|
@@ -150,94 +113,103 @@ module SleepRoom
|
|
150
113
|
@broadcast_host = api.broadcast_host
|
151
114
|
@broadcast_key = api.broadcast_key
|
152
115
|
rescue API::NotFoundError
|
153
|
-
|
116
|
+
error("The room does not exist.")
|
154
117
|
log("Task stopped.")
|
155
|
-
|
118
|
+
task.stop
|
156
119
|
rescue => e
|
157
|
-
|
158
|
-
log("
|
120
|
+
error(e.message)
|
121
|
+
log("Cannot parse room info.")
|
122
|
+
log("try again...")
|
123
|
+
task.sleep 5
|
159
124
|
retry
|
160
125
|
end
|
161
126
|
|
162
127
|
def parse_streaming_url(task: Async::Task.current)
|
163
128
|
api = API::StreamingAPI.new(@room_id)
|
164
|
-
|
129
|
+
api.streaming_url
|
165
130
|
rescue => e
|
166
131
|
SleepRoom.error(e.full_message)
|
167
|
-
log("
|
132
|
+
log("Unable to parse HLS url.")
|
133
|
+
task.sleep 1
|
168
134
|
retry
|
169
135
|
end
|
170
136
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
start_time: start_time,
|
185
|
-
name: @room_name,
|
186
|
-
group: @group,
|
187
|
-
live: true,
|
188
|
-
status: :downloading,
|
189
|
-
streaming_url: streaming_url,
|
190
|
-
download_pid: pid
|
191
|
-
})
|
137
|
+
# Downloader
|
138
|
+
def download_process(task: Async::Task.current)
|
139
|
+
completed = false
|
140
|
+
@downloading = true
|
141
|
+
log("Download start.")
|
142
|
+
streaming_url = parse_streaming_url
|
143
|
+
output = build_output
|
144
|
+
# Call time
|
145
|
+
call_time = Time.now
|
146
|
+
pid = SleepRoom::Record.call_minyami(url: streaming_url, output: output)
|
147
|
+
@status.downloading(room: @room, url: streaming_url, pid: pid, start_time: call_time, output: output)
|
148
|
+
log("Waiting for download process.")
|
149
|
+
# Status
|
192
150
|
task.async do |t|
|
193
151
|
loop do
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
status
|
204
|
-
|
152
|
+
if SleepRoom.running?(pid) && @is_live
|
153
|
+
# Downloading
|
154
|
+
elsif SleepRoom.running?(pid) && @is_live == false
|
155
|
+
# Live stopped, Minyami process running.
|
156
|
+
retries = 0
|
157
|
+
while retries < 3
|
158
|
+
set_room_info
|
159
|
+
break if @is_live == true
|
160
|
+
|
161
|
+
log("Waiting for latest status...")
|
162
|
+
task.sleep 5
|
163
|
+
retries += 1
|
164
|
+
end
|
165
|
+
completed = true if retries == 3 && @is_live == false
|
166
|
+
elsif (SleepRoom.running?(pid) == false && @is_live == false) || completed
|
167
|
+
# Live stopped, Minyami process stopped.
|
168
|
+
@status.add(room: @room, status: :completed, live: false)
|
169
|
+
log("Download completed.")
|
170
|
+
if configatron.minyami.no_merge
|
171
|
+
log("Find minyami temp files...")
|
172
|
+
tmp_path = SleepRoom.find_tmp_directory(output, call_time)
|
173
|
+
if tmp_path
|
174
|
+
log("Temp files in #{tmp_path}.")
|
175
|
+
save_path = File.dirname("#{configatron.save_path}/#{output}")
|
176
|
+
dir_name = File.basename(output).sub(".ts", "")
|
177
|
+
SleepRoom.move_ts_to_archive(tmp_path, save_path, dir_name)
|
178
|
+
log("Save chunks to #{save_path}/#{dir_name}.")
|
179
|
+
else
|
180
|
+
log("Can not find temp file")
|
181
|
+
end
|
182
|
+
end
|
183
|
+
@ws.close
|
184
|
+
@running = false
|
205
185
|
break
|
206
|
-
elsif
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
186
|
+
elsif SleepRoom.running?(pid) == false && @is_live == true
|
187
|
+
# Live broadcast, Minyami process stopped.
|
188
|
+
set_room_info
|
189
|
+
next if @is_live == false
|
190
|
+
|
191
|
+
log("Minyami stopped, Try to call Minyami again.")
|
192
|
+
download_process
|
213
193
|
end
|
214
|
-
t.sleep
|
215
|
-
rescue Faraday::ConnectionFailed
|
216
|
-
log("Network error.")
|
217
|
-
retry
|
194
|
+
t.sleep 1
|
218
195
|
end
|
219
|
-
end
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
group: @group,
|
237
|
-
name: @room_name,
|
238
|
-
status: :waiting,
|
239
|
-
ws: status
|
240
|
-
})
|
196
|
+
end
|
197
|
+
ensure
|
198
|
+
@downloading = false
|
199
|
+
end
|
200
|
+
|
201
|
+
# @return [String]
|
202
|
+
def build_output
|
203
|
+
room = @room
|
204
|
+
group = @group
|
205
|
+
tmp_str = configatron.default_save_name
|
206
|
+
tmp_str = tmp_str.sub("\%TIME\%", Time.now.strftime("%Y-%m-%d-%H-%M-%S")) if tmp_str.include?("\%TIME\%")
|
207
|
+
tmp_str = tmp_str.sub("\%ROOMNAME\%", room) if tmp_str.include?("\%ROOMNAME\%")
|
208
|
+
File.join(group, room, tmp_str)
|
209
|
+
end
|
210
|
+
|
211
|
+
def update_status
|
212
|
+
@status.waiting(room: @room, group: @group, room_name: @room_name, key: @broadcast_key)
|
241
213
|
end
|
242
214
|
end
|
243
215
|
end
|