Merge pull request #487 from balloob/media-player-play-media

Media Player play_media function
This commit is contained in:
Paulus Schoutsen 2015-10-06 22:40:36 -07:00
commit 5e0a4c316f
4 changed files with 68 additions and 1 deletions

View File

@ -31,6 +31,7 @@ DISCOVERY_PLATFORMS = {
}
SERVICE_YOUTUBE_VIDEO = 'play_youtube_video'
SERVICE_PLAY_MEDIA = 'play_media'
ATTR_MEDIA_VOLUME_LEVEL = 'volume_level'
ATTR_MEDIA_VOLUME_MUTED = 'is_volume_muted'
@ -46,6 +47,8 @@ ATTR_MEDIA_TRACK = 'media_track'
ATTR_MEDIA_SERIES_TITLE = 'media_series_title'
ATTR_MEDIA_SEASON = 'media_season'
ATTR_MEDIA_EPISODE = 'media_episode'
ATTR_MEDIA_CHANNEL = 'media_channel'
ATTR_MEDIA_PLAYLIST = 'media_playlist'
ATTR_APP_ID = 'app_id'
ATTR_APP_NAME = 'app_name'
ATTR_SUPPORTED_MEDIA_COMMANDS = 'supported_media_commands'
@ -53,6 +56,9 @@ ATTR_SUPPORTED_MEDIA_COMMANDS = 'supported_media_commands'
MEDIA_TYPE_MUSIC = 'music'
MEDIA_TYPE_TVSHOW = 'tvshow'
MEDIA_TYPE_VIDEO = 'movie'
MEDIA_TYPE_EPISODE = 'episode'
MEDIA_TYPE_CHANNEL = 'channel'
MEDIA_TYPE_PLAYLIST = 'playlist'
SUPPORT_PAUSE = 1
SUPPORT_SEEK = 2
@ -63,6 +69,7 @@ SUPPORT_NEXT_TRACK = 32
SUPPORT_YOUTUBE = 64
SUPPORT_TURN_ON = 128
SUPPORT_TURN_OFF = 256
SUPPORT_PLAY_MEDIA = 512
YOUTUBE_COVER_URL_FORMAT = 'https://img.youtube.com/vi/{}/1.jpg'
@ -76,6 +83,7 @@ SERVICE_TO_METHOD = {
SERVICE_MEDIA_PAUSE: 'media_pause',
SERVICE_MEDIA_NEXT_TRACK: 'media_next_track',
SERVICE_MEDIA_PREVIOUS_TRACK: 'media_previous_track',
SERVICE_PLAY_MEDIA: 'play_media',
}
ATTR_TO_PROPERTY = [
@ -92,6 +100,8 @@ ATTR_TO_PROPERTY = [
ATTR_MEDIA_SERIES_TITLE,
ATTR_MEDIA_SEASON,
ATTR_MEDIA_EPISODE,
ATTR_MEDIA_CHANNEL,
ATTR_MEDIA_PLAYLIST,
ATTR_APP_ID,
ATTR_APP_NAME,
ATTR_SUPPORTED_MEDIA_COMMANDS,
@ -180,6 +190,16 @@ def media_previous_track(hass, entity_id=None):
hass.services.call(DOMAIN, SERVICE_MEDIA_PREVIOUS_TRACK, data)
def play_media(hass, media_type, media_id, entity_id=None):
""" Send the media player the command for playing media. """
data = {"media_type": media_type, "media_id": media_id}
if entity_id:
data[ATTR_ENTITY_ID] = entity_id
hass.services.call(DOMAIN, SERVICE_PLAY_MEDIA, data)
def setup(hass, config):
""" Track states and offer events for media_players. """
component = EntityComponent(
@ -275,6 +295,23 @@ def setup(hass, config):
if player.should_poll:
player.update_ha_state(True)
def play_media_service(service):
""" Plays specified media_id on the media player. """
media_type = service.data.get('media_type')
media_id = service.data.get('media_id')
if media_type is None:
return
if media_id is None:
return
for player in component.extract_from_service(service):
player.play_media(media_type, media_id)
if player.should_poll:
player.update_ha_state(True)
hass.services.register(
DOMAIN, "start_fireplace",
lambda service: play_youtube_video_service(service, "eyU3bRy2x44"),
@ -289,6 +326,10 @@ def setup(hass, config):
DOMAIN, SERVICE_YOUTUBE_VIDEO, play_youtube_video_service,
descriptions.get(SERVICE_YOUTUBE_VIDEO))
hass.services.register(
DOMAIN, SERVICE_PLAY_MEDIA, play_media_service,
descriptions.get(SERVICE_PLAY_MEDIA))
return True
@ -373,6 +414,16 @@ class MediaPlayerDevice(Entity):
""" Episode of current playing media. (TV Show only) """
return None
@property
def media_channel(self):
""" Channel currently playing. """
return None
@property
def media_playlist(self):
""" Title of Playlist currently playing. """
return None
@property
def app_id(self):
""" ID of the current running app. """
@ -433,6 +484,10 @@ class MediaPlayerDevice(Entity):
""" Plays a YouTube media. """
raise NotImplementedError()
def play_media(self, media_type, media_id):
""" Plays a piece of media. """
raise NotImplementedError()
# No need to overwrite these.
@property
def support_pause(self):
@ -469,6 +524,11 @@ class MediaPlayerDevice(Entity):
""" Boolean if YouTube is supported. """
return bool(self.supported_media_commands & SUPPORT_YOUTUBE)
@property
def support_play_media(self):
""" Boolean if play media command supported. """
return bool(self.supported_media_commands & SUPPORT_PLAY_MEDIA)
def volume_up(self):
""" volume_up media player. """
if self.volume_level < 1:

View File

@ -90,6 +90,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
class CastDevice(MediaPlayerDevice):
""" Represents a Cast device on the network. """
# pylint: disable=abstract-method
# pylint: disable=too-many-public-methods
def __init__(self, host):

View File

@ -13,6 +13,8 @@ from homeassistant.const import (
SERVICE_MEDIA_PLAY, SERVICE_MEDIA_PAUSE,
STATE_PLAYING, STATE_PAUSED, ATTR_ENTITY_ID)
from homeassistant.components.media_player import (SERVICE_PLAY_MEDIA)
_LOGGER = logging.getLogger(__name__)
@ -61,6 +63,10 @@ def reproduce_state(hass, states, blocking=False):
service = SERVICE_MEDIA_PAUSE
elif state.domain == 'media_player' and state.state == STATE_PLAYING:
service = SERVICE_MEDIA_PLAY
elif state.domain == 'media_player' and state.attributes and \
'media_type' in state.attributes and \
'media_id' in state.attributes:
service = SERVICE_PLAY_MEDIA
elif state.state == STATE_ON:
service = SERVICE_TURN_ON
elif state.state == STATE_OFF:

View File

@ -40,7 +40,7 @@ class TestMediaPlayer(unittest.TestCase):
def test_services(self):
"""
Test if the call service methods conver to correct service calls.
Test if the call service methods convert to correct service calls.
"""
services = {
SERVICE_TURN_ON: media_player.turn_on,