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 +4 -4
- data/README.md +1 -0
- data/lib/muzak/cmd/player.rb +1 -3
- data/lib/muzak/const.rb +1 -1
- data/lib/muzak/player/mpv.rb +34 -106
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99bf2869397efa5ed245f727b5a6d4ccf57c9f6c
|
4
|
+
data.tar.gz: 4903fe98bf3a597ed41f7d9c0e3f76a5afd6366d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a50fd4a229375188d327ad6703565656945996e0ef6746df3bd62745cddb6111b30195488ea87f1fdbe41e47e804d8a05d36b5cbbc8445bb4e9a7edcd0b4441
|
7
|
+
data.tar.gz: 22238bb77209eb6eec0a2719d1ddd3c1e59d0d4e332f3965208661dd2014527c6670fa11149c213df633a259e1c9ea6fcf96b32c63a1cf5de6ef3fa58606530d
|
data/README.md
CHANGED
data/lib/muzak/cmd/player.rb
CHANGED
@@ -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
|
-
|
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)
|
data/lib/muzak/const.rb
CHANGED
data/lib/muzak/player/mpv.rb
CHANGED
@@ -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
|
-
|
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
|
-
@
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
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.
|
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-
|
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:
|