Add new features to Apple TV media player (#45828)

This commit is contained in:
Pierre Ståhl 2021-02-06 21:29:48 +01:00 committed by GitHub
parent 60e3fce7dc
commit cefde8721d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 80 additions and 24 deletions

View File

@ -180,20 +180,23 @@ class AppleTVManager:
This is a callback function from pyatv.interface.DeviceListener.
"""
_LOGGER.warning('Connection lost to Apple TV "%s"', self.atv.name)
if self.atv:
self.atv.close()
self.atv = None
_LOGGER.warning(
'Connection lost to Apple TV "%s"', self.config_entry.data.get(CONF_NAME)
)
self._connection_was_lost = True
self._dispatch_send(SIGNAL_DISCONNECTED)
self._start_connect_loop()
self._handle_disconnect()
def connection_closed(self):
"""Device connection was (intentionally) closed.
This is a callback function from pyatv.interface.DeviceListener.
"""
self._handle_disconnect()
def _handle_disconnect(self):
"""Handle that the device disconnected and restart connect loop."""
if self.atv:
self.atv.listener = None
self.atv.close()
self.atv = None
self._dispatch_send(SIGNAL_DISCONNECTED)

View File

@ -1,22 +1,35 @@
"""Support for Apple TV media player."""
import logging
from pyatv.const import DeviceState, FeatureName, FeatureState, MediaType
from pyatv.const import (
DeviceState,
FeatureName,
FeatureState,
MediaType,
RepeatState,
ShuffleState,
)
from homeassistant.components.media_player import MediaPlayerEntity
from homeassistant.components.media_player.const import (
MEDIA_TYPE_MUSIC,
MEDIA_TYPE_TVSHOW,
MEDIA_TYPE_VIDEO,
REPEAT_MODE_ALL,
REPEAT_MODE_OFF,
REPEAT_MODE_ONE,
SUPPORT_NEXT_TRACK,
SUPPORT_PAUSE,
SUPPORT_PLAY,
SUPPORT_PLAY_MEDIA,
SUPPORT_PREVIOUS_TRACK,
SUPPORT_REPEAT_SET,
SUPPORT_SEEK,
SUPPORT_SHUFFLE_SET,
SUPPORT_STOP,
SUPPORT_TURN_OFF,
SUPPORT_TURN_ON,
SUPPORT_VOLUME_STEP,
)
from homeassistant.const import (
CONF_NAME,
@ -46,6 +59,9 @@ SUPPORT_APPLE_TV = (
| SUPPORT_STOP
| SUPPORT_NEXT_TRACK
| SUPPORT_PREVIOUS_TRACK
| SUPPORT_VOLUME_STEP
| SUPPORT_REPEAT_SET
| SUPPORT_SHUFFLE_SET
)
@ -110,17 +126,15 @@ class AppleTvMediaPlayer(AppleTVEntity, MediaPlayerEntity):
@property
def app_id(self):
"""ID of the current running app."""
if self.atv:
if self.atv.features.in_state(FeatureState.Available, FeatureName.App):
return self.atv.metadata.app.identifier
if self._is_feature_available(FeatureName.App):
return self.atv.metadata.app.identifier
return None
@property
def app_name(self):
"""Name of the current running app."""
if self.atv:
if self.atv.features.in_state(FeatureState.Available, FeatureName.App):
return self.atv.metadata.app.name
if self._is_feature_available(FeatureName.App):
return self.atv.metadata.app.name
return None
@property
@ -198,6 +212,23 @@ class AppleTvMediaPlayer(AppleTVEntity, MediaPlayerEntity):
return self._playing.album
return None
@property
def repeat(self):
"""Return current repeat mode."""
if self._is_feature_available(FeatureName.Repeat):
return {
RepeatState.Track: REPEAT_MODE_ONE,
RepeatState.All: REPEAT_MODE_ALL,
}.get(self._playing.repeat, REPEAT_MODE_OFF)
return None
@property
def shuffle(self):
"""Boolean if shuffle is enabled."""
if self._is_feature_available(FeatureName.Shuffle):
return self._playing.shuffle != ShuffleState.Off
return None
@property
def supported_features(self):
"""Flag media player features that are supported."""
@ -221,39 +252,61 @@ class AppleTvMediaPlayer(AppleTVEntity, MediaPlayerEntity):
async def async_media_play_pause(self):
"""Pause media on media player."""
if self._playing:
state = self.state
if state == STATE_PAUSED:
await self.atv.remote_control.play()
elif state == STATE_PLAYING:
await self.atv.remote_control.pause()
await self.atv.remote_control.play_pause()
return None
async def async_media_play(self):
"""Play media."""
if self._playing:
if self.atv:
await self.atv.remote_control.play()
async def async_media_stop(self):
"""Stop the media player."""
if self._playing:
if self.atv:
await self.atv.remote_control.stop()
async def async_media_pause(self):
"""Pause the media player."""
if self._playing:
if self.atv:
await self.atv.remote_control.pause()
async def async_media_next_track(self):
"""Send next track command."""
if self._playing:
if self.atv:
await self.atv.remote_control.next()
async def async_media_previous_track(self):
"""Send previous track command."""
if self._playing:
if self.atv:
await self.atv.remote_control.previous()
async def async_media_seek(self, position):
"""Send seek command."""
if self._playing:
if self.atv:
await self.atv.remote_control.set_position(position)
async def async_volume_up(self):
"""Turn volume up for media player."""
if self.atv:
await self.atv.remote_control.volume_up()
async def async_volume_down(self):
"""Turn volume down for media player."""
if self.atv:
await self.atv.remote_control.volume_down()
async def async_set_repeat(self, repeat):
"""Set repeat mode."""
if self.atv:
mode = {
REPEAT_MODE_ONE: RepeatState.Track,
REPEAT_MODE_ALL: RepeatState.All,
}.get(repeat, RepeatState.Off)
await self.atv.remote_control.set_repeat(mode)
async def async_set_shuffle(self, shuffle):
"""Enable/disable shuffle mode."""
if self.atv:
await self.atv.remote_control.set_shuffle(
ShuffleState.Songs if shuffle else ShuffleState.Off
)