Class: MPD

Inherits:
Object
  • Object
show all
Includes:
Parser, Plugins::Channels, Plugins::Controls, Plugins::Database, Plugins::Information, Plugins::Outputs, Plugins::PlaybackOptions, Plugins::Playlists, Plugins::Queue, Plugins::Reflection, Plugins::Stickers
Defined in:
lib/ruby-mpd.rb,
lib/ruby-mpd/song.rb,
lib/ruby-mpd/parser.rb,
lib/ruby-mpd/playlist.rb,
lib/ruby-mpd/plugins/queue.rb,
lib/ruby-mpd/plugins/outputs.rb,
lib/ruby-mpd/plugins/channels.rb,
lib/ruby-mpd/plugins/controls.rb,
lib/ruby-mpd/plugins/database.rb,
lib/ruby-mpd/plugins/stickers.rb,
lib/ruby-mpd/plugins/playlists.rb,
lib/ruby-mpd/plugins/reflection.rb,
lib/ruby-mpd/plugins/information.rb,
lib/ruby-mpd/plugins/playback_options.rb

Overview

The main class/namespace of the MPD client.

Defined Under Namespace

Modules: Parser, Plugins Classes: MPDError, Playlist, Song

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Plugins::Channels

#channels, #readmessages, #sendmessage, #subscribe, #unsubscribe

Methods included from Plugins::Reflection

#commands, #config, #decoders, #notcommands, #url_handlers

Methods included from Plugins::Outputs

#disableoutput, #enableoutput, #outputs

Methods included from Plugins::Stickers

#delete_sticker, #find_sticker, #get_sticker, #list_stickers, #set_sticker

Methods included from Plugins::Database

#count, #find, #list, #rescan, #search, #songs, #update

Methods included from Plugins::Playlists

#playlists

Methods included from Plugins::Queue

#add, #addid, #clear, #delete, #deleteid, #move, #moveid, #queue, #queue_changes, #save, #shuffle, #song_with_id, #swap, #swapid

Methods included from Plugins::Controls

#next, #pause=, #play, #playid, #previous, #seek, #seekid, #seekpos, #stop

Methods included from Plugins::PlaybackOptions

#consume=, #crossfade=, #mixrampdb=, #mixrampdelay=, #random=, #repeat=, #replay_gain_mode=, #replay_gain_status, #single=, #volume=

Methods included from Plugins::Information

#clearerror, #consume?, #crossfade, #current_song, #idle, #paused?, #playing?, #playlist_version, #random?, #repeat?, #single?, #stats, #status, #stopped?, #volume

Constructor Details

#initialize(hostname = 'localhost', port = 6600) ⇒ MPD

Initialize an MPD object with the specified hostname and port. When called without arguments, ‘localhost’ and 6600 are used.



70
71
72
73
74
75
76
77
78
79
80
# File 'lib/ruby-mpd.rb', line 70

def initialize(hostname = 'localhost', port = 6600)
  @hostname = hostname
  @port = port
  @socket = nil
  @version = nil

  @stop_cb_thread = false
  @mutex = Mutex.new
  @cb_thread = nil
  @callbacks = {}
end

Instance Attribute Details

#tagsObject (readonly)

A list of tags MPD accepts.



66
67
68
# File 'lib/ruby-mpd.rb', line 66

def tags
  @tags
end

#versionObject (readonly)

The version of the MPD protocol the server is using.



64
65
66
# File 'lib/ruby-mpd.rb', line 64

def version
  @version
end

Instance Method Details

#albums(artist = nil) ⇒ Array<String>

Lists all of the albums in the database. The optional argument is for specifying an artist to list the albums for

Returns:

  • (Array<String>)

    An array of album names.



218
219
220
# File 'lib/ruby-mpd.rb', line 218

def albums(artist = nil)
  list :album, artist
end

#artistsArray<String>

Lists all of the artists in the database.

Returns:

  • (Array<String>)

    An array of artist names.



225
226
227
# File 'lib/ruby-mpd.rb', line 225

def artists
  list :artist
end

#connect(callbacks = false) ⇒ true

Connect to the daemon.

When called without any arguments, this will just connect to the server and wait for your commands.

When called with true as an argument, this will enable callbacks by starting a seperate polling thread, which will also automatically reconnect if disconnected for whatever reason.

Returns:

  • (true)

    Successfully connected.

Raises:

  • (MPDError)

    If connect is called on an already connected instance.



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/ruby-mpd.rb', line 120

