muzak 0.2.3 → 0.2.4

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
  SHA1:
3
- metadata.gz: c0f970a0a6e2731b8014245f91e9b97e10bdbfa8
4
- data.tar.gz: 0c8d58beb2f2bd3b8cf77af94a6a4e8aef753b0c
3
+ metadata.gz: 99bf2869397efa5ed245f727b5a6d4ccf57c9f6c
4
+ data.tar.gz: 4903fe98bf3a597ed41f7d9c0e3f76a5afd6366d
5
5
  SHA512:
6
- metadata.gz: bd1b4f8bc4af206042d99b6156d1dd90d57cb263d0a2885e8d29b4ce4d25b56ba13358ce1dc23d28142a9f0a9228e419f1816df5aa1619c05a31d2e8b07ba102
7
- data.tar.gz: 12bc26a48046a905bcd3678b8e829fc5f2a221f13eee34ce0d0d87bcc72add2528c5f37244ce0d272999f2d58647b42558991cbc5fb62d57c0ff2b82a100f7de
6
+ metadata.gz: 6a50fd4a229375188d327ad6703565656945996e0ef6746df3bd62745cddb6111b30195488ea87f1fdbe41e47e804d8a05d36b5cbbc8445bb4e9a7edcd0b4441
7
+ data.tar.gz: 22238bb77209eb6eec0a2719d1ddd3c1e59d0d4e332f3965208661dd2014527c6670fa11149c213df633a259e1c9ea6fcf96b32c63a1cf5de6ef3fa58606530d
data/README.md CHANGED
@@ -37,3 +37,4 @@ as well as on RubyDoc.
37
37
  * GUI "frontend"?
38
38
  * isolation of art and music output (`Muzak::ArtProvider`?)
39
39
  * current indexing/sorting logic is terrible
