mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Add add_uri_to_queue support to (sonos) media player (#1946)
Sonos (SoCo) supports add_uri_to_queue capability, making it possible to stream media available via HTTP for example. This patch extends media_player component and sonos platform to support this feature
This commit is contained in:
parent
1eb3181c14
commit
a4409da700
@ -63,6 +63,7 @@ ATTR_APP_NAME = 'app_name'
|
|||||||
ATTR_SUPPORTED_MEDIA_COMMANDS = 'supported_media_commands'
|
ATTR_SUPPORTED_MEDIA_COMMANDS = 'supported_media_commands'
|
||||||
ATTR_INPUT_SOURCE = 'source'
|
ATTR_INPUT_SOURCE = 'source'
|
||||||
ATTR_INPUT_SOURCE_LIST = 'source_list'
|
ATTR_INPUT_SOURCE_LIST = 'source_list'
|
||||||
|
ATTR_MEDIA_ENQUEUE = 'enqueue'
|
||||||
|
|
||||||
MEDIA_TYPE_MUSIC = 'music'
|
MEDIA_TYPE_MUSIC = 'music'
|
||||||
MEDIA_TYPE_TVSHOW = 'tvshow'
|
MEDIA_TYPE_TVSHOW = 'tvshow'
|
||||||
@ -145,6 +146,7 @@ MEDIA_PLAYER_MEDIA_SEEK_SCHEMA = MEDIA_PLAYER_SCHEMA.extend({
|
|||||||
MEDIA_PLAYER_PLAY_MEDIA_SCHEMA = MEDIA_PLAYER_SCHEMA.extend({
|
MEDIA_PLAYER_PLAY_MEDIA_SCHEMA = MEDIA_PLAYER_SCHEMA.extend({
|
||||||
vol.Required(ATTR_MEDIA_CONTENT_TYPE): cv.string,
|
vol.Required(ATTR_MEDIA_CONTENT_TYPE): cv.string,
|
||||||
vol.Required(ATTR_MEDIA_CONTENT_ID): cv.string,
|
vol.Required(ATTR_MEDIA_CONTENT_ID): cv.string,
|
||||||
|
ATTR_MEDIA_ENQUEUE: cv.boolean,
|
||||||
})
|
})
|
||||||
|
|
||||||
MEDIA_PLAYER_SELECT_SOURCE_SCHEMA = MEDIA_PLAYER_SCHEMA.extend({
|
MEDIA_PLAYER_SELECT_SOURCE_SCHEMA = MEDIA_PLAYER_SCHEMA.extend({
|
||||||
@ -256,7 +258,7 @@ def media_seek(hass, position, entity_id=None):
|
|||||||
hass.services.call(DOMAIN, SERVICE_MEDIA_SEEK, data)
|
hass.services.call(DOMAIN, SERVICE_MEDIA_SEEK, data)
|
||||||
|
|
||||||
|
|
||||||
def play_media(hass, media_type, media_id, entity_id=None):
|
def play_media(hass, media_type, media_id, entity_id=None, enqueue=None):
|
||||||
"""Send the media player the command for playing media."""
|
"""Send the media player the command for playing media."""
|
||||||
data = {ATTR_MEDIA_CONTENT_TYPE: media_type,
|
data = {ATTR_MEDIA_CONTENT_TYPE: media_type,
|
||||||
ATTR_MEDIA_CONTENT_ID: media_id}
|
ATTR_MEDIA_CONTENT_ID: media_id}
|
||||||
@ -264,6 +266,9 @@ def play_media(hass, media_type, media_id, entity_id=None):
|
|||||||
if entity_id:
|
if entity_id:
|
||||||
data[ATTR_ENTITY_ID] = entity_id
|
data[ATTR_ENTITY_ID] = entity_id
|
||||||
|
|
||||||
|
if enqueue:
|
||||||
|
data[ATTR_MEDIA_ENQUEUE] = enqueue
|
||||||
|
|
||||||
hass.services.call(DOMAIN, SERVICE_PLAY_MEDIA, data)
|
hass.services.call(DOMAIN, SERVICE_PLAY_MEDIA, data)
|
||||||
|
|
||||||
|
|
||||||
@ -364,9 +369,14 @@ def setup(hass, config):
|
|||||||
"""Play specified media_id on the media player."""
|
"""Play specified media_id on the media player."""
|
||||||
media_type = service.data.get(ATTR_MEDIA_CONTENT_TYPE)
|
media_type = service.data.get(ATTR_MEDIA_CONTENT_TYPE)
|
||||||
media_id = service.data.get(ATTR_MEDIA_CONTENT_ID)
|
media_id = service.data.get(ATTR_MEDIA_CONTENT_ID)
|
||||||
|
enqueue = service.data.get(ATTR_MEDIA_ENQUEUE)
|
||||||
|
|
||||||
|
kwargs = {
|
||||||
|
ATTR_MEDIA_ENQUEUE: enqueue,
|
||||||
|
}
|
||||||
|
|
||||||
for player in component.extract_from_service(service):
|
for player in component.extract_from_service(service):
|
||||||
player.play_media(media_type, media_id)
|
player.play_media(media_type, media_id, **kwargs)
|
||||||
|
|
||||||
if player.should_poll:
|
if player.should_poll:
|
||||||
player.update_ha_state(True)
|
player.update_ha_state(True)
|
||||||
|
@ -253,7 +253,7 @@ class CastDevice(MediaPlayerDevice):
|
|||||||
"""Seek the media to a specific location."""
|
"""Seek the media to a specific location."""
|
||||||
self.cast.media_controller.seek(position)
|
self.cast.media_controller.seek(position)
|
||||||
|
|
||||||
def play_media(self, media_type, media_id):
|
def play_media(self, media_type, media_id, **kwargs):
|
||||||
"""Play media from a URL."""
|
"""Play media from a URL."""
|
||||||
self.cast.media_controller.play_media(media_id, media_type)
|
self.cast.media_controller.play_media(media_id, media_type)
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ class DemoYoutubePlayer(AbstractDemoPlayer):
|
|||||||
"""Flag of media commands that are supported."""
|
"""Flag of media commands that are supported."""
|
||||||
return YOUTUBE_PLAYER_SUPPORT
|
return YOUTUBE_PLAYER_SUPPORT
|
||||||
|
|
||||||
def play_media(self, media_type, media_id):
|
def play_media(self, media_type, media_id, **kwargs):
|
||||||
"""Play a piece of media."""
|
"""Play a piece of media."""
|
||||||
self.youtube_id = media_id
|
self.youtube_id = media_id
|
||||||
self.update_ha_state()
|
self.update_ha_state()
|
||||||
|
@ -320,7 +320,7 @@ class ItunesDevice(MediaPlayerDevice):
|
|||||||
response = self.client.previous()
|
response = self.client.previous()
|
||||||
self.update_state(response)
|
self.update_state(response)
|
||||||
|
|
||||||
def play_media(self, media_type, media_id):
|
def play_media(self, media_type, media_id, **kwargs):
|
||||||
"""Send the play_media command to the media player."""
|
"""Send the play_media command to the media player."""
|
||||||
if media_type == MEDIA_TYPE_PLAYLIST:
|
if media_type == MEDIA_TYPE_PLAYLIST:
|
||||||
response = self.client.play_playlist(media_id)
|
response = self.client.play_playlist(media_id)
|
||||||
|
@ -278,6 +278,6 @@ class KodiDevice(MediaPlayerDevice):
|
|||||||
|
|
||||||
self.update_ha_state()
|
self.update_ha_state()
|
||||||
|
|
||||||
def play_media(self, media_type, media_id):
|
def play_media(self, media_type, media_id, **kwargs):
|
||||||
"""Send the play_media command to the media player."""
|
"""Send the play_media command to the media player."""
|
||||||
self._server.Player.Open({media_type: media_id}, {})
|
self._server.Player.Open({media_type: media_id}, {})
|
||||||
|
@ -212,7 +212,7 @@ class MpdDevice(MediaPlayerDevice):
|
|||||||
"""Service to send the MPD the command for previous track."""
|
"""Service to send the MPD the command for previous track."""
|
||||||
self.client.previous()
|
self.client.previous()
|
||||||
|
|
||||||
def play_media(self, media_type, media_id):
|
def play_media(self, media_type, media_id, **kwargs):
|
||||||
"""Send the media player the command for playing a playlist."""
|
"""Send the media player the command for playing a playlist."""
|
||||||
_LOGGER.info(str.format("Playing playlist: {0}", media_id))
|
_LOGGER.info(str.format("Playing playlist: {0}", media_id))
|
||||||
if media_type == MEDIA_TYPE_PLAYLIST:
|
if media_type == MEDIA_TYPE_PLAYLIST:
|
||||||
|
@ -9,10 +9,9 @@ import logging
|
|||||||
import socket
|
import socket
|
||||||
|
|
||||||
from homeassistant.components.media_player import (
|
from homeassistant.components.media_player import (
|
||||||
MEDIA_TYPE_MUSIC, SUPPORT_NEXT_TRACK, SUPPORT_PAUSE,
|
ATTR_MEDIA_ENQUEUE, MEDIA_TYPE_MUSIC, SUPPORT_NEXT_TRACK, SUPPORT_PAUSE,
|
||||||
SUPPORT_PLAY_MEDIA, SUPPORT_PREVIOUS_TRACK, SUPPORT_SEEK,
|
SUPPORT_PLAY_MEDIA, SUPPORT_PREVIOUS_TRACK, SUPPORT_SEEK,
|
||||||
SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET,
|
SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET, MediaPlayerDevice)
|
||||||
MediaPlayerDevice)
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
STATE_IDLE, STATE_PAUSED, STATE_PLAYING, STATE_UNKNOWN, STATE_OFF)
|
STATE_IDLE, STATE_PAUSED, STATE_PLAYING, STATE_UNKNOWN, STATE_OFF)
|
||||||
|
|
||||||
@ -268,9 +267,22 @@ class SonosDevice(MediaPlayerDevice):
|
|||||||
self._player.play()
|
self._player.play()
|
||||||
|
|
||||||
@only_if_coordinator
|
@only_if_coordinator
|
||||||
def play_media(self, media_type, media_id):
|
def play_media(self, media_type, media_id, **kwargs):
|
||||||
"""Send the play_media command to the media player."""
|
"""
|
||||||
self._player.play_uri(media_id)
|
Send the play_media command to the media player.
|
||||||
|
|
||||||
|
If ATTR_MEDIA_ENQUEUE is True, add `media_id` to the queue.
|
||||||
|
"""
|
||||||
|
if kwargs.get(ATTR_MEDIA_ENQUEUE):
|
||||||
|
from soco.exceptions import SoCoUPnPException
|
||||||
|
try:
|
||||||
|
self._player.add_uri_to_queue(media_id)
|
||||||
|
except SoCoUPnPException:
|
||||||
|
_LOGGER.error('Error parsing media uri "%s", '
|
||||||
|
"please check it's a valid media resource "
|
||||||
|
'supported by Sonos', media_id)
|
||||||
|
else:
|
||||||
|
self._player.play_uri(media_id)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def available(self):
|
def available(self):
|
||||||
|
@ -402,7 +402,7 @@ class UniversalMediaPlayer(MediaPlayerDevice):
|
|||||||
data = {ATTR_MEDIA_SEEK_POSITION: position}
|
data = {ATTR_MEDIA_SEEK_POSITION: position}
|
||||||
self._call_service(SERVICE_MEDIA_SEEK, data)
|
self._call_service(SERVICE_MEDIA_SEEK, data)
|
||||||
|
|
||||||
def play_media(self, media_type, media_id):
|
def play_media(self, media_type, media_id, **kwargs):
|
||||||
"""Play a piece of media."""
|
"""Play a piece of media."""
|
||||||
data = {ATTR_MEDIA_CONTENT_TYPE: media_type,
|
data = {ATTR_MEDIA_CONTENT_TYPE: media_type,
|
||||||
ATTR_MEDIA_CONTENT_ID: media_id}
|
ATTR_MEDIA_CONTENT_ID: media_id}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user