ruby-mpd 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +22 -0
- data/AUTHORS +1 -0
- data/COPYING +340 -0
- data/DOC.rdoc +78 -0
- data/README.rdoc +174 -0
- data/data/database.yaml +347 -0
- data/examples/rmpc.rb +67 -0
- data/examples/tailmpc.rb +115 -0
- data/lib/mpdserver.rb +1206 -0
- data/lib/ruby-mpd.rb +310 -0
- data/lib/ruby-mpd/parser.rb +151 -0
- data/lib/ruby-mpd/playlist.rb +77 -0
- data/lib/ruby-mpd/plugins/channels.rb +58 -0
- data/lib/ruby-mpd/plugins/controls.rb +72 -0
- data/lib/ruby-mpd/plugins/database.rb +79 -0
- data/lib/ruby-mpd/plugins/information.rb +146 -0
- data/lib/ruby-mpd/plugins/outputs.rb +26 -0
- data/lib/ruby-mpd/plugins/playback_options.rb +88 -0
- data/lib/ruby-mpd/plugins/playlists.rb +17 -0
- data/lib/ruby-mpd/plugins/queue.rb +125 -0
- data/lib/ruby-mpd/plugins/reflection.rb +46 -0
- data/lib/ruby-mpd/plugins/stickers.rb +52 -0
- data/lib/ruby-mpd/song.rb +31 -0
- data/ruby-mpd.gemspec +17 -0
- data/tests/libtests.rb +1145 -0
- data/tests/servertests.rb +3405 -0
- metadata +73 -0
@@ -0,0 +1,77 @@
|
|
1
|
+
class MPD
|
2
|
+
# An object representing an .m3u playlist stored by MPD.
|
3
|
+
#
|
4
|
+
# Playlists are stored inside the configured playlist directory. They are
|
5
|
+
# addressed with their file name (without the directory and without the
|
6
|
+
# .m3u suffix).
|
7
|
+
#
|
8
|
+
# Some of the commands described in this section can be used to run playlist
|
9
|
+
# plugins instead of the hard-coded simple m3u parser. They can access
|
10
|
+
# playlists in the music directory (relative path including the suffix) or
|
11
|
+
# remote playlists (absolute URI with a supported scheme).
|
12
|
+
#
|
13
|
+
# Changes: rm -> destroy. listplaylistinfo -> songs. Playlist prefixes
|
14
|
+
# dropped also of course. Listplaylist not used, kinda inferior to listplaylistinfo
|
15
|
+
class Playlist
|
16
|
+
|
17
|
+
attr_accessor :name
|
18
|
+
|
19
|
+
def initialize(mpd, options)
|
20
|
+
@name = options[:playlist]
|
21
|
+
@mpd = mpd
|
22
|
+
#@last_modified = options[:'last-modified']
|
23
|
+
end
|
24
|
+
|
25
|
+
# Lists the songs in the playlist. Playlist plugins are supported.
|
26
|
+
# @return [Array<MPD::Song>] songs in the playlist.
|
27
|
+
def songs
|
28
|
+
mpd.build_songs_list @mpd.send_command(:listplaylistinfo, @name)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Loads the playlist into the current queue. Playlist plugins are supported.
|
32
|
+
#
|
33
|
+
# Since 0.17, a range can be passed to load, to load only a part of the playlist.
|
34
|
+
# @macro returnraise
|
35
|
+
def load(range=nil)
|
36
|
+
@mpd.send_command :load, @name, range
|
37
|
+
end
|
38
|
+
|
39
|
+
# Adds URI to the playlist.
|
40
|
+
# @macro returnraise
|
41
|
+
def add(uri)
|
42
|
+
@mpd.send_command :playlistadd, @name, uri
|
43
|
+
end
|
44
|
+
|
45
|
+
# Clears the playlist.
|
46
|
+
# @macro returnraise
|
47
|
+
def clear
|
48
|
+
@mpd.send_command :playlistclear, @name
|
49
|
+
end
|
50
|
+
|
51
|
+
# Deletes song at position POS from the playlist.
|
52
|
+
# @macro returnraise
|
53
|
+
def delete(pos)
|
54
|
+
@mpd.send_command :playlistdelete, @name, pos
|
55
|
+
end
|
56
|
+
|
57
|
+
# Moves song with SONGID in the playlist to the position SONGPOS.
|
58
|
+
# @macro returnraise
|
59
|
+
def move(songid, songpos)
|
60
|
+
@mpd.send_command :playlistmove, @name
|
61
|
+
end
|
62
|
+
|
63
|
+
# Renames the playlist to +new_name+.
|
64
|
+
# @macro returnraise
|
65
|
+
def rename(new_name)
|
66
|
+
@mpd.send_command :rename, @name, new_name
|
67
|
+
@name = new_name
|
68
|
+
end
|
69
|
+
|
70
|
+
# Deletes the playlist from the disk.
|
71
|
+
# @macro returnraise
|
72
|
+
def destroy
|
73
|
+
@mpd.send_command :rm, @name
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
class MPD
|
2
|
+
module Plugins
|
3
|
+
# = Client to client commands
|
4
|
+
#
|
5
|
+
# Clients can communicate with each others over "channels". A channel
|
6
|
+
# is created by a client subscribing to it. More than one client can be
|
7
|
+
# subscribed to a channel at a time; all of them will receive the messages
|
8
|
+
# which get sent to it.
|
9
|
+
#
|
10
|
+
# Each time a client subscribes or unsubscribes, the global idle event
|
11
|
+
# subscription is generated. In conjunction with the channels command, this
|
12
|
+
# may be used to auto-detect clients providing additional services.
|
13
|
+
#
|
14
|
+
# New messages are indicated by the message idle event.
|
15
|
+
module Channels
|
16
|
+
|
17
|
+
# Subscribe to a channel. The channel is created if it does not exist already.
|
18
|
+
# The name may consist of alphanumeric ASCII characters plus underscore, dash, dot and colon.
|
19
|
+
# @param [Symbol, String] channel The channel to subscribe to.
|
20
|
+
# @macro returnraise
|
21
|
+
def subscribe(channel)
|
22
|
+
send_command :subscribe, channel
|
23
|
+
end
|
24
|
+
|
25
|
+
# Unsubscribe from a channel.
|
26
|
+
# @param [Symbol, String] channel The channel to unsibscribe from.
|
27
|
+
# @macro returnraise
|
28
|
+
def unsubscribe(channel)
|
29
|
+
send_command :unsubscribe, channel
|
30
|
+
end
|
31
|
+
|
32
|
+
# Obtain a list of all channels.
|
33
|
+
# @return [Array<String>]
|
34
|
+
# @return [String] if only one channel exists.
|
35
|
+
# @return [true] if no channels exist.
|
36
|
+
def channels
|
37
|
+
send_command :channels
|
38
|
+
end
|
39
|
+
|
40
|
+
# Reads messages for this client. The response is an array of
|
41
|
+
# hashes with +:channel+ and +:message+ keys or true if no messages.
|
42
|
+
# @return [Array<Hash>] Messages recieved.
|
43
|
+
# @return [Hash] if only one message recieved
|
44
|
+
# @return [true] if no messages.
|
45
|
+
def readmessages
|
46
|
+
send_command :readmessages
|
47
|
+
end
|
48
|
+
|
49
|
+
# Send a message to the specified channel.
|
50
|
+
# @param [Symbol, String] channel The channel to send to.
|
51
|
+
# @param [String] message The message to send.
|
52
|
+
# @macro returnraise
|
53
|
+
def sendmessage(channel, message)
|
54
|
+
send_command :sendmessage, channel, message
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
class MPD
|
2
|
+
module Plugins
|
3
|
+
# Commands for controlling playback. Changes have been made to {#seek},
|
4
|
+
# command maps to +seekcur+ from MPD and the original seek command is
|
5
|
+
# {#seekpos} here.
|
6
|
+
module Controls
|
7
|
+
# Plays the next song in the playlist.
|
8
|
+
# @macro returnraise
|
9
|
+
def next
|
10
|
+
send_command :next
|
11
|
+
end
|
12
|
+
|
13
|
+
# Resume/pause playback.
|
14
|
+
# @note The use of pause without an argument is deprecated in MPD.
|
15
|
+
# @macro returnraise
|
16
|
+
def pause=(toggle)
|
17
|
+
send_command :pause, toggle
|
18
|
+
end
|
19
|
+
|
20
|
+
# Begin playing the playist.
|
21
|
+
# @param [Integer] pos Position in the playlist to start playing.
|
22
|
+
# @macro returnraise
|
23
|
+
def play(pos = nil)
|
24
|
+
send_command :play, pos
|
25
|
+
end
|
26
|
+
|
27
|
+
# Begin playing the playlist.
|
28
|
+
# @param [Integer] songid ID of the song where to start playing.
|
29
|
+
# @macro returnraise
|
30
|
+
def playid(songid = nil)
|
31
|
+
send_command :playid, songid
|
32
|
+
end
|
33
|
+
|
34
|
+
# Plays the previous song in the playlist.
|
35
|
+
# @macro returnraise
|
36
|
+
def previous
|
37
|
+
send_command :previous
|
38
|
+
end
|
39
|
+
|
40
|
+
# Seeks to the position in seconds within the current song.
|
41
|
+
# If prefixed by '+' or '-', then the time is relative to the current
|
42
|
+
# playing position.
|
43
|
+
#
|
44
|
+
# @since MPD 0.17
|
45
|
+
# @param [Integer, String] time Position within the current song.
|
46
|
+
# Returns true if successful,
|
47
|
+
def seek(time)
|
48
|
+
send_command :seekcur, time
|
49
|
+
end
|
50
|
+
|
51
|
+
# Seeks to the position +time+ (in seconds) of the
|
52
|
+
# song at +pos+ in the playlist.
|
53
|
+
# @macro returnraise
|
54
|
+
def seekpos(pos, time)
|
55
|
+
send_command :seek, pos, time
|
56
|
+
end
|
57
|
+
|
58
|
+
# Seeks to the position +time+ (in seconds) of the song with
|
59
|
+
# the id of +songid+.
|
60
|
+
# @macro returnraise
|
61
|
+
def seekid(songid, time)
|
62
|
+
send_command :seekid, songid, time
|
63
|
+
end
|
64
|
+
|
65
|
+
# Stop playing.
|
66
|
+
# @macro returnraise
|
67
|
+
def stop
|
68
|
+
send_command :stop
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
class MPD
|
2
|
+
module Plugins
|
3
|
+
# Commands for interacting with the music database.
|
4
|
+
#
|
5
|
+
# Changes: listallinfo -> songs
|
6
|
+
module Database
|
7
|
+
|
8
|
+
# Counts the number of songs and their total playtime
|
9
|
+
# in the db matching, matching the searched tag exactly.
|
10
|
+
# @return [Hash] a hash with +songs+ and +playtime+ keys.
|
11
|
+
def count(type, what)
|
12
|
+
send_command :count, type, what
|
13
|
+
end
|
14
|
+
|
15
|
+
# Finds songs in the database that are *EXACTLY* matched by the what
|
16
|
+
# argument.
|
17
|
+
#
|
18
|
+
# @param [Symbol] type Can be any tag supported by MPD, or one of the two special
|
19
|
+
# parameters: +:file+ to search by full path (relative to database root),
|
20
|
+
# and +:any+ to match against all available tags.
|
21
|
+
# @return [Array<MPD::Song>] Songs that matched.
|
22
|
+
def find(type, what)
|
23
|
+
build_songs_list send_command(:find, type, what)
|
24
|
+
end
|
25
|
+
|
26
|
+
# findadd
|
27
|
+
|
28
|
+
# List all tags of the specified type.
|
29
|
+
# Type can be any tag supported by MPD or +:file+.
|
30
|
+
# If type is 'album' then arg can be a specific artist to list the albums for
|
31
|
+
#
|
32
|
+
# @return [Array<String>]
|
33
|
+
def list(type, arg = nil)
|
34
|
+
send_command :list, type, arg
|
35
|
+
end
|
36
|
+
|
37
|
+
# listall
|
38
|
+
|
39
|
+
# List all of the songs in the database starting at path.
|
40
|
+
# If path isn't specified, the root of the database is used
|
41
|
+
#
|
42
|
+
# @return [Array<MPD::Song>]
|
43
|
+
def songs(path = nil)
|
44
|
+
build_songs_list send_command(:listallinfo, path)
|
45
|
+
end
|
46
|
+
|
47
|
+
# lsinfo
|
48
|
+
|
49
|
+
# Searches for any song that contains +what+ in the +type+ field.
|
50
|
+
# Searches are *NOT* case sensitive.
|
51
|
+
#
|
52
|
+
# @param (see #find)
|
53
|
+
# @return [Array<MPD::Song>] Songs that matched.
|
54
|
+
def search(type, what)
|
55
|
+
build_songs_list(send_command(:search, type, what))
|
56
|
+
end
|
57
|
+
|
58
|
+
# searchadd
|
59
|
+
|
60
|
+
# searchaddpl
|
61
|
+
|
62
|
+
# Tell the server to update the database. Optionally,
|
63
|
+
# specify the path to update.
|
64
|
+
#
|
65
|
+
# @return [Integer] Update job ID
|
66
|
+
def update(path = nil)
|
67
|
+
send_command :update, path
|
68
|
+
end
|
69
|
+
|
70
|
+
# Same as {#update}, but also rescans unmodified files.
|
71
|
+
#
|
72
|
+
# @return [Integer] Update job ID
|
73
|
+
def rescan(path = nil)
|
74
|
+
send_command :rescan, path
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
class MPD
|
2
|
+
module Plugins
|
3
|
+
# Informational commands regarding MPD's current status.
|
4
|
+
module Information
|
5
|
+
|
6
|
+
# Clears the current error message reported in status
|
7
|
+
# (also accomplished by any command that starts playback).
|
8
|
+
#
|
9
|
+
# @macro returnraise
|
10
|
+
def clearerror
|
11
|
+
send_command :clearerror
|
12
|
+
end
|
13
|
+
|
14
|
+
# Get the currently playing song
|
15
|
+
#
|
16
|
+
# @return [MPD::Song]
|
17
|
+
def current_song
|
18
|
+
Song.new send_command :currentsong
|
19
|
+
end
|
20
|
+
|
21
|
+
# Waits until there is a noteworthy change in one or more of MPD's subsystems.
|
22
|
+
# As soon as there is one, it lists all changed systems in a line in the format
|
23
|
+
# 'changed: SUBSYSTEM', where SUBSYSTEM is one of the following:
|
24
|
+
#
|
25
|
+
# * *database*: the song database has been modified after update.
|
26
|
+
# * *update*: a database update has started or finished. If the database was modified
|
27
|
+
# during the update, the database event is also emitted.
|
28
|
+
# * *stored_playlist*: a stored playlist has been modified, renamed, created or deleted
|
29
|
+
# * *playlist*: the current playlist has been modified
|
30
|
+
# * *player*: the player has been started, stopped or seeked
|
31
|
+
# * *mixer*: the volume has been changed
|
32
|
+
# * *output*: an audio output has been enabled or disabled
|
33
|
+
# * *options*: options like repeat, random, crossfade, replay gain
|
34
|
+
# * *sticker*: the sticker database has been modified.
|
35
|
+
# * *subscription*: a client has subscribed or unsubscribed to a channel
|
36
|
+
# * *message*: a message was received on a channel this client is subscribed to; this
|
37
|
+
# event is only emitted when the queue is empty
|
38
|
+
#
|
39
|
+
# If the optional +masks+ argument is used, MPD will only send notifications
|
40
|
+
# when something changed in one of the specified subsytems.
|
41
|
+
#
|
42
|
+
# @since MPD 0.14
|
43
|
+
# @param [Symbol] masks A list of subsystems we want to be notified on.
|
44
|
+
def idle(*masks)
|
45
|
+
send_command(:idle, *masks)
|
46
|
+
end
|
47
|
+
|
48
|
+
# MPD status: volume, time, modes...
|
49
|
+
# * *volume*: 0-100
|
50
|
+
# * *repeat*: true or false
|
51
|
+
# * *random*: true or false
|
52
|
+
# * *single*: true or false
|
53
|
+
# * *consume*: true or false
|
54
|
+
# * *playlist*: 31-bit unsigned integer, the playlist version number
|
55
|
+
# * *playlistlength*: integer, the length of the playlist
|
56
|
+
# * *state*: :play, :stop, or :pause
|
57
|
+
# * *song*: playlist song number of the current song stopped on or playing
|
58
|
+
# * *songid*: playlist songid of the current song stopped on or playing
|
59
|
+
# * *nextsong*: playlist song number of the next song to be played
|
60
|
+
# * *nextsongid*: playlist songid of the next song to be played
|
61
|
+
# * *time*: total time elapsed (of current playing/paused song)
|
62
|
+
# * *elapsed*: Total time elapsed within the current song, but with higher resolution.
|
63
|
+
# * *bitrate*: instantaneous bitrate in kbps
|
64
|
+
# * *xfade*: crossfade in seconds
|
65
|
+
# * *mixrampdb*: mixramp threshold in dB
|
66
|
+
# * *mixrampdelay*: mixrampdelay in seconds
|
67
|
+
# * *audio*: [sampleRate, bits, channels]
|
68
|
+
# * *updating_db*: job id
|
69
|
+
# * *error*: if there is an error, returns message here
|
70
|
+
#
|
71
|
+
# @return [Hash] Current MPD status.
|
72
|
+
def status
|
73
|
+
send_command :status
|
74
|
+
end
|
75
|
+
|
76
|
+
# Statistics.
|
77
|
+
#
|
78
|
+
# * *artists*: number of artists
|
79
|
+
# * *songs*: number of albums
|
80
|
+
# * *uptime*: daemon uptime in seconds
|
81
|
+
# * *db_playtime*: sum of all song times in the db
|
82
|
+
# * *db_update*: last db update in a Time object
|
83
|
+
# * *playtime*: time length of music played
|
84
|
+
#
|
85
|
+
# @return [Hash] MPD statistics.
|
86
|
+
def stats
|
87
|
+
send_command :stats
|
88
|
+
end
|
89
|
+
|
90
|
+
# Unofficial additions below
|
91
|
+
|
92
|
+
# Is MPD paused?
|
93
|
+
# @return [Boolean]
|
94
|
+
def paused?
|
95
|
+
return status[:state] == :pause
|
96
|
+
end
|
97
|
+
|
98
|
+
# Is MPD playing?
|
99
|
+
# @return [Boolean]
|
100
|
+
def playing?
|
101
|
+
return status[:state] == :play
|
102
|
+
end
|
103
|
+
|
104
|
+
# @return [Boolean] Is MPD stopped?
|
105
|
+
def stopped?
|
106
|
+
return status[:state] == :stop
|
107
|
+
end
|
108
|
+
|
109
|
+
# Gets the volume level.
|
110
|
+
# @return [Integer]
|
111
|
+
def volume
|
112
|
+
return status[:volume]
|
113
|
+
end
|
114
|
+
|
115
|
+
# @return [Integer] Crossfade in seconds.
|
116
|
+
def crossfade
|
117
|
+
return status[:xfade]
|
118
|
+
end
|
119
|
+
|
120
|
+
# @return [Integer] Current playlist version number.
|
121
|
+
def playlist_version
|
122
|
+
return status[:playlist]
|
123
|
+
end
|
124
|
+
|
125
|
+
# Returns true if consume is enabled.
|
126
|
+
def consume?
|
127
|
+
return status[:consume]
|
128
|
+
end
|
129
|
+
|
130
|
+
# Returns true if single is enabled.
|
131
|
+
def single?
|
132
|
+
return status[:single]
|
133
|
+
end
|
134
|
+
|
135
|
+
# Returns true if random playback is currently enabled,
|
136
|
+
def random?
|
137
|
+
return status[:random]
|
138
|
+
end
|
139
|
+
|
140
|
+
# Returns true if repeat is enabled,
|
141
|
+
def repeat?
|
142
|
+
return status[:repeat]
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class MPD
|
2
|
+
module Plugins
|
3
|
+
# Commands related to audio output devices.
|
4
|
+
module Outputs
|
5
|
+
# Gives a list of all outputs
|
6
|
+
# @return [Array<Hash>] An array of outputs.
|
7
|
+
def outputs
|
8
|
+
send_command :outputs
|
9
|
+
end
|
10
|
+
|
11
|
+
# Enables specified output.
|
12
|
+
# @param [Integer] num Number of the output to enable.
|
13
|
+
# @macro returnraise
|
14
|
+
def enableoutput(num)
|
15
|
+
send_command :enableoutput, num
|
16
|
+
end
|
17
|
+
|
18
|
+
# Disables specified output.
|
19
|
+
# @param [Integer] num Number of the output to disable.
|
20
|
+
# @macro returnraise
|
21
|
+
def disableoutput(num)
|
22
|
+
send_command :disableoutput, num
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|