40
+ * replace MPV IPC implementation with [ruby-mpv](https://github.com/woodruffw/ruby-mpv)
@@ -119,9 +119,7 @@ module Muzak
119
119
  def jukebox(count = Config.jukebox_size)
120
120
  songs = index.jukebox(count.to_i)
121
121
 
122
- Thread.new do
123
- songs.each { |s| player.enqueue_song s }
124
- end
122
+ songs.each { |s| player.enqueue_song s }
125
123
 
126
124
  build_response data: {
127
125
  jukebox: songs.map(&:full_title)
@@ -1,6 +1,6 @@
1
1
  module Muzak
2
2
  # Muzak's current version
3
- VERSION = "0.2.3".freeze
3
+ VERSION = "0.2.4".freeze
4
4
 
5
5
  # The root directory for all user configuration, data, etc
6
6
  CONFIG_DIR = File.expand_path("~/.config/muzak").freeze
@@ -2,6 +2,7 @@ require "tempfile"
2
2
  require "socket"
3
3
  require "json"
4
4
  require "thread"
5
+ require "mpv"
5
6
 
6
7
  module Muzak
7
8
  module Player
@@ -14,11 +15,7 @@ module Muzak
14
15
 
15
16
  # @return [Boolean] Whether or not the current instance is running.
16
17
  def running?
17
- begin
18
- !!@pid && Process.waitpid(@pid, Process::WNOHANG).nil?
19
- rescue Errno::ECHILD
20
- false
21
- end
18
+ @mpv&.running?
22
19
  end
23
20
 
24
21
  # Activate mpv by executing it and preparing for event processing.
@@ -28,39 +25,24 @@ module Muzak
28
25
 
29
26
  debug "activating #{self.class}"
30
27
 
31
- @sock_path = Dir::Tmpname.make_tmpname("/tmp/mpv", ".sock")
32
28
  mpv_args = [
33
- "--idle",
34
29
  # if i get around to separating album art from playback,
35
30
  # these two flags disable mpv's video output entirely
36
31
  # "--no-force-window",
37
32
  # "--no-video",
33
+ # there's also this, which (might) also work
34
+ # "--audio-display=no",
38
35
  "--no-osc",
39
36
  "--no-osd-bar",
40
37
  "--no-input-default-bindings",
41
38
  "--no-input-cursor",
42
- "--no-terminal",
43
39
  "--load-scripts=no", # autoload and other scripts with clobber our mpv management
44
- "--input-ipc-server=%{socket}" % { socket: @sock_path }
45
40
  ]
46
41
 
47
42
  mpv_args << "--geometry=#{Config.art_geometry}" if Config.art_geometry
48
43
 
49
- @pid = Process.spawn("mpv", *mpv_args)
50
-
51
- until File.exists?(@sock_path)
52
- sleep 0.1
53
- end
54
-
55
- @socket = UNIXSocket.new(@sock_path)
56
-
57
- @command_queue = Queue.new
58
- @result_queue = Queue.new
59
- @event_queue = Queue.new
60
-
61
- @command_thread = Thread.new { pump_commands! }
62
- @results_thread = Thread.new { pump_results! }
63
- @events_thread = Thread.new { dispatch_events! }
44
+ @mpv = ::MPV::Session.new(user_args: mpv_args)
45
+ @mpv.callbacks << ::MPV::Callback.new(self, :dispatch_event!)
64
46
 
65
47
  instance.event :player_activated
66
48
  end
@@ -72,17 +54,10 @@ module Muzak
72
54
 
73
55
  debug "deactivating #{self.class}"
74
56
 
75
- command "quit"
76
-
77
- Process.kill :TERM, @pid
78
- Process.wait @pid
79
- @pid = nil
80
-
81
- @socket.close
57
+ @mpv.quit!
82
58
  ensure
83
59
  @_now_playing = nil
84
60
  instance.event :player_deactivated
85
- File.delete(@sock_path) if @sock_path && File.exists?(@sock_path)
86
61
  end
87
62
 
88
63
  # Tell mpv to begin playback.
@@ -91,7 +66,7 @@ module Muzak
91
66
  def play
92
67
  return unless running?
93
68
 
94
- set_property "pause", false
69
+ @mpv.set_property "pause", false
95
70
  end
96
71
 
97
72
  # Tell mpv to pause playback.
@@ -100,28 +75,28 @@ module Muzak
100
75
  def pause
101
76
  return unless running?
102
77
 
103
- set_property "pause", true
78
+ @mpv.set_property "pause", true
104
79
  end
105
80
 
106
81
  # @return [Boolean] Whether or not mpv is currently playing.
107
82
  def playing?
108
83
  return false unless running?
109
84
 
110
- !get_property "pause"
85
+ !@mpv.get_property "pause"
111
86
  end
112
87
 
113
88
  # Tell mpv to play the next song in its queue.
114
89
  # @return [void]
115
90
  # @note Does nothing if the current song is the last.
116
91
  def next_song
117
- command "playlist-next"
92
+ @mpv.command "playlist-next"
118
93
  end
119
94
 
120
95
  # Tell mpv to play the previous song in its queue.
121
96
  # @return [void]
122
97
  # @note Does nothing if the current song is the first.
123
98
  def previous_song
124
- command "playlist-prev"
99
+ @mpv.command "playlist-prev"
125
100
  end
126
101
 
127
102
  # Tell mpv to add the given song to its queue.
@@ -170,7 +145,7 @@ module Muzak
170
145
  # TODO: this is slow and should be avoided at all costs,
171
146
  # since we have access to these Song instances earlier
172
147
  # in the object's lifecycle.
173
- playlist << Song.new(get_property("playlist/#{i}/filename"))
148
+ playlist << Song.new(@mpv.get_property("playlist/#{i}/filename"))
174
149
  end
175
150
 
176
151
  playlist
@@ -181,7 +156,7 @@ module Muzak
181
156
  def shuffle_queue
182
157
  return unless running?
183
158
 
184
- command "playlist-shuffle"
159
+ @mpv.command "playlist-shuffle"
185
160
  end
186
161
 
187
162
  # Clears mpv's internal queue.
@@ -189,88 +164,41 @@ module Muzak
189
164
  def clear_queue
190
165
  return unless running?
191
166
 
192
- command "playlist-clear"
167
+ @mpv.command "playlist-clear"
193
168
  end
194
169
 
195
170
  # Get mpv's currently loaded song.
196
171
  # @return [Song, nil] the currently loaded song
197
172
  def now_playing
198
- path = get_property "path"
173
+ path = @mpv.get_property "path"
199
174
  return if path&.empty?
200
- @_now_playing ||= Song.new(get_property "path")
175
+ @_now_playing ||= Song.new(@mpv.get_property "path")
201
176
  end
202
177
 
203
- private
204
-
178
+ # Load a song and optional album art into mpv.
179
+ # @param song [Song] the song to load
180
+ # @param art [String] the art file to load
181
+ # @return [void]
182
+ # @api private
205
183
  def load_song(song, art)
206
184
  cmds = ["loadfile", song.path, "append-play"]
207
185
  cmds << "external-file=\"#{art}\"" if art
208
- command *cmds
209
- end
210
-
211
- def pump_commands!
212
- loop do
213
- begin
214
- @socket.puts(@command_queue.pop)
215
- rescue EOFError # the player is deactivating
216
- Thread.exit
217
- end
218
- end
219
- end
220
-
221
- def pump_results!
222
- loop do
223
- begin
224
- response = JSON.parse(@socket.readline)
225
-
226
- if response["event"]
227
- @event_queue << response["event"]
228
- else
229
- @result_queue << response
230
- end
231
- rescue EOFError, IOError # the player is deactivating
232
- Thread.exit
233
- end
234
- end
186
+ @mpv.command *cmds
235
187
  end
236
188
 
237
- def dispatch_events!
238
- loop do
239
- event = @event_queue.pop
240
-
241
- Thread.new do
242
- case event
243
- when "file-loaded"
244
- instance.event :song_loaded, now_playing
245
- when "end-file"
246
- instance.event :song_unloaded
247
- @_now_playing = nil
248
- end
249
- end
189
+ # Dispatch the given event to the active {Muzak::Instance}.
190
+ # @param event [String] the event
191
+ # @return [void]
192
+ # @api private
193
+ def dispatch_event!(event)
194
+ case event
195
+ when "file-loaded"
196
+ instance.event :song_loaded, now_playing
197
+ when "end-file"
198
+ instance.event :song_unloaded
199
+ @_now_playing = nil
250
200
  end
251
201
  end
252
-
253
- def command(*args)
254
- return unless running?
255
-
256
- payload = {
257
- "command" => args
258
- }
259
-
260
- debug "mpv payload: #{payload.to_s}"
261
-
262
- @command_queue << JSON.generate(payload)
263
-
264
- @result_queue.pop
265
- end
266
-
267
- def set_property(*args)
268
- command "set_property", *args
269
- end
270
-
271
- def get_property(*args)
272
- command("get_property", *args)["data"]
273
- end
274
202
  end
275
203
  end
276
204
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: muzak
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - William Woodruff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-12 00:00:00.000000000 Z
11
+ date: 2017-01-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: taglib-ruby
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mpv
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.1.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.1.0
27
41
  description: A library for controlling playlists and media players.
28
42
  email: william@tuffbizz.com
29
43
  executables: