muzak 0.2.3 → 0.2.4

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
  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: