sleeproom 0.4.3 → 0.9.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 16490f0f3a48428466310c0a5ab4c89a7395aeeb9c71aaba2679b43894c145db
4
- data.tar.gz: e03f35faf54bd848151501bbb0dd14c56ea935647fe7bc1e8b9f00095d665691
3
+ metadata.gz: 1164a0ff4adcb7d05b1a089972e1d895a10a334eb0d42be870a13198efbeec65
4
+ data.tar.gz: a22e22bc58e4db57da69b233d81026f6449645a4755a93c2353cb40430ab3ad9
5
5
  SHA512:
6
- metadata.gz: 819b5780ed280aefcc693986715e30c014128da80d110fc8abb35a23992efdda1f3344ec9b343a1ce746b29a8bd89cf2f90d1beb3989abf9c3d333b8b8f03d5c
7
- data.tar.gz: 90a9e5e52b573c39b8627521b04ac7811067a8a1c6f379d597f7c35fbdb7b94a345980feaf74ef4bd49df793d35f40d6135b9e3984633937517d045d6b32140c
6
+ metadata.gz: 2999e46c33eaf5eed3fe5687e7815f74fcf0b0b702a9fc25113f10234c4d8e2d54d4023d460e7fb54a1f84a02b266c3d3f27dfb823ec0e16a0db2292ae6e8dad
7
+ data.tar.gz: 284d500d464e090b83dc7d72a4e1ed1e6db3322095e60f93e079359a0c25a8cef12804b3c9eb3f3a0a7a6fd45aaf32dbd684b03284eacd3317cbb33df367e968
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", "~> 12.0"
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
@@ -1,28 +1,35 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sleeproom (0.4.3)
4
+ sleeproom (0.9.0.pre1)
5
5
  async (~> 1.26.0)
6
6
  async-http-faraday (~> 0.9.0)
7
7
  async-websocket (~> 0.15.0)
8
+ backports (~> 3.0)
8
9
  colorize (~> 0.8.0)
9
10
  configatron (~> 4.5.0)
11
+ falcon (~> 0.36.0)
12
+ roda (~> 3.33.0)
13
+ ruby-next-core (~> 0.9.0)
10
14
  terminal-table (~> 1.8.0)
11
15
 
12
16
  GEM
13
17
  remote: https://rubygems.org/
14
18
  specs:
15
- activesupport (6.0.3.1)
19
+ activesupport (6.0.3.2)
16
20
  concurrent-ruby (~> 1.0, >= 1.0.2)
17
21
  i18n (>= 0.7, < 2)
18
22
  minitest (~> 5.1)
19
23
  tzinfo (~> 1.1)
20
24
  zeitwerk (~> 2.2, >= 2.2.2)
21
- ast (2.4.0)
22
- async (1.26.1)
25
+ ast (2.4.1)
26
+ async (1.26.2)
23
27
  console (~> 1.0)
24
28
  nio4r (~> 2.3)
25
29
  timers (~> 4.1)
30
+ async-container (0.16.6)
31
+ async (~> 1.0)
32
+ async-io (~> 1.26)
26
33
  async-http (0.52.4)
27
34
  async (~> 1.25)
28
35
  async-io (~> 1.28)
@@ -30,6 +37,8 @@ GEM
30
37
  protocol-http (~> 0.20.0)
31
38
  protocol-http1 (~> 0.13.0)
32
39
  protocol-http2 (~> 0.14.0)
40
+ async-http-cache (0.2.0)
41
+ async-http (~> 0.51)
33
42
  async-http-faraday (0.9.0)
34
43
  async-http (~> 0.42)
35
44
  faraday
@@ -41,22 +50,40 @@ GEM
41
50
  async-http (~> 0.51)
42
51
  async-io (~> 1.23)
43
52
  protocol-websocket (~> 0.7.0)
53
+ backports (3.18.1)
54
+ build-environment (1.13.0)
44
55
  colorize (0.8.1)
45
56
  concurrent-ruby (1.1.6)
46
57
  configatron (4.5.1)
47
58
  console (1.8.2)
48
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)
49
71
  faraday (1.0.1)
50
72
  multipart-post (>= 1.2, < 3)
51
73
  i18n (1.8.3)
52
74
  concurrent-ruby (~> 1.0)
53
75
  jaro_winkler (1.5.4)
76
+ localhost (1.1.6)
77
+ mapping (1.1.1)
54
78
  minitest (5.14.1)
55
79
  multipart-post (2.1.1)
56
80
  nio4r (2.5.2)
