Class: Radiodan::MPD

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Logging
Defined in:
lib/radiodan/adapter/mpd.rb,
lib/radiodan/adapter/mpd/ack.rb,
lib/radiodan/adapter/mpd/response.rb,
lib/radiodan/adapter/mpd/connection.rb,
lib/radiodan/adapter/mpd/playlist_parser.rb

Defined Under Namespace

Modules: PlaylistParser Classes: Ack, AckError, Connection, Response

Constant Summary collapse

COMMANDS =
%w{stop pause clear play next previous enqueue search update}
SEARCH_SCOPE =
%w{artist album title track name genre date composer performer comment disc filename any}

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Logging

included, level, level=, #logger, output, output=

Constructor Details

#initialize(options = {}) ⇒ MPD

Returns a new instance of MPD.



18
19
20
21
22
# File 'lib/radiodan/adapter/mpd.rb', line 18

def initialize(options={})
  @connection = Connection.new(options)
  @connection.cmd('clear')
  @connection.cmd('update')
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object



157
158
159
160
161
162
163
# File 'lib/radiodan/adapter/mpd.rb', line 157

def method_missing(method, *args, &block)
  if COMMANDS.include?(method.to_s)
    cmd(method.to_s, *args, &block)
  else
    super
  end
end

Instance Attribute Details

#playerObject

Returns the value of attribute player.



16
17
18
# File 'lib/radiodan/adapter/mpd.rb', line 16

def player
  @player
end

Instance Method Details

#enqueue(tracks) ⇒ Object



81
82
83
84
85
# File 'lib/radiodan/adapter/mpd.rb', line 81

def enqueue(tracks)
  tracks.each do |track|
    cmd(%Q{add "#{track[:file]}"})
  end
end

#play(song_number = nil) ⇒ Object



87
88
89
# File 'lib/radiodan/adapter/mpd.rb', line 87

def play(song_number=nil)
  cmd("play #{song_number}")
end

#playlistObject



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/radiodan/adapter/mpd.rb', line 91

def playlist
  begin
    status = cmd('status')
    tracks = cmd('playlistinfo')
  
    playlist = PlaylistParser.parse(status, tracks)
    playlist
  rescue  Playlist::StateError,
          Playlist::ModeError,
          Playlist::PositionError,
          Playlist::SeekError,
          Playlist::VolumeError => e
    logger.warn("Playlist parsing raised error: #{e}")
    retry
  end
end

#playlist=(playlist) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/radiodan/adapter/mpd.rb', line 49

def playlist=(playlist)
  # get rid of current playlist, stop playback
  clear
  
  # set random & repeat
  cmd(%Q{random #{boolean_to_s(playlist.random?)}})
  cmd(%Q{repeat #{boolean_to_s(playlist.repeat?)}})
  
  # set volume
  begin
    volume = playlist.volume
  rescue AckError => e
    logger.error e.msg
  end

  if playlist.empty?
    logger.error 'Playlist empty, nothing to do'
    return false
  end

  if enqueue playlist.tracks
    # set for seek position (will play from seek point)
    cmd(%Q{seek #{playlist.position} #{Integer(playlist.seek)}})
  else
    raise "Cannot load playlist #{playlist}" 
  end
end

#respond_to?(method) ⇒ Boolean

Returns:

  • (Boolean)


149
150
151
152
153
154
155
# File 'lib/radiodan/adapter/mpd.rb', line 149

def respond_to?(method)
  if COMMANDS.include?(method.to_s)
    true
  else
    super
  end
end

#search(args) ⇒ Object

search :artist => “Bob Marley”, :exact => true search :filename => ‘./bob.mp3’ search “Bob Marley”



111
112
113
114
115
116
117
118
119
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
# File 'lib/radiodan/adapter/mpd.rb', line 111

def search(args)
  if args.nil?
    logger.error 'no query found' 
    return []
  end
  
  if args.to_s == args
    args = {'any' => args}
  end
  
  if args.delete(:exact)
    command = 'find'
  else
    command = 'search'
  end
  
  if args.keys.size > 1
    raise 'Too many arguments for search'
  end
  
  scope = args.keys.first.to_s
  term  = args.values.first
  
  unless SEARCH_SCOPE.include?(scope)
    raise "Unknown search scope #{scope}"
  end
  
  cmd_string = %Q{#{command} #{scope} "#{term}"}
      
  tracks = cmd(cmd_string)

  if tracks.respond_to?(:collect)
    tracks.collect { |t| Track.new(t) }
  else
    []
  end
end

#volume=(new_volume) ⇒ Object



77
78
79
# File 'lib/radiodan/adapter/mpd.rb', line 77

def volume=(new_volume)
  cmd(%Q{setvol #{Integer(new_volume)}})
end