async def start(self, address, port, credentials): """Start the proxy instance.""" self.connection = MrpConnection(address, port, self.loop) protocol = MrpProtocol( self.connection, SRPAuthHandler(), MrpService(None, port, credentials=credentials), ) await protocol.start(skip_initial_messages=True) self.connection.listener = self self._process_buffer()
def __init__(self, loop, session, details, airplay): """Initialize a new Apple TV.""" super().__init__() self._session = session self._mrp_service = details.usable_service() self._connection = MrpConnection(details.address, self._mrp_service.port, loop) self._srp = SRPAuthHandler() self._protocol = MrpProtocol(loop, self._connection, self._srp, self._mrp_service) self._mrp_remote = MrpRemoteControl(loop, self._protocol) self._mrp_metadata = MrpMetadata(self._protocol) self._mrp_push_updater = MrpPushUpdater(loop, self._mrp_metadata, self._protocol) self._mrp_pairing = MrpPairingHandler(self._protocol, self._srp, self._mrp_service) self._airplay = airplay
def setup( # pylint: disable=too-many-locals loop: asyncio.AbstractEventLoop, config: conf.AppleTV, interfaces: Dict[Any, Relayer], device_listener: StateProducer, session_manager: ClientSessionManager, ) -> Optional[ Tuple[Callable[[], Awaitable[None]], Callable[[], None], Set[FeatureName]] ]: """Set up a new MRP service.""" service = config.get_service(Protocol.MRP) assert service is not None connection = MrpConnection(config.address, service.port, loop, atv=device_listener) protocol = MrpProtocol(connection, SRPAuthHandler(), service) psm = PlayerStateManager(protocol) remote_control = MrpRemoteControl(loop, psm, protocol) metadata = MrpMetadata(protocol, psm, config.identifier) push_updater = MrpPushUpdater(loop, metadata, psm) power = MrpPower(loop, protocol, remote_control) interfaces[RemoteControl].register(remote_control, Protocol.MRP) interfaces[Metadata].register(metadata, Protocol.MRP) interfaces[Power].register(power, Protocol.MRP) interfaces[PushUpdater].register(push_updater, Protocol.MRP) interfaces[Features].register(MrpFeatures(config, psm), Protocol.MRP) # Forward power events to the facade instance power.listener = interfaces[Power] async def _connect() -> None: await protocol.start() def _close() -> None: push_updater.stop() protocol.stop() # Features managed by this protocol features = set( [ FeatureName.Artwork, FeatureName.VolumeDown, FeatureName.VolumeUp, FeatureName.App, ] ) features.update(_FEATURES_SUPPORTED) features.update(_FEATURE_COMMAND_MAP.keys()) features.update(_FIELD_FEATURES.keys()) return _connect, _close, features
def __init__(self, loop, session, config, airplay): """Initialize a new Apple TV.""" super().__init__() self._session = session self._mrp_service = config.get_service(Protocol.MRP) self._connection = MrpConnection(config.address, self._mrp_service.port, loop, atv=self) self._srp = SRPAuthHandler() self._protocol = MrpProtocol(loop, self._connection, self._srp, self._mrp_service) self._psm = PlayerStateManager(self._protocol, loop) self._mrp_remote = MrpRemoteControl(loop, self._protocol) self._mrp_metadata = MrpMetadata(self._protocol, self._psm, config.identifier) self._mrp_push_updater = MrpPushUpdater(loop, self._mrp_metadata, self._psm) self._airplay = airplay
class MrpAppleTV(AppleTV): """Implementation of API support for Apple TV.""" # This is a container class so it's OK with many attributes # pylint: disable=too-many-instance-attributes def __init__( self, loop: asyncio.AbstractEventLoop, session_manager: ClientSessionManager, config: conf.AppleTV, airplay: Stream, ) -> None: """Initialize a new Apple TV.""" super().__init__() self._session_manager = session_manager self._config = config self._mrp_service = config.get_service(Protocol.MRP) assert self._mrp_service is not None self._connection = MrpConnection(config.address, self._mrp_service.port, loop, atv=self) self._srp = SRPAuthHandler() self._protocol = MrpProtocol(self._connection, self._srp, self._mrp_service) self._psm = PlayerStateManager(self._protocol, loop) self._mrp_remote = MrpRemoteControl(loop, self._psm, self._protocol) self._mrp_metadata = MrpMetadata(self._protocol, self._psm, config.identifier) self._mrp_power = MrpPower(loop, self._protocol, self._mrp_remote) self._mrp_push_updater = MrpPushUpdater(loop, self._mrp_metadata, self._psm) self._mrp_features = MrpFeatures(self._config, self._psm) self._airplay = airplay async def connect(self) -> None: """Initiate connection to device. No need to call it yourself, it's done automatically. """ await self._protocol.start() def close(self) -> None: """Close connection and release allocated resources.""" asyncio.ensure_future(self._session_manager.close()) self._airplay.close() self.push_updater.stop() self._protocol.stop() @property def device_info(self) -> DeviceInfo: """Return API for device information.""" return self._config.device_info @property def service(self): """Return service used to connect to the Apple TV.""" return self._mrp_service @property def remote_control(self) -> RemoteControl: """Return API for controlling the Apple TV.""" return self._mrp_remote @property def metadata(self) -> Metadata: """Return API for retrieving metadata from Apple TV.""" return self._mrp_metadata @property def push_updater(self) -> PushUpdater: """Return API for handling push update from the Apple TV.""" return self._mrp_push_updater @property def stream(self) -> Stream: """Return API for streaming media.""" return self._airplay @property def power(self) -> Power: """Return API for streaming media.""" return self._mrp_power @property def features(self) -> Features: """Return features interface.""" return self._mrp_features
class MrpAppleTV(AppleTV): """Implementation of API support for Apple TV.""" # This is a container class so it's OK with many attributes # pylint: disable=too-many-instance-attributes def __init__(self, loop, session, config, airplay): """Initialize a new Apple TV.""" super().__init__() self._session = session self._mrp_service = config.get_service(Protocol.MRP) self._connection = MrpConnection(config.address, self._mrp_service.port, loop, atv=self) self._srp = SRPAuthHandler() self._protocol = MrpProtocol(loop, self._connection, self._srp, self._mrp_service) self._psm = PlayerStateManager(self._protocol, loop) self._mrp_remote = MrpRemoteControl(loop, self._protocol) self._mrp_metadata = MrpMetadata(self._protocol, self._psm, config.identifier) self._mrp_push_updater = MrpPushUpdater(loop, self._mrp_metadata, self._psm) self._airplay = airplay async def connect(self): """Initiate connection to device. No need to call it yourself, it's done automatically. """ await self._protocol.start() async def close(self): """Close connection and release allocated resources.""" if net.is_custom_session(self._session): await self._session.close() self._protocol.stop() @property def service(self): """Return service used to connect to the Apple TV.""" return self._mrp_service @property def remote_control(self): """Return API for controlling the Apple TV.""" return self._mrp_remote @property def metadata(self): """Return API for retrieving metadata from Apple TV.""" return self._mrp_metadata @property def push_updater(self): """Return API for handling push update from the Apple TV.""" return self._mrp_push_updater @property def stream(self): """Return API for streaming media.""" return self._airplay
class MrpAppleTV(AppleTV): """Implementation of API support for Apple TV.""" # This is a container class so it's OK with many attributes # pylint: disable=too-many-instance-attributes def __init__(self, loop, session, details, airplay): """Initialize a new Apple TV.""" super().__init__() self._session = session self._mrp_service = details.usable_service() self._connection = MrpConnection(details.address, self._mrp_service.port, loop) self._srp = SRPAuthHandler() self._protocol = MrpProtocol(loop, self._connection, self._srp, self._mrp_service) self._mrp_remote = MrpRemoteControl(loop, self._protocol) self._mrp_metadata = MrpMetadata(self._protocol) self._mrp_push_updater = MrpPushUpdater(loop, self._mrp_metadata, self._protocol) self._mrp_pairing = MrpPairingHandler(self._protocol, self._srp, self._mrp_service) self._airplay = airplay async def login(self): """Perform an explicit login.""" await self._protocol.start() async def logout(self): """Perform an explicit logout. Must be done when session is no longer needed to not leak resources. """ await self._session.close() self._protocol.stop() @property def service(self): """Return service used to connect to the Apple TV..""" return self._mrp_service @property def pairing(self): """Return API for pairing with the Apple TV.""" return self._mrp_pairing @property def remote_control(self): """Return API for controlling the Apple TV.""" return self._mrp_remote @property def metadata(self): """Return API for retrieving metadata from Apple TV.""" return self._mrp_metadata @property def push_updater(self): """Return API for handling push update from the Apple TV.""" return self._mrp_push_updater @property def airplay(self): """Return API for working with AirPlay.""" return self._airplay