57
- parallel (1.19.1)
58
- parser (2.7.1.3)
59
- ast (~> 2.4.0)
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)
60
87
  protocol-hpack (1.4.2)
61
88
  protocol-http (0.20.0)
62
89
  protocol-http1 (0.13.0)
@@ -67,9 +94,12 @@ GEM
67
94
  protocol-websocket (0.7.4)
68
95
  protocol-http (~> 0.2)
69
96
  protocol-http1 (~> 0.2)
70
- rack (2.2.2)
97
+ rack (2.2.3)
71
98
  rainbow (3.0.0)
72
- rake (12.3.3)
99
+ rake (13.0.1)
100
+ rexml (3.2.4)
101
+ roda (3.33.0)
102
+ rack
73
103
  rspec (3.9.0)
74
104
  rspec-core (~> 3.9.0)
75
105
  rspec-expectations (~> 3.9.0)
@@ -83,31 +113,36 @@ GEM
83
113
  diff-lcs (>= 1.2.0, < 2.0)
84
114
  rspec-support (~> 3.9.0)
85
115
  rspec-support (3.9.3)
86
- rubocop (0.79.0)
116
+ rubocop (0.82.0)
87
117
  jaro_winkler (~> 1.5.1)
88
118
  parallel (~> 1.10)
89
119
  parser (>= 2.7.0.1)
90
120
  rainbow (>= 2.2.2, < 4.0)
121
+ rexml
91
122
  ruby-progressbar (~> 1.7)
92
- unicode-display_width (>= 1.4.0, < 1.7)
123
+ unicode-display_width (>= 1.4.0, < 2.0)
93
124
  rubocop-github (0.16.0)
94
125
  rubocop (<= 0.82.0)
95
126
  rubocop-performance (~> 1.0)
96
127
  rubocop-rails (~> 2.0)
97
128
  rubocop-performance (1.6.1)
98
129
  rubocop (>= 0.71.0)
99
- rubocop-rails (2.5.2)
100
- activesupport
130
+ rubocop-rails (2.6.0)
131
+ activesupport (>= 4.2.0)
101
132
  rack (>= 1.1)
102
- rubocop (>= 0.72.0)
133
+ rubocop (>= 0.82.0)
134
+ ruby-next-core (0.9.2)
103
135
  ruby-progressbar (1.10.1)
136
+ samovar (2.1.4)
137
+ console (~> 1.0)
138
+ mapping (~> 1.0)
104
139
  terminal-table (1.8.0)
105
140
  unicode-display_width (~> 1.1, >= 1.1.1)
106
141
  thread_safe (0.3.6)
107
142
  timers (4.3.0)
108
143
  tzinfo (1.2.7)
109
144
  thread_safe (~> 0.1)
110
- unicode-display_width (1.6.1)
145
+ unicode-display_width (1.7.0)
111
146
  zeitwerk (2.3.0)
112
147
 
113
148
  PLATFORMS
@@ -115,9 +150,8 @@ PLATFORMS
115
150
  x64-mingw32
116
151
 
117
152
  DEPENDENCIES
118
- rake (~> 12.0)
153
+ rake (~> 13.0)
119
154
  rspec (~> 3.0)
120
- rubocop (~> 0.79.0)
121
155
  rubocop-github
122
156
  rubocop-performance
123
157
  sleeproom!
data/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/gem_tasks"
2
4
  require "rspec/core/rake_task"
3
5
 
4
6
  RSpec::Core::RakeTask.new(:spec)
5
7
 
6
- task :default => :spec
8
+ task default: :spec
@@ -3,5 +3,4 @@
3
3
 
4
4
  require "sleeproom/cli"
5
5
 
6
- cli = SleepRoom::CLI.new(ARGV)
7
- cli.run
6
+ SleepRoom::CLI.new(ARGV)
@@ -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
- return buffer
16
+ buffer
15
17
  end
16
-
18
+
17
19
  def dump(object)
18
- return object
20
+ object
19
21
  end
20
- end
22
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "backports/2.5" if RUBY_VERSION < "2.5.0"
4
+ require "ruby-next"
3
5
  require "optparse"
4
6
  require "yaml"
5
7
  require "sleeproom/record"
@@ -11,15 +13,16 @@ module SleepRoom
11
13
  SleepRoom.reload_config
12
14
  @options = {}
13
15
  build
14
- unless argv.empty?
16
+ if argv.empty? == false
15
17
  @parser.parse!(argv)
16
18
  action = argv.shift
17
- if action == "status"
19
+ case action
20
+ when "status"
18
21
  SleepRoom::Record::Tasks.status
