import { EventEmitter } from "events"; import { AudioBitrate, AudioSamplerate } from "../camera"; import { HDSProtocolSpecificErrorReason, DataStreamConnection, DataStreamProtocolHandler, EventHandler, RequestHandler } from "../datastream"; import type { AudioStreamManagement, DataStreamTransportManagement, Siri, TargetControl, TargetControlManagement } from "../definitions"; import { ControllerIdentifier, ControllerServiceMap, SerializableController, StateChangeDelegate } from "./Controller"; /** * @group Apple TV Remote */ export declare const enum ButtonType { UNDEFINED = 0, MENU = 1, PLAY_PAUSE = 2, TV_HOME = 3, SELECT = 4, ARROW_UP = 5, ARROW_RIGHT = 6, ARROW_DOWN = 7, ARROW_LEFT = 8, VOLUME_UP = 9, VOLUME_DOWN = 10, SIRI = 11, POWER = 12, GENERIC = 13 } /** * @group Apple TV Remote */ export declare const enum TargetCategory { UNDEFINED = 0, APPLE_TV = 24 } /** * @group Apple TV Remote */ export declare const enum ButtonState { UP = 0, DOWN = 1 } /** * @group Apple TV Remote */ export type SupportedConfiguration = { maximumTargets: number; ticksPerSecond: number; supportedButtonConfiguration: SupportedButtonConfiguration[]; hardwareImplemented: boolean; }; /** * @group Apple TV Remote */ export type SupportedButtonConfiguration = { buttonID: number; buttonType: ButtonType; }; /** * @group Apple TV Remote */ export type TargetConfiguration = { targetIdentifier: number; targetName?: string; targetCategory?: TargetCategory; buttonConfiguration: Record; }; /** * @group Apple TV Remote */ export type ButtonConfiguration = { buttonID: number; buttonType: ButtonType; buttonName?: string; }; /** * @group Camera */ export declare const enum AudioCodecTypes { PCMU = 0, PCMA = 1, AAC_ELD = 2, OPUS = 3, MSBC = 4,// mSBC is a bluetooth codec (lol) AMR = 5, AMR_WB = 6 } type SupportedAudioStreamConfiguration = { audioCodecConfiguration: AudioCodecConfiguration; }; /** * @group Apple TV Remote */ export type AudioCodecConfiguration = { codecType: AudioCodecTypes; parameters: AudioCodecParameters; }; /** * @group Apple TV Remote */ export type AudioCodecParameters = { channels: number; bitrate: AudioBitrate; samplerate: AudioSamplerate; rtpTime?: RTPTime; }; /** * @group Apple TV Remote */ export type RTPTime = 20 | 30 | 40 | 60; declare const enum SiriAudioSessionState { STARTING = 0,// we are currently waiting for a response for the start request SENDING = 1,// we are sending data CLOSING = 2,// we are currently waiting for the acknowledgment event CLOSED = 3 } /** * @group Apple TV Remote */ export type AudioFrame = { data: Buffer; rms: number; }; /** * @group Apple TV Remote */ export type FrameHandler = (frame: AudioFrame) => void; /** * @group Apple TV Remote */ export type ErrorHandler = (error: HDSProtocolSpecificErrorReason) => void; /** * @group Apple TV Remote */ export interface SiriAudioStreamProducer { startAudioProduction(selectedAudioConfiguration: AudioCodecConfiguration): void; stopAudioProduction(): void; } /** * @group Apple TV Remote */ export interface SiriAudioStreamProducerConstructor { /** * Creates a new instance of a SiriAudioStreamProducer * * @param frameHandler - called for every opus frame recorded * @param errorHandler - should be called with an appropriate reason when the producing process errored * @param options - optional parameter for passing any configuration related options */ new (frameHandler: FrameHandler, errorHandler: ErrorHandler, options?: any): SiriAudioStreamProducer; } /** * @group Apple TV Remote */ export declare const enum TargetUpdates { NAME = 0, CATEGORY = 1, UPDATED_BUTTONS = 2, REMOVED_BUTTONS = 3 } /** * @group Apple TV Remote */ export declare const enum RemoteControllerEvents { /** * This event is emitted when the active state of the remote has changed. * active = true indicates that there is currently an Apple TV listening of button presses and audio streams. */ ACTIVE_CHANGE = "active-change", /** * This event is emitted when the currently selected target has changed. * Possible reasons for a changed active identifier: manual change via api call, first target configuration * gets added, active target gets removed, accessory gets unpaired, reset request was sent. * An activeIdentifier of 0 indicates that no target is selected. */ ACTIVE_IDENTIFIER_CHANGE = "active-identifier-change", /** * This event is emitted when a new target configuration is received. As we currently do not persistently store * configured targets, this will be called at every startup for every Apple TV configured in the home. */ TARGET_ADDED = "target-add", /** * This event is emitted when an existing target was updated. * The 'updates' array indicates what exactly was changed for the target. */ TARGET_UPDATED = "target-update", /** * This event is emitted when an existing configuration for a target was removed. */ TARGET_REMOVED = "target-remove", /** * This event is emitted when a reset of the target configuration is requested. * With this event every configuration made should be reset. This event is also called * when the accessory gets unpaired. */ TARGETS_RESET = "targets-reset" } /** * @group Apple TV Remote */ export declare interface RemoteController { on(event: "active-change", listener: (active: boolean) => void): this; on(event: "active-identifier-change", listener: (activeIdentifier: number) => void): this; on(event: "target-add", listener: (targetConfiguration: TargetConfiguration) => void): this; on(event: "target-update", listener: (targetConfiguration: TargetConfiguration, updates: TargetUpdates[]) => void): this; on(event: "target-remove", listener: (targetIdentifier: number) => void): this; on(event: "targets-reset", listener: () => void): this; emit(event: "active-change", active: boolean): boolean; emit(event: "active-identifier-change", activeIdentifier: number): boolean; emit(event: "target-add", targetConfiguration: TargetConfiguration): boolean; emit(event: "target-update", targetConfiguration: TargetConfiguration, updates: TargetUpdates[]): boolean; emit(event: "target-remove", targetIdentifier: number): boolean; emit(event: "targets-reset"): boolean; } /** * @group Apple TV Remote */ export interface RemoteControllerServiceMap extends ControllerServiceMap { targetControlManagement: TargetControlManagement; targetControl: TargetControl; siri?: Siri; audioStreamManagement?: AudioStreamManagement; dataStreamTransportManagement?: DataStreamTransportManagement; } /** * @group Apple TV Remote */ export interface SerializedControllerState { activeIdentifier: number; targetConfigurations: Record; } /** * Handles everything needed to implement a fully working HomeKit remote controller. * * @group Apple TV Remote */ export declare class RemoteController extends EventEmitter implements SerializableController, DataStreamProtocolHandler { private stateChangeDelegate?; private readonly audioSupported; private readonly audioProducerConstructor?; private readonly audioProducerOptions?; private targetControlManagementService?; private targetControlService?; private siriService?; private audioStreamManagementService?; private dataStreamManagement?; private buttons; private readonly supportedConfiguration; targetConfigurations: Map; private targetConfigurationsString; private lastButtonEvent; activeIdentifier: number; private activeConnection?; private activeConnectionDisconnectListener?; private readonly supportedAudioConfiguration; private selectedAudioConfiguration; private selectedAudioConfigurationString; private dataStreamConnections; private activeAudioSession?; private nextAudioSession?; /** * @private */ eventHandler?: Record; /** * @private */ requestHandler?: Record; /** * Creates a new RemoteController. * If siri voice input is supported the constructor to an SiriAudioStreamProducer needs to be supplied. * Otherwise, a remote without voice support will be created. * * For every audio session a new SiriAudioStreamProducer will be constructed. * * @param audioProducerConstructor - constructor for a SiriAudioStreamProducer * @param producerOptions - if supplied this argument will be supplied as third argument of the SiriAudioStreamProducer * constructor. This should be used to supply configurations to the stream producer. */ constructor(audioProducerConstructor?: SiriAudioStreamProducerConstructor, producerOptions?: any); /** * @private */ controllerId(): ControllerIdentifier; /** * Set a new target as active target. A value of 0 indicates that no target is selected currently. * * @param activeIdentifier - target identifier */ setActiveIdentifier(activeIdentifier: number): void; /** * @returns if the current target is active, meaning the active device is listening for button events or audio sessions */ isActive(): boolean; /** * Checks if the supplied targetIdentifier is configured. * * @param targetIdentifier - The target identifier. */ isConfigured(targetIdentifier: number): boolean; /** * Returns the targetIdentifier for a give device name * * @param name - The name of the device. * @returns The targetIdentifier of the device or undefined if not existent. */ getTargetIdentifierByName(name: string): number | undefined; /** * Sends a button event to press the supplied button. * * @param button - button to be pressed */ pushButton(button: ButtonType): void; /** * Sends a button event that the supplied button was released. * * @param button - button which was released */ releaseButton(button: ButtonType): void; /** * Presses a supplied button for a given time. * * @param button - button to be pressed and released * @param time - time in milliseconds (defaults to 200ms) */ pushAndReleaseButton(button: ButtonType, time?: number): void; protected constructSupportedConfiguration(): SupportedConfiguration; protected constructSupportedAudioConfiguration(): SupportedAudioStreamConfiguration; private handleTargetControlWrite; private handleAddTarget; private handleUpdateTarget; private handleRemoveTarget; private handleResetTargets; private handleListTargets; private handleActiveWrite; private setInactive; private handleActiveSessionDisconnected; private sendButtonEvent; private parseTargetConfigurationTLV; private updatedTargetConfiguration; private buildTargetControlSupportedConfigurationTLV; private handleTargetControlWhoAmI; private handleSiriAudioStart; private handleSiriAudioStop; private handleDataSendAckEvent; private handleDataSendCloseEvent; private handleSiriAudioSessionClosed; private handleDataStreamConnectionClosed; private handleSelectedAudioConfigurationWrite; private static buildSupportedAudioConfigurationTLV; private static buildSelectedAudioConfigurationTLV; private static buildCodecConfigurationTLV; /** * @private */ constructServices(): RemoteControllerServiceMap; /** * @private */ initWithServices(serviceMap: RemoteControllerServiceMap): void | RemoteControllerServiceMap; /** * @private */ configureServices(): void; /** * @private */ handleControllerRemoved(): void; /** * @private */ handleFactoryReset(): void; /** * @private */ serialize(): SerializedControllerState | undefined; /** * @private */ deserialize(serialized: SerializedControllerState): void; /** * @private */ setupStateChangeDelegate(delegate?: StateChangeDelegate): void; } /** * @group Apple TV Remote */ export declare const enum SiriAudioSessionEvents { CLOSE = "close" } /** * @group Apple TV Remote */ export declare interface SiriAudioSession { on(event: "close", listener: () => void): this; emit(event: "close"): boolean; } /** * Represents an ongoing audio transmission * @group Apple TV Remote */ export declare class SiriAudioSession extends EventEmitter { readonly connection: DataStreamConnection; private readonly selectedAudioConfiguration; private readonly producer; private producerRunning; private producerTimer?; /** * @private file private API */ state: SiriAudioSessionState; streamId?: number; endOfStream: boolean; private audioFrameQueue; private readonly maxQueueSize; private sequenceNumber; private readonly closeListener; constructor(connection: DataStreamConnection, selectedAudioConfiguration: AudioCodecConfiguration, producerConstructor: SiriAudioStreamProducerConstructor, producerOptions?: any); /** * Called when siri button is pressed */ start(): void; /** * @returns if the audio session is closing */ isClosing(): boolean; /** * Called when siri button is released (or active identifier is changed to another device) */ stop(): void; private startAudioProducer; private stopAudioProducer; private handleSiriAudioFrame; private handleProducerError; handleDataSendAckEvent(endOfStream: boolean): void; handleDataSendCloseEvent(reason: HDSProtocolSpecificErrorReason): void; private sendDataSendCloseEvent; private handleDataStreamConnectionClosed; private closed; private popSome; } export {}; //# sourceMappingURL=RemoteController.d.ts.map