sleeproom 0.9.0.beta3 → 0.9.0.pre1
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 +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
|