mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 05:07:41 +00:00
Add new features to Apple TV media player (#45828)
This commit is contained in:
parent
60e3fce7dc
commit
cefde8721d
@ -180,20 +180,23 @@ class AppleTVManager:
|
|||||||
|
|
||||||
This is a callback function from pyatv.interface.DeviceListener.
|
This is a callback function from pyatv.interface.DeviceListener.
|
||||||
"""
|
"""
|
||||||
_LOGGER.warning('Connection lost to Apple TV "%s"', self.atv.name)
|
_LOGGER.warning(
|
||||||
if self.atv:
|
'Connection lost to Apple TV "%s"', self.config_entry.data.get(CONF_NAME)
|
||||||
self.atv.close()
|
)
|
||||||
self.atv = None
|
|
||||||
self._connection_was_lost = True
|
self._connection_was_lost = True
|
||||||
self._dispatch_send(SIGNAL_DISCONNECTED)
|
self._handle_disconnect()
|
||||||
self._start_connect_loop()
|
|
||||||
|
|
||||||
def connection_closed(self):
|
def connection_closed(self):
|
||||||
"""Device connection was (intentionally) closed.
|
"""Device connection was (intentionally) closed.
|
||||||
|
|
||||||
This is a callback function from pyatv.interface.DeviceListener.
|
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:
|
if self.atv:
|
||||||
|
self.atv.listener = None
|
||||||
self.atv.close()
|
self.atv.close()
|
||||||
self.atv = None
|
self.atv = None
|
||||||
self._dispatch_send(SIGNAL_DISCONNECTED)
|
self._dispatch_send(SIGNAL_DISCONNECTED)
|
||||||
|
@ -1,22 +1,35 @@
|
|||||||
"""Support for Apple TV media player."""
|
"""Support for Apple TV media player."""
|
||||||
import logging
|
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 import MediaPlayerEntity
|
||||||
from homeassistant.components.media_player.const import (
|
from homeassistant.components.media_player.const import (
|
||||||
MEDIA_TYPE_MUSIC,
|
MEDIA_TYPE_MUSIC,
|
||||||
MEDIA_TYPE_TVSHOW,
|
MEDIA_TYPE_TVSHOW,
|
||||||
MEDIA_TYPE_VIDEO,
|
MEDIA_TYPE_VIDEO,
|
||||||
|
REPEAT_MODE_ALL,
|
||||||
|
REPEAT_MODE_OFF,
|
||||||
|
REPEAT_MODE_ONE,
|
||||||
SUPPORT_NEXT_TRACK,
|
SUPPORT_NEXT_TRACK,
|
||||||
SUPPORT_PAUSE,
|
SUPPORT_PAUSE,
|
||||||
SUPPORT_PLAY,
|
SUPPORT_PLAY,
|
||||||
SUPPORT_PLAY_MEDIA,
|
SUPPORT_PLAY_MEDIA,
|
||||||
SUPPORT_PREVIOUS_TRACK,
|
SUPPORT_PREVIOUS_TRACK,
|
||||||
|
SUPPORT_REPEAT_SET,
|
||||||
SUPPORT_SEEK,
|
SUPPORT_SEEK,
|
||||||
|
SUPPORT_SHUFFLE_SET,
|
||||||
SUPPORT_STOP,
|
SUPPORT_STOP,
|
||||||
SUPPORT_TURN_OFF,
|
SUPPORT_TURN_OFF,
|
||||||
SUPPORT_TURN_ON,
|
SUPPORT_TURN_ON,
|
||||||
|
SUPPORT_VOLUME_STEP,
|
||||||
)
|
)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
@ -46,6 +59,9 @@ SUPPORT_APPLE_TV = (
|
|||||||
| SUPPORT_STOP
|
| SUPPORT_STOP
|
||||||
| SUPPORT_NEXT_TRACK
|
| SUPPORT_NEXT_TRACK
|
||||||
| SUPPORT_PREVIOUS_TRACK
|
| SUPPORT_PREVIOUS_TRACK
|
||||||
|
| SUPPORT_VOLUME_STEP
|
||||||
|
| SUPPORT_REPEAT_SET
|
||||||
|
| SUPPORT_SHUFFLE_SET
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -110,16 +126,14 @@ class AppleTvMediaPlayer(AppleTVEntity, MediaPlayerEntity):
|
|||||||
@property
|
@property
|
||||||
def app_id(self):
|
def app_id(self):
|
||||||
"""ID of the current running app."""
|
"""ID of the current running app."""
|
||||||
if self.atv:
|
if self._is_feature_available(FeatureName.App):
|
||||||
if self.atv.features.in_state(FeatureState.Available, FeatureName.App):
|
|
||||||
return self.atv.metadata.app.identifier
|
return self.atv.metadata.app.identifier
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def app_name(self):
|
def app_name(self):
|
||||||
"""Name of the current running app."""
|
"""Name of the current running app."""
|
||||||
if self.atv:
|
if self._is_feature_available(FeatureName.App):
|
||||||
if self.atv.features.in_state(FeatureState.Available, FeatureName.App):
|
|
||||||
return self.atv.metadata.app.name
|
return self.atv.metadata.app.name
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -198,6 +212,23 @@ class AppleTvMediaPlayer(AppleTVEntity, MediaPlayerEntity):
|
|||||||
return self._playing.album
|
return self._playing.album
|
||||||
return None
|
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
|
@property
|
||||||
def supported_features(self):
|
def supported_features(self):
|
||||||
"""Flag media player features that are supported."""
|
"""Flag media player features that are supported."""
|
||||||
@ -221,39 +252,61 @@ class AppleTvMediaPlayer(AppleTVEntity, MediaPlayerEntity):
|
|||||||
async def async_media_play_pause(self):
|
async def async_media_play_pause(self):
|
||||||
"""Pause media on media player."""
|
"""Pause media on media player."""
|
||||||
if self._playing:
|
if self._playing:
|
||||||
state = self.state
|
await self.atv.remote_control.play_pause()
|
||||||
if state == STATE_PAUSED:
|
|
||||||
await self.atv.remote_control.play()
|
|
||||||
elif state == STATE_PLAYING:
|
|
||||||
await self.atv.remote_control.pause()
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def async_media_play(self):
|
async def async_media_play(self):
|
||||||
"""Play media."""
|
"""Play media."""
|
||||||
if self._playing:
|
if self.atv:
|
||||||
await self.atv.remote_control.play()
|
await self.atv.remote_control.play()
|
||||||
|
|
||||||
async def async_media_stop(self):
|
async def async_media_stop(self):
|
||||||
"""Stop the media player."""
|
"""Stop the media player."""
|
||||||
if self._playing:
|
if self.atv:
|
||||||
await self.atv.remote_control.stop()
|
await self.atv.remote_control.stop()
|
||||||
|
|
||||||
async def async_media_pause(self):
|
async def async_media_pause(self):
|
||||||
"""Pause the media player."""
|
"""Pause the media player."""
|
||||||
if self._playing:
|
if self.atv:
|
||||||
await self.atv.remote_control.pause()
|
await self.atv.remote_control.pause()
|
||||||
|
|
||||||
async def async_media_next_track(self):
|
async def async_media_next_track(self):
|
||||||
"""Send next track command."""
|
"""Send next track command."""
|
||||||
if self._playing:
|
if self.atv:
|
||||||
await self.atv.remote_control.next()
|
await self.atv.remote_control.next()
|
||||||
|
|
||||||
async def async_media_previous_track(self):
|
async def async_media_previous_track(self):
|
||||||
"""Send previous track command."""
|
"""Send previous track command."""
|
||||||
if self._playing:
|
if self.atv:
|
||||||
await self.atv.remote_control.previous()
|
await self.atv.remote_control.previous()
|
||||||
|
|
||||||
async def async_media_seek(self, position):
|
async def async_media_seek(self, position):
|
||||||
"""Send seek command."""
|
"""Send seek command."""
|
||||||
if self._playing:
|
if self.atv:
|
||||||
await self.atv.remote_control.set_position(position)
|
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
|
||||||
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user