From 2b3caa716a66075543856382056fafa72d3718df Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen <paulus@paulusschoutsen.nl> Date: Sun, 4 Dec 2016 15:30:55 -0800 Subject: [PATCH] Cast progress (#4735) * add progress to google cast * Add progress to media player demo --- homeassistant/components/media_player/cast.py | 27 ++++++++ homeassistant/components/media_player/demo.py | 68 ++++++++++++++----- 2 files changed, 78 insertions(+), 17 deletions(-) diff --git a/homeassistant/components/media_player/cast.py b/homeassistant/components/media_player/cast.py index 1d01f0058ec..0f3b98cab46 100644 --- a/homeassistant/components/media_player/cast.py +++ b/homeassistant/components/media_player/cast.py @@ -18,6 +18,7 @@ from homeassistant.const import ( CONF_HOST, STATE_IDLE, STATE_OFF, STATE_PAUSED, STATE_PLAYING, STATE_UNKNOWN) import homeassistant.helpers.config_validation as cv +import homeassistant.util.dt as dt_util REQUIREMENTS = ['pychromecast==0.7.6'] @@ -105,6 +106,7 @@ class CastDevice(MediaPlayerDevice): self.cast_status = self.cast.status self.media_status = self.cast.media_controller.status + self.media_status_received = None @property def should_poll(self): @@ -231,6 +233,30 @@ class CastDevice(MediaPlayerDevice): """Flag of media commands that are supported.""" return SUPPORT_CAST + @property + def media_position(self): + """Position of current playing media in seconds.""" + if self.media_status is None or not ( + self.media_status.player_is_playing or + self.media_status.player_is_idle): + return None + + position = self.media_status.current_time + + if self.media_status.player_is_playing: + position += (dt_util.utcnow() - + self.media_status_received).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(). + """ + return self.media_status_received + def turn_on(self): """Turn on the ChromeCast.""" # The only way we can turn the Chromecast is on is by launching an app @@ -292,4 +318,5 @@ class CastDevice(MediaPlayerDevice): def new_media_status(self, status): """Called when a new media status is received.""" self.media_status = status + self.media_status_received = dt_util.utcnow() self.schedule_update_ha_state() diff --git a/homeassistant/components/media_player/demo.py b/homeassistant/components/media_player/demo.py index 1c1687de319..226ddfe4769 100644 --- a/homeassistant/components/media_player/demo.py +++ b/homeassistant/components/media_player/demo.py @@ -10,6 +10,7 @@ from homeassistant.components.media_player import ( SUPPORT_TURN_OFF, SUPPORT_TURN_ON, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET, SUPPORT_SELECT_SOURCE, SUPPORT_CLEAR_PLAYLIST, MediaPlayerDevice) from homeassistant.const import STATE_OFF, STATE_PAUSED, STATE_PLAYING +import homeassistant.util.dt as dt_util # pylint: disable=unused-argument @@ -18,8 +19,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None): add_devices([ DemoYoutubePlayer( 'Living Room', 'eyU3bRy2x44', - '♥♥ The Best Fireplace Video (3 hours)'), - DemoYoutubePlayer('Bedroom', 'kxopViU98Xo', 'Epic sax guy 10 hours'), + '♥♥ The Best Fireplace Video (3 hours)', 300), + DemoYoutubePlayer('Bedroom', 'kxopViU98Xo', 'Epic sax guy 10 hours', + 360000), DemoMusicPlayer(), DemoTVShowPlayer(), ]) @@ -78,32 +80,32 @@ class AbstractDemoPlayer(MediaPlayerDevice): def turn_on(self): """Turn the media player on.""" self._player_state = STATE_PLAYING - self.update_ha_state() + self.schedule_update_ha_state() def turn_off(self): """Turn the media player off.""" self._player_state = STATE_OFF - self.update_ha_state() + self.schedule_update_ha_state() def mute_volume(self, mute): """Mute the volume.""" self._volume_muted = mute - self.update_ha_state() + self.schedule_update_ha_state() def set_volume_level(self, volume): """Set the volume level, range 0..1.""" self._volume_level = volume - self.update_ha_state() + self.schedule_update_ha_state() def media_play(self): """Send play command.""" self._player_state = STATE_PLAYING - self.update_ha_state() + self.schedule_update_ha_state() def media_pause(self): """Send pause command.""" self._player_state = STATE_PAUSED - self.update_ha_state() + self.schedule_update_ha_state() class DemoYoutubePlayer(AbstractDemoPlayer): @@ -111,11 +113,14 @@ class DemoYoutubePlayer(AbstractDemoPlayer): # We only implement the methods that we support - def __init__(self, name, youtube_id=None, media_title=None): + def __init__(self, name, youtube_id=None, media_title=None, duration=360): """Initialize the demo device.""" 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() @property def media_content_id(self): @@ -130,7 +135,7 @@ class DemoYoutubePlayer(AbstractDemoPlayer): @property def media_duration(self): """Return the duration of current playing media in seconds.""" - return 360 + return self._duration @property def media_image_url(self): @@ -152,10 +157,39 @@ class DemoYoutubePlayer(AbstractDemoPlayer): """Flag of media commands that are supported.""" 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.""" self.youtube_id = media_id - self.update_ha_state() + 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() class DemoMusicPlayer(AbstractDemoPlayer): @@ -249,20 +283,20 @@ class DemoMusicPlayer(AbstractDemoPlayer): """Send previous track command.""" if self._cur_track > 0: self._cur_track -= 1 - self.update_ha_state() + self.schedule_update_ha_state() def media_next_track(self): """Send next track command.""" if self._cur_track < len(self.tracks) - 1: self._cur_track += 1 - self.update_ha_state() + self.schedule_update_ha_state() def clear_playlist(self): """Clear players playlist.""" self.tracks = [] self._cur_track = 0 self._player_state = STATE_OFF - self.update_ha_state() + self.schedule_update_ha_state() class DemoTVShowPlayer(AbstractDemoPlayer): @@ -344,15 +378,15 @@ class DemoTVShowPlayer(AbstractDemoPlayer): """Send previous track command.""" if self._cur_episode > 1: self._cur_episode -= 1 - self.update_ha_state() + self.schedule_update_ha_state() def media_next_track(self): """Send next track command.""" if self._cur_episode < self._episode_count: self._cur_episode += 1 - self.update_ha_state() + self.schedule_update_ha_state() def select_source(self, source): """Set the input source.""" self._source = source - self.update_ha_state() + self.schedule_update_ha_state() -- GitLab