mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 19:27:45 +00:00
Cast progress (#4735)
* add progress to google cast * Add progress to media player demo
This commit is contained in:
parent
6574dd8439
commit
2b3caa716a
@ -18,6 +18,7 @@ from homeassistant.const import (
|
|||||||
CONF_HOST, STATE_IDLE, STATE_OFF, STATE_PAUSED, STATE_PLAYING,
|
CONF_HOST, STATE_IDLE, STATE_OFF, STATE_PAUSED, STATE_PLAYING,
|
||||||
STATE_UNKNOWN)
|
STATE_UNKNOWN)
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
REQUIREMENTS = ['pychromecast==0.7.6']
|
REQUIREMENTS = ['pychromecast==0.7.6']
|
||||||
|
|
||||||
@ -105,6 +106,7 @@ class CastDevice(MediaPlayerDevice):
|
|||||||
|
|
||||||
self.cast_status = self.cast.status
|
self.cast_status = self.cast.status
|
||||||
self.media_status = self.cast.media_controller.status
|
self.media_status = self.cast.media_controller.status
|
||||||
|
self.media_status_received = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def should_poll(self):
|
def should_poll(self):
|
||||||
@ -231,6 +233,30 @@ class CastDevice(MediaPlayerDevice):
|
|||||||
"""Flag of media commands that are supported."""
|
"""Flag of media commands that are supported."""
|
||||||
return SUPPORT_CAST
|
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):
|
def turn_on(self):
|
||||||
"""Turn on the ChromeCast."""
|
"""Turn on the ChromeCast."""
|
||||||
# The only way we can turn the Chromecast is on is by launching an app
|
# 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):
|
def new_media_status(self, status):
|
||||||
"""Called when a new media status is received."""
|
"""Called when a new media status is received."""
|
||||||
self.media_status = status
|
self.media_status = status
|
||||||
|
self.media_status_received = dt_util.utcnow()
|
||||||
self.schedule_update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
@ -10,6 +10,7 @@ from homeassistant.components.media_player import (
|
|||||||
SUPPORT_TURN_OFF, SUPPORT_TURN_ON, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET,
|
SUPPORT_TURN_OFF, SUPPORT_TURN_ON, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET,
|
||||||
SUPPORT_SELECT_SOURCE, SUPPORT_CLEAR_PLAYLIST, MediaPlayerDevice)
|
SUPPORT_SELECT_SOURCE, SUPPORT_CLEAR_PLAYLIST, MediaPlayerDevice)
|
||||||
from homeassistant.const import STATE_OFF, STATE_PAUSED, STATE_PLAYING
|
from homeassistant.const import STATE_OFF, STATE_PAUSED, STATE_PLAYING
|
||||||
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
# pylint: disable=unused-argument
|
||||||
@ -18,8 +19,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||||||
add_devices([
|
add_devices([
|
||||||
DemoYoutubePlayer(
|
DemoYoutubePlayer(
|
||||||
'Living Room', 'eyU3bRy2x44',
|
'Living Room', 'eyU3bRy2x44',
|
||||||
'♥♥ The Best Fireplace Video (3 hours)'),
|
'♥♥ The Best Fireplace Video (3 hours)', 300),
|
||||||
DemoYoutubePlayer('Bedroom', 'kxopViU98Xo', 'Epic sax guy 10 hours'),
|
DemoYoutubePlayer('Bedroom', 'kxopViU98Xo', 'Epic sax guy 10 hours',
|
||||||
|
360000),
|
||||||
DemoMusicPlayer(), DemoTVShowPlayer(),
|
DemoMusicPlayer(), DemoTVShowPlayer(),
|
||||||
])
|
])
|
||||||
|
|
||||||
@ -78,32 +80,32 @@ class AbstractDemoPlayer(MediaPlayerDevice):
|
|||||||
def turn_on(self):
|
def turn_on(self):
|
||||||
"""Turn the media player on."""
|
"""Turn the media player on."""
|
||||||
self._player_state = STATE_PLAYING
|
self._player_state = STATE_PLAYING
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def turn_off(self):
|
def turn_off(self):
|
||||||
"""Turn the media player off."""
|
"""Turn the media player off."""
|
||||||
self._player_state = STATE_OFF
|
self._player_state = STATE_OFF
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def mute_volume(self, mute):
|
def mute_volume(self, mute):
|
||||||
"""Mute the volume."""
|
"""Mute the volume."""
|
||||||
self._volume_muted = mute
|
self._volume_muted = mute
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def set_volume_level(self, volume):
|
def set_volume_level(self, volume):
|
||||||
"""Set the volume level, range 0..1."""
|
"""Set the volume level, range 0..1."""
|
||||||
self._volume_level = volume
|
self._volume_level = volume
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def media_play(self):
|
def media_play(self):
|
||||||
"""Send play command."""
|
"""Send play command."""
|
||||||
self._player_state = STATE_PLAYING
|
self._player_state = STATE_PLAYING
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def media_pause(self):
|
def media_pause(self):
|
||||||
"""Send pause command."""
|
"""Send pause command."""
|
||||||
self._player_state = STATE_PAUSED
|
self._player_state = STATE_PAUSED
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
|
|
||||||
class DemoYoutubePlayer(AbstractDemoPlayer):
|
class DemoYoutubePlayer(AbstractDemoPlayer):
|
||||||
@ -111,11 +113,14 @@ class DemoYoutubePlayer(AbstractDemoPlayer):
|
|||||||
|
|
||||||
# We only implement the methods that we support
|
# 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."""
|
"""Initialize the demo device."""
|
||||||
super().__init__(name)
|
super().__init__(name)
|
||||||
self.youtube_id = youtube_id
|
self.youtube_id = youtube_id
|
||||||
self._media_title = media_title
|
self._media_title = media_title
|
||||||
|
self._duration = duration
|
||||||
|
self._progress = int(duration * .15)
|
||||||
|
self._progress_updated_at = dt_util.utcnow()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def media_content_id(self):
|
def media_content_id(self):
|
||||||
@ -130,7 +135,7 @@ class DemoYoutubePlayer(AbstractDemoPlayer):
|
|||||||
@property
|
@property
|
||||||
def media_duration(self):
|
def media_duration(self):
|
||||||
"""Return the duration of current playing media in seconds."""
|
"""Return the duration of current playing media in seconds."""
|
||||||
return 360
|
return self._duration
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def media_image_url(self):
|
def media_image_url(self):
|
||||||
@ -152,10 +157,39 @@ 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
|
||||||
|
|
||||||
|
@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):
|
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.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):
|
class DemoMusicPlayer(AbstractDemoPlayer):
|
||||||
@ -249,20 +283,20 @@ class DemoMusicPlayer(AbstractDemoPlayer):
|
|||||||
"""Send previous track command."""
|
"""Send previous track command."""
|
||||||
if self._cur_track > 0:
|
if self._cur_track > 0:
|
||||||
self._cur_track -= 1
|
self._cur_track -= 1
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def media_next_track(self):
|
def media_next_track(self):
|
||||||
"""Send next track command."""
|
"""Send next track command."""
|
||||||
if self._cur_track < len(self.tracks) - 1:
|
if self._cur_track < len(self.tracks) - 1:
|
||||||
self._cur_track += 1
|
self._cur_track += 1
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def clear_playlist(self):
|
def clear_playlist(self):
|
||||||
"""Clear players playlist."""
|
"""Clear players playlist."""
|
||||||
self.tracks = []
|
self.tracks = []
|
||||||
self._cur_track = 0
|
self._cur_track = 0
|
||||||
self._player_state = STATE_OFF
|
self._player_state = STATE_OFF
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
|
|
||||||
class DemoTVShowPlayer(AbstractDemoPlayer):
|
class DemoTVShowPlayer(AbstractDemoPlayer):
|
||||||
@ -344,15 +378,15 @@ class DemoTVShowPlayer(AbstractDemoPlayer):
|
|||||||
"""Send previous track command."""
|
"""Send previous track command."""
|
||||||
if self._cur_episode > 1:
|
if self._cur_episode > 1:
|
||||||
self._cur_episode -= 1
|
self._cur_episode -= 1
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def media_next_track(self):
|
def media_next_track(self):
|
||||||
"""Send next track command."""
|
"""Send next track command."""
|
||||||
if self._cur_episode < self._episode_count:
|
if self._cur_episode < self._episode_count:
|
||||||
self._cur_episode += 1
|
self._cur_episode += 1
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def select_source(self, source):
|
def select_source(self, source):
|
||||||
"""Set the input source."""
|
"""Set the input source."""
|
||||||
self._source = source
|
self._source = source
|
||||||
self.update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user