19
- elsif action == "start"
20
- SleepRoom::Record::Tasks.start
21
- elsif action == "exit"
22
- SleepRoom::Record::Tasks.stop
22
+ when "start"
23
+ SleepRoom::Record::Tasks.start(**@options)
24
+ when "lists"
25
+ SleepRoom::Record::Tasks.lists
23
26
  end
24
27
  exit(0)
25
28
  else
@@ -28,22 +31,20 @@ module SleepRoom
28
31
  end
29
32
  end
30
33
 
31
- # @return [void]
32
- def run
33
- SleepRoom::Record::Tasks.start
34
- end
35
-
36
34
  # @return [void]
37
35
  def build
38
36
  @parser = OptionParser.new do |opt|
39
37
  opt.version = "SleepRoom / #{SleepRoom::VERSION}"
40
- opt.banner = "#{opt.version}"
38
+ opt.banner = opt.version.to_s
41
39
  opt.banner += "\nUsage: sleeproom [Options]\n\n"
42
40
 
43
41
  opt.banner += "Action:\n"
44
42
  opt.banner += "status".rjust(10)
45
43
  opt.banner += "显示任务状态".rjust(33)
46
44
  opt.banner += "\n"
45
+ opt.banner += "list".rjust(8)
46
+ opt.banner += "显示录制列表".rjust(35)
47
+ opt.banner += "\n"
47
48
  opt.banner += "exit".rjust(8)
48
49
  opt.banner += "关闭任务队列".rjust(35)
49
50
  opt.banner += "\n\nCommands:\n"
@@ -57,19 +58,20 @@ module SleepRoom
57
58
  end
58
59
 
59
60
  opt.on("-d", "--download [ROOM]", "录制指定房间") do |room|
