sleeproom 0.9.0.beta3 → 0.9.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -2
- data/Gemfile.lock +160 -0
- data/README.md +1 -0
- data/lib/sleeproom/cli.rb +7 -13
- data/lib/sleeproom/record/record.rb +57 -77
- data/lib/sleeproom/record/tasks.rb +9 -7
- data/lib/sleeproom/record/web/app.rb +53 -0
- data/lib/sleeproom/record/websocket.rb +62 -53
- data/lib/sleeproom/record/write_status.rb +2 -5
- data/lib/sleeproom/record.rb +4 -3
- data/lib/sleeproom/utils.rb +7 -20
- data/lib/sleeproom/version.rb +1 -1
- data/sleeproom.gemspec +11 -10
- metadata +42 -28
- data/lib/sleeproom/record/plugins/youtube/upload.rb +0 -1
- data/lib/sleeproom/record/plugins.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1164a0ff4adcb7d05b1a089972e1d895a10a334eb0d42be870a13198efbeec65
|
4
|
+
data.tar.gz: a22e22bc58e4db57da69b233d81026f6449645a4755a93c2353cb40430ab3ad9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2999e46c33eaf5eed3fe5687e7815f74fcf0b0b702a9fc25113f10234c4d8e2d54d4023d460e7fb54a1f84a02b266c3d3f27dfb823ec0e16a0db2292ae6e8dad
|
7
|
+
data.tar.gz: 284d500d464e090b83dc7d72a4e1ed1e6db3322095e60f93e079359a0c25a8cef12804b3c9eb3f3a0a7a6fd45aaf32dbd684b03284eacd3317cbb33df367e968
|
data/.gitignore
CHANGED
data/Gemfile.lock
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
sleeproom (0.9.0.pre1)
|
5
|
+
async (~> 1.26.0)
|
6
|
+
async-http-faraday (~> 0.9.0)
|
7
|
+
async-websocket (~> 0.15.0)
|
8
|
+
backports (~> 3.0)
|
9
|
+
colorize (~> 0.8.0)
|
10
|
+
configatron (~> 4.5.0)
|
11
|
+
falcon (~> 0.36.0)
|
12
|
+
roda (~> 3.33.0)
|
13
|
+
ruby-next-core (~> 0.9.0)
|
14
|
+
terminal-table (~> 1.8.0)
|
15
|
+
|
16
|
+
GEM
|
17
|
+
remote: https://rubygems.org/
|
18
|
+
specs:
|
19
|
+
activesupport (6.0.3.2)
|
20
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
21
|
+
i18n (>= 0.7, < 2)
|
22
|
+
minitest (~> 5.1)
|
23
|
+
tzinfo (~> 1.1)
|
24
|
+
zeitwerk (~> 2.2, >= 2.2.2)
|
25
|
+
ast (2.4.1)
|
26
|
+
async (1.26.2)
|
27
|
+
console (~> 1.0)
|
28
|
+
nio4r (~> 2.3)
|
29
|
+
timers (~> 4.1)
|
30
|
+
async-container (0.16.6)
|
31
|
+
async (~> 1.0)
|
32
|
+
async-io (~> 1.26)
|
33
|
+
async-http (0.52.4)
|
34
|
+
async (~> 1.25)
|
35
|
+
async-io (~> 1.28)
|
36
|
+
async-pool (~> 0.2)
|
37
|
+
protocol-http (~> 0.20.0)
|
38
|
+
protocol-http1 (~> 0.13.0)
|
39
|
+
protocol-http2 (~> 0.14.0)
|
40
|
+
async-http-cache (0.2.0)
|
41
|
+
async-http (~> 0.51)
|
42
|
+
async-http-faraday (0.9.0)
|
43
|
+
async-http (~> 0.42)
|
44
|
+
faraday
|
45
|
+
async-io (1.30.0)
|
46
|
+
async (~> 1.14)
|
47
|
+
async-pool (0.3.2)
|
48
|
+
async (~> 1.25)
|
49
|
+
async-websocket (0.15.0)
|
50
|
+
async-http (~> 0.51)
|
51
|
+
async-io (~> 1.23)
|
52
|
+
protocol-websocket (~> 0.7.0)
|
53
|
+
backports (3.18.1)
|
54
|
+
build-environment (1.13.0)
|
55
|
+
colorize (0.8.1)
|
56
|
+
concurrent-ruby (1.1.6)
|
57
|
+
configatron (4.5.1)
|
58
|
+
console (1.8.2)
|
59
|
+
diff-lcs (1.3)
|
60
|
+
falcon (0.36.4)
|
61
|
+
async (~> 1.13)
|
62
|
+
async-container (~> 0.16.0)
|
63
|
+
async-http (~> 0.52.0)
|
64
|
+
async-http-cache (~> 0.2.0)
|
65
|
+
async-io (~> 1.22)
|
66
|
+
build-environment (~> 1.13)
|
67
|
+
localhost (~> 1.1)
|
68
|
+
process-metrics (~> 0.2.0)
|
69
|
+
rack (>= 1.0)
|
70
|
+
samovar (~> 2.1)
|
71
|
+
faraday (1.0.1)
|
72
|
+
multipart-post (>= 1.2, < 3)
|
73
|
+
i18n (1.8.3)
|
74
|
+
concurrent-ruby (~> 1.0)
|
75
|
+
jaro_winkler (1.5.4)
|
76
|
+
localhost (1.1.6)
|
77
|
+
mapping (1.1.1)
|
78
|
+
minitest (5.14.1)
|
79
|
+
multipart-post (2.1.1)
|
80
|
+
nio4r (2.5.2)
|
81
|
+
parallel (1.19.2)
|
82
|
+
parser (2.7.1.4)
|
83
|
+
ast (~> 2.4.1)
|
84
|
+
process-metrics (0.2.1)
|
85
|
+
console (~> 1.8)
|
86
|
+
samovar (~> 2.1)
|
87
|
+
protocol-hpack (1.4.2)
|
88
|
+
protocol-http (0.20.0)
|
89
|
+
protocol-http1 (0.13.0)
|
90
|
+
protocol-http (~> 0.19)
|
91
|
+
protocol-http2 (0.14.0)
|
92
|
+
protocol-hpack (~> 1.4)
|
93
|
+
protocol-http (~> 0.18)
|
94
|
+
protocol-websocket (0.7.4)
|
95
|
+
protocol-http (~> 0.2)
|
96
|
+
protocol-http1 (~> 0.2)
|
97
|
+
rack (2.2.3)
|
98
|
+
rainbow (3.0.0)
|
99
|
+
rake (13.0.1)
|
100
|
+
rexml (3.2.4)
|
101
|
+
roda (3.33.0)
|
102
|
+
rack
|
103
|
+
rspec (3.9.0)
|
104
|
+
rspec-core (~> 3.9.0)
|
105
|
+
rspec-expectations (~> 3.9.0)
|
106
|
+
rspec-mocks (~> 3.9.0)
|
107
|
+
rspec-core (3.9.2)
|
108
|
+
rspec-support (~> 3.9.3)
|
109
|
+
rspec-expectations (3.9.2)
|
110
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
111
|
+
rspec-support (~> 3.9.0)
|
112
|
+
rspec-mocks (3.9.1)
|
113
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
114
|
+
rspec-support (~> 3.9.0)
|
115
|
+
rspec-support (3.9.3)
|
116
|
+
rubocop (0.82.0)
|
117
|
+
jaro_winkler (~> 1.5.1)
|
118
|
+
parallel (~> 1.10)
|
119
|
+
parser (>= 2.7.0.1)
|
120
|
+
rainbow (>= 2.2.2, < 4.0)
|
121
|
+
rexml
|
122
|
+
ruby-progressbar (~> 1.7)
|
123
|
+
unicode-display_width (>= 1.4.0, < 2.0)
|
124
|
+
rubocop-github (0.16.0)
|
125
|
+
rubocop (<= 0.82.0)
|
126
|
+
rubocop-performance (~> 1.0)
|
127
|
+
rubocop-rails (~> 2.0)
|
128
|
+
rubocop-performance (1.6.1)
|
129
|
+
rubocop (>= 0.71.0)
|
130
|
+
rubocop-rails (2.6.0)
|
131
|
+
activesupport (>= 4.2.0)
|
132
|
+
rack (>= 1.1)
|
133
|
+
rubocop (>= 0.82.0)
|
134
|
+
ruby-next-core (0.9.2)
|
135
|
+
ruby-progressbar (1.10.1)
|
136
|
+
samovar (2.1.4)
|
137
|
+
console (~> 1.0)
|
138
|
+
mapping (~> 1.0)
|
139
|
+
terminal-table (1.8.0)
|
140
|
+
unicode-display_width (~> 1.1, >= 1.1.1)
|
141
|
+
thread_safe (0.3.6)
|
142
|
+
timers (4.3.0)
|
143
|
+
tzinfo (1.2.7)
|
144
|
+
thread_safe (~> 0.1)
|
145
|
+
unicode-display_width (1.7.0)
|
146
|
+
zeitwerk (2.3.0)
|
147
|
+
|
148
|
+
PLATFORMS
|
149
|
+
ruby
|
150
|
+
x64-mingw32
|
151
|
+
|
152
|
+
DEPENDENCIES
|
153
|
+
rake (~> 13.0)
|
154
|
+
rspec (~> 3.0)
|
155
|
+
rubocop-github
|
156
|
+
rubocop-performance
|
157
|
+
sleeproom!
|
158
|
+
|
159
|
+
BUNDLED WITH
|
160
|
+
2.1.4
|
data/README.md
CHANGED
data/lib/sleeproom/cli.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "backports/2.5" if RUBY_VERSION < "2.5.0"
|
3
4
|
require "ruby-next"
|
4
5
|
require "optparse"
|
5
6
|
require "yaml"
|
@@ -11,12 +12,6 @@ module SleepRoom
|
|
11
12
|
def initialize(argv)
|
12
13
|
SleepRoom.reload_config
|
13
14
|
@options = {}
|
14
|
-
begin
|
15
|
-
minyami = `minyami --version`
|
16
|
-
status = $?
|
17
|
-
rescue => e
|
18
|
-
SleepRoom.warning("无法调用 Minyami: #{e.message}")
|
19
|
-
end
|
20
15
|
build
|
21
16
|
if argv.empty? == false
|
22
17
|
@parser.parse!(argv)
|
@@ -47,18 +42,18 @@ module SleepRoom
|
|
47
42
|
opt.banner += "status".rjust(10)
|
48
43
|
opt.banner += "显示任务状态".rjust(33)
|
49
44
|
opt.banner += "\n"
|
50
|
-
opt.banner += "
|
51
|
-
opt.banner += "显示录制列表".rjust(
|
45
|
+
opt.banner += "list".rjust(8)
|
46
|
+
opt.banner += "显示录制列表".rjust(35)
|
52
47
|
opt.banner += "\n"
|
53
48
|
opt.banner += "exit".rjust(8)
|
54
49
|
opt.banner += "关闭任务队列".rjust(35)
|
55
50
|
opt.banner += "\n\nCommands:\n"
|
56
51
|
|
57
|
-
opt.on("-a ROOM, NAME", "--add ROOM, GROUP", Array, "
|
52
|
+
opt.on("-a ROOM, NAME", "--add ROOM, GROUP", Array, "添加到监视列表") do |room|
|
58
53
|
SleepRoom::Record::Tasks.add(room[0].to_s, room[1].to_s)
|
59
54
|
end
|
60
55
|
|
61
|
-
opt.on("-r", "--remove [ROOM]", "
|
56
|
+
opt.on("-r", "--remove [ROOM]", "从监视列表移除") do |room|
|
62
57
|
SleepRoom::Record::Tasks.remove(room)
|
63
58
|
end
|
64
59
|
|
@@ -73,12 +68,11 @@ module SleepRoom
|
|
73
68
|
end
|
74
69
|
end
|
75
70
|
|
76
|
-
opt.on("--verbose", "
|
77
|
-
ENV["SR_DEBUG"] = "DEBUG"
|
71
|
+
opt.on("-v", "--verbose", "Print log") do
|
78
72
|
@options[:verbose] = true
|
79
73
|
end
|
80
74
|
|
81
|
-
opt.on_tail("
|
75
|
+
opt.on_tail("--version", "Print version") do
|
82
76
|
STDOUT.puts(opt.version)
|
83
77
|
end
|
84
78
|
|
@@ -15,24 +15,21 @@ module SleepRoom
|
|
15
15
|
@group = group
|
16
16
|
@status = queue
|
17
17
|
@running = false
|
18
|
-
@downloading = false
|
19
|
-
set_room_info
|
20
18
|
end
|
21
19
|
|
22
20
|
# Record Room
|
23
|
-
def
|
21
|
+
def recore
|
22
|
+
set_room_info
|
24
23
|
if @is_live
|
25
24
|
log("Status: broadcast.")
|
26
|
-
download_process
|
25
|
+
download_process
|
27
26
|
else
|
28
|
-
update_status
|
29
27
|
log("Status: Stop.")
|
30
28
|
end
|
31
29
|
start_websocket
|
32
30
|
rescue => e
|
33
31
|
error(e.full_message)
|
34
32
|
Async::Task.current.sleep 5
|
35
|
-
set_room_info
|
36
33
|
retry
|
37
34
|
end
|
38
35
|
|
@@ -42,10 +39,6 @@ module SleepRoom
|
|
42
39
|
SleepRoom.info("[#{@room}] #{str}")
|
43
40
|
end
|
44
41
|
|
45
|
-
def debug(str)
|
46
|
-
SleepRoom.debug("[#{@room}] #{str}")
|
47
|
-
end
|
48
|
-
|
49
42
|
# Print log
|
50
43
|
# @param str [String]
|
51
44
|
def error(str)
|
@@ -54,54 +47,47 @@ module SleepRoom
|
|
54
47
|
|
55
48
|
private
|
56
49
|
|
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
50
|
# Websocket connect
|
84
51
|
def start_websocket(task: Async::Task.current)
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
52
|
+
log("Broadcast Key: #{@broadcast_key}")
|
53
|
+
ws = WebSocket.new(room: @room, broadcast_key: @broadcast_key, url: @broadcast_host)
|
54
|
+
@running = true
|
55
|
+
update_status
|
56
|
+
begin
|
57
|
+
ws.connect do |event, message|
|
58
|
+
if event == :websocket
|
59
|
+
case message["t"].to_i
|
60
|
+
when 101
|
61
|
+
log("Live stop.")
|
62
|
+
@is_live = false
|
63
|
+
ws.running = false
|
64
|
+
when 104
|
65
|
+
log("Live start.")
|
66
|
+
download_process
|
67
|
+
end
|
68
|
+
elsif event == :status
|
69
|
+
case message[:event]
|
70
|
+
when :ack
|
71
|
+
update_status
|
72
|
+
when :close
|
73
|
+
log("WebSocket Close.")
|
74
|
+
task.sleep 5
|
75
|
+
record
|
76
|
+
when :error
|
77
|
+
error("Network Error.")
|
78
|
+
log("Try to reconnect server.")
|
79
|
+
task.sleep 5
|
80
|
+
record
|
81
|
+
end
|
82
|
+
else
|
83
|
+
# TODO
|
84
|
+
end
|
99
85
|
end
|
86
|
+
rescue => e
|
87
|
+
error("WebSocket stopped.")
|
88
|
+
puts(e.full_message)
|
100
89
|
end
|
101
|
-
task.children.each(&:wait)
|
102
90
|
ensure
|
103
|
-
log("Websocket task stop.")
|
104
|
-
connection&.stop
|
105
91
|
@running = false
|
106
92
|
end
|
107
93
|
|
@@ -118,33 +104,31 @@ module SleepRoom
|
|
118
104
|
task.stop
|
119
105
|
rescue => e
|
120
106
|
error(e.message)
|
121
|
-
log("
|
122
|
-
log("
|
107
|
+
log("获取房间信息失败.")
|
108
|
+
log("等待5秒...")
|
123
109
|
task.sleep 5
|
124
110
|
retry
|
125
111
|
end
|
126
112
|
|
127
|
-
def parse_streaming_url
|
113
|
+
def parse_streaming_url
|
128
114
|
api = API::StreamingAPI.new(@room_id)
|
129
115
|
api.streaming_url
|
130
116
|
rescue => e
|
131
117
|
SleepRoom.error(e.full_message)
|
132
|
-
log("
|
133
|
-
task.sleep 1
|
118
|
+
log("获取 HLS 地址失败.")
|
134
119
|
retry
|
135
120
|
end
|
136
121
|
|
137
122
|
# Downloader
|
138
123
|
def download_process(task: Async::Task.current)
|
139
124
|
completed = false
|
140
|
-
@downloading = true
|
141
125
|
log("Download start.")
|
142
126
|
streaming_url = parse_streaming_url
|
143
127
|
output = build_output
|
144
128
|
# Call time
|
145
129
|
call_time = Time.now
|
146
130
|
pid = SleepRoom::Record.call_minyami(url: streaming_url, output: output)
|
147
|
-
@status.downloading(room: @room, url: streaming_url, pid: pid, start_time: call_time
|
131
|
+
@status.downloading(room: @room, url: streaming_url, pid: pid, start_time: call_time)
|
148
132
|
log("Waiting for download process.")
|
149
133
|
# Status
|
150
134
|
task.async do |t|
|
@@ -159,7 +143,7 @@ module SleepRoom
|
|
159
143
|
break if @is_live == true
|
160
144
|
|
161
145
|
log("Waiting for latest status...")
|
162
|
-
task.sleep
|
146
|
+
task.sleep 20
|
163
147
|
retries += 1
|
164
148
|
end
|
165
149
|
completed = true if retries == 3 && @is_live == false
|
@@ -167,20 +151,18 @@ module SleepRoom
|
|
167
151
|
# Live stopped, Minyami process stopped.
|
168
152
|
@status.add(room: @room, status: :completed, live: false)
|
169
153
|
log("Download completed.")
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
log("Can not find temp file")
|
181
|
-
end
|
154
|
+
log("Find minyami temp files...")
|
155
|
+
tmp_path = SleepRoom.find_tmp_directory(output, call_time)
|
156
|
+
if tmp_path
|
157
|
+
log("Temp files in #{tmp_path}.")
|
158
|
+
save_path = File.dirname("#{configatron.save_path}/#{output}")
|
159
|
+
dir_name = File.basename(output).sub(".ts", "")
|
160
|
+
SleepRoom.move_ts_to_archive(tmp_path, save_path, dir_name)
|
161
|
+
log("Save chunks to #{save_path}/#{dir_name}.")
|
162
|
+
else
|
163
|
+
log("Can not find temp file")
|
182
164
|
end
|
183
|
-
|
165
|
+
record
|
184
166
|
@running = false
|
185
167
|
break
|
186
168
|
elsif SleepRoom.running?(pid) == false && @is_live == true
|
@@ -194,8 +176,6 @@ module SleepRoom
|
|
194
176
|
t.sleep 1
|
195
177
|
end
|
196
178
|
end
|
197
|
-
ensure
|
198
|
-
@downloading = false
|
199
179
|
end
|
200
180
|
|
201
181
|
# @return [String]
|
@@ -209,7 +189,7 @@ module SleepRoom
|
|
209
189
|
end
|
210
190
|
|
211
191
|
def update_status
|
212
|
-
@status.waiting(room: @room, group: @group, room_name: @room_name
|
192
|
+
@status.waiting(room: @room, group: @group, room_name: @room_name)
|
213
193
|
end
|
214
194
|
end
|
215
195
|
end
|
@@ -35,6 +35,14 @@ module SleepRoom
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
SleepRoom.info("共启动 #{running_task_count} 个任务.")
|
38
|
+
if configatron.web.use
|
39
|
+
Async do
|
40
|
+
host = configatron.web.server.to_s
|
41
|
+
port = configatron.web.port.to_i
|
42
|
+
Rack::Handler.get(:falcon).run(Web::App, Host: host, Port: port)
|
43
|
+
SleepRoom.info("Web server running. http://#{host}:#{port}/")
|
44
|
+
end
|
45
|
+
end
|
38
46
|
task.children.each(&:wait)
|
39
47
|
rescue StandardError => e
|
40
48
|
puts e.full_message
|
@@ -97,13 +105,7 @@ module SleepRoom
|
|
97
105
|
|
98
106
|
def self.add(room, group)
|
99
107
|
Async do
|
100
|
-
if group.empty?
|
101
|
-
if group_match = room.match(/(?<=[((]).*?(?=[))])/)
|
102
|
-
group = group_match[0]
|
103
|
-
else
|
104
|
-
group = "default"
|
105
|
-
end
|
106
|
-
end
|
108
|
+
group = "default" if group.empty?
|
107
109
|
old_record = SleepRoom.load_config(:record)
|
108
110
|
name = API::RoomAPI.new(room).room_name
|
109
111
|
input_record = { "room" => room, "name" => name }
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "roda"
|
4
|
+
module SleepRoom
|
5
|
+
module Web
|
6
|
+
class App < Roda
|
7
|
+
plugin :default_headers,
|
8
|
+
"Content-Type" => "application/json",
|
9
|
+
"X-Frame-Options" => "deny",
|
10
|
+
"X-Content-Type-Options" => "nosniff",
|
11
|
+
"X-XSS-Protection" => "1; mode=block"
|
12
|
+
plugin :content_security_policy do |csp|
|
13
|
+
csp.default_src :none
|
14
|
+
csp.style_src :self
|
15
|
+
csp.form_action :self
|
16
|
+
csp.script_src :self
|
17
|
+
csp.connect_src :self
|
18
|
+
csp.base_uri :none
|
19
|
+
csp.frame_ancestors :none
|
20
|
+
end
|
21
|
+
plugin :public
|
22
|
+
plugin :multi_route
|
23
|
+
plugin :not_found do
|
24
|
+
end
|
25
|
+
plugin :error_handler do |e|
|
26
|
+
$stderr.print "#{e.class}: #{e.message}\n"
|
27
|
+
warn e.backtrace
|
28
|
+
next exception_page(e, assets: true) if ENV["RACK_ENV"] == "development"
|
29
|
+
end
|
30
|
+
|
31
|
+
route "status" do |r|
|
32
|
+
SleepRoom.load_status.sort_by { |hash| hash[:group] }.to_json
|
33
|
+
end
|
34
|
+
|
35
|
+
route "lists" do |r|
|
36
|
+
r.get do
|
37
|
+
SleepRoom.load_config(:record).to_json
|
38
|
+
end
|
39
|
+
|
40
|
+
r.post do
|
41
|
+
end
|
42
|
+
end
|
43
|
+
route do |r|
|
44
|
+
r.public
|
45
|
+
r.multi_route
|
46
|
+
|
47
|
+
r.root do
|
48
|
+
"SleepRoom Web API"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -8,85 +8,94 @@ require "json"
|
|
8
8
|
module SleepRoom
|
9
9
|
module Record
|
10
10
|
class WebSocket
|
11
|
-
|
11
|
+
attr_accessor :last_ack
|
12
|
+
def initialize(room:, broadcast_key:, url:)
|
12
13
|
@room = room
|
13
14
|
@url = "wss://" + url
|
14
15
|
@broadcast_key = broadcast_key
|
15
16
|
@running = false
|
16
|
-
@
|
17
|
-
@open_handler = open_handler
|
18
|
-
@message_handler = message_handler
|
19
|
-
@close_handler = close_handler
|
20
|
-
@error_handler = error_handler
|
21
|
-
@ping_handler = ping_handler
|
17
|
+
@last_ack = nil
|
22
18
|
end
|
23
19
|
|
24
20
|
def connect(task: Async::Task.current)
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
21
|
+
url = @url
|
22
|
+
endpoint = Async::HTTP::Endpoint.parse(url)
|
23
|
+
Async::WebSocket::Client.connect(endpoint, handler: WebSocketConnection) do |connection|
|
24
|
+
begin
|
25
|
+
@connection = connection
|
26
|
+
@running = true
|
27
|
+
connection.write("SUB\t#{@broadcast_key}")
|
28
|
+
connection.flush
|
29
|
+
log("Connect to websocket server.")
|
30
|
+
yield :status, { event: :connect, time: Time.now }
|
29
31
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
send("PING\tshowroom")
|
32
|
+
ping_task = task.async do |sub|
|
33
|
+
while @running
|
34
|
+
sub.sleep 60
|
35
|
+
connection.write("PING\tshowroom")
|
36
|
+
connection.flush
|
37
|
+
end
|
37
38
|
end
|
38
|
-
end
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
status_task = task.async do |sub|
|
41
|
+
loop do
|
42
|
+
sub.sleep 1
|
43
|
+
connection.close if @running == false
|
44
|
+
end
|
45
|
+
end
|
43
46
|
|
44
|
-
|
47
|
+
reconnect_task = task.async do |t|
|
48
|
+
loop do
|
49
|
+
t.sleep 10
|
50
|
+
if !@last_ack.nil? && Time.now.to_i - @last_ack.to_i > 65
|
51
|
+
begin
|
52
|
+
yield :status, { event: :close, time: Time.now }
|
53
|
+
connection.close
|
54
|
+
rescue
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
while message = connection.read
|
60
|
+
if message == "ACK\tshowroom"
|
61
|
+
@last_ack = Time.now
|
62
|
+
yield :status, { event: :ack, time: Time.now } if message == "ACK\tshowroom"
|
63
|
+
end
|
64
|
+
next unless message.start_with?("MSG")
|
45
65
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
66
|
+
begin
|
67
|
+
yield :websocket, JSON.parse(message.split("\t")[2])
|
68
|
+
rescue => e
|
69
|
+
SleepRoom.error(e.message)
|
70
|
+
end
|
51
71
|
end
|
72
|
+
rescue => e
|
73
|
+
yield :status, { event: :error, error: e }
|
74
|
+
SleepRoom.error(e.message)
|
75
|
+
ensure
|
76
|
+
ping_task&.stop
|
77
|
+
status_task&.stop
|
78
|
+
connection.close
|
79
|
+
reconnect_task&.stop
|
80
|
+
log("WebSocket closed.")
|
52
81
|
end
|
53
|
-
rescue => e
|
54
|
-
error "error"
|
55
|
-
@error_handler.call(e)
|
56
|
-
log(e.full_message)
|
57
|
-
ensure
|
58
|
-
ping&.stop
|
59
|
-
@close_handler.call(nil)
|
60
|
-
@running = false
|
61
|
-
log("WebSocket closed.")
|
62
82
|
end
|
63
83
|
end
|
64
84
|
|
65
|
-
def send(data)
|
66
|
-
debug("SEND: #{data}")
|
67
|
-
@connection.write(data)
|
68
|
-
@connection.flush
|
69
|
-
end
|
70
|
-
|
71
85
|
def running?
|
72
86
|
@running
|
73
87
|
end
|
74
88
|
|
89
|
+
attr_writer :running
|
90
|
+
|
75
91
|
def stop
|
92
|
+
@running = false
|
76
93
|
@connection.close
|
77
94
|
end
|
78
95
|
|
79
96
|
def log(str)
|
80
97
|
SleepRoom.info("[#{@room}] #{str}")
|
81
98
|
end
|
82
|
-
|
83
|
-
def error(str)
|
84
|
-
SleepRoom.error("[#{@room}] #{str}")
|
85
|
-
end
|
86
|
-
|
87
|
-
def debug(str)
|
88
|
-
SleepRoom.debug("[#{@room}] #{str}")
|
89
|
-
end
|
90
|
-
end
|
91
99
|
end
|
92
|
-
end
|
100
|
+
end
|
101
|
+
end
|
@@ -34,7 +34,7 @@ module SleepRoom
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
def downloading(room:, url:, pid:, start_time
|
37
|
+
def downloading(room:, url:, pid:, start_time:)
|
38
38
|
add(
|
39
39
|
{
|
40
40
|
room: room,
|
@@ -47,7 +47,7 @@ module SleepRoom
|
|
47
47
|
)
|
48
48
|
end
|
49
49
|
|
50
|
-
def waiting(room:, group:, room_name
|
50
|
+
def waiting(room:, group:, room_name:)
|
51
51
|
add(
|
52
52
|
{
|
53
53
|
room: room,
|
@@ -55,9 +55,6 @@ module SleepRoom
|
|
55
55
|
group: group,
|
56
56
|
name: room_name,
|
57
57
|
status: :waiting,
|
58
|
-
websocket: {
|
59
|
-
key: key
|
60
|
-
}
|
61
58
|
}
|
62
59
|
)
|
63
60
|
end
|
data/lib/sleeproom/record.rb
CHANGED
@@ -8,20 +8,21 @@ 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/
|
11
|
+
require "sleeproom/record/web/app"
|
12
12
|
require "async"
|
13
|
+
require "roda"
|
14
|
+
require "rack/handler/falcon"
|
13
15
|
require "shellwords"
|
14
16
|
module SleepRoom
|
15
17
|
module Record
|
16
18
|
# Okite!!!
|
17
19
|
# @param url [String]
|
18
20
|
# @return [Integer]
|
19
|
-
def self.call_minyami(url:, is_live: true, threads: configatron.minyami.threads, output:, retries: configatron.minyami.retries
|
21
|
+
def self.call_minyami(url:, is_live: true, threads: configatron.minyami.threads, output:, retries: configatron.minyami.retries)
|
20
22
|
command = "minyami -d #{Shellwords.escape(url)}"
|
21
23
|
command += " --retries #{retries.to_i}" if retries
|
22
24
|
command += " --threads #{threads.to_i}" if threads
|
23
25
|
command += " --live" if is_live
|
24
|
-
command += " --nomerge" if no_merge
|
25
26
|
output = File.join(configatron.save_path, output)
|
26
27
|
command += " --output #{Shellwords.escape(output)}" if output
|
27
28
|
download_dir_check(output)
|
data/lib/sleeproom/utils.rb
CHANGED
@@ -6,14 +6,9 @@ require "fileutils"
|
|
6
6
|
require "tmpdir"
|
7
7
|
require "yaml"
|
8
8
|
require "logger"
|
9
|
-
require "dry/files"
|
10
9
|
|
11
10
|
module SleepRoom
|
12
11
|
class Error < StandardError; end
|
13
|
-
def self.files
|
14
|
-
Dry::Files.new
|
15
|
-
end
|
16
|
-
|
17
12
|
# @return [String]
|
18
13
|
def self.root_path
|
19
14
|
Dir.pwd
|
@@ -90,10 +85,15 @@ module SleepRoom
|
|
90
85
|
|
91
86
|
def self.init_base
|
92
87
|
base = {
|
88
|
+
web: {
|
89
|
+
use: true,
|
90
|
+
server: "localhost",
|
91
|
+
port: 3000
|
92
|
+
},
|
93
93
|
proxy: {
|
94
94
|
use: false,
|
95
95
|
server: "localhost",
|
96
|
-
port:
|
96
|
+
port: 8080,
|
97
97
|
type: "socks5"
|
98
98
|
},
|
99
99
|
record: {
|
@@ -107,8 +107,7 @@ module SleepRoom
|
|
107
107
|
default_save_name: "%ROOMNAME%-%TIME%.ts",
|
108
108
|
minyami: {
|
109
109
|
threads: 8,
|
110
|
-
retries: 999
|
111
|
-
no_merge: false,
|
110
|
+
retries: 999
|
112
111
|
},
|
113
112
|
logger: {
|
114
113
|
console: true,
|
@@ -196,10 +195,6 @@ module SleepRoom
|
|
196
195
|
SleepRoom.write_config_file(:pid, pid)
|
197
196
|
end
|
198
197
|
|
199
|
-
def self.plugins
|
200
|
-
|
201
|
-
end
|
202
|
-
|
203
198
|
def self.find_tmp_directory(output, call_time)
|
204
199
|
regex = /Proccessing (.*) finished./
|
205
200
|
output = "#{configatron.save_path}/#{output}"
|
@@ -234,12 +229,6 @@ module SleepRoom
|
|
234
229
|
log(:info, string)
|
235
230
|
end
|
236
231
|
|
237
|
-
# @param string [String]
|
238
|
-
# @return [nil]
|
239
|
-
def self.debug(string)
|
240
|
-
log(:debug, string) if ENV["SR_DEBUG"]
|
241
|
-
end
|
242
|
-
|
243
232
|
# @param string [String]
|
244
233
|
# @return [nil]
|
245
234
|
def self.warning(string)
|
@@ -261,8 +250,6 @@ module SleepRoom
|
|
261
250
|
warn("[WARN] #{log}".colorize(:yellow))
|
262
251
|
when :error
|
263
252
|
puts("[ERROR] #{log}".colorize(:red))
|
264
|
-
when :debug
|
265
|
-
puts("[DEBUG] #{log}".colorize(:gray))
|
266
253
|
end
|
267
254
|
end
|
268
255
|
file_logger(type, log) if configatron.logger.file.use == true
|
data/lib/sleeproom/version.rb
CHANGED
data/sleeproom.gemspec
CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.summary = "sleeproom"
|
12
12
|
spec.homepage = "https://github.com/KoellM/sleeproom"
|
13
13
|
spec.license = "MIT"
|
14
|
-
spec.required_ruby_version = Gem::Requirement.new(">= 2.
|
14
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
15
15
|
|
16
16
|
spec.metadata["homepage_uri"] = spec.homepage
|
17
17
|
# spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
|
@@ -25,15 +25,16 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.executables = ["sleeproom"]
|
26
26
|
spec.require_paths = ["lib"]
|
27
27
|
|
28
|
-
spec.add_runtime_dependency("async", "~> 1.
|
29
|
-
spec.add_runtime_dependency("async-http-faraday", "~> 0.9")
|
30
|
-
spec.add_runtime_dependency("async-websocket", "~> 0.
|
31
|
-
spec.add_runtime_dependency("
|
32
|
-
spec.add_runtime_dependency("
|
33
|
-
spec.add_runtime_dependency("
|
34
|
-
spec.add_runtime_dependency("
|
35
|
-
spec.add_runtime_dependency("
|
36
|
-
spec.add_runtime_dependency("
|
28
|
+
spec.add_runtime_dependency("async", "~> 1.26.0")
|
29
|
+
spec.add_runtime_dependency("async-http-faraday", "~> 0.9.0")
|
30
|
+
spec.add_runtime_dependency("async-websocket", "~> 0.15.0")
|
31
|
+
spec.add_runtime_dependency("backports", "~> 3.0")
|
32
|
+
spec.add_runtime_dependency("colorize", "~> 0.8.0")
|
33
|
+
spec.add_runtime_dependency("configatron", "~> 4.5.0")
|
34
|
+
spec.add_runtime_dependency("falcon", "~> 0.36.0")
|
35
|
+
spec.add_runtime_dependency("roda", "~> 3.33.0")
|
36
|
+
spec.add_runtime_dependency("ruby-next-core", "~> 0.9.0")
|
37
|
+
spec.add_runtime_dependency("terminal-table", "~> 1.8.0")
|
37
38
|
|
38
39
|
spec.post_install_message = <<~STR
|
39
40
|
SleepRoom 需要:
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sleeproom
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.0.
|
4
|
+
version: 0.9.0.pre1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Koell
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-07-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async
|
@@ -16,126 +16,140 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 1.26.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 1.26.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: async-http-faraday
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 0.9.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 0.9.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: async-websocket
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 0.15.0
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 0.15.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: backports
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: colorize
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
73
|
- - "~>"
|
60
74
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
75
|
+
version: 0.8.0
|
62
76
|
type: :runtime
|
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: 0.8.0
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: configatron
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
87
|
- - "~>"
|
74
88
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
89
|
+
version: 4.5.0
|
76
90
|
type: :runtime
|
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: 4.5.0
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
98
|
+
name: falcon
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
101
|
- - "~>"
|
88
102
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
103
|
+
version: 0.36.0
|
90
104
|
type: :runtime
|
91
105
|
prerelease: false
|
92
106
|
version_requirements: !ruby/object:Gem::Requirement
|
93
107
|
requirements:
|
94
108
|
- - "~>"
|
95
109
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
110
|
+
version: 0.36.0
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
112
|
+
name: roda
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
100
114
|
requirements:
|
101
115
|
- - "~>"
|
102
116
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
117
|
+
version: 3.33.0
|
104
118
|
type: :runtime
|
105
119
|
prerelease: false
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
107
121
|
requirements:
|
108
122
|
- - "~>"
|
109
123
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
124
|
+
version: 3.33.0
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
126
|
+
name: ruby-next-core
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
114
128
|
requirements:
|
115
129
|
- - "~>"
|
116
130
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
131
|
+
version: 0.9.0
|
118
132
|
type: :runtime
|
119
133
|
prerelease: false
|
120
134
|
version_requirements: !ruby/object:Gem::Requirement
|
121
135
|
requirements:
|
122
136
|
- - "~>"
|
123
137
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
138
|
+
version: 0.9.0
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
140
|
+
name: terminal-table
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
128
142
|
requirements:
|
129
143
|
- - "~>"
|
130
144
|
- !ruby/object:Gem::Version
|
131
|
-
version:
|
145
|
+
version: 1.8.0
|
132
146
|
type: :runtime
|
133
147
|
prerelease: false
|
134
148
|
version_requirements: !ruby/object:Gem::Requirement
|
135
149
|
requirements:
|
136
150
|
- - "~>"
|
137
151
|
- !ruby/object:Gem::Version
|
138
|
-
version:
|
152
|
+
version: 1.8.0
|
139
153
|
description:
|
140
154
|
email:
|
141
155
|
- i@wug.moe
|
@@ -149,6 +163,7 @@ files:
|
|
149
163
|
- ".rubocop.yml"
|
150
164
|
- ".rubocop_todo.yml"
|
151
165
|
- Gemfile
|
166
|
+
- Gemfile.lock
|
152
167
|
- LICENSE.txt
|
153
168
|
- README.md
|
154
169
|
- Rakefile
|
@@ -160,10 +175,9 @@ files:
|
|
160
175
|
- lib/sleeproom/record/api/room.rb
|
161
176
|
- lib/sleeproom/record/api/room_api.rb
|
162
177
|
- lib/sleeproom/record/api/streaming_api.rb
|
163
|
-
- lib/sleeproom/record/plugins.rb
|
164
|
-
- lib/sleeproom/record/plugins/youtube/upload.rb
|
165
178
|
- lib/sleeproom/record/record.rb
|
166
179
|
- lib/sleeproom/record/tasks.rb
|
180
|
+
- lib/sleeproom/record/web/app.rb
|
167
181
|
- lib/sleeproom/record/websocket.rb
|
168
182
|
- lib/sleeproom/record/write_status.rb
|
169
183
|
- lib/sleeproom/utils.rb
|
@@ -186,14 +200,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
186
200
|
requirements:
|
187
201
|
- - ">="
|
188
202
|
- !ruby/object:Gem::Version
|
189
|
-
version: 2.
|
203
|
+
version: 2.3.0
|
190
204
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
191
205
|
requirements:
|
192
206
|
- - ">"
|
193
207
|
- !ruby/object:Gem::Version
|
194
208
|
version: 1.3.1
|
195
209
|
requirements: []
|
196
|
-
rubygems_version: 3.
|
210
|
+
rubygems_version: 3.1.4
|
197
211
|
signing_key:
|
198
212
|
specification_version: 4
|
199
213
|
summary: sleeproom
|
@@ -1 +0,0 @@
|
|
1
|
-
# Youtube Uploader
|