def connect(callbacks = false)
  raise MPDError, 'Already Connected!' if self.connected?

  @socket = File.exists?(@hostname) ? UNIXSocket.new(@hostname) : TCPSocket.new(@hostname, @port)
  @version = @socket.gets.chomp.gsub('OK MPD ', '') # Read the version

  if callbacks and (@cb_thread.nil? or !@cb_thread.alive?)
    @stop_cb_thread = false
    @cb_thread = Thread.new(self) { |mpd|
      old_status = {}
      connected = ''
      while !@stop_cb_thread
        status = mpd.status rescue {}
        c = mpd.connected?

        # @todo Move into status[:connection]?
        if connected != c
          connected = c
          emit(:connection, connected)
        end

        status[:time] = [nil, nil] if !status[:time] # elapsed, total
        status[:audio] = [nil, nil, nil] if !status[:audio] # samp, bits, chans

        status.each do |key, val|
          next if val == old_status[key] # skip unchanged keys

          if key == :song
            emit(:song, mpd.current_song)
          else # convert arrays to splat arguments
            val.is_a?(Array) ? emit(key, *val) : emit(key, val)
          end
        end

        old_status = status
        sleep 0.1

        if !connected
          sleep 2
          unless @stop_cb_thread
            mpd.connect rescue nil
          end
        end
      end
    }
  end

  return true
end

#connected?Boolean

Check if the client is connected.

Returns:

  • (Boolean)

    True only if the server responds otherwise false.



173
174
175
176
177
178
# File 'lib/ruby-mpd.rb', line 173

def connected?
  return false if !@socket

  ret = send_command(:ping) rescue false
  return ret
end

#directories(path = nil) ⇒ Array<String>

List all of the directories in the database, starting at path. If path isn’t specified, the root of the database is used

Returns:

  • (Array<String>)

    Array of directory names



233
234
235
236
# File 'lib/ruby-mpd.rb', line 233

def directories(path = nil)
  response = send_command :listall, path
  return response[:directory]
end

#disconnectObject

Disconnect from the MPD daemon. This has no effect if the client is not connected. Reconnect using the #connect method. This will also stop the callback thread, thus disabling callbacks.



183
184
185
186
187
188
189
190
191
# File 'lib/ruby-mpd.rb', line 183

def disconnect
  @stop_cb_thread = true

  return if @socket.nil?

  @socket.puts 'close'
  @socket.close
  @socket = nil
end

#emit(event, *args) ⇒ Object

Triggers an event, running it’s callbacks.

Parameters:

  • event (Symbol)

    The event that happened.



102
103
104
105
106
107
# File 'lib/ruby-mpd.rb', line 102

def emit(event, *args)
  @callbacks[event] ||= []
  @callbacks[event].each do |handle|
    handle.call *args
  end
end

#files(path = nil) ⇒ Array<String>

List all of the files in the database, starting at path. If path isn’t specified, the root of the database is used

Returns:

  • (Array<String>)

    Array of file names



242
243
244
245
# File 'lib/ruby-mpd.rb', line 242

def files(path = nil)
  response = send_command(:listall, path)
  return response[:file]
end

#killBoolean

Kills the MPD process.

Returns:

  • (Boolean)

    returns true if successful.

Raises:



195
196
197
# File 'lib/ruby-mpd.rb', line 195

def kill
  send_command :kill
end

#on(event, &block) ⇒ Object

This will register a block callback that will trigger whenever that specific event happens.

mpd.on :volume do |volume|
  puts "Volume was set to #{volume}"!
end

One can also define separate methods or Procs and whatnot, just pass them in as a parameter.

method = Proc.new {|volume| puts "Volume was set to #{volume}"! }
mpd.on :volume, &method


95
96
97
98
# File 'lib/ruby-mpd.rb', line 95

def on(event, &block)
  @callbacks[event] ||= []
  @callbacks[event].push block
end

#password(pass) ⇒ Object

Used for authentication with the server

Parameters:

  • pass (String)

    Plaintext password



201
202
203
# File 'lib/ruby-mpd.rb', line 201

def password(pass)
  send_command :password, pass
end

#pingBoolean

Ping the server.

Returns:

  • (Boolean)

    returns true if successful.

Raises:



207
208
209
# File 'lib/ruby-mpd.rb', line 207

def ping
  send_command :ping
end

#send_command(command, *args) ⇒ true, ...

Used to send a command to the server. This synchronizes on a mutex to be thread safe

Returns:

  • (true)

    If “OK” is returned.

  • (Array<Hash>, Array<String>, String, Integer)

    Parsed response.

Raises:



259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'lib/ruby-mpd.rb', line 259

def send_command(command, *args)
  raise MPDError, "Not Connected to the Server" if @socket.nil?

  @mutex.synchronize do
    begin
      @socket.puts convert_command(command, *args)
      return handle_server_response
    rescue Errno::EPIPE
      @socket = nil
      raise MPDError, 'Broken Pipe (Disconnected)'
    end
  end
end

#songs_by_artist(artist) ⇒ Array<MPD::Song>

List all of the songs by an artist.

Returns:



250
251
252
# File 'lib/ruby-mpd.rb', line 250

def songs_by_artist(artist)
  find :artist, artist
end