sleeproom 0.4.3 → 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 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