60
- raise Error.new("房间名不能为空") if room.nil?
61
- if room.match?("https://www.showroom-live.com/")
62
- room = room.match(/https:\/\/www.showroom-live.com\/(.*)/)[1]
63
- end
61
+ raise Error, "房间名不能为空" if room.nil?
62
+
63
+ room = room.match(%r{https://www.showroom-live.com/(.*)})[1] if room.match?("https://www.showroom-live.com/")
64
64
  write_status = SleepRoom::Record::WriteStatus.new
65
- record = SleepRoom::Record::Showroom.new(room: room, group: "download", queue: write_status)
66
- record.record
65
+ Async do
66
+ record = SleepRoom::Record::Showroom.new(room: room, group: "download", queue: write_status)
67
+ record.record
68
+ end
67
69
  end
68
70
 
69
71
  opt.on("-v", "--verbose", "Print log") do
70
72
  @options[:verbose] = true
71
73
  end
72
-
74
+
73
75
  opt.on_tail("--version", "Print version") do
74
76
  STDOUT.puts(opt.version)
75
77
  end
@@ -8,13 +8,16 @@ 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/web/app"
11
12
  require "async"
13
+ require "roda"
14
+ require "rack/handler/falcon"
12
15
  require "shellwords"
13
16
  module SleepRoom
14
17
  module Record
15
18
  # Okite!!!
16
19
  # @param url [String]
17
- # @return [Boolean]
20
+ # @return [Integer]
18
21
  def self.call_minyami(url:, is_live: true, threads: configatron.minyami.threads, output:, retries: configatron.minyami.retries)
19
22
  command = "minyami -d #{Shellwords.escape(url)}"
20
23
  command += " --retries #{retries.to_i}" if retries
@@ -24,23 +27,23 @@ module SleepRoom
24
27
  command += " --output #{Shellwords.escape(output)}" if output
25
28
  download_dir_check(output)
26
29
  pid = exec_command(command, output)
27
- return pid
30
+ pid
28
31
  end
29
32
 
30
33
  # @param command [String]
31
- # @return [Boolean]
34
+ # @return [Integer]
32
35
  def self.exec_command(command, output)
33
36
  SleepRoom.info("Call command: #{command}")
34
37
  SleepRoom.info("STDOUT: #{output}.out , STDERR: #{output}.err")
35
38
  pid = spawn(command, out: "#{output}.out", err: "#{output}.err")
36
39
  SleepRoom.info("PID: #{pid}")
37
40
  Process.detach(pid)
38
- return pid
41
+ pid
39
42
  end
40
43
 
41
44
  def self.download_dir_check(output)
42
45
  dir = File.dirname(output)
43
- if !Dir.exist?(dir)
46
+ unless Dir.exist?(dir)
44
47
  SleepRoom.info("#{dir} does not exist, creating...")
45
48
  SleepRoom.mkdir(dir)
46
49
  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
- Async do
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(task: Async::Task.current)
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(task: Async::Task.current)
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(task: Async::Task.current)
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.new("streaming url is null.")
20
+ raise Error, "streaming url is null."
20
21
  else
21
- @json["streaming_url_list"].sort_by{|hash| -hash["quality"]}.first["url"]
22
+ @json["streaming_url_list"].min_by { |hash| -hash["quality"] }["url"]
22
23
  end
23
24
  end
24
25
  end
@@ -1,148 +1,97 @@
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
- SITE = "showroom"
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
- @queue = queue
16
+ @status = queue
12
17
  @running = false
13
- @downlaoding = false
14
- @reconnection = false
15
18
  end
16
19
 
17
- # @param user [String]
18
- # @return [Boolean]
19
- def record(reconnection: false)
20
- room = @room
21
- Async do |task|
22
- set_room_info
23
- task.async do |t|
24
- while @is_live
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
20
+ # Record Room
21
+ def recore
22
+ set_room_info
23
+ if @is_live
24
+ log("Status: broadcast.")
25
+ download_process
26
+ else
27
+ log("Status: Stop.")
67
28
  end
29
+ start_websocket
30
+ rescue => e
31
+ error(e.full_message)
32
+ Async::Task.current.sleep 5
33
+ retry
68
34
  end
69
35
 
36
+ # Print log
37
+ # @param str [String]
70
38
  def log(str)
71
39
  SleepRoom.info("[#{@room}] #{str}")
72
40
  end
73
-
41
+
42
+ # Print log
43
+ # @param str [String]
44
+ def error(str)
45
+ SleepRoom.error("[#{@room}] #{str}")
46
+ end
47
+
74
48
  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|
49
+
50
+ # Websocket connect
51
+ def start_websocket(task: Async::Task.current)
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
86
59
  case message["t"].to_i
87
60
  when 101
88
61
  log("Live stop.")
62
+ @is_live = false
89
63
  ws.running = false
90
- @running = false
91
- record
92
64
  when 104
93
65
  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
66
+ download_process
104
67
  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
-
114
- Async do |task|
115
- last_ack = nil
116
- last_ping = nil
117
- while @running && @downlaoding == false
118
- queue = ws.queue.items
119
- if !queue.empty?
120
- queue.each do |event|
121
- case event[:event]
122
- when :ack
123
- last_ack = event[:time]
124
- when :ping
125
- last_ping = event[:ping]
126
- end
127
- end
128
- end
129
- if !last_ack.nil? && Time.now.to_i - last_ack.to_i > 65
130
- ws.running = false
131
- @running = false
132
- task.stop
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
133
81
  end
134
- waiting_live({last_ack: last_ack})
135
- task.sleep 1
82
+ else
83
+ # TODO
136
84
  end
137
85
  end
138
- task.children.each(&:wait)
139
- ensure
140
- ws.running = false
141
- @running = false
86
+ rescue => e
87
+ error("WebSocket stopped.")
88
+ puts(e.full_message)
142
89
  end
90
+ ensure
91
+ @running = false
143
92
  end
144
-
145
- def set_room_info
93
+
94
+ def set_room_info(task: Async::Task.current)
146
95
  api = API::RoomAPI.new(@room)
147
96
  @room_id = api.room_id
148
97
  @room_name = api.room_name
@@ -150,94 +99,97 @@ module SleepRoom
150
99
  @broadcast_host = api.broadcast_host
151
100
  @broadcast_key = api.broadcast_key
152
101
  rescue API::NotFoundError
153
- SleepRoom.error("[#{@room}] The room does not exist.")
102
+ error("The room does not exist.")
154
103
  log("Task stopped.")
155
- Async::Task.current.stop
104
+ task.stop
156
105
  rescue => e
157
- SleepRoom.error(e.message)
158
- log("[setRoomInfo] Retry...")
106
+ error(e.message)
107
+ log("获取房间信息失败.")
108
+ log("等待5秒...")
109
+ task.sleep 5
159
110
  retry
160
111
  end
161
112
 
162
- def parse_streaming_url(task: Async::Task.current)
113
+ def parse_streaming_url
163
114
  api = API::StreamingAPI.new(@room_id)
164
- streaming_url_list = api.streaming_url
115
+ api.streaming_url
165
116
  rescue => e
166
117
  SleepRoom.error(e.full_message)
167
- log("[parseStreamingUrl] Retry...")
118
+ log("获取 HLS 地址失败.")
168
119
  retry
169
120
  end
170
121
 
171
- def build_output(task: Async::Task.current)
172
- room = @room
173
- group = @group
174
- tmp_str = configatron.default_save_name
175
- tmp_str = tmp_str.sub("\%TIME\%", Time.now.strftime("%Y-%m-%d-%H-%M-%S")) if tmp_str.include?("\%TIME\%")
176
- tmp_str = tmp_str.sub("\%ROOMNAME\%", room) if tmp_str.include?("\%ROOMNAME\%")
177
- File.join(group, room, "showroom", tmp_str)
178
- end
179
-
180
- def downloading(streaming_url, pid, start_time, task: Async::Task.current)
181
- @downlaoding = true
182
- @queue.add({
183
- room: @room,
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
- })
122
+ # Downloader
123
+ def download_process(task: Async::Task.current)
124
+ completed = false
125
+ log("Download start.")
126
+ streaming_url = parse_streaming_url
127
+ output = build_output
128
+ # Call time
129
+ call_time = Time.now
130
+ pid = SleepRoom::Record.call_minyami(url: streaming_url, output: output)
131
+ @status.downloading(room: @room, url: streaming_url, pid: pid, start_time: call_time)
132
+ log("Waiting for download process.")
133
+ # Status
192
134
  task.async do |t|
193
135
  loop do
194
- live = API::RoomAPI.new(@room).live?
195
- if !SleepRoom.running?(pid) && !live
196
- log("Download complete.")
197
- @downlaoding = false
198
- @queue.add({
199
- room: @room,
200
- name: @room_name,
201
- group: @group,
202
- live: API::RoomAPI.new(@room).live?,
203
- status: :complete,
204
- })
136
+ if SleepRoom.running?(pid) && @is_live
137
+ # Downloading
138
+ elsif SleepRoom.running?(pid) && @is_live == false
139
+ # Live stopped, Minyami process running.
140
+ retries = 0
141
+ while retries < 3
142
+ set_room_info
143
+ break if @is_live == true
144
+
145
+ log("Waiting for latest status...")
146
+ task.sleep 20
147
+ retries += 1
148
+ end
149
+ completed = true if retries == 3 && @is_live == false
150
+ elsif (SleepRoom.running?(pid) == false && @is_live == false) || completed
151
+ # Live stopped, Minyami process stopped.
152
+ @status.add(room: @room, status: :completed, live: false)
153
+ log("Download completed.")
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")
164
+ end
165
+ record
166
+ @running = false
205
167
  break
206
- elsif live && !SleepRoom.running?(pid)
207
- log("Minyami crash.")
208
- streaming_url = parse_streaming_url
209
- output = build_output
210
- pid = SleepRoom::Record.call_minyami(url: streaming_url, output: output)
211
- elsif !live && SleepRoom.running?(pid)
212
- log("Live stop.")
168
+ elsif SleepRoom.running?(pid) == false && @is_live == true
169
+ # Live broadcast, Minyami process stopped.
170
+ set_room_info
171
+ next if @is_live == false
172
+
173
+ log("Minyami stopped, Try to call Minyami again.")
174
+ download_process
213
175
  end
214
- t.sleep 120
215
- rescue Faraday::ConnectionFailed
216
- log("Network error.")
217
- retry
176
+ t.sleep 1
218
177
  end
219
- end.wait
178
+ end
220
179
  end
221
180
 
222
- def add_error(error)
223
- @queue.add({
224
- room: @room,
225
- name: @room_name,
226
- group: @group,
227
- status: :retry,
228
- error: error.message
229
- })
181
+ # @return [String]
182
+ def build_output
183
+ room = @room
184
+ group = @group
185
+ tmp_str = configatron.default_save_name
186
+ tmp_str = tmp_str.sub("\%TIME\%", Time.now.strftime("%Y-%m-%d-%H-%M-%S")) if tmp_str.include?("\%TIME\%")
187
+ tmp_str = tmp_str.sub("\%ROOMNAME\%", room) if tmp_str.include?("\%ROOMNAME\%")
188
+ File.join(group, room, tmp_str)
230
189
  end
231
190
 
232
- def waiting_live(status)
233
- @queue.add({
234
- room: @room,
235
- live: false,
236
- group: @group,
237
- name: @room_name,
238
- status: :waiting,
239
- ws: status
240
- })
191
+ def update_status
192
+ @status.waiting(room: @room, group: @group, room_name: @room_name)
241
193
  end
242
194
  end
243
195
  end