UNPKG

14.4 kBTypeScriptView Raw
1import { EventEmitter } from "events";
2import { AudioBitrate, AudioSamplerate } from "../camera";
3import { HDSProtocolSpecificErrorReason, DataStreamConnection, DataStreamProtocolHandler, EventHandler, RequestHandler } from "../datastream";
4import type { AudioStreamManagement, DataStreamTransportManagement, Siri, TargetControl, TargetControlManagement } from "../definitions";
5import { ControllerIdentifier, ControllerServiceMap, SerializableController, StateChangeDelegate } from "./Controller";
6/**
7 * @group Apple TV Remote
8 */
9export declare const enum ButtonType {
10 UNDEFINED = 0,
11 MENU = 1,
12 PLAY_PAUSE = 2,
13 TV_HOME = 3,
14 SELECT = 4,
15 ARROW_UP = 5,
16 ARROW_RIGHT = 6,
17 ARROW_DOWN = 7,
18 ARROW_LEFT = 8,
19 VOLUME_UP = 9,
20 VOLUME_DOWN = 10,
21 SIRI = 11,
22 POWER = 12,
23 GENERIC = 13
24}
25/**
26 * @group Apple TV Remote
27 */
28export declare const enum TargetCategory {
29 UNDEFINED = 0,
30 APPLE_TV = 24
31}
32/**
33 * @group Apple TV Remote
34 */
35export declare const enum ButtonState {
36 UP = 0,
37 DOWN = 1
38}
39/**
40 * @group Apple TV Remote
41 */
42export type SupportedConfiguration = {
43 maximumTargets: number;
44 ticksPerSecond: number;
45 supportedButtonConfiguration: SupportedButtonConfiguration[];
46 hardwareImplemented: boolean;
47};
48/**
49 * @group Apple TV Remote
50 */
51export type SupportedButtonConfiguration = {
52 buttonID: number;
53 buttonType: ButtonType;
54};
55/**
56 * @group Apple TV Remote
57 */
58export type TargetConfiguration = {
59 targetIdentifier: number;
60 targetName?: string;
61 targetCategory?: TargetCategory;
62 buttonConfiguration: Record<number, ButtonConfiguration>;
63};
64/**
65 * @group Apple TV Remote
66 */
67export type ButtonConfiguration = {
68 buttonID: number;
69 buttonType: ButtonType;
70 buttonName?: string;
71};
72/**
73 * @group Camera
74 */
75export declare const enum AudioCodecTypes {
76 PCMU = 0,
77 PCMA = 1,
78 AAC_ELD = 2,
79 OPUS = 3,
80 MSBC = 4,// mSBC is a bluetooth codec (lol)
81 AMR = 5,
82 AMR_WB = 6
83}
84type SupportedAudioStreamConfiguration = {
85 audioCodecConfiguration: AudioCodecConfiguration;
86};
87/**
88 * @group Apple TV Remote
89 */
90export type AudioCodecConfiguration = {
91 codecType: AudioCodecTypes;
92 parameters: AudioCodecParameters;
93};
94/**
95 * @group Apple TV Remote
96 */
97export type AudioCodecParameters = {
98 channels: number;
99 bitrate: AudioBitrate;
100 samplerate: AudioSamplerate;
101 rtpTime?: RTPTime;
102};
103/**
104 * @group Apple TV Remote
105 */
106export type RTPTime = 20 | 30 | 40 | 60;
107declare const enum SiriAudioSessionState {
108 STARTING = 0,// we are currently waiting for a response for the start request
109 SENDING = 1,// we are sending data
110 CLOSING = 2,// we are currently waiting for the acknowledgment event
111 CLOSED = 3
112}
113/**
114 * @group Apple TV Remote
115 */
116export type AudioFrame = {
117 data: Buffer;
118 rms: number;
119};
120/**
121 * @group Apple TV Remote
122 */
123export type FrameHandler = (frame: AudioFrame) => void;
124/**
125 * @group Apple TV Remote
126 */
127export type ErrorHandler = (error: HDSProtocolSpecificErrorReason) => void;
128/**
129 * @group Apple TV Remote
130 */
131export interface SiriAudioStreamProducer {
132 startAudioProduction(selectedAudioConfiguration: AudioCodecConfiguration): void;
133 stopAudioProduction(): void;
134}
135/**
136 * @group Apple TV Remote
137 */
138export interface SiriAudioStreamProducerConstructor {
139 /**
140 * Creates a new instance of a SiriAudioStreamProducer
141 *
142 * @param frameHandler - called for every opus frame recorded
143 * @param errorHandler - should be called with an appropriate reason when the producing process errored
144 * @param options - optional parameter for passing any configuration related options
145 */
146 new (frameHandler: FrameHandler, errorHandler: ErrorHandler, options?: any): SiriAudioStreamProducer;
147}
148/**
149 * @group Apple TV Remote
150 */
151export declare const enum TargetUpdates {
152 NAME = 0,
153 CATEGORY = 1,
154 UPDATED_BUTTONS = 2,
155 REMOVED_BUTTONS = 3
156}
157/**
158 * @group Apple TV Remote
159 */
160export declare const enum RemoteControllerEvents {
161 /**
162 * This event is emitted when the active state of the remote has changed.
163 * active = true indicates that there is currently an Apple TV listening of button presses and audio streams.
164 */
165 ACTIVE_CHANGE = "active-change",
166 /**
167 * This event is emitted when the currently selected target has changed.
168 * Possible reasons for a changed active identifier: manual change via api call, first target configuration
169 * gets added, active target gets removed, accessory gets unpaired, reset request was sent.
170 * An activeIdentifier of 0 indicates that no target is selected.
171 */
172 ACTIVE_IDENTIFIER_CHANGE = "active-identifier-change",
173 /**
174 * This event is emitted when a new target configuration is received. As we currently do not persistently store
175 * configured targets, this will be called at every startup for every Apple TV configured in the home.
176 */
177 TARGET_ADDED = "target-add",
178 /**
179 * This event is emitted when an existing target was updated.
180 * The 'updates' array indicates what exactly was changed for the target.
181 */
182 TARGET_UPDATED = "target-update",
183 /**
184 * This event is emitted when an existing configuration for a target was removed.
185 */
186 TARGET_REMOVED = "target-remove",
187 /**
188 * This event is emitted when a reset of the target configuration is requested.
189 * With this event every configuration made should be reset. This event is also called
190 * when the accessory gets unpaired.
191 */
192 TARGETS_RESET = "targets-reset"
193}
194/**
195 * @group Apple TV Remote
196 */
197export declare interface RemoteController {
198 on(event: "active-change", listener: (active: boolean) => void): this;
199 on(event: "active-identifier-change", listener: (activeIdentifier: number) => void): this;
200 on(event: "target-add", listener: (targetConfiguration: TargetConfiguration) => void): this;
201 on(event: "target-update", listener: (targetConfiguration: TargetConfiguration, updates: TargetUpdates[]) => void): this;
202 on(event: "target-remove", listener: (targetIdentifier: number) => void): this;
203 on(event: "targets-reset", listener: () => void): this;
204 emit(event: "active-change", active: boolean): boolean;
205 emit(event: "active-identifier-change", activeIdentifier: number): boolean;
206 emit(event: "target-add", targetConfiguration: TargetConfiguration): boolean;
207 emit(event: "target-update", targetConfiguration: TargetConfiguration, updates: TargetUpdates[]): boolean;
208 emit(event: "target-remove", targetIdentifier: number): boolean;
209 emit(event: "targets-reset"): boolean;
210}
211/**
212 * @group Apple TV Remote
213 */
214export interface RemoteControllerServiceMap extends ControllerServiceMap {
215 targetControlManagement: TargetControlManagement;
216 targetControl: TargetControl;
217 siri?: Siri;
218 audioStreamManagement?: AudioStreamManagement;
219 dataStreamTransportManagement?: DataStreamTransportManagement;
220}
221/**
222 * @group Apple TV Remote
223 */
224export interface SerializedControllerState {
225 activeIdentifier: number;
226 targetConfigurations: Record<number, TargetConfiguration>;
227}
228/**
229 * Handles everything needed to implement a fully working HomeKit remote controller.
230 *
231 * @group Apple TV Remote
232 */
233export declare class RemoteController extends EventEmitter implements SerializableController<RemoteControllerServiceMap, SerializedControllerState>, DataStreamProtocolHandler {
234 private stateChangeDelegate?;
235 private readonly audioSupported;
236 private readonly audioProducerConstructor?;
237 private readonly audioProducerOptions?;
238 private targetControlManagementService?;
239 private targetControlService?;
240 private siriService?;
241 private audioStreamManagementService?;
242 private dataStreamManagement?;
243 private buttons;
244 private readonly supportedConfiguration;
245 targetConfigurations: Map<number, TargetConfiguration>;
246 private targetConfigurationsString;
247 private lastButtonEvent;
248 activeIdentifier: number;
249 private activeConnection?;
250 private activeConnectionDisconnectListener?;
251 private readonly supportedAudioConfiguration;
252 private selectedAudioConfiguration;
253 private selectedAudioConfigurationString;
254 private dataStreamConnections;
255 private activeAudioSession?;
256 private nextAudioSession?;
257 /**
258 * @private
259 */
260 eventHandler?: Record<string, EventHandler>;
261 /**
262 * @private
263 */
264 requestHandler?: Record<string, RequestHandler>;
265 /**
266 * Creates a new RemoteController.
267 * If siri voice input is supported the constructor to an SiriAudioStreamProducer needs to be supplied.
268 * Otherwise, a remote without voice support will be created.
269 *
270 * For every audio session a new SiriAudioStreamProducer will be constructed.
271 *
272 * @param audioProducerConstructor - constructor for a SiriAudioStreamProducer
273 * @param producerOptions - if supplied this argument will be supplied as third argument of the SiriAudioStreamProducer
274 * constructor. This should be used to supply configurations to the stream producer.
275 */
276 constructor(audioProducerConstructor?: SiriAudioStreamProducerConstructor, producerOptions?: any);
277 /**
278 * @private
279 */
280 controllerId(): ControllerIdentifier;
281 /**
282 * Set a new target as active target. A value of 0 indicates that no target is selected currently.
283 *
284 * @param activeIdentifier - target identifier
285 */
286 setActiveIdentifier(activeIdentifier: number): void;
287 /**
288 * @returns if the current target is active, meaning the active device is listening for button events or audio sessions
289 */
290 isActive(): boolean;
291 /**
292 * Checks if the supplied targetIdentifier is configured.
293 *
294 * @param targetIdentifier - The target identifier.
295 */
296 isConfigured(targetIdentifier: number): boolean;
297 /**
298 * Returns the targetIdentifier for a give device name
299 *
300 * @param name - The name of the device.
301 * @returns The targetIdentifier of the device or undefined if not existent.
302 */
303 getTargetIdentifierByName(name: string): number | undefined;
304 /**
305 * Sends a button event to press the supplied button.
306 *
307 * @param button - button to be pressed
308 */
309 pushButton(button: ButtonType): void;
310 /**
311 * Sends a button event that the supplied button was released.
312 *
313 * @param button - button which was released
314 */
315 releaseButton(button: ButtonType): void;
316 /**
317 * Presses a supplied button for a given time.
318 *
319 * @param button - button to be pressed and released
320 * @param time - time in milliseconds (defaults to 200ms)
321 */
322 pushAndReleaseButton(button: ButtonType, time?: number): void;
323 protected constructSupportedConfiguration(): SupportedConfiguration;
324 protected constructSupportedAudioConfiguration(): SupportedAudioStreamConfiguration;
325 private handleTargetControlWrite;
326 private handleAddTarget;
327 private handleUpdateTarget;
328 private handleRemoveTarget;
329 private handleResetTargets;
330 private handleListTargets;
331 private handleActiveWrite;
332 private setInactive;
333 private handleActiveSessionDisconnected;
334 private sendButtonEvent;
335 private parseTargetConfigurationTLV;
336 private updatedTargetConfiguration;
337 private buildTargetControlSupportedConfigurationTLV;
338 private handleTargetControlWhoAmI;
339 private handleSiriAudioStart;
340 private handleSiriAudioStop;
341 private handleDataSendAckEvent;
342 private handleDataSendCloseEvent;
343 private handleSiriAudioSessionClosed;
344 private handleDataStreamConnectionClosed;
345 private handleSelectedAudioConfigurationWrite;
346 private static buildSupportedAudioConfigurationTLV;
347 private static buildSelectedAudioConfigurationTLV;
348 private static buildCodecConfigurationTLV;
349 /**
350 * @private
351 */
352 constructServices(): RemoteControllerServiceMap;
353 /**
354 * @private
355 */
356 initWithServices(serviceMap: RemoteControllerServiceMap): void | RemoteControllerServiceMap;
357 /**
358 * @private
359 */
360 configureServices(): void;
361 /**
362 * @private
363 */
364 handleControllerRemoved(): void;
365 /**
366 * @private
367 */
368 handleFactoryReset(): void;
369 /**
370 * @private
371 */
372 serialize(): SerializedControllerState | undefined;
373 /**
374 * @private
375 */
376 deserialize(serialized: SerializedControllerState): void;
377 /**
378 * @private
379 */
380 setupStateChangeDelegate(delegate?: StateChangeDelegate): void;
381}
382/**
383 * @group Apple TV Remote
384 */
385export declare const enum SiriAudioSessionEvents {
386 CLOSE = "close"
387}
388/**
389 * @group Apple TV Remote
390 */
391export declare interface SiriAudioSession {
392 on(event: "close", listener: () => void): this;
393 emit(event: "close"): boolean;
394}
395/**
396 * Represents an ongoing audio transmission
397 * @group Apple TV Remote
398 */
399export declare class SiriAudioSession extends EventEmitter {
400 readonly connection: DataStreamConnection;
401 private readonly selectedAudioConfiguration;
402 private readonly producer;
403 private producerRunning;
404 private producerTimer?;
405 /**
406 * @private file private API
407 */
408 state: SiriAudioSessionState;
409 streamId?: number;
410 endOfStream: boolean;
411 private audioFrameQueue;
412 private readonly maxQueueSize;
413 private sequenceNumber;
414 private readonly closeListener;
415 constructor(connection: DataStreamConnection, selectedAudioConfiguration: AudioCodecConfiguration, producerConstructor: SiriAudioStreamProducerConstructor, producerOptions?: any);
416 /**
417 * Called when siri button is pressed
418 */
419 start(): void;
420 /**
421 * @returns if the audio session is closing
422 */
423 isClosing(): boolean;
424 /**
425 * Called when siri button is released (or active identifier is changed to another device)
426 */
427 stop(): void;
428 private startAudioProducer;
429 private stopAudioProducer;
430 private handleSiriAudioFrame;
431 private handleProducerError;
432 handleDataSendAckEvent(endOfStream: boolean): void;
433 handleDataSendCloseEvent(reason: HDSProtocolSpecificErrorReason): void;
434 private sendDataSendCloseEvent;
435 private handleDataStreamConnectionClosed;
436 private closed;
437 private popSome;
438}
439export {};
440//# sourceMappingURL=RemoteController.d.ts.map
\No newline at end of file