lib/sonos/endpoint/a_v_transport.rb in sonos-0.3.5 vs lib/sonos/endpoint/a_v_transport.rb in sonos-0.3.6
- old
+ new
@@ -46,10 +46,16 @@
state: body[:current_transport_state],
speed: body[:current_speed],
}
end
+ # Returns true if the player is not in a paused or stopped state
+ def is_playing?
+ state = get_player_state[:state]
+ !['PAUSED_PLAYBACK', 'STOPPED'].include?(state)
+ end
+
# Pause the currently playing track.
def pause
parse_response send_transport_message('Pause')
end
@@ -75,11 +81,11 @@
# Play the previous track.
def previous
parse_response send_transport_message('Previous')
end
-
+
def line_in(speaker)
set_av_transport_uri('x-rincon-stream:' + speaker.uid.sub('uuid:', ''))
end
# Seeks to a given timestamp in the current track
@@ -88,37 +94,44 @@
# Must be sent in the format of HH:MM:SS
timestamp = Time.at(seconds).utc.strftime('%H:%M:%S')
parse_response send_transport_message('Seek', "<Unit>REL_TIME</Unit><Target>#{timestamp}</Target>")
end
+ # Seeks the playlist selection to the provided index
+ def select_track(index)
+ parse_response send_transport_message('Seek', "<Unit>TRACK_NR</Unit><Target>#{index}</Target>")
+ end
+
# Clear the queue
def clear_queue
- parse_response parse_response send_transport_message('RemoveAllTracksFromQueue')
+ parse_response send_transport_message('RemoveAllTracksFromQueue')
end
# Save queue
def save_queue(title)
parse_response send_transport_message('SaveQueue', "<Title>#{title}</Title><ObjectID></ObjectID>")
end
# Adds a track to the queue
# @param[String] uri Uri of track
# @param[String] didl Stanza of DIDL-Lite metadata (generally created by #add_spotify_to_queue)
+ # @param[Integer] position Optional queue insertion position. Leaving this blank inserts at the end.
# @return[Integer] Queue position of the added track
- def add_to_queue(uri, didl = '')
- response = send_transport_message('AddURIToQueue', "<EnqueuedURI>#{uri}</EnqueuedURI><EnqueuedURIMetaData>#{didl}</EnqueuedURIMetaData><DesiredFirstTrackNumberEnqueued>0</DesiredFirstTrackNumberEnqueued><EnqueueAsNext>1</EnqueueAsNext>")
+ def add_to_queue(uri, didl = '', position = 0)
+ response = send_transport_message('AddURIToQueue', "<EnqueuedURI>#{uri}</EnqueuedURI><EnqueuedURIMetaData>#{didl}</EnqueuedURIMetaData><DesiredFirstTrackNumberEnqueued>#{position}</DesiredFirstTrackNumberEnqueued><EnqueueAsNext>1</EnqueueAsNext>")
# TODO yeah, this error handling is a bit soft. For consistency's sake :)
pos = response.xpath('.//FirstTrackNumberEnqueued').text
if pos.length != 0
pos.to_i
end
end
# Adds a Spotify track to the queue along with extra data for better metadata retrieval
# @param[Hash] opts Various options (id, user, region and type)
+ # @param[Integer] position Optional queue insertion position. Leaving this blank inserts at the end.
# @return[Integer] Queue position of the added track(s)
- def add_spotify_to_queue(opts = {})
+ def add_spotify_to_queue(opts = {}, position = 0)
opts = {
:id => '',
:user => nil,
:region => nil,
:type => 'track'
@@ -151,13 +164,52 @@
uri = "x-sonos-spotify:spotify%3a#{opts[:type]}%3a#{opts[:id]}"
else
return nil
end
- add_to_queue(uri, didl_metadata)
+ add_to_queue(uri, didl_metadata, position)
end
+ # Add an Rdio object to the queue (album or track), anything else can only
+ # be streamed (play now).
+ # @param[Hash] opts Various options (album/track keys, username and type)
+ # @param[Integer] position Optional queue insertion position. Leaving this blank inserts at the end.
+ # @return[Integer] Queue position of the added track(s)
+ def add_rdio_to_queue(opts = {}, position = 0)
+ opts = {
+ :username => nil,
+ :album => nil,
+ :track => nil,
+ :type => 'track',
+ :format => 'mp3' # can be changed, but only 'mp3' is valid.
+ }.merge(opts)
+
+ return nil if opts[:username].nil?
+
+ # Both tracks and albums require the album key. And tracks need a track
+ # key of course.
+ return nil if opts[:album].nil?
+ return nil if opts[:type] == 'track' and opts[:track].nil?
+
+ # In order for valid DIDL we'll pass an empty :track for albums.
+ opts[:track] = '' if opts[:type] == 'album'
+
+ didl_metadata = "<DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"><item id="00030020_t%3a%3a#{opts[:track]}%3a%3aa%3a%3a#{opts[:album]}" parentID="0004006c_a%3a%3a#{opts[:album]}" restricted="true"><dc:title></dc:title><upnp:class>object.item.audioItem.musicTrack</upnp:class><desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">SA_RINCON2823_#{opts[:username]}</desc></item></DIDL-Lite>"
+
+ case opts[:type]
+ when /track/
+ uri = "x-sonos-http:_t%3a%3a#{opts[:track]}%3a%3aa%3a%3a#{opts[:album]}.#{opts[:format]}?sid=11&flags=32"
+ when /album/
+ type_id = '0004006c_a'
+ uri = "x-rincon-cpcontainer:#{type_id}%3a%3a#{opts[:album]}"
+ else
+ return nil
+ end
+
+ add_to_queue(uri, didl_metadata, position)
+ end
+
# Removes a track from the queue
# @param[String] object_id Track's queue ID
def remove_from_queue(object_id)
parse_response send_transport_message('RemoveTrackFromQueue', "<ObjectID>#{object_id}</ObjectID><UpdateID>0</UpdateID></u:RemoveTrackFromQueue>")
end
@@ -176,9 +228,22 @@
# Ungroup from its current group.
# Trying to call this on a stereo pair slave will fail.
def ungroup
parse_response send_transport_message('BecomeCoordinatorOfStandaloneGroup')
+ end
+
+ # Set a sleep timer up to 23:59:59
+ # E.g. '00:11:00' for 11 minutes.
+ # @param duration [String] Duration of timer or nil to clear.
+ def set_sleep_timer(duration)
+ if duration.nil?
+ duration = ''
+ elsif duration.gsub(':', '').to_i > 235959
+ duration = '23:59:59'
+ end
+
+ parse_response send_transport_message('ConfigureSleepTimer', "<NewSleepTimerDuration>#{duration}</NewSleepTimerDuration>")
end
private
# Play a stream.