core/homeassistant/components/media_player/demo.py

395 lines
12 KiB
Python
Raw Normal View History

"""
Demo implementation of the media player.
For more details about this platform, please refer to the documentation
https://home-assistant.io/components/demo/
2015-05-10 21:27:22 +00:00
"""
from homeassistant.components.media_player import (
2016-02-19 05:27:50 +00:00
MEDIA_TYPE_MUSIC, MEDIA_TYPE_TVSHOW, MEDIA_TYPE_VIDEO, SUPPORT_NEXT_TRACK,
SUPPORT_PAUSE, SUPPORT_PLAY_MEDIA, SUPPORT_PREVIOUS_TRACK,
SUPPORT_TURN_OFF, SUPPORT_TURN_ON, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET,
SUPPORT_SELECT_SOURCE, SUPPORT_CLEAR_PLAYLIST, SUPPORT_PLAY,
MediaPlayerDevice)
2016-02-19 05:27:50 +00:00
from homeassistant.const import STATE_OFF, STATE_PAUSED, STATE_PLAYING
import homeassistant.util.dt as dt_util
# pylint: disable=unused-argument
def setup_platform(hass, config, add_devices, discovery_info=None):
2016-03-08 09:34:33 +00:00
"""Setup the media player demo platform."""
add_devices([
2015-06-01 07:24:17 +00:00
DemoYoutubePlayer(
'Living Room', 'eyU3bRy2x44',
'♥♥ The Best Fireplace Video (3 hours)', 300),
DemoYoutubePlayer('Bedroom', 'kxopViU98Xo', 'Epic sax guy 10 hours',
360000),
2016-04-09 04:28:59 +00:00
DemoMusicPlayer(), DemoTVShowPlayer(),
])
2016-04-10 08:33:01 +00:00
YOUTUBE_COVER_URL_FORMAT = 'https://img.youtube.com/vi/{}/hqdefault.jpg'
2016-02-02 08:31:36 +00:00
2015-06-01 07:24:17 +00:00
YOUTUBE_PLAYER_SUPPORT = \
SUPPORT_PAUSE | SUPPORT_VOLUME_SET | SUPPORT_VOLUME_MUTE | \
SUPPORT_TURN_ON | SUPPORT_TURN_OFF | SUPPORT_PLAY_MEDIA | SUPPORT_PLAY
2015-06-01 07:24:17 +00:00
2015-06-02 06:42:19 +00:00
MUSIC_PLAYER_SUPPORT = \
SUPPORT_PAUSE | SUPPORT_VOLUME_SET | SUPPORT_VOLUME_MUTE | \
SUPPORT_TURN_ON | SUPPORT_TURN_OFF | SUPPORT_CLEAR_PLAYLIST | SUPPORT_PLAY
2015-06-01 07:24:17 +00:00
2015-06-02 06:53:36 +00:00
NETFLIX_PLAYER_SUPPORT = \
SUPPORT_PAUSE | SUPPORT_TURN_ON | SUPPORT_TURN_OFF | \
SUPPORT_SELECT_SOURCE | SUPPORT_PLAY
2015-06-02 06:42:19 +00:00
class AbstractDemoPlayer(MediaPlayerDevice):
2016-03-08 09:34:33 +00:00
"""A demo media players."""
2015-06-09 05:49:43 +00:00
# We only implement the methods that we support
2015-06-02 06:42:19 +00:00
def __init__(self, name):
2016-03-08 09:34:33 +00:00
"""Initialize the demo device."""
self._name = name
2015-06-01 07:24:17 +00:00
self._player_state = STATE_PLAYING
self._volume_level = 1.0
self._volume_muted = False
@property
def should_poll(self):
"""Push an update after each command."""
return False
@property
def name(self):
"""Return the name of the media player."""
return self._name
@property
def state(self):
"""Return the state of the player."""
2015-06-01 07:24:17 +00:00
return self._player_state
@property
def volume_level(self):
"""Return the volume level of the media player (0..1)."""
2015-06-01 07:24:17 +00:00
return self._volume_level
@property
def is_volume_muted(self):
"""Return boolean if volume is currently muted."""
2015-06-01 07:24:17 +00:00
return self._volume_muted
2015-06-02 06:42:19 +00:00
def turn_on(self):
"""Turn the media player on."""
2015-06-02 06:42:19 +00:00
self._player_state = STATE_PLAYING
self.schedule_update_ha_state()
2015-06-02 06:42:19 +00:00
def turn_off(self):
"""Turn the media player off."""
2015-06-02 06:42:19 +00:00
self._player_state = STATE_OFF
self.schedule_update_ha_state()
2015-06-02 06:42:19 +00:00
def mute_volume(self, mute):
"""Mute the volume."""
2015-06-02 06:42:19 +00:00
self._volume_muted = mute
self.schedule_update_ha_state()
2015-06-02 06:42:19 +00:00
def set_volume_level(self, volume):
"""Set the volume level, range 0..1."""
2015-06-02 06:42:19 +00:00
self._volume_level = volume
self.schedule_update_ha_state()
2015-06-02 06:42:19 +00:00
def media_play(self):
"""Send play command."""
2015-06-02 06:42:19 +00:00
self._player_state = STATE_PLAYING
self.schedule_update_ha_state()
2015-06-02 06:42:19 +00:00
def media_pause(self):
"""Send pause command."""
2015-06-02 06:42:19 +00:00
self._player_state = STATE_PAUSED
self.schedule_update_ha_state()
2015-06-02 06:42:19 +00:00
class DemoYoutubePlayer(AbstractDemoPlayer):
"""A Demo media player that only supports YouTube."""
2016-03-08 09:34:33 +00:00
2015-06-02 06:42:19 +00:00
# We only implement the methods that we support
def __init__(self, name, youtube_id=None, media_title=None, duration=360):
2016-03-08 09:34:33 +00:00
"""Initialize the demo device."""
2015-06-02 06:42:19 +00:00
super().__init__(name)
self.youtube_id = youtube_id
self._media_title = media_title
self._duration = duration
self._progress = int(duration * .15)
self._progress_updated_at = dt_util.utcnow()
2015-06-02 06:42:19 +00:00
2015-06-01 07:24:17 +00:00
@property
def media_content_id(self):
"""Return the content ID of current playing media."""
2015-06-01 07:24:17 +00:00
return self.youtube_id
@property
def media_content_type(self):
"""Return the content type of current playing media."""
2015-06-01 07:24:17 +00:00
return MEDIA_TYPE_VIDEO
@property
def media_duration(self):
2016-03-08 09:34:33 +00:00
"""Return the duration of current playing media in seconds."""
return self._duration
2015-06-01 07:24:17 +00:00
@property
def media_image_url(self):
"""Return the image url of current playing media."""
2015-06-01 07:24:17 +00:00
return YOUTUBE_COVER_URL_FORMAT.format(self.youtube_id)
@property
def media_title(self):
"""Return the title of current playing media."""
2015-06-01 07:24:17 +00:00
return self._media_title
@property
def app_name(self):
"""Return the current running application."""
2015-06-01 07:24:17 +00:00
return "YouTube"
@property
2015-06-01 07:24:17 +00:00
def supported_media_commands(self):
2016-03-08 09:34:33 +00:00
"""Flag of media commands that are supported."""
2015-06-01 07:24:17 +00:00
return YOUTUBE_PLAYER_SUPPORT
@property
def media_position(self):
"""Position of current playing media in seconds."""
if self._progress is None:
return None
position = self._progress
if self._player_state == STATE_PLAYING:
position += (dt_util.utcnow() -
self._progress_updated_at).total_seconds()
return position
@property
def media_position_updated_at(self):
"""When was the position of the current playing media valid.
Returns value from homeassistant.util.dt.utcnow().
"""
if self._player_state == STATE_PLAYING:
return self._progress_updated_at
def play_media(self, media_type, media_id, **kwargs):
"""Play a piece of media."""
2015-06-02 06:42:19 +00:00
self.youtube_id = media_id
self.schedule_update_ha_state()
def media_pause(self):
"""Send pause command."""
self._progress = self.media_position
self._progress_updated_at = dt_util.utcnow()
super().media_pause()
2015-06-01 04:07:58 +00:00
2015-06-02 06:42:19 +00:00
class DemoMusicPlayer(AbstractDemoPlayer):
"""A Demo media player that only supports YouTube."""
2016-03-08 09:34:33 +00:00
2015-06-02 06:42:19 +00:00
# We only implement the methods that we support
2015-06-02 06:42:19 +00:00
tracks = [
('Technohead', 'I Wanna Be A Hippy (Flamman & Abraxas Radio Mix)'),
('Paul Elstak', 'Luv U More'),
('Dune', 'Hardcore Vibes'),
('Nakatomi', 'Children Of The Night'),
('Party Animals',
'Have You Ever Been Mellow? (Flamman & Abraxas Radio Mix)'),
('Rob G.*', 'Ecstasy, You Got What I Need'),
('Lipstick', "I'm A Raver"),
('4 Tune Fairytales', 'My Little Fantasy (Radio Edit)'),
('Prophet', "The Big Boys Don't Cry"),
('Lovechild', 'All Out Of Love (DJ Weirdo & Sim Remix)'),
('Stingray & Sonic Driver', 'Cold As Ice (El Bruto Remix)'),
('Highlander', 'Hold Me Now (Bass-D & King Matthew Remix)'),
('Juggernaut', 'Ruffneck Rules Da Artcore Scene (12" Edit)'),
('Diss Reaction', 'Jiiieehaaaa '),
('Flamman And Abraxas', 'Good To Go (Radio Mix)'),
('Critical Mass', 'Dancing Together'),
2015-06-09 05:49:43 +00:00
('Charly Lownoise & Mental Theo',
'Ultimate Sex Track (Bass-D & King Matthew Remix)'),
2015-06-02 06:42:19 +00:00
]
def __init__(self):
2016-03-08 09:34:33 +00:00
"""Initialize the demo device."""
2015-06-02 06:42:19 +00:00
super().__init__('Walkman')
self._cur_track = 0
2015-06-02 06:42:19 +00:00
@property
def media_content_id(self):
"""Return the content ID of current playing media."""
2015-06-02 06:42:19 +00:00
return 'bounzz-1'
2015-06-02 06:42:19 +00:00
@property
def media_content_type(self):
"""Return the content type of current playing media."""
2015-06-02 06:42:19 +00:00
return MEDIA_TYPE_MUSIC
2015-06-02 06:42:19 +00:00
@property
def media_duration(self):
"""Return the duration of current playing media in seconds."""
2015-06-02 06:42:19 +00:00
return 213
@property
def media_image_url(self):
"""Return the image url of current playing media."""
2016-04-10 08:33:01 +00:00
return 'https://graph.facebook.com/v2.5/107771475912710/' \
'picture?type=large'
2015-06-02 06:42:19 +00:00
@property
def media_title(self):
"""Return the title of current playing media."""
return self.tracks[self._cur_track][1] if len(self.tracks) > 0 else ""
2015-06-02 06:42:19 +00:00
@property
def media_artist(self):
"""Return the artist of current playing media (Music track only)."""
return self.tracks[self._cur_track][0] if len(self.tracks) > 0 else ""
2015-06-02 06:42:19 +00:00
@property
2015-06-09 06:06:41 +00:00
def media_album_name(self):
"""Return the album of current playing media (Music track only)."""
2015-06-09 05:49:43 +00:00
# pylint: disable=no-self-use
2015-06-02 06:42:19 +00:00
return "Bounzz"
@property
def media_track(self):
2016-03-08 09:34:33 +00:00
"""Return the track number of current media (Music track only)."""
2015-06-02 06:42:19 +00:00
return self._cur_track + 1
@property
def supported_media_commands(self):
2016-03-08 09:34:33 +00:00
"""Flag of media commands that are supported."""
2015-06-09 05:49:43 +00:00
support = MUSIC_PLAYER_SUPPORT
2016-02-02 08:31:36 +00:00
if self._cur_track > 0:
2015-06-09 05:49:43 +00:00
support |= SUPPORT_PREVIOUS_TRACK
if self._cur_track < len(self.tracks) - 1:
2015-06-09 05:49:43 +00:00
support |= SUPPORT_NEXT_TRACK
return support
2015-06-02 06:42:19 +00:00
def media_previous_track(self):
"""Send previous track command."""
2015-06-02 06:42:19 +00:00
if self._cur_track > 0:
self._cur_track -= 1
self.schedule_update_ha_state()
2015-06-02 06:42:19 +00:00
def media_next_track(self):
"""Send next track command."""
if self._cur_track < len(self.tracks) - 1:
2015-06-02 06:42:19 +00:00
self._cur_track += 1
self.schedule_update_ha_state()
2015-06-02 06:53:36 +00:00
def clear_playlist(self):
"""Clear players playlist."""
self.tracks = []
self._cur_track = 0
self._player_state = STATE_OFF
self.schedule_update_ha_state()
2015-06-02 06:53:36 +00:00
class DemoTVShowPlayer(AbstractDemoPlayer):
"""A Demo media player that only supports YouTube."""
2016-03-08 09:34:33 +00:00
2015-06-02 06:53:36 +00:00
# We only implement the methods that we support
2015-06-02 06:53:36 +00:00
def __init__(self):
2016-03-08 09:34:33 +00:00
"""Initialize the demo device."""
2015-06-02 06:53:36 +00:00
super().__init__('Lounge room')
self._cur_episode = 1
self._episode_count = 13
2016-04-09 04:28:59 +00:00
self._source = 'dvd'
2015-06-02 06:53:36 +00:00
@property
def media_content_id(self):
"""Return the content ID of current playing media."""
2015-06-02 06:53:36 +00:00
return 'house-of-cards-1'
@property
def media_content_type(self):
"""Return the content type of current playing media."""
2015-06-02 06:53:36 +00:00
return MEDIA_TYPE_TVSHOW
@property
def media_duration(self):
"""Return the duration of current playing media in seconds."""
2015-06-02 06:53:36 +00:00
return 3600
@property
def media_image_url(self):
"""Return the image url of current playing media."""
2016-04-10 08:33:01 +00:00
return 'https://graph.facebook.com/v2.5/HouseofCards/picture?width=400'
2015-06-02 06:53:36 +00:00
@property
def media_title(self):
"""Return the title of current playing media."""
2015-06-02 06:53:36 +00:00
return 'Chapter {}'.format(self._cur_episode)
@property
def media_series_title(self):
"""Return the series title of current playing media (TV Show only)."""
2015-06-02 06:53:36 +00:00
return 'House of Cards'
@property
def media_season(self):
"""Return the season of current playing media (TV Show only)."""
2015-06-02 06:53:36 +00:00
return 1
@property
def media_episode(self):
"""Return the episode of current playing media (TV Show only)."""
2015-06-02 06:53:36 +00:00
return self._cur_episode
@property
def app_name(self):
"""Return the current running application."""
2015-06-02 06:53:36 +00:00
return "Netflix"
2016-04-09 04:28:59 +00:00
@property
def source(self):
"""Return the current input source."""
return self._source
2015-06-02 06:53:36 +00:00
@property
def supported_media_commands(self):
"""Flag of media commands that are supported."""
2015-06-09 05:49:43 +00:00
support = NETFLIX_PLAYER_SUPPORT
if self._cur_episode > 1:
support |= SUPPORT_PREVIOUS_TRACK
if self._cur_episode < self._episode_count:
support |= SUPPORT_NEXT_TRACK
return support
2015-06-02 06:53:36 +00:00
def media_previous_track(self):
"""Send previous track command."""
2015-06-02 06:53:36 +00:00
if self._cur_episode > 1:
self._cur_episode -= 1
self.schedule_update_ha_state()
2015-06-02 06:53:36 +00:00
def media_next_track(self):
"""Send next track command."""
2015-06-02 06:53:36 +00:00
if self._cur_episode < self._episode_count:
self._cur_episode += 1
self.schedule_update_ha_state()
def select_source(self, source):
"""Set the input source."""
self._source = source
self.schedule_update_ha_state()