@dtelecom/server-sdk-node 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +6 -0
- package/dist/index.js +93 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -423,6 +423,8 @@ declare class RTCEngine extends TypedEmitter<EngineEvents> {
|
|
|
423
423
|
private pendingCandidates;
|
|
424
424
|
private joinResponse;
|
|
425
425
|
private publishWaiters;
|
|
426
|
+
private _negotiateResolve;
|
|
427
|
+
private _publisherConnectedResolve;
|
|
426
428
|
get isConnected(): boolean;
|
|
427
429
|
get publisherPC(): RTCPeerConnection | null;
|
|
428
430
|
get subscriberPC(): RTCPeerConnection | null;
|
|
@@ -436,6 +438,8 @@ declare class RTCEngine extends TypedEmitter<EngineEvents> {
|
|
|
436
438
|
muted?: boolean;
|
|
437
439
|
}): Promise<TrackPublishedResponse>;
|
|
438
440
|
negotiate(): Promise<void>;
|
|
441
|
+
/** Wait for publisher ICE to reach connected state (DTLS+SRTP ready). */
|
|
442
|
+
waitForPublisherConnected(timeoutMs?: number): Promise<void>;
|
|
439
443
|
sendData(data: Uint8Array, kind: 'reliable' | 'lossy'): void;
|
|
440
444
|
disconnect(): Promise<void>;
|
|
441
445
|
private buildIceServers;
|
|
@@ -518,6 +522,8 @@ declare class AudioSource {
|
|
|
518
522
|
flush(): void;
|
|
519
523
|
/** Release encoder resources */
|
|
520
524
|
destroy(): void;
|
|
525
|
+
private _rtpCount;
|
|
526
|
+
private _warnedNoCallback;
|
|
521
527
|
private encodeAndSend;
|
|
522
528
|
}
|
|
523
529
|
|
package/dist/index.js
CHANGED
|
@@ -1380,6 +1380,8 @@ var RTCEngine = class extends TypedEmitter {
|
|
|
1380
1380
|
pendingCandidates = [];
|
|
1381
1381
|
joinResponse = null;
|
|
1382
1382
|
publishWaiters = /* @__PURE__ */ new Map();
|
|
1383
|
+
_negotiateResolve = null;
|
|
1384
|
+
_publisherConnectedResolve = null;
|
|
1383
1385
|
get isConnected() {
|
|
1384
1386
|
return this._isConnected;
|
|
1385
1387
|
}
|
|
@@ -1450,11 +1452,39 @@ var RTCEngine = class extends TypedEmitter {
|
|
|
1450
1452
|
log2.debug(`Publisher signaling state before negotiate: ${this.publisher.signalingState}`);
|
|
1451
1453
|
const offer = await this.publisher.createOffer();
|
|
1452
1454
|
await this.publisher.setLocalDescription(offer);
|
|
1455
|
+
const answerPromise = new Promise((resolve, reject) => {
|
|
1456
|
+
const timeout = setTimeout(() => {
|
|
1457
|
+
reject(new Error("Timed out waiting for publisher answer"));
|
|
1458
|
+
}, 1e4);
|
|
1459
|
+
this._negotiateResolve = () => {
|
|
1460
|
+
clearTimeout(timeout);
|
|
1461
|
+
resolve();
|
|
1462
|
+
};
|
|
1463
|
+
});
|
|
1453
1464
|
log2.debug("Sending publisher offer");
|
|
1454
1465
|
this.signal.sendOffer({
|
|
1455
1466
|
type: offer.type,
|
|
1456
1467
|
sdp: offer.sdp
|
|
1457
1468
|
});
|
|
1469
|
+
await answerPromise;
|
|
1470
|
+
log2.debug("Negotiate complete (answer applied)");
|
|
1471
|
+
}
|
|
1472
|
+
/** Wait for publisher ICE to reach connected state (DTLS+SRTP ready). */
|
|
1473
|
+
async waitForPublisherConnected(timeoutMs = 1e4) {
|
|
1474
|
+
if (!this.publisher) throw new Error("Publisher PC not initialized");
|
|
1475
|
+
const iceState = this.publisher.iceConnectionState;
|
|
1476
|
+
if (iceState === "connected" || iceState === "completed") {
|
|
1477
|
+
return;
|
|
1478
|
+
}
|
|
1479
|
+
return new Promise((resolve, reject) => {
|
|
1480
|
+
const timeout = setTimeout(() => {
|
|
1481
|
+
reject(new Error(`Publisher ICE timed out (state: ${this.publisher?.iceConnectionState})`));
|
|
1482
|
+
}, timeoutMs);
|
|
1483
|
+
this._publisherConnectedResolve = () => {
|
|
1484
|
+
clearTimeout(timeout);
|
|
1485
|
+
resolve();
|
|
1486
|
+
};
|
|
1487
|
+
});
|
|
1458
1488
|
}
|
|
1459
1489
|
sendData(data, kind) {
|
|
1460
1490
|
const channel = kind === "reliable" ? this.reliableChannel : this.lossyChannel;
|
|
@@ -1512,6 +1542,12 @@ var RTCEngine = class extends TypedEmitter {
|
|
|
1512
1542
|
});
|
|
1513
1543
|
this.publisher.iceConnectionStateChange.subscribe((state) => {
|
|
1514
1544
|
log2.debug(`Publisher ICE state: ${state}`);
|
|
1545
|
+
if (state === "connected" || state === "completed") {
|
|
1546
|
+
if (this._publisherConnectedResolve) {
|
|
1547
|
+
this._publisherConnectedResolve();
|
|
1548
|
+
this._publisherConnectedResolve = null;
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1515
1551
|
});
|
|
1516
1552
|
log2.debug("Publisher PC created");
|
|
1517
1553
|
}
|
|
@@ -1628,6 +1664,10 @@ var RTCEngine = class extends TypedEmitter {
|
|
|
1628
1664
|
);
|
|
1629
1665
|
log2.debug("Set publisher remote description");
|
|
1630
1666
|
this.flushPendingCandidates(0 /* PUBLISHER */);
|
|
1667
|
+
if (this._negotiateResolve) {
|
|
1668
|
+
this._negotiateResolve();
|
|
1669
|
+
this._negotiateResolve = null;
|
|
1670
|
+
}
|
|
1631
1671
|
} catch (err) {
|
|
1632
1672
|
log2.error("Failed to handle publisher answer", err);
|
|
1633
1673
|
}
|
|
@@ -2256,22 +2296,49 @@ var LocalAudioTrack = class _LocalAudioTrack {
|
|
|
2256
2296
|
*/
|
|
2257
2297
|
setTransceiver(transceiver) {
|
|
2258
2298
|
this.transceiver = transceiver;
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2299
|
+
const sender = transceiver.sender;
|
|
2300
|
+
const dtlsState = sender?.dtlsTransport?.state;
|
|
2301
|
+
log7.info(`setTransceiver: mid=${transceiver.mid}, codec=${sender?.codec?.name}, dtls=${dtlsState}`);
|
|
2302
|
+
const wireAudio = () => {
|
|
2303
|
+
let rtpWriteCount = 0;
|
|
2304
|
+
log7.info(`Audio wired: dtls=${sender?.dtlsTransport?.state}, codec=${sender?.codec?.name}`);
|
|
2305
|
+
this.source.onEncodedFrame = (opusData) => {
|
|
2306
|
+
if (this.mediaTrack.stopped) return;
|
|
2307
|
+
try {
|
|
2308
|
+
const info = this.packetizer.nextPacketInfo();
|
|
2309
|
+
const header = new import_werift2.RtpHeader();
|
|
2310
|
+
header.payloadType = OPUS_PAYLOAD_TYPE;
|
|
2311
|
+
header.sequenceNumber = info.sequenceNumber;
|
|
2312
|
+
header.timestamp = info.timestamp;
|
|
2313
|
+
header.ssrc = info.ssrc;
|
|
2314
|
+
header.marker = false;
|
|
2315
|
+
const packet = new import_werift2.RtpPacket(header, opusData);
|
|
2316
|
+
this.mediaTrack.writeRtp(packet);
|
|
2317
|
+
rtpWriteCount++;
|
|
2318
|
+
if (rtpWriteCount === 1) {
|
|
2319
|
+
log7.info(`First RTP sent: dtls=${sender?.dtlsTransport?.state}`);
|
|
2320
|
+
}
|
|
2321
|
+
} catch (err) {
|
|
2322
|
+
log7.error("Failed to send RTP via track", err);
|
|
2323
|
+
}
|
|
2324
|
+
};
|
|
2274
2325
|
};
|
|
2326
|
+
if (dtlsState === "connected") {
|
|
2327
|
+
wireAudio();
|
|
2328
|
+
} else {
|
|
2329
|
+
const dtls = sender?.dtlsTransport;
|
|
2330
|
+
if (dtls?.onStateChange) {
|
|
2331
|
+
const { unSubscribe } = dtls.onStateChange.subscribe((state) => {
|
|
2332
|
+
if (state === "connected") {
|
|
2333
|
+
unSubscribe();
|
|
2334
|
+
wireAudio();
|
|
2335
|
+
}
|
|
2336
|
+
});
|
|
2337
|
+
} else {
|
|
2338
|
+
log7.warn("Cannot subscribe to DTLS state changes, wiring audio immediately");
|
|
2339
|
+
wireAudio();
|
|
2340
|
+
}
|
|
2341
|
+
}
|
|
2275
2342
|
}
|
|
2276
2343
|
/** Stop the track and release resources */
|
|
2277
2344
|
stop() {
|
|
@@ -2379,8 +2446,9 @@ var LocalParticipant = class extends Participant {
|
|
|
2379
2446
|
track.sid = response.track.sid;
|
|
2380
2447
|
log8.debug(`Track published: cid=${track.cid}, sid=${track.sid}`);
|
|
2381
2448
|
const transceiver = await this.engine.addTransceiver(track.mediaTrack);
|
|
2382
|
-
track.setTransceiver(transceiver);
|
|
2383
2449
|
await this.engine.negotiate();
|
|
2450
|
+
await this.engine.waitForPublisherConnected();
|
|
2451
|
+
track.setTransceiver(transceiver);
|
|
2384
2452
|
const publication = new LocalTrackPublication(response.track, track);
|
|
2385
2453
|
this._trackPublications.set(response.track.sid, publication);
|
|
2386
2454
|
this.publishedTracks.set(track.cid, track);
|
|
@@ -2842,12 +2910,21 @@ var AudioSource = class {
|
|
|
2842
2910
|
this._onEncodedFrame = null;
|
|
2843
2911
|
this.track = null;
|
|
2844
2912
|
}
|
|
2913
|
+
_rtpCount = 0;
|
|
2914
|
+
_warnedNoCallback = false;
|
|
2845
2915
|
encodeAndSend(pcm) {
|
|
2846
2916
|
if (!this.encoder) return;
|
|
2847
2917
|
try {
|
|
2848
2918
|
const opusData = this.encoder.encode(pcm);
|
|
2849
2919
|
if (this._onEncodedFrame) {
|
|
2850
2920
|
this._onEncodedFrame(opusData);
|
|
2921
|
+
this._rtpCount++;
|
|
2922
|
+
if (this._rtpCount === 1) {
|
|
2923
|
+
log10.info(`First RTP packet sent (${opusData.byteLength} bytes)`);
|
|
2924
|
+
}
|
|
2925
|
+
} else if (!this._warnedNoCallback) {
|
|
2926
|
+
this._warnedNoCallback = true;
|
|
2927
|
+
log10.debug("Waiting for DTLS \u2014 buffered audio will be dropped");
|
|
2851
2928
|
}
|
|
2852
2929
|
} catch (err) {
|
|
2853
2930
|
log10.error("Opus encode failed", err);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/utils/events.ts","../src/utils/logger.ts","../src/engine.ts","../src/signal.ts","../src/proto/signal.ts","../src/proto/models.ts","../src/track.ts","../src/audio/audio-frame.ts","../src/audio/opus-encoder.ts","../src/audio/opus-decoder.ts","../src/audio/rtp-opus.ts","../src/audio/resampler.ts","../src/utils/queue.ts","../src/audio/audio-stream.ts","../src/participant.ts","../src/room.ts","../src/audio/audio-source.ts","../src/data/data-channel.ts"],"sourcesContent":["/**\n * @dtelecom/server-sdk-node\n *\n * Node.js RTC SDK for dTelecom — WebRTC participant for AI bots.\n *\n * Key classes:\n * - Room: Connect to a dTelecom room\n * - AudioSource: Feed PCM16 audio to publish\n * - AudioStream: Receive decoded PCM16 audio\n * - AudioFrame: PCM16 audio container\n * - LocalAudioTrack: Local audio track for publishing\n */\n\n// ─── Room ───────────────────────────────────────────────────────────────────\nexport { Room } from './room';\nexport type { RoomOptions, RoomEvents } from './room';\n\n// ─── Participants ───────────────────────────────────────────────────────────\nexport {\n Participant,\n LocalParticipant,\n RemoteParticipant,\n} from './participant';\nexport type { DataPublishOptions, ParticipantEvents, RemoteParticipantEvents } from './participant';\n\n// ─── Tracks ─────────────────────────────────────────────────────────────────\nexport {\n LocalAudioTrack,\n RemoteAudioTrack,\n TrackPublication,\n LocalTrackPublication,\n RemoteTrackPublication,\n} from './track';\nexport type { TrackPublishOptions } from './track';\n\n// ─── Audio ──────────────────────────────────────────────────────────────────\nexport { AudioFrame } from './audio/audio-frame';\nexport { AudioSource } from './audio/audio-source';\nexport { AudioStream } from './audio/audio-stream';\nexport { resample, downsample, upsample } from './audio/resampler';\n\n// ─── Data ───────────────────────────────────────────────────────────────────\nexport {\n encodeDataPacket,\n decodeDataPacket,\n createTextMessage,\n} from './data/data-channel';\n\n// ─── Proto types (for advanced usage) ───────────────────────────────────────\nexport {\n TrackType,\n TrackSource,\n DataPacket_Kind,\n ParticipantInfo_State,\n ConnectionQuality,\n DisconnectReason,\n} from './proto/models';\nexport type {\n Room as RoomInfo,\n ParticipantInfo,\n TrackInfo,\n DataPacket,\n UserPacket,\n ICEServer,\n SpeakerInfo,\n} from './proto/models';\n\n// ─── Utils ──────────────────────────────────────────────────────────────────\nexport { setLogLevel, LogLevel } from './utils/logger';\nexport type { Logger } from './utils/logger';\n","import { EventEmitter } from 'events';\n\n/**\n * A typed EventEmitter that provides type-safe event handling.\n * Usage:\n * interface MyEvents {\n * data: (payload: string) => void;\n * error: (err: Error) => void;\n * }\n * class MyClass extends TypedEmitter<MyEvents> {}\n */\nexport type EventMap = { [key: string]: (...args: any[]) => void };\n\nexport class TypedEmitter<T extends { [key: string]: (...args: any[]) => void }> {\n private emitter = new EventEmitter();\n\n constructor() {\n this.emitter.setMaxListeners(50);\n }\n\n on<K extends keyof T & string>(event: K, listener: T[K]): this {\n this.emitter.on(event, listener as (...args: any[]) => void);\n return this;\n }\n\n once<K extends keyof T & string>(event: K, listener: T[K]): this {\n this.emitter.once(event, listener as (...args: any[]) => void);\n return this;\n }\n\n off<K extends keyof T & string>(event: K, listener: T[K]): this {\n this.emitter.off(event, listener as (...args: any[]) => void);\n return this;\n }\n\n emit<K extends keyof T & string>(event: K, ...args: Parameters<T[K]>): boolean {\n return this.emitter.emit(event, ...args);\n }\n\n removeAllListeners<K extends keyof T & string>(event?: K): this {\n if (event) {\n this.emitter.removeAllListeners(event);\n } else {\n this.emitter.removeAllListeners();\n }\n return this;\n }\n\n listenerCount<K extends keyof T & string>(event: K): number {\n return this.emitter.listenerCount(event);\n }\n}\n","export enum LogLevel {\n TRACE = 0,\n DEBUG = 1,\n INFO = 2,\n WARN = 3,\n ERROR = 4,\n SILENT = 5,\n}\n\nconst levelNames: Record<LogLevel, string> = {\n [LogLevel.TRACE]: 'TRACE',\n [LogLevel.DEBUG]: 'DEBUG',\n [LogLevel.INFO]: 'INFO',\n [LogLevel.WARN]: 'WARN',\n [LogLevel.ERROR]: 'ERROR',\n [LogLevel.SILENT]: 'SILENT',\n};\n\nlet globalLevel: LogLevel = LogLevel.INFO;\n\nexport function setLogLevel(level: LogLevel): void {\n globalLevel = level;\n}\n\nexport function getLogLevel(): LogLevel {\n return globalLevel;\n}\n\nexport interface Logger {\n trace(msg: string, ...args: unknown[]): void;\n debug(msg: string, ...args: unknown[]): void;\n info(msg: string, ...args: unknown[]): void;\n warn(msg: string, ...args: unknown[]): void;\n error(msg: string, ...args: unknown[]): void;\n}\n\nexport function createLogger(component: string): Logger {\n const log = (level: LogLevel, msg: string, args: unknown[]) => {\n if (level < globalLevel) return;\n const ts = new Date().toISOString();\n const prefix = `${ts} [${levelNames[level]}] [${component}]`;\n if (args.length > 0) {\n console.log(prefix, msg, ...args);\n } else {\n console.log(prefix, msg);\n }\n };\n\n return {\n trace: (msg, ...args) => log(LogLevel.TRACE, msg, args),\n debug: (msg, ...args) => log(LogLevel.DEBUG, msg, args),\n info: (msg, ...args) => log(LogLevel.INFO, msg, args),\n warn: (msg, ...args) => log(LogLevel.WARN, msg, args),\n error: (msg, ...args) => log(LogLevel.ERROR, msg, args),\n };\n}\n","/**\n * RTCEngine — manages dual PeerConnections (publisher + subscriber)\n * for communication with the dTelecom SFU.\n *\n * Publisher PC: sends local audio + data channels\n * Subscriber PC: receives remote audio + data channels\n */\n\nimport {\n RTCPeerConnection,\n RTCSessionDescription,\n RTCIceCandidate,\n RTCDataChannel,\n MediaStreamTrack,\n RTCRtpTransceiver,\n} from 'werift';\nimport { TypedEmitter } from './utils/events';\nimport { createLogger } from './utils/logger';\nimport { SignalClient } from './signal';\nimport {\n SignalTarget,\n SessionDescription,\n JoinResponse,\n TrackPublishedResponse,\n AddTrackRequest,\n} from './proto/signal';\nimport { TrackType, TrackSource, ICEServer } from './proto/models';\n\nconst log = createLogger('RTCEngine');\n\nexport interface EngineEvents {\n [key: string]: (...args: any[]) => void;\n connected: () => void;\n disconnected: (reason?: string) => void;\n remoteTrack: (track: MediaStreamTrack, transceiver: RTCRtpTransceiver) => void;\n dataMessage: (data: Uint8Array, kind: 'reliable' | 'lossy') => void;\n dataChannelReady: () => void;\n trackPublished: (response: TrackPublishedResponse) => void;\n subscriberOffer: (sd: SessionDescription) => void;\n}\n\nexport interface EngineOptions {\n connectTimeout?: number;\n autoSubscribe?: boolean;\n}\n\nexport class RTCEngine extends TypedEmitter<EngineEvents> {\n readonly signal: SignalClient;\n\n private publisher: RTCPeerConnection | null = null;\n private subscriber: RTCPeerConnection | null = null;\n\n private reliableChannel: RTCDataChannel | null = null;\n private lossyChannel: RTCDataChannel | null = null;\n private subscriberReliableChannel: RTCDataChannel | null = null;\n private subscriberLossyChannel: RTCDataChannel | null = null;\n\n private subscriberPrimary = true;\n private _isConnected = false;\n private pendingCandidates: { candidate: RTCIceCandidate; target: SignalTarget }[] = [];\n private joinResponse: JoinResponse | null = null;\n\n private publishWaiters: Map<string, (response: TrackPublishedResponse) => void> = new Map();\n\n get isConnected(): boolean {\n return this._isConnected;\n }\n\n get publisherPC(): RTCPeerConnection | null {\n return this.publisher;\n }\n\n get subscriberPC(): RTCPeerConnection | null {\n return this.subscriber;\n }\n\n get reliableDataChannel(): RTCDataChannel | null {\n return this.reliableChannel;\n }\n\n get lossyDataChannel(): RTCDataChannel | null {\n return this.lossyChannel;\n }\n\n constructor() {\n super();\n this.signal = new SignalClient();\n }\n\n async connect(url: string, token: string, options: EngineOptions = {}): Promise<JoinResponse> {\n const joinResponse = await this.signal.connect(url, token, {\n autoSubscribe: options.autoSubscribe ?? true,\n connectTimeout: options.connectTimeout ?? 10000,\n });\n this.joinResponse = joinResponse;\n this.subscriberPrimary = joinResponse.subscriberPrimary;\n\n log.info(`Joined room \"${joinResponse.room?.name}\", subscriber_primary=${this.subscriberPrimary}`);\n log.debug(`ICE servers: ${joinResponse.iceServers.length}, participants: ${joinResponse.otherParticipants.length}`);\n\n const iceServers = this.buildIceServers(joinResponse.iceServers);\n this.createPublisher(iceServers);\n this.createSubscriber(iceServers);\n this.setupSignalHandlers();\n this.createDataChannels();\n\n if (!this.subscriberPrimary) {\n await this.negotiate();\n }\n\n return joinResponse;\n }\n\n async addTransceiver(track: MediaStreamTrack): Promise<RTCRtpTransceiver> {\n if (!this.publisher) {\n throw new Error('Publisher PC not initialized');\n }\n const transceiver = this.publisher.addTransceiver(track, { direction: 'sendonly' });\n return transceiver;\n }\n\n async requestPublishTrack(\n cid: string,\n name: string,\n type: TrackType,\n source: TrackSource,\n options?: { disableDtx?: boolean; muted?: boolean },\n ): Promise<TrackPublishedResponse> {\n const request: AddTrackRequest = {\n cid,\n name,\n type,\n source,\n width: 0,\n height: 0,\n muted: options?.muted ?? false,\n disableDtx: options?.disableDtx ?? false,\n layers: [],\n sid: '',\n };\n\n return new Promise<TrackPublishedResponse>((resolve) => {\n this.publishWaiters.set(cid, resolve);\n this.signal.sendAddTrack(request);\n });\n }\n\n async negotiate(): Promise<void> {\n if (!this.publisher) {\n throw new Error('Publisher PC not initialized');\n }\n\n log.debug(`Publisher signaling state before negotiate: ${this.publisher.signalingState}`);\n const offer = await this.publisher.createOffer();\n await this.publisher.setLocalDescription(offer);\n\n log.debug('Sending publisher offer');\n this.signal.sendOffer({\n type: offer.type,\n sdp: offer.sdp,\n });\n }\n\n sendData(data: Uint8Array, kind: 'reliable' | 'lossy'): void {\n const channel = kind === 'reliable' ? this.reliableChannel : this.lossyChannel;\n if (!channel || channel.readyState !== 'open') {\n log.warn(`Data channel ${kind} not open`);\n return;\n }\n channel.send(Buffer.from(data));\n }\n\n async disconnect(): Promise<void> {\n this._isConnected = false;\n\n try {\n this.signal.sendLeave();\n } catch {\n // ignore\n }\n\n this.reliableChannel?.close();\n this.lossyChannel?.close();\n this.publisher?.close();\n this.subscriber?.close();\n this.signal.close();\n\n this.publisher = null;\n this.subscriber = null;\n this.reliableChannel = null;\n this.lossyChannel = null;\n this.subscriberReliableChannel = null;\n this.subscriberLossyChannel = null;\n this.publishWaiters.clear();\n\n log.info('Disconnected');\n this.emit('disconnected', 'client_initiated');\n }\n\n // ─── Private ────────────────────────────────────────────────────────────\n\n private buildIceServers(servers: ICEServer[]): { urls: string; username?: string; credential?: string }[] {\n const result: { urls: string; username?: string; credential?: string }[] = [];\n for (const s of servers) {\n for (const url of s.urls) {\n result.push({\n urls: url,\n username: s.username || undefined,\n credential: s.credential || undefined,\n });\n }\n }\n return result;\n }\n\n private createPublisher(iceServers: { urls: string; username?: string; credential?: string }[]): void {\n this.publisher = new RTCPeerConnection({\n iceServers,\n iceTransportPolicy: 'all',\n });\n\n this.publisher.onIceCandidate.subscribe((candidate) => {\n if (candidate) {\n const init = JSON.stringify(candidate.toJSON());\n this.signal.sendIceCandidate(init, SignalTarget.PUBLISHER);\n }\n });\n\n this.publisher.iceConnectionStateChange.subscribe((state) => {\n log.debug(`Publisher ICE state: ${state}`);\n });\n\n log.debug('Publisher PC created');\n }\n\n private createSubscriber(iceServers: { urls: string; username?: string; credential?: string }[]): void {\n this.subscriber = new RTCPeerConnection({\n iceServers,\n iceTransportPolicy: 'all',\n });\n\n this.subscriber.onIceCandidate.subscribe((candidate) => {\n if (candidate) {\n const init = JSON.stringify(candidate.toJSON());\n this.signal.sendIceCandidate(init, SignalTarget.SUBSCRIBER);\n }\n });\n\n // Remote track received on subscriber (fires after negotiation with actual track)\n this.subscriber.on('track', (event: any) => {\n const track = event.track as MediaStreamTrack;\n const transceiver = event.transceiver as RTCRtpTransceiver;\n log.debug(`Subscriber received track: mid=${transceiver?.mid}, kind=${track?.kind}`);\n if (track) {\n this.emit('remoteTrack', track, transceiver);\n }\n });\n\n // Data channels on subscriber (server creates them)\n this.subscriber.onDataChannel.subscribe((channel) => {\n log.debug(`Subscriber data channel: \"${channel.label}\"`);\n if (channel.label === '_reliable') {\n this.subscriberReliableChannel = channel;\n this.setupSubscriberDataChannel(channel, 'reliable');\n } else if (channel.label === '_lossy') {\n this.subscriberLossyChannel = channel;\n this.setupSubscriberDataChannel(channel, 'lossy');\n }\n });\n\n this.subscriber.iceConnectionStateChange.subscribe((state) => {\n log.debug(`Subscriber ICE state: ${state}`);\n if (state === 'connected') {\n if (!this._isConnected) {\n this._isConnected = true;\n this.emit('connected');\n }\n } else if (state === 'disconnected' || state === 'failed') {\n this._isConnected = false;\n this.emit('disconnected', `ICE ${state}`);\n }\n });\n\n log.debug('Subscriber PC created');\n }\n\n private createDataChannels(): void {\n if (!this.publisher) return;\n\n this.reliableChannel = this.publisher.createDataChannel('_reliable', {\n ordered: true,\n });\n\n this.lossyChannel = this.publisher.createDataChannel('_lossy', {\n ordered: true,\n maxRetransmits: 1,\n });\n\n let readyCount = 0;\n const checkReady = () => {\n readyCount++;\n if (readyCount >= 2) {\n log.debug('Publisher data channels ready');\n this.emit('dataChannelReady');\n }\n };\n\n this.reliableChannel.stateChanged.subscribe((state) => {\n if (state === 'open') {\n log.debug('Reliable data channel opened');\n checkReady();\n }\n });\n\n this.lossyChannel.stateChanged.subscribe((state) => {\n if (state === 'open') {\n log.debug('Lossy data channel opened');\n checkReady();\n }\n });\n\n log.debug('Data channels created on publisher');\n }\n\n private setupSubscriberDataChannel(channel: RTCDataChannel, kind: 'reliable' | 'lossy'): void {\n channel.onMessage.subscribe((event) => {\n let data: Uint8Array;\n if (event instanceof Buffer) {\n data = new Uint8Array(event);\n } else if (typeof event === 'string') {\n data = new TextEncoder().encode(event);\n } else {\n data = new Uint8Array(event as any);\n }\n this.emit('dataMessage', data, kind);\n });\n }\n\n private setupSignalHandlers(): void {\n this.signal.on('offer', async (sd) => {\n if (!this.subscriber) return;\n\n try {\n await this.subscriber.setRemoteDescription(\n new RTCSessionDescription(sd.sdp, sd.type as 'offer'),\n );\n\n const answer = await this.subscriber.createAnswer();\n await this.subscriber.setLocalDescription(answer);\n\n this.signal.sendAnswer({\n type: answer.type,\n sdp: answer.sdp,\n });\n log.debug('Sent subscriber answer');\n } catch (err) {\n log.error('Failed to handle subscriber offer', err);\n }\n });\n\n this.signal.on('answer', async (sd) => {\n if (!this.publisher) return;\n\n try {\n await this.publisher.setRemoteDescription(\n new RTCSessionDescription(sd.sdp, sd.type as 'answer'),\n );\n log.debug('Set publisher remote description');\n\n this.flushPendingCandidates(SignalTarget.PUBLISHER);\n } catch (err) {\n log.error('Failed to handle publisher answer', err);\n }\n });\n\n this.signal.on('trickle', async (trickle) => {\n try {\n const candidateInit = JSON.parse(trickle.candidateInit);\n const candidate = new RTCIceCandidate(candidateInit);\n const pc = trickle.target === SignalTarget.PUBLISHER ? this.publisher : this.subscriber;\n\n if (!pc) return;\n\n if (pc.remoteDescription) {\n await pc.addIceCandidate(candidate);\n } else {\n this.pendingCandidates.push({ candidate, target: trickle.target });\n }\n } catch (err) {\n log.error('Failed to add ICE candidate', err);\n }\n });\n\n this.signal.on('trackPublished', (response) => {\n const waiter = this.publishWaiters.get(response.cid);\n if (waiter) {\n this.publishWaiters.delete(response.cid);\n waiter(response);\n }\n this.emit('trackPublished', response);\n });\n\n this.signal.on('leave', () => {\n this.disconnect();\n });\n\n this.signal.on('close', (reason) => {\n if (this._isConnected) {\n this._isConnected = false;\n this.emit('disconnected', reason);\n }\n });\n }\n\n private flushPendingCandidates(target: SignalTarget): void {\n const pc = target === SignalTarget.PUBLISHER ? this.publisher : this.subscriber;\n if (!pc) return;\n\n const toFlush = this.pendingCandidates.filter((c) => c.target === target);\n this.pendingCandidates = this.pendingCandidates.filter((c) => c.target !== target);\n\n for (const { candidate } of toFlush) {\n pc.addIceCandidate(candidate).catch((err: any) => {\n log.error('Failed to flush ICE candidate', err);\n });\n }\n }\n}\n","/**\n * SignalClient — WebSocket connection to dTelecom SFU.\n *\n * Handles binary protobuf signaling: SignalRequest (client→server)\n * and SignalResponse (server→client).\n */\n\nimport WebSocket from 'ws';\nimport { TypedEmitter } from './utils/events';\nimport { createLogger } from './utils/logger';\nimport {\n SignalRequest,\n SignalResponse,\n SignalTarget,\n JoinResponse,\n SessionDescription,\n TrickleRequest,\n AddTrackRequest,\n MuteTrackRequest,\n UpdateSubscription,\n LeaveRequest,\n TrackPublishedResponse,\n ParticipantUpdate,\n SpeakersChanged,\n RoomUpdate,\n ConnectionQualityUpdate,\n StreamStateUpdate,\n TrackUnpublishedResponse,\n} from './proto/signal';\nimport { DisconnectReason } from './proto/models';\n\nconst log = createLogger('SignalClient');\n\nconst PROTOCOL_VERSION = 8;\nconst SDK_NAME = 'node';\nconst SDK_VERSION = '0.1.0';\n\nexport interface SignalOptions {\n /** Auto-subscribe to all tracks (default: true) */\n autoSubscribe?: boolean;\n /** WebSocket connection timeout in ms (default: 10000) */\n connectTimeout?: number;\n}\n\nexport interface SignalEvents {\n [key: string]: (...args: any[]) => void;\n join: (response: JoinResponse) => void;\n offer: (sd: SessionDescription) => void;\n answer: (sd: SessionDescription) => void;\n trickle: (request: TrickleRequest) => void;\n participantUpdate: (update: ParticipantUpdate) => void;\n trackPublished: (response: TrackPublishedResponse) => void;\n trackUnpublished: (response: TrackUnpublishedResponse) => void;\n speakersChanged: (update: SpeakersChanged) => void;\n roomUpdate: (update: RoomUpdate) => void;\n connectionQuality: (update: ConnectionQualityUpdate) => void;\n streamStateUpdate: (update: StreamStateUpdate) => void;\n leave: (request: LeaveRequest) => void;\n tokenRefresh: (token: string) => void;\n close: (reason: string) => void;\n error: (error: Error) => void;\n}\n\nexport class SignalClient extends TypedEmitter<SignalEvents> {\n private ws: WebSocket | null = null;\n private pingInterval: NodeJS.Timeout | null = null;\n private _isConnected = false;\n private joinResponse: JoinResponse | null = null;\n\n get isConnected(): boolean {\n return this._isConnected;\n }\n\n /**\n * Connect to the dTelecom SFU signaling server.\n * Returns JoinResponse on successful connection.\n */\n async connect(url: string, token: string, options: SignalOptions = {}): Promise<JoinResponse> {\n const autoSubscribe = options.autoSubscribe ?? true;\n const connectTimeout = options.connectTimeout ?? 10000;\n\n // Build WebSocket URL\n const wsUrl = this.buildUrl(url, token, autoSubscribe);\n log.info(`Connecting to ${wsUrl.replace(/access_token=[^&]+/, 'access_token=***')}`);\n\n return new Promise<JoinResponse>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.close();\n reject(new Error(`Signal connection timed out after ${connectTimeout}ms`));\n }, connectTimeout);\n\n try {\n this.ws = new WebSocket(wsUrl, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n this.ws.binaryType = 'arraybuffer';\n } catch (err) {\n clearTimeout(timeout);\n reject(err);\n return;\n }\n\n this.ws.on('open', () => {\n log.debug('WebSocket connected');\n });\n\n this.ws.on('message', (data: WebSocket.Data) => {\n try {\n const bytes = data instanceof ArrayBuffer\n ? new Uint8Array(data)\n : new Uint8Array(data as Buffer);\n\n const response = SignalResponse.decode(bytes);\n this.handleResponse(response);\n\n // First message should be JoinResponse\n if (response.join) {\n clearTimeout(timeout);\n this.joinResponse = response.join;\n this._isConnected = true;\n\n // Set up ping if configured\n if (response.join.pingInterval > 0) {\n this.startPing(response.join.pingInterval);\n }\n\n resolve(response.join);\n }\n } catch (err) {\n log.error('Failed to decode signal response', err);\n }\n });\n\n this.ws.on('error', (err) => {\n log.error('WebSocket error', err);\n clearTimeout(timeout);\n this.emit('error', err instanceof Error ? err : new Error(String(err)));\n reject(err);\n });\n\n this.ws.on('close', (code, reason) => {\n clearTimeout(timeout);\n this._isConnected = false;\n this.stopPing();\n const reasonStr = reason?.toString() || `code ${code}`;\n log.info(`WebSocket closed: ${reasonStr}`);\n this.emit('close', reasonStr);\n\n // If we haven't joined yet, reject\n if (!this.joinResponse) {\n reject(new Error(`WebSocket closed before join: ${reasonStr}`));\n }\n });\n });\n }\n\n /** Send an SDP offer (publisher → server) */\n sendOffer(sd: SessionDescription): void {\n this.sendRequest({ offer: sd });\n }\n\n /** Send an SDP answer (subscriber → server) */\n sendAnswer(sd: SessionDescription): void {\n this.sendRequest({ answer: sd });\n }\n\n /** Send an ICE candidate */\n sendIceCandidate(candidate: string, target: SignalTarget): void {\n this.sendRequest({\n trickle: { candidateInit: candidate, target },\n });\n }\n\n /** Request to add (publish) a track */\n sendAddTrack(request: AddTrackRequest): void {\n this.sendRequest({ addTrack: request });\n }\n\n /** Mute/unmute a track */\n sendMuteTrack(trackSid: string, muted: boolean): void {\n this.sendRequest({ mute: { sid: trackSid, muted } });\n }\n\n /** Update track subscription */\n sendSubscription(update: UpdateSubscription): void {\n this.sendRequest({ subscription: update });\n }\n\n /** Send leave request */\n sendLeave(): void {\n this.sendRequest({\n leave: { canReconnect: false, reason: DisconnectReason.CLIENT_INITIATED },\n });\n }\n\n /** Close the WebSocket connection */\n close(): void {\n this.stopPing();\n this._isConnected = false;\n if (this.ws) {\n this.ws.removeAllListeners();\n if (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) {\n this.ws.close();\n }\n this.ws = null;\n }\n }\n\n // ─── Private ────────────────────────────────────────────────────────────\n\n private buildUrl(url: string, token: string, autoSubscribe: boolean): string {\n // Normalize URL: ensure wss:// and /rtc path\n let wsUrl = url;\n if (wsUrl.startsWith('http://')) {\n wsUrl = wsUrl.replace('http://', 'ws://');\n } else if (wsUrl.startsWith('https://')) {\n wsUrl = wsUrl.replace('https://', 'wss://');\n } else if (!wsUrl.startsWith('ws://') && !wsUrl.startsWith('wss://')) {\n wsUrl = `wss://${wsUrl}`;\n }\n\n if (!wsUrl.includes('/rtc')) {\n wsUrl = wsUrl.replace(/\\/?$/, '/rtc');\n }\n\n const params = new URLSearchParams({\n protocol: String(PROTOCOL_VERSION),\n sdk: SDK_NAME,\n version: SDK_VERSION,\n auto_subscribe: autoSubscribe ? '1' : '0',\n access_token: token,\n });\n\n return `${wsUrl}?${params.toString()}`;\n }\n\n private sendRequest(request: SignalRequest): void {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n log.warn('Cannot send: WebSocket not open');\n return;\n }\n\n try {\n const bytes = SignalRequest.encode(request).finish();\n this.ws.send(bytes);\n } catch (err) {\n log.error('Failed to encode signal request', err);\n }\n }\n\n private handleResponse(response: SignalResponse): void {\n // join is handled in the connect() promise\n if (response.offer) {\n log.debug(`Received OFFER from server (type=${response.offer.type})`);\n this.emit('offer', response.offer);\n }\n if (response.answer) {\n log.debug(`Received ANSWER from server (type=${response.answer.type})`);\n this.emit('answer', response.answer);\n }\n if (response.trickle) {\n this.emit('trickle', response.trickle);\n }\n if (response.update) {\n this.emit('participantUpdate', response.update);\n }\n if (response.trackPublished) {\n log.debug('Track published confirmed:', response.trackPublished.cid);\n this.emit('trackPublished', response.trackPublished);\n }\n if (response.trackUnpublished) {\n this.emit('trackUnpublished', response.trackUnpublished);\n }\n if (response.speakersChanged) {\n this.emit('speakersChanged', response.speakersChanged);\n }\n if (response.roomUpdate) {\n this.emit('roomUpdate', response.roomUpdate);\n }\n if (response.connectionQuality) {\n this.emit('connectionQuality', response.connectionQuality);\n }\n if (response.streamStateUpdate) {\n this.emit('streamStateUpdate', response.streamStateUpdate);\n }\n if (response.leave) {\n log.info('Server requested leave', response.leave.reason);\n this.emit('leave', response.leave);\n }\n if (response.refreshToken) {\n this.emit('tokenRefresh', response.refreshToken);\n }\n if (response.mute) {\n // Server-initiated mute — handled via participant update\n }\n if (response.pong !== undefined) {\n // Pong received — connection alive\n }\n }\n\n private startPing(intervalSec: number): void {\n this.stopPing();\n const intervalMs = intervalSec * 1000;\n this.pingInterval = setInterval(() => {\n this.sendRequest({ ping: Date.now() });\n }, intervalMs);\n }\n\n private stopPing(): void {\n if (this.pingInterval) {\n clearInterval(this.pingInterval);\n this.pingInterval = null;\n }\n }\n}\n","/**\n * Signaling protocol types for dTelecom RTC.\n * Matches livekit_rtc.proto from github.com/dtelecom/protocol.\n *\n * These types define the WebSocket signaling messages between\n * client and SFU (Selective Forwarding Unit).\n */\n\nimport * as _m0 from 'protobufjs/minimal';\nimport {\n Room,\n Codec,\n ParticipantInfo,\n TrackInfo,\n TrackType,\n TrackSource,\n ICEServer,\n ClientInfo,\n SpeakerInfo,\n DataPacket_Kind,\n DisconnectReason,\n} from './models';\n\n// ─── Enums ──────────────────────────────────────────────────────────────────\n\nexport enum SignalTarget {\n PUBLISHER = 0,\n SUBSCRIBER = 1,\n}\n\nexport enum StreamState {\n ACTIVE = 0,\n PAUSED = 1,\n}\n\nexport enum CandidateProtocol {\n UDP = 0,\n TCP = 1,\n TLS = 2,\n}\n\n// ─── Session Description ────────────────────────────────────────────────────\n\nexport interface SessionDescription {\n /** SDP offer/answer string */\n type: string;\n sdp: string;\n}\n\n// ─── Signal Request (client → server) ───────────────────────────────────────\n\nexport interface SignalRequest {\n offer?: SessionDescription;\n answer?: SessionDescription;\n trickle?: TrickleRequest;\n addTrack?: AddTrackRequest;\n mute?: MuteTrackRequest;\n subscription?: UpdateSubscription;\n trackSetting?: UpdateTrackSettings;\n leave?: LeaveRequest;\n updateLayers?: UpdateVideoLayers;\n subscriptionPermission?: SubscriptionPermission;\n syncState?: SyncState;\n simulate?: SimulateScenario;\n ping?: number;\n}\n\n// ─── Signal Response (server → client) ──────────────────────────────────────\n\nexport interface SignalResponse {\n join?: JoinResponse;\n offer?: SessionDescription;\n answer?: SessionDescription;\n trickle?: TrickleRequest;\n update?: ParticipantUpdate;\n trackPublished?: TrackPublishedResponse;\n leave?: LeaveRequest;\n mute?: MuteTrackRequest;\n speakersChanged?: SpeakersChanged;\n roomUpdate?: RoomUpdate;\n connectionQuality?: ConnectionQualityUpdate;\n streamStateUpdate?: StreamStateUpdate;\n subscribedQualityUpdate?: SubscribedQualityUpdate;\n subscriptionPermissionUpdate?: SubscriptionPermissionUpdate;\n refreshToken?: string;\n trackUnpublished?: TrackUnpublishedResponse;\n pong?: number;\n}\n\n// ─── Sub-messages ───────────────────────────────────────────────────────────\n\nexport interface TrickleRequest {\n candidateInit: string;\n target: SignalTarget;\n}\n\nexport interface AddTrackRequest {\n cid: string;\n name: string;\n type: TrackType;\n width: number;\n height: number;\n muted: boolean;\n disableDtx: boolean;\n source: TrackSource;\n layers: SimulcastCodec[];\n sid: string;\n}\n\nexport interface SimulcastCodec {\n codec: string;\n cid: string;\n enableSimulcastLayers: boolean;\n}\n\nexport interface MuteTrackRequest {\n sid: string;\n muted: boolean;\n}\n\nexport interface UpdateSubscription {\n trackSids: string[];\n subscribe: boolean;\n participantTracks: ParticipantTrackInfo[];\n}\n\nexport interface ParticipantTrackInfo {\n participantSid: string;\n trackSids: string[];\n}\n\nexport interface UpdateTrackSettings {\n trackSids: string[];\n disabled: boolean;\n quality: number;\n width: number;\n height: number;\n fps: number;\n}\n\nexport interface LeaveRequest {\n canReconnect: boolean;\n reason: DisconnectReason;\n}\n\nexport interface UpdateVideoLayers {\n trackSid: string;\n layers: VideoLayerInfo[];\n}\n\nexport interface VideoLayerInfo {\n quality: number;\n width: number;\n height: number;\n bitrate: number;\n ssrc: number;\n}\n\nexport interface SubscriptionPermission {\n allParticipants: boolean;\n trackPermissions: TrackPermission[];\n}\n\nexport interface TrackPermission {\n participantSid: string;\n allTracks: boolean;\n trackSids: string[];\n}\n\nexport interface SyncState {\n answer?: SessionDescription;\n subscription?: UpdateSubscription;\n publishTracks: TrackPublishedResponse[];\n dataChannels: DataChannelInfo[];\n}\n\nexport interface DataChannelInfo {\n label: string;\n id: number;\n target: SignalTarget;\n}\n\nexport interface SimulateScenario {\n speakerUpdate?: number;\n nodeFailure?: boolean;\n migration?: boolean;\n serverLeave?: boolean;\n switchCandidateProtocol?: CandidateProtocol;\n}\n\n// ─── Response sub-messages ──────────────────────────────────────────────────\n\nexport interface JoinResponse {\n room?: Room;\n participant?: ParticipantInfo;\n otherParticipants: ParticipantInfo[];\n serverVersion: string;\n iceServers: ICEServer[];\n subscriberPrimary: boolean;\n alternativeUrl: string;\n clientConfiguration?: ClientConfiguration;\n serverRegion: string;\n pingTimeout: number;\n pingInterval: number;\n}\n\nexport interface ClientConfiguration {\n video?: VideoConfiguration;\n screen?: VideoConfiguration;\n resumeConnection: number;\n disabledCodecs?: DisabledCodecs;\n forceRelay: number;\n}\n\nexport interface VideoConfiguration {\n hardwareEncoder: number;\n}\n\nexport interface DisabledCodecs {\n codecs: CodecInfo[];\n}\n\nexport interface CodecInfo {\n mime: string;\n fmtpLine: string;\n}\n\nexport interface ParticipantUpdate {\n participants: ParticipantInfo[];\n}\n\nexport interface TrackPublishedResponse {\n cid: string;\n track?: TrackInfo;\n}\n\nexport interface TrackUnpublishedResponse {\n trackSid: string;\n}\n\nexport interface SpeakersChanged {\n speakers: SpeakerInfo[];\n}\n\nexport interface RoomUpdate {\n room?: Room;\n}\n\nexport interface ConnectionQualityInfo {\n participantSid: string;\n quality: number;\n score: number;\n}\n\nexport interface ConnectionQualityUpdate {\n updates: ConnectionQualityInfo[];\n}\n\nexport interface StreamStateInfo {\n participantSid: string;\n trackSid: string;\n state: StreamState;\n}\n\nexport interface StreamStateUpdate {\n streamStates: StreamStateInfo[];\n}\n\nexport interface SubscribedQualityUpdate {\n trackSid: string;\n subscribedQualities: SubscribedQuality[];\n subscribedCodecs: SubscribedCodec[];\n}\n\nexport interface SubscribedQuality {\n quality: number;\n enabled: boolean;\n}\n\nexport interface SubscribedCodec {\n codec: string;\n qualities: SubscribedQuality[];\n}\n\nexport interface SubscriptionPermissionUpdate {\n participantSid: string;\n trackSid: string;\n allowed: boolean;\n}\n\n// ─── Encode / Decode ────────────────────────────────────────────────────────\n\n// Helper to write a nested message\nfunction writeMessage(writer: _m0.Writer, fieldNumber: number, encodeFn: (w: _m0.Writer) => _m0.Writer): void {\n encodeFn(writer.uint32((fieldNumber << 3) | 2).fork()).ldelim();\n}\n\nfunction writeString(writer: _m0.Writer, fieldNumber: number, value: string): void {\n if (value !== '') {\n writer.uint32((fieldNumber << 3) | 2).string(value);\n }\n}\n\nfunction writeInt32(writer: _m0.Writer, fieldNumber: number, value: number): void {\n if (value !== 0) {\n writer.uint32((fieldNumber << 3) | 0).int32(value);\n }\n}\n\nfunction writeUint32(writer: _m0.Writer, fieldNumber: number, value: number): void {\n if (value !== 0) {\n writer.uint32((fieldNumber << 3) | 0).uint32(value);\n }\n}\n\nfunction writeBool(writer: _m0.Writer, fieldNumber: number, value: boolean): void {\n if (value) {\n writer.uint32((fieldNumber << 3) | 0).bool(value);\n }\n}\n\n// ─── SessionDescription encode/decode ───────────────────────────────────────\n\nexport const SessionDescription = {\n encode(message: SessionDescription, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n writeString(writer, 1, message.type);\n writeString(writer, 2, message.sdp);\n return writer;\n },\n\n decode(input: _m0.Reader | Uint8Array, length?: number): SessionDescription {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: SessionDescription = { type: '', sdp: '' };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.type = reader.string(); break;\n case 2: message.sdp = reader.string(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\n// ─── TrickleRequest encode/decode ───────────────────────────────────────────\n\nexport const TrickleRequest = {\n encode(message: TrickleRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n writeString(writer, 1, message.candidateInit);\n writeInt32(writer, 2, message.target);\n return writer;\n },\n\n decode(input: _m0.Reader | Uint8Array, length?: number): TrickleRequest {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: TrickleRequest = { candidateInit: '', target: 0 };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.candidateInit = reader.string(); break;\n case 2: message.target = reader.int32() as SignalTarget; break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\n// ─── AddTrackRequest encode/decode ──────────────────────────────────────────\n\nexport const AddTrackRequest = {\n encode(message: AddTrackRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n writeString(writer, 1, message.cid);\n writeString(writer, 2, message.name);\n writeInt32(writer, 3, message.type);\n writeUint32(writer, 4, message.width);\n writeUint32(writer, 5, message.height);\n writeBool(writer, 6, message.muted);\n writeBool(writer, 7, message.disableDtx);\n writeInt32(writer, 8, message.source);\n writeString(writer, 10, message.sid);\n return writer;\n },\n\n decode(input: _m0.Reader | Uint8Array, length?: number): AddTrackRequest {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: AddTrackRequest = {\n cid: '', name: '', type: 0, width: 0, height: 0,\n muted: false, disableDtx: false, source: 0, layers: [], sid: '',\n };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.cid = reader.string(); break;\n case 2: message.name = reader.string(); break;\n case 3: message.type = reader.int32() as TrackType; break;\n case 4: message.width = reader.uint32(); break;\n case 5: message.height = reader.uint32(); break;\n case 6: message.muted = reader.bool(); break;\n case 7: message.disableDtx = reader.bool(); break;\n case 8: message.source = reader.int32() as TrackSource; break;\n case 10: message.sid = reader.string(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\n// ─── MuteTrackRequest encode/decode ─────────────────────────────────────────\n\nexport const MuteTrackRequest = {\n encode(message: MuteTrackRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n writeString(writer, 1, message.sid);\n writeBool(writer, 2, message.muted);\n return writer;\n },\n\n decode(input: _m0.Reader | Uint8Array, length?: number): MuteTrackRequest {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: MuteTrackRequest = { sid: '', muted: false };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.sid = reader.string(); break;\n case 2: message.muted = reader.bool(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\n// ─── LeaveRequest encode/decode ─────────────────────────────────────────────\n\nexport const LeaveRequest = {\n encode(message: LeaveRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n writeBool(writer, 1, message.canReconnect);\n writeInt32(writer, 2, message.reason);\n return writer;\n },\n\n decode(input: _m0.Reader | Uint8Array, length?: number): LeaveRequest {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: LeaveRequest = { canReconnect: false, reason: 0 };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.canReconnect = reader.bool(); break;\n case 2: message.reason = reader.int32() as DisconnectReason; break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\n// ─── UpdateSubscription encode/decode ───────────────────────────────────────\n\nexport const UpdateSubscription = {\n encode(message: UpdateSubscription, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n for (const v of message.trackSids) {\n writeString(writer, 1, v);\n }\n writeBool(writer, 2, message.subscribe);\n return writer;\n },\n\n decode(input: _m0.Reader | Uint8Array, length?: number): UpdateSubscription {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: UpdateSubscription = { trackSids: [], subscribe: false, participantTracks: [] };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.trackSids.push(reader.string()); break;\n case 2: message.subscribe = reader.bool(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\n// ─── JoinResponse decode ────────────────────────────────────────────────────\n\nconst Room_decode = (reader: _m0.Reader, length: number): Room => {\n const end = reader.pos + length;\n const msg: Room = {\n sid: '', name: '', emptyTimeout: 0, maxParticipants: 0,\n creationTime: 0, turnPassword: '', enabledCodecs: [],\n metadata: '', numParticipants: 0, activeRecording: false,\n };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: msg.sid = reader.string(); break;\n case 2: msg.name = reader.string(); break;\n case 3: msg.emptyTimeout = reader.uint32(); break;\n case 4: msg.maxParticipants = reader.uint32(); break;\n case 5: msg.creationTime = reader.int64() as unknown as number; break;\n case 6: msg.turnPassword = reader.string(); break;\n case 7: {\n const codec: Codec = { mime: '', fmtpLine: '' };\n const cEnd = reader.pos + reader.uint32();\n while (reader.pos < cEnd) {\n const cTag = reader.uint32();\n switch (cTag >>> 3) {\n case 1: codec.mime = reader.string(); break;\n case 2: codec.fmtpLine = reader.string(); break;\n default: reader.skipType(cTag & 7); break;\n }\n }\n msg.enabledCodecs.push(codec);\n break;\n }\n case 8: msg.metadata = reader.string(); break;\n case 9: msg.numParticipants = reader.uint32(); break;\n case 10: msg.activeRecording = reader.bool(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return msg;\n};\n\nconst ICEServer_decode = (reader: _m0.Reader, length: number): ICEServer => {\n const end = reader.pos + length;\n const msg: ICEServer = { urls: [], username: '', credential: '' };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: msg.urls.push(reader.string()); break;\n case 2: msg.username = reader.string(); break;\n case 3: msg.credential = reader.string(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return msg;\n};\n\nconst TrackInfo_decode = (reader: _m0.Reader, length: number): TrackInfo => {\n const end = reader.pos + length;\n const msg: TrackInfo = {\n sid: '', type: 0, name: '', muted: false, width: 0, height: 0,\n simulcast: false, disableDtx: false, source: 0, layers: [],\n mimeType: '', mid: '',\n };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: msg.sid = reader.string(); break;\n case 2: msg.type = reader.int32() as TrackType; break;\n case 3: msg.name = reader.string(); break;\n case 4: msg.muted = reader.bool(); break;\n case 5: msg.width = reader.uint32(); break;\n case 6: msg.height = reader.uint32(); break;\n case 7: msg.simulcast = reader.bool(); break;\n case 8: msg.disableDtx = reader.bool(); break;\n case 9: msg.source = reader.int32() as TrackSource; break;\n case 11: msg.mimeType = reader.string(); break;\n case 12: msg.mid = reader.string(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return msg;\n};\n\nconst ParticipantInfo_decode = (reader: _m0.Reader, length: number): ParticipantInfo => {\n const end = reader.pos + length;\n const msg: ParticipantInfo = {\n sid: '', identity: '', state: 0, tracks: [], metadata: '',\n joinedAt: 0, name: '', version: 0, region: '', isPublisher: false,\n };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: msg.sid = reader.string(); break;\n case 2: msg.identity = reader.string(); break;\n case 3: msg.state = reader.int32(); break;\n case 4: msg.tracks.push(TrackInfo_decode(reader, reader.uint32())); break;\n case 5: msg.metadata = reader.string(); break;\n case 6: msg.joinedAt = reader.int64() as unknown as number; break;\n case 7: msg.name = reader.string(); break;\n case 10: msg.version = reader.uint32(); break;\n case 11: {\n const pEnd = reader.pos + reader.uint32();\n const perm: import('./models').ParticipantPermission = {\n canSubscribe: false, canPublish: false,\n canPublishData: false, hidden: false, recorder: false,\n };\n while (reader.pos < pEnd) {\n const pTag = reader.uint32();\n switch (pTag >>> 3) {\n case 1: perm.canSubscribe = reader.bool(); break;\n case 2: perm.canPublish = reader.bool(); break;\n case 3: perm.canPublishData = reader.bool(); break;\n case 7: perm.hidden = reader.bool(); break;\n case 8: perm.recorder = reader.bool(); break;\n default: reader.skipType(pTag & 7); break;\n }\n }\n msg.permission = perm;\n break;\n }\n case 12: msg.region = reader.string(); break;\n case 13: msg.isPublisher = reader.bool(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return msg;\n};\n\nconst SpeakerInfo_decode = (reader: _m0.Reader, length: number): SpeakerInfo => {\n const end = reader.pos + length;\n const msg: SpeakerInfo = { sid: '', level: 0, active: false };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: msg.sid = reader.string(); break;\n case 2: msg.level = reader.float(); break;\n case 3: msg.active = reader.bool(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return msg;\n};\n\nexport const JoinResponse = {\n decode(input: _m0.Reader | Uint8Array, length?: number): JoinResponse {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: JoinResponse = {\n otherParticipants: [], serverVersion: '', iceServers: [],\n subscriberPrimary: false, alternativeUrl: '', serverRegion: '',\n pingTimeout: 0, pingInterval: 0,\n };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.room = Room_decode(reader, reader.uint32()); break;\n case 2: message.participant = ParticipantInfo_decode(reader, reader.uint32()); break;\n case 3: message.otherParticipants.push(ParticipantInfo_decode(reader, reader.uint32())); break;\n case 4: message.serverVersion = reader.string(); break;\n case 5: message.iceServers.push(ICEServer_decode(reader, reader.uint32())); break;\n case 6: message.subscriberPrimary = reader.bool(); break;\n case 7: message.alternativeUrl = reader.string(); break;\n case 9: message.serverRegion = reader.string(); break;\n case 10: message.pingTimeout = reader.int32(); break;\n case 11: message.pingInterval = reader.int32(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\nexport const TrackPublishedResponse = {\n decode(input: _m0.Reader | Uint8Array, length?: number): TrackPublishedResponse {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: TrackPublishedResponse = { cid: '' };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.cid = reader.string(); break;\n case 2: message.track = TrackInfo_decode(reader, reader.uint32()); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\nexport const ParticipantUpdate = {\n decode(input: _m0.Reader | Uint8Array, length?: number): ParticipantUpdate {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: ParticipantUpdate = { participants: [] };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.participants.push(ParticipantInfo_decode(reader, reader.uint32())); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\nexport const SpeakersChanged = {\n decode(input: _m0.Reader | Uint8Array, length?: number): SpeakersChanged {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: SpeakersChanged = { speakers: [] };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.speakers.push(SpeakerInfo_decode(reader, reader.uint32())); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\nexport const RoomUpdate = {\n decode(input: _m0.Reader | Uint8Array, length?: number): RoomUpdate {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: RoomUpdate = {};\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.room = Room_decode(reader, reader.uint32()); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\nexport const TrackUnpublishedResponse = {\n decode(input: _m0.Reader | Uint8Array, length?: number): TrackUnpublishedResponse {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: TrackUnpublishedResponse = { trackSid: '' };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.trackSid = reader.string(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\nexport const ConnectionQualityUpdate = {\n decode(input: _m0.Reader | Uint8Array, length?: number): ConnectionQualityUpdate {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: ConnectionQualityUpdate = { updates: [] };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: {\n const cEnd = reader.pos + reader.uint32();\n const info: ConnectionQualityInfo = { participantSid: '', quality: 0, score: 0 };\n while (reader.pos < cEnd) {\n const cTag = reader.uint32();\n switch (cTag >>> 3) {\n case 1: info.participantSid = reader.string(); break;\n case 2: info.quality = reader.int32(); break;\n case 3: info.score = reader.float(); break;\n default: reader.skipType(cTag & 7); break;\n }\n }\n message.updates.push(info);\n break;\n }\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\nexport const StreamStateUpdate = {\n decode(input: _m0.Reader | Uint8Array, length?: number): StreamStateUpdate {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: StreamStateUpdate = { streamStates: [] };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: {\n const sEnd = reader.pos + reader.uint32();\n const info: StreamStateInfo = { participantSid: '', trackSid: '', state: 0 };\n while (reader.pos < sEnd) {\n const sTag = reader.uint32();\n switch (sTag >>> 3) {\n case 1: info.participantSid = reader.string(); break;\n case 2: info.trackSid = reader.string(); break;\n case 3: info.state = reader.int32(); break;\n default: reader.skipType(sTag & 7); break;\n }\n }\n message.streamStates.push(info);\n break;\n }\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\n// ─── SignalRequest encode ───────────────────────────────────────────────────\n\nexport const SignalRequest = {\n encode(message: SignalRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n if (message.offer !== undefined) {\n writeMessage(writer, 1, (w) => SessionDescription.encode(message.offer!, w));\n }\n if (message.answer !== undefined) {\n writeMessage(writer, 2, (w) => SessionDescription.encode(message.answer!, w));\n }\n if (message.trickle !== undefined) {\n writeMessage(writer, 3, (w) => TrickleRequest.encode(message.trickle!, w));\n }\n if (message.addTrack !== undefined) {\n writeMessage(writer, 4, (w) => AddTrackRequest.encode(message.addTrack!, w));\n }\n if (message.mute !== undefined) {\n writeMessage(writer, 5, (w) => MuteTrackRequest.encode(message.mute!, w));\n }\n if (message.subscription !== undefined) {\n writeMessage(writer, 6, (w) => UpdateSubscription.encode(message.subscription!, w));\n }\n if (message.leave !== undefined) {\n writeMessage(writer, 8, (w) => LeaveRequest.encode(message.leave!, w));\n }\n if (message.ping !== undefined) {\n writer.uint32(72).int64(message.ping);\n }\n return writer;\n },\n};\n\n// ─── SignalResponse decode ──────────────────────────────────────────────────\n\nexport const SignalResponse = {\n decode(input: _m0.Reader | Uint8Array, length?: number): SignalResponse {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: SignalResponse = {};\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.join = JoinResponse.decode(reader, reader.uint32()); break;\n case 2: message.answer = SessionDescription.decode(reader, reader.uint32()); break;\n case 3: message.offer = SessionDescription.decode(reader, reader.uint32()); break;\n case 4: message.trickle = TrickleRequest.decode(reader, reader.uint32()); break;\n case 5: message.update = ParticipantUpdate.decode(reader, reader.uint32()); break;\n case 6: message.trackPublished = TrackPublishedResponse.decode(reader, reader.uint32()); break;\n case 8: message.leave = LeaveRequest.decode(reader, reader.uint32()); break;\n case 9: message.mute = MuteTrackRequest.decode(reader, reader.uint32()); break;\n case 10: message.speakersChanged = SpeakersChanged.decode(reader, reader.uint32()); break;\n case 11: message.roomUpdate = RoomUpdate.decode(reader, reader.uint32()); break;\n case 12: message.connectionQuality = ConnectionQualityUpdate.decode(reader, reader.uint32()); break;\n case 13: message.streamStateUpdate = StreamStateUpdate.decode(reader, reader.uint32()); break;\n case 15: message.refreshToken = reader.string(); break;\n case 17: message.trackUnpublished = TrackUnpublishedResponse.decode(reader, reader.uint32()); break;\n case 18: message.pong = reader.int64() as unknown as number; break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n","/**\n * Core protocol model types for dTelecom.\n * Manually defined to match github.com/dtelecom/protocol (dtelecom-db branch).\n * These mirror the types in livekit_models.proto.\n */\n\nimport * as _m0 from 'protobufjs/minimal';\n\n// ─── Enums ──────────────────────────────────────────────────────────────────\n\nexport enum TrackType {\n AUDIO = 0,\n VIDEO = 1,\n DATA = 2,\n}\n\nexport enum TrackSource {\n UNKNOWN = 0,\n CAMERA = 1,\n MICROPHONE = 2,\n SCREEN_SHARE = 3,\n SCREEN_SHARE_AUDIO = 4,\n}\n\nexport enum VideoQuality {\n LOW = 0,\n MEDIUM = 1,\n HIGH = 2,\n OFF = 3,\n}\n\nexport enum ParticipantInfo_State {\n JOINING = 0,\n JOINED = 1,\n ACTIVE = 2,\n DISCONNECTED = 3,\n}\n\nexport enum DataPacket_Kind {\n RELIABLE = 0,\n LOSSY = 1,\n}\n\nexport enum ConnectionQuality {\n POOR = 0,\n GOOD = 1,\n EXCELLENT = 2,\n}\n\nexport enum DisconnectReason {\n UNKNOWN_REASON = 0,\n CLIENT_INITIATED = 1,\n DUPLICATE_IDENTITY = 2,\n SERVER_SHUTDOWN = 3,\n PARTICIPANT_REMOVED = 4,\n ROOM_DELETED = 5,\n STATE_MISMATCH = 6,\n JOIN_FAILURE = 7,\n}\n\n// ─── Messages ───────────────────────────────────────────────────────────────\n\nexport interface Room {\n sid: string;\n name: string;\n emptyTimeout: number;\n maxParticipants: number;\n creationTime: number;\n turnPassword: string;\n enabledCodecs: Codec[];\n metadata: string;\n numParticipants: number;\n activeRecording: boolean;\n}\n\nexport interface Codec {\n mime: string;\n fmtpLine: string;\n}\n\nexport interface ParticipantPermission {\n canSubscribe: boolean;\n canPublish: boolean;\n canPublishData: boolean;\n hidden: boolean;\n recorder: boolean;\n}\n\nexport interface ParticipantInfo {\n sid: string;\n identity: string;\n state: ParticipantInfo_State;\n tracks: TrackInfo[];\n metadata: string;\n joinedAt: number;\n name: string;\n version: number;\n permission?: ParticipantPermission;\n region: string;\n isPublisher: boolean;\n}\n\nexport interface TrackInfo {\n sid: string;\n type: TrackType;\n name: string;\n muted: boolean;\n width: number;\n height: number;\n simulcast: boolean;\n disableDtx: boolean;\n source: TrackSource;\n layers: VideoLayer[];\n mimeType: string;\n mid: string;\n}\n\nexport interface VideoLayer {\n quality: VideoQuality;\n width: number;\n height: number;\n bitrate: number;\n ssrc: number;\n}\n\nexport interface DataPacket {\n kind: DataPacket_Kind;\n user?: UserPacket;\n speaker?: ActiveSpeakerUpdate;\n}\n\nexport interface UserPacket {\n participantSid: string;\n payload: Uint8Array;\n destinationSids: string[];\n topic?: string;\n}\n\nexport interface ActiveSpeakerUpdate {\n speakers: SpeakerInfo[];\n}\n\nexport interface SpeakerInfo {\n sid: string;\n level: number;\n active: boolean;\n}\n\nexport interface ParticipantTracks {\n participantSid: string;\n trackSids: string[];\n}\n\nexport interface ICEServer {\n urls: string[];\n username: string;\n credential: string;\n}\n\nexport interface ClientInfo {\n sdk: ClientInfo_SDK;\n version: string;\n protocol: number;\n os: string;\n osVersion: string;\n deviceModel: string;\n browser: string;\n browserVersion: string;\n address: string;\n network: string;\n}\n\nexport enum ClientInfo_SDK {\n UNKNOWN = 0,\n JS = 1,\n SWIFT = 2,\n ANDROID = 3,\n FLUTTER = 4,\n GO = 5,\n UNITY = 6,\n REACT_NATIVE = 7,\n RUST = 8,\n PYTHON = 9,\n CPP = 10,\n NODE = 11,\n}\n\n// ─── Encode / Decode helpers ────────────────────────────────────────────────\n\nexport const DataPacket = {\n encode(message: DataPacket, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n if (message.kind !== 0) {\n writer.uint32(8).int32(message.kind);\n }\n if (message.user !== undefined) {\n UserPacket.encode(message.user, writer.uint32(18).fork()).ldelim();\n }\n if (message.speaker !== undefined) {\n ActiveSpeakerUpdate.encode(message.speaker, writer.uint32(26).fork()).ldelim();\n }\n return writer;\n },\n\n decode(input: _m0.Reader | Uint8Array, length?: number): DataPacket {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: DataPacket = { kind: 0 };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1:\n message.kind = reader.int32() as DataPacket_Kind;\n break;\n case 2:\n message.user = UserPacket.decode(reader, reader.uint32());\n break;\n case 3:\n message.speaker = ActiveSpeakerUpdate.decode(reader, reader.uint32());\n break;\n default:\n reader.skipType(tag & 7);\n break;\n }\n }\n return message;\n },\n};\n\nexport const UserPacket = {\n encode(message: UserPacket, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n if (message.participantSid !== '') {\n writer.uint32(10).string(message.participantSid);\n }\n if (message.payload.length !== 0) {\n writer.uint32(18).bytes(message.payload);\n }\n for (const v of message.destinationSids) {\n writer.uint32(26).string(v);\n }\n if (message.topic !== undefined) {\n writer.uint32(34).string(message.topic);\n }\n return writer;\n },\n\n decode(input: _m0.Reader | Uint8Array, length?: number): UserPacket {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: UserPacket = {\n participantSid: '',\n payload: new Uint8Array(),\n destinationSids: [],\n };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1:\n message.participantSid = reader.string();\n break;\n case 2:\n message.payload = reader.bytes() as Uint8Array;\n break;\n case 3:\n message.destinationSids.push(reader.string());\n break;\n case 4:\n message.topic = reader.string();\n break;\n default:\n reader.skipType(tag & 7);\n break;\n }\n }\n return message;\n },\n};\n\nexport const ActiveSpeakerUpdate = {\n encode(message: ActiveSpeakerUpdate, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n for (const v of message.speakers) {\n SpeakerInfo.encode(v, writer.uint32(10).fork()).ldelim();\n }\n return writer;\n },\n\n decode(input: _m0.Reader | Uint8Array, length?: number): ActiveSpeakerUpdate {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: ActiveSpeakerUpdate = { speakers: [] };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1:\n message.speakers.push(SpeakerInfo.decode(reader, reader.uint32()));\n break;\n default:\n reader.skipType(tag & 7);\n break;\n }\n }\n return message;\n },\n};\n\nexport const SpeakerInfo = {\n encode(message: SpeakerInfo, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n if (message.sid !== '') {\n writer.uint32(10).string(message.sid);\n }\n if (message.level !== 0) {\n writer.uint32(21).float(message.level);\n }\n if (message.active) {\n writer.uint32(24).bool(message.active);\n }\n return writer;\n },\n\n decode(input: _m0.Reader | Uint8Array, length?: number): SpeakerInfo {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: SpeakerInfo = { sid: '', level: 0, active: false };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1:\n message.sid = reader.string();\n break;\n case 2:\n message.level = reader.float();\n break;\n case 3:\n message.active = reader.bool();\n break;\n default:\n reader.skipType(tag & 7);\n break;\n }\n }\n return message;\n },\n};\n","/**\n * Track classes — LocalAudioTrack, RemoteAudioTrack, TrackPublication.\n *\n * Tracks represent individual media streams within a room.\n */\n\nimport { MediaStreamTrack, RTCRtpTransceiver, RtpPacket, RtpHeader } from 'werift';\nimport { TypedEmitter } from './utils/events';\nimport { createLogger } from './utils/logger';\nimport { AudioSource } from './audio/audio-source';\nimport { AudioStream } from './audio/audio-stream';\nimport { TrackInfo, TrackType, TrackSource } from './proto/models';\nimport { OpusRtpPacketizer, OPUS_PAYLOAD_TYPE } from './audio/rtp-opus';\n\nconst log = createLogger('Track');\n\n// ─── Track Publication ──────────────────────────────────────────────────────\n\nexport interface TrackPublicationEvents {\n [key: string]: (...args: any[]) => void;\n muted: () => void;\n unmuted: () => void;\n}\n\nexport class TrackPublication extends TypedEmitter<TrackPublicationEvents> {\n sid: string;\n name: string;\n kind: TrackType;\n source: TrackSource;\n mimeType: string;\n muted: boolean;\n\n constructor(info: TrackInfo) {\n super();\n this.sid = info.sid;\n this.name = info.name;\n this.kind = info.type;\n this.source = info.source;\n this.mimeType = info.mimeType;\n this.muted = info.muted;\n }\n\n updateInfo(info: TrackInfo): void {\n const wasMuted = this.muted;\n this.sid = info.sid;\n this.name = info.name;\n this.kind = info.type;\n this.source = info.source;\n this.mimeType = info.mimeType;\n this.muted = info.muted;\n\n if (wasMuted !== info.muted) {\n this.emit(info.muted ? 'muted' : 'unmuted');\n }\n }\n}\n\nexport class LocalTrackPublication extends TrackPublication {\n track: LocalAudioTrack;\n\n constructor(info: TrackInfo, track: LocalAudioTrack) {\n super(info);\n this.track = track;\n }\n}\n\nexport class RemoteTrackPublication extends TrackPublication {\n track: RemoteAudioTrack | null = null;\n\n setTrack(track: RemoteAudioTrack | null): void {\n this.track = track;\n }\n}\n\n// ─── Local Audio Track ──────────────────────────────────────────────────────\n\nexport interface TrackPublishOptions {\n /** Track name (default: auto-generated) */\n name?: string;\n /** Audio source type (default: MICROPHONE) */\n source?: TrackSource;\n /** Disable DTX (Discontinuous Transmission) */\n disableDtx?: boolean;\n}\n\nexport class LocalAudioTrack {\n readonly name: string;\n readonly source: AudioSource;\n /** werift MediaStreamTrack used by the PeerConnection sender */\n readonly mediaTrack: MediaStreamTrack;\n private transceiver: RTCRtpTransceiver | null = null;\n private packetizer: OpusRtpPacketizer;\n private _cid: string;\n private _sid: string = '';\n\n private constructor(name: string, source: AudioSource) {\n this.name = name;\n this.source = source;\n this.mediaTrack = new MediaStreamTrack({ kind: 'audio' });\n this.packetizer = new OpusRtpPacketizer(0, OPUS_PAYLOAD_TYPE);\n this._cid = `track-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n }\n\n /** Create a local audio track from an AudioSource */\n static createAudioTrack(name: string, source: AudioSource): LocalAudioTrack {\n return new LocalAudioTrack(name, source);\n }\n\n /** Client-generated track ID (used before server assigns SID) */\n get cid(): string {\n return this._cid;\n }\n\n /** Server-assigned track SID */\n get sid(): string {\n return this._sid;\n }\n\n set sid(value: string) {\n this._sid = value;\n }\n\n /**\n * Set the RTP transceiver for sending audio.\n * Called internally by LocalParticipant after negotiation.\n */\n setTransceiver(transceiver: RTCRtpTransceiver): void {\n this.transceiver = transceiver;\n\n // Wire up AudioSource to send encoded Opus frames via RTP through the MediaStreamTrack.\n // werift's sender subscribes to mediaTrack.onReceiveRtp and transmits automatically.\n this.source.onEncodedFrame = (opusData: Buffer) => {\n if (this.mediaTrack.stopped) return;\n\n try {\n const info = this.packetizer.nextPacketInfo();\n const header = new RtpHeader();\n header.payloadType = OPUS_PAYLOAD_TYPE;\n header.sequenceNumber = info.sequenceNumber;\n header.timestamp = info.timestamp;\n header.ssrc = info.ssrc;\n header.marker = false;\n\n const packet = new RtpPacket(header, opusData);\n this.mediaTrack.writeRtp(packet);\n } catch (err) {\n log.error('Failed to send RTP via track', err);\n }\n };\n }\n\n /** Stop the track and release resources */\n stop(): void {\n this.source.flush();\n this.source.destroy();\n this.mediaTrack.stop();\n this.transceiver = null;\n }\n}\n\n// ─── Remote Audio Track ─────────────────────────────────────────────────────\n\nexport interface RemoteAudioTrackEvents {\n [key: string]: (...args: any[]) => void;\n audioFrame: () => void;\n ended: () => void;\n}\n\nexport class RemoteAudioTrack extends TypedEmitter<RemoteAudioTrackEvents> {\n readonly sid: string;\n readonly name: string;\n readonly mediaTrack: MediaStreamTrack;\n private _streams: AudioStream[] = [];\n\n constructor(sid: string, name: string, mediaTrack: MediaStreamTrack) {\n super();\n this.sid = sid;\n this.name = name;\n this.mediaTrack = mediaTrack;\n }\n\n /**\n * Create an AudioStream to consume decoded PCM16 frames from this track.\n * @param sampleRate Desired output sample rate (default: 16000 for STT)\n * @param channels Desired channels (default: 1)\n */\n createStream(sampleRate: number = 16000, channels: number = 1): AudioStream {\n const stream = new AudioStream(this.mediaTrack, sampleRate, channels);\n this._streams.push(stream);\n return stream;\n }\n\n /** Close all streams and release resources */\n stop(): void {\n for (const stream of this._streams) {\n stream.close();\n }\n this._streams = [];\n this.emit('ended');\n }\n}\n","/**\n * AudioFrame — PCM16 audio container.\n *\n * This is the primary audio type exposed to users.\n * All audio flowing in/out of the SDK uses this format.\n */\n\nexport class AudioFrame {\n /** PCM16 samples (interleaved if stereo) */\n readonly data: Int16Array;\n /** Sample rate in Hz (e.g. 16000, 48000) */\n readonly sampleRate: number;\n /** Number of channels (1 = mono, 2 = stereo) */\n readonly channels: number;\n /** Number of samples per channel */\n readonly samplesPerChannel: number;\n\n constructor(data: Int16Array, sampleRate: number, channels: number, samplesPerChannel: number) {\n this.data = data;\n this.sampleRate = sampleRate;\n this.channels = channels;\n this.samplesPerChannel = samplesPerChannel;\n }\n\n /** Create an empty (silent) AudioFrame */\n static create(sampleRate: number, channels: number, samplesPerChannel: number): AudioFrame {\n const data = new Int16Array(samplesPerChannel * channels);\n return new AudioFrame(data, sampleRate, channels, samplesPerChannel);\n }\n\n /** Duration of this frame in seconds */\n get duration(): number {\n return this.samplesPerChannel / this.sampleRate;\n }\n\n /** Duration of this frame in milliseconds */\n get durationMs(): number {\n return (this.samplesPerChannel / this.sampleRate) * 1000;\n }\n\n /** Total number of samples (channels * samplesPerChannel) */\n get totalSamples(): number {\n return this.data.length;\n }\n\n /** Convert to Buffer (for Opus encoder or file I/O) */\n toBuffer(): Buffer {\n return Buffer.from(this.data.buffer, this.data.byteOffset, this.data.byteLength);\n }\n\n /** Create AudioFrame from a Buffer of PCM16 data */\n static fromBuffer(buffer: Buffer, sampleRate: number, channels: number): AudioFrame {\n const data = new Int16Array(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength / 2,\n );\n const samplesPerChannel = data.length / channels;\n return new AudioFrame(data, sampleRate, channels, samplesPerChannel);\n }\n\n /** Clone this AudioFrame */\n clone(): AudioFrame {\n return new AudioFrame(\n new Int16Array(this.data),\n this.sampleRate,\n this.channels,\n this.samplesPerChannel,\n );\n }\n}\n","/**\n * Opus encoder wrapper around @discordjs/opus.\n *\n * Encodes PCM16 audio (48kHz) into Opus frames.\n */\n\nimport { createLogger } from '../utils/logger';\n\nconst log = createLogger('OpusEncoder');\n\n// Opus constants\nexport const OPUS_SAMPLE_RATE = 48000;\nexport const OPUS_FRAME_DURATION_MS = 20;\nexport const OPUS_FRAME_SIZE = OPUS_SAMPLE_RATE * OPUS_FRAME_DURATION_MS / 1000; // 960\n\nlet OpusEncoderClass: any = null;\n\nfunction getOpusEncoder(): any {\n if (!OpusEncoderClass) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const opus = require('@discordjs/opus');\n OpusEncoderClass = opus.OpusEncoder;\n } catch {\n try {\n // Fallback to opusscript (WASM)\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const OpusScript = require('opusscript');\n OpusEncoderClass = OpusScript;\n } catch {\n throw new Error(\n 'No Opus library found. Install @discordjs/opus (recommended) or opusscript (WASM fallback).',\n );\n }\n }\n }\n return OpusEncoderClass;\n}\n\nexport class OpusEncoder {\n private encoder: any;\n private readonly channels: number;\n\n /**\n * Create an Opus encoder.\n * @param sampleRate Must be 48000 (Opus native rate)\n * @param channels Number of channels (1 = mono, 2 = stereo)\n * @param bitrate Target bitrate in bps (default: 64000)\n */\n constructor(sampleRate: number = OPUS_SAMPLE_RATE, channels: number = 1, bitrate: number = 64000) {\n if (sampleRate !== OPUS_SAMPLE_RATE) {\n throw new Error(`Opus encoder requires ${OPUS_SAMPLE_RATE}Hz, got ${sampleRate}Hz. Resample first.`);\n }\n this.channels = channels;\n\n const Encoder = getOpusEncoder();\n this.encoder = new Encoder(sampleRate, channels);\n\n // Set bitrate if the encoder supports it\n if (typeof this.encoder.setBitrate === 'function') {\n this.encoder.setBitrate(bitrate);\n }\n\n log.debug(`Created Opus encoder: ${sampleRate}Hz, ${channels}ch, ${bitrate}bps`);\n }\n\n /**\n * Encode a PCM16 frame to Opus.\n * @param pcm PCM16 samples (Int16Array or Buffer). Must be exactly OPUS_FRAME_SIZE * channels samples.\n * @returns Opus-encoded bytes\n */\n encode(pcm: Buffer | Int16Array): Buffer {\n const buf = pcm instanceof Int16Array\n ? Buffer.from(pcm.buffer, pcm.byteOffset, pcm.byteLength)\n : pcm;\n return this.encoder.encode(buf, OPUS_FRAME_SIZE);\n }\n\n /** Clean up native resources */\n destroy(): void {\n if (this.encoder && typeof this.encoder.delete === 'function') {\n this.encoder.delete();\n }\n this.encoder = null;\n }\n}\n","/**\n * Opus decoder using opusscript (WASM).\n *\n * @discordjs/opus v0.9.0 segfaults when decoding SILK or hybrid mode\n * Opus frames (TOC configs < 16). WebRTC browsers switch to these modes\n * when bitrate estimation drops below ~52kbps. opusscript (WASM) handles\n * all Opus modes correctly and cannot segfault.\n *\n * @discordjs/opus is still used for encoding (CELT-only at 64kbps) where\n * it works reliably.\n */\n\nimport { createLogger } from '../utils/logger';\nimport { OPUS_SAMPLE_RATE, OPUS_FRAME_SIZE } from './opus-encoder';\n\nconst log = createLogger('OpusDecoder');\n\nlet OpusDecoderClass: any = null;\n\nfunction getOpusDecoder(): any {\n if (!OpusDecoderClass) {\n try {\n OpusDecoderClass = require('opusscript');\n } catch {\n throw new Error(\n 'opusscript is required for Opus decoding. Install it: npm install opusscript',\n );\n }\n }\n return OpusDecoderClass;\n}\n\nexport class OpusDecoder {\n private decoder: any;\n private readonly channels: number;\n\n /**\n * Create an Opus decoder.\n * @param sampleRate Must be 48000 (Opus native rate)\n * @param channels Number of channels (1 = mono, 2 = stereo)\n */\n constructor(sampleRate: number = OPUS_SAMPLE_RATE, channels: number = 1) {\n if (sampleRate !== OPUS_SAMPLE_RATE) {\n throw new Error(`Opus decoder requires ${OPUS_SAMPLE_RATE}Hz, got ${sampleRate}Hz`);\n }\n this.channels = channels;\n\n const Decoder = getOpusDecoder();\n this.decoder = new Decoder(sampleRate, channels);\n\n log.debug(`Created Opus decoder: ${sampleRate}Hz, ${channels}ch`);\n }\n\n /**\n * Decode an Opus frame to PCM16.\n * @param opus Opus-encoded bytes\n * @returns PCM16 samples as Buffer (OPUS_FRAME_SIZE * channels * 2 bytes)\n */\n decode(opus: Buffer): Buffer {\n return this.decoder.decode(opus);\n }\n\n /**\n * Decode an Opus frame to Int16Array.\n * @param opus Opus-encoded bytes\n * @returns PCM16 samples\n */\n decodeToInt16Array(opus: Buffer): Int16Array {\n const decoded = this.decode(opus);\n return new Int16Array(\n decoded.buffer,\n decoded.byteOffset,\n decoded.byteLength / 2,\n );\n }\n\n /** Generate a silence frame (packet loss concealment) */\n decodeMissing(): Buffer {\n return Buffer.alloc(OPUS_FRAME_SIZE * this.channels * 2);\n }\n\n /** Clean up resources */\n destroy(): void {\n if (this.decoder && typeof this.decoder.delete === 'function') {\n this.decoder.delete();\n }\n this.decoder = null;\n }\n}\n","/**\n * RTP packetizer and depacketizer for Opus audio.\n *\n * Opus in RTP follows RFC 7587:\n * - Payload type: dynamic (typically 111)\n * - Clock rate: 48000\n * - One Opus frame per RTP packet (no aggregation for 20ms frames)\n *\n * werift handles RTP framing and SRTP, but we need to:\n * - Set correct timestamps (increment by frame_size per packet)\n * - Set correct payload type\n * - Handle sequence numbers\n */\n\nimport { createLogger } from '../utils/logger';\nimport { OPUS_SAMPLE_RATE, OPUS_FRAME_SIZE } from './opus-encoder';\n\nconst log = createLogger('RTP-Opus');\n\n/** Standard Opus RTP payload type */\nexport const OPUS_PAYLOAD_TYPE = 111;\n\n/** RTP clock rate for Opus (always 48000) */\nexport const OPUS_CLOCK_RATE = OPUS_SAMPLE_RATE;\n\n/** RTP timestamp increment per 20ms Opus frame */\nexport const OPUS_TIMESTAMP_INCREMENT = OPUS_FRAME_SIZE; // 960\n\n/**\n * Tracks RTP sequence numbers and timestamps for an outgoing Opus stream.\n */\nexport class OpusRtpPacketizer {\n private sequenceNumber: number;\n private timestamp: number;\n private ssrc: number;\n readonly payloadType: number;\n\n constructor(ssrc: number = 0, payloadType: number = OPUS_PAYLOAD_TYPE) {\n // Start with random values per RFC 3550\n this.sequenceNumber = Math.floor(Math.random() * 0xFFFF);\n this.timestamp = Math.floor(Math.random() * 0xFFFFFFFF);\n this.ssrc = ssrc;\n this.payloadType = payloadType;\n }\n\n /**\n * Get the next RTP header values for an Opus frame.\n * Call this for each 20ms frame to get incrementing seq/ts.\n */\n nextPacketInfo(): { sequenceNumber: number; timestamp: number; ssrc: number } {\n const info = {\n sequenceNumber: this.sequenceNumber & 0xFFFF,\n timestamp: this.timestamp >>> 0,\n ssrc: this.ssrc,\n };\n\n this.sequenceNumber = (this.sequenceNumber + 1) & 0xFFFF;\n this.timestamp = (this.timestamp + OPUS_TIMESTAMP_INCREMENT) >>> 0;\n\n return info;\n }\n\n /** Reset the packetizer state */\n reset(): void {\n this.sequenceNumber = Math.floor(Math.random() * 0xFFFF);\n this.timestamp = Math.floor(Math.random() * 0xFFFFFFFF);\n }\n}\n\n/**\n * Tracks and reorders incoming Opus RTP packets.\n * Detects packet loss and provides frames in order.\n */\nexport class OpusRtpDepacketizer {\n private lastSequenceNumber: number = -1;\n private lastTimestamp: number = -1;\n private lostPackets: number = 0;\n\n /**\n * Process an incoming RTP packet containing an Opus frame.\n * Returns the Opus payload and metadata.\n */\n processPacket(payload: Buffer, sequenceNumber: number, timestamp: number): {\n opusFrame: Buffer;\n lost: number;\n isFirst: boolean;\n } {\n let lost = 0;\n const isFirst = this.lastSequenceNumber === -1;\n\n if (!isFirst) {\n const expectedSeq = (this.lastSequenceNumber + 1) & 0xFFFF;\n if (sequenceNumber !== expectedSeq) {\n // Calculate lost packets (handle wraparound)\n if (sequenceNumber > this.lastSequenceNumber) {\n lost = sequenceNumber - this.lastSequenceNumber - 1;\n } else {\n lost = (0xFFFF - this.lastSequenceNumber) + sequenceNumber;\n }\n this.lostPackets += lost;\n if (lost > 0) {\n log.debug(`Lost ${lost} packets (seq ${this.lastSequenceNumber} → ${sequenceNumber})`);\n }\n }\n }\n\n this.lastSequenceNumber = sequenceNumber;\n this.lastTimestamp = timestamp;\n\n return {\n opusFrame: payload,\n lost,\n isFirst,\n };\n }\n\n /** Total packets lost since creation */\n get totalLost(): number {\n return this.lostPackets;\n }\n\n /** Reset depacketizer state */\n reset(): void {\n this.lastSequenceNumber = -1;\n this.lastTimestamp = -1;\n this.lostPackets = 0;\n }\n}\n","/**\n * Audio resampler for converting between sample rates.\n *\n * Supports integer-ratio resampling (e.g. 48kHz ↔ 16kHz = 3:1).\n * Uses linear interpolation for downsampling and zero-fill + interpolation\n * for upsampling. Adequate quality for speech audio.\n */\n\n/**\n * Downsample PCM16 from a higher sample rate to a lower sample rate.\n * Supports integer-ratio downsampling (e.g. 48000 → 16000 = 3:1).\n *\n * Uses simple averaging of N samples → 1 output sample (anti-alias filter).\n */\nexport function downsample(\n input: Int16Array,\n fromRate: number,\n toRate: number,\n channels: number = 1,\n): Int16Array {\n if (fromRate === toRate) {\n return new Int16Array(input);\n }\n\n if (fromRate < toRate) {\n throw new Error(`downsample: fromRate (${fromRate}) must be >= toRate (${toRate})`);\n }\n\n const ratio = fromRate / toRate;\n if (!Number.isInteger(ratio)) {\n // Non-integer ratio — use linear interpolation\n return resampleLinear(input, fromRate, toRate, channels);\n }\n\n const inputSamplesPerChannel = input.length / channels;\n const outputSamplesPerChannel = Math.floor(inputSamplesPerChannel / ratio);\n const output = new Int16Array(outputSamplesPerChannel * channels);\n\n for (let ch = 0; ch < channels; ch++) {\n for (let i = 0; i < outputSamplesPerChannel; i++) {\n // Average `ratio` input samples to produce 1 output sample\n let sum = 0;\n for (let j = 0; j < ratio; j++) {\n sum += input[(i * ratio + j) * channels + ch];\n }\n output[i * channels + ch] = Math.round(sum / ratio);\n }\n }\n\n return output;\n}\n\n/**\n * Upsample PCM16 from a lower sample rate to a higher sample rate.\n * Supports integer-ratio upsampling (e.g. 16000 → 48000 = 1:3).\n *\n * Uses linear interpolation between samples.\n */\nexport function upsample(\n input: Int16Array,\n fromRate: number,\n toRate: number,\n channels: number = 1,\n): Int16Array {\n if (fromRate === toRate) {\n return new Int16Array(input);\n }\n\n if (fromRate > toRate) {\n throw new Error(`upsample: fromRate (${fromRate}) must be <= toRate (${toRate})`);\n }\n\n const ratio = toRate / fromRate;\n if (!Number.isInteger(ratio)) {\n return resampleLinear(input, fromRate, toRate, channels);\n }\n\n const inputSamplesPerChannel = input.length / channels;\n const outputSamplesPerChannel = inputSamplesPerChannel * ratio;\n const output = new Int16Array(outputSamplesPerChannel * channels);\n\n for (let ch = 0; ch < channels; ch++) {\n for (let i = 0; i < inputSamplesPerChannel; i++) {\n const currentSample = input[i * channels + ch];\n const nextSample = i + 1 < inputSamplesPerChannel\n ? input[(i + 1) * channels + ch]\n : currentSample;\n\n // Linear interpolation between current and next sample\n for (let j = 0; j < ratio; j++) {\n const t = j / ratio;\n const interpolated = currentSample + (nextSample - currentSample) * t;\n output[(i * ratio + j) * channels + ch] = Math.round(interpolated);\n }\n }\n }\n\n return output;\n}\n\n/**\n * General linear interpolation resampler for non-integer ratios.\n */\nfunction resampleLinear(\n input: Int16Array,\n fromRate: number,\n toRate: number,\n channels: number,\n): Int16Array {\n const inputSamplesPerChannel = input.length / channels;\n const outputSamplesPerChannel = Math.round(inputSamplesPerChannel * toRate / fromRate);\n const output = new Int16Array(outputSamplesPerChannel * channels);\n const ratio = fromRate / toRate;\n\n for (let ch = 0; ch < channels; ch++) {\n for (let i = 0; i < outputSamplesPerChannel; i++) {\n const srcPos = i * ratio;\n const srcIndex = Math.floor(srcPos);\n const frac = srcPos - srcIndex;\n\n const s0 = srcIndex < inputSamplesPerChannel\n ? input[srcIndex * channels + ch]\n : 0;\n const s1 = srcIndex + 1 < inputSamplesPerChannel\n ? input[(srcIndex + 1) * channels + ch]\n : s0;\n\n output[i * channels + ch] = Math.round(s0 + (s1 - s0) * frac);\n }\n }\n\n return output;\n}\n\n/**\n * Resample to any target rate (auto-detects up/downsample).\n */\nexport function resample(\n input: Int16Array,\n fromRate: number,\n toRate: number,\n channels: number = 1,\n): Int16Array {\n if (fromRate === toRate) return new Int16Array(input);\n if (fromRate > toRate) return downsample(input, fromRate, toRate, channels);\n return upsample(input, fromRate, toRate, channels);\n}\n","/**\n * Async queue for passing items between producer and consumer.\n * Implements AsyncIterable for for-await-of consumption.\n */\nexport class AsyncQueue<T> implements AsyncIterable<T> {\n private buffer: T[] = [];\n private resolvers: Array<(result: IteratorResult<T>) => void> = [];\n private closed = false;\n\n /** Push an item into the queue. */\n push(item: T): void {\n if (this.closed) return;\n\n if (this.resolvers.length > 0) {\n const resolve = this.resolvers.shift()!;\n resolve({ value: item, done: false });\n } else {\n this.buffer.push(item);\n }\n }\n\n /** Close the queue. Pending consumers receive done. */\n close(): void {\n this.closed = true;\n for (const resolve of this.resolvers) {\n resolve({ value: undefined as any, done: true });\n }\n this.resolvers.length = 0;\n }\n\n /** Number of buffered items. */\n get size(): number {\n return this.buffer.length;\n }\n\n /** Whether the queue is closed. */\n get isClosed(): boolean {\n return this.closed;\n }\n\n [Symbol.asyncIterator](): AsyncIterator<T> {\n return {\n next: (): Promise<IteratorResult<T>> => {\n if (this.buffer.length > 0) {\n return Promise.resolve({ value: this.buffer.shift()!, done: false });\n }\n\n if (this.closed) {\n return Promise.resolve({ value: undefined as any, done: true });\n }\n\n return new Promise<IteratorResult<T>>((resolve) => {\n this.resolvers.push(resolve);\n });\n },\n };\n }\n}\n","/**\n * AudioStream — async iterable stream of decoded audio frames\n * from a remote participant's audio track.\n *\n * Handles:\n * - RTP depacketization\n * - Opus decoding → PCM16 @ 48kHz\n * - Resampling to desired output rate (e.g. 16kHz for STT)\n * - Packet loss concealment\n */\n\nimport { MediaStreamTrack, RtpPacket } from 'werift';\nimport { AudioFrame } from './audio-frame';\nimport { OpusDecoder } from './opus-decoder';\nimport { OPUS_SAMPLE_RATE, OPUS_FRAME_SIZE } from './opus-encoder';\nimport { OpusRtpDepacketizer } from './rtp-opus';\nimport { downsample } from './resampler';\nimport { AsyncQueue } from '../utils/queue';\nimport { createLogger } from '../utils/logger';\n\nconst log = createLogger('AudioStream');\n\nexport class AudioStream implements AsyncIterable<AudioFrame> {\n private decoder: OpusDecoder | null = null;\n private depacketizer: OpusRtpDepacketizer;\n private queue: AsyncQueue<AudioFrame>;\n private readonly outputSampleRate: number;\n private readonly outputChannels: number;\n private track: MediaStreamTrack | null = null;\n private _closed = false;\n\n /**\n * @param track The remote audio track to stream from\n * @param sampleRate Desired output sample rate (default: 16000 for STT)\n * @param channels Desired output channels (default: 1 = mono)\n */\n constructor(track: MediaStreamTrack, sampleRate: number = 16000, channels: number = 1) {\n this.outputSampleRate = sampleRate;\n this.outputChannels = channels;\n this.depacketizer = new OpusRtpDepacketizer();\n this.queue = new AsyncQueue<AudioFrame>();\n this.track = track;\n this.start();\n }\n\n get closed(): boolean {\n return this._closed;\n }\n\n /** Close the stream and release resources */\n close(): void {\n if (this._closed) return;\n this._closed = true;\n this.queue.close();\n\n if (this.decoder) {\n this.decoder.destroy();\n this.decoder = null;\n }\n\n this.track = null;\n log.debug('AudioStream closed');\n }\n\n [Symbol.asyncIterator](): AsyncIterator<AudioFrame> {\n return this.queue[Symbol.asyncIterator]();\n }\n\n private start(): void {\n if (!this.track) return;\n\n // Listen for RTP packets on the track\n this.track.onReceiveRtp.subscribe((rtpPacket: RtpPacket) => {\n if (this._closed) return;\n\n try {\n this.processRtpPacket(rtpPacket);\n } catch (err) {\n log.error('Failed to process RTP packet', err);\n }\n });\n\n // Track ended\n this.track.onReceiveRtp.once(() => {\n // Note: werift doesn't have a clean \"track ended\" event,\n // we rely on the Room/Participant layer to call close()\n });\n\n log.debug(`AudioStream started, output: ${this.outputSampleRate}Hz ${this.outputChannels}ch`);\n }\n\n private processRtpPacket(rtp: RtpPacket): void {\n // Skip empty payloads\n if (!rtp.payload || rtp.payload.length === 0) {\n return;\n }\n\n // Ensure payload is a proper Buffer copy (werift may reuse internal buffers)\n const payloadCopy = Buffer.from(rtp.payload);\n\n // Skip suspiciously large payloads (not Opus)\n if (payloadCopy.length > 1500) {\n log.warn(`Skipping oversized RTP payload: ${payloadCopy.length} bytes`);\n return;\n }\n\n // Lazy init decoder\n if (!this.decoder) {\n this.decoder = new OpusDecoder(OPUS_SAMPLE_RATE, this.outputChannels);\n }\n\n const { opusFrame, lost } = this.depacketizer.processPacket(\n payloadCopy,\n rtp.header.sequenceNumber,\n rtp.header.timestamp,\n );\n\n // Handle packet loss — generate silence frames (PLC via null can segfault native addon)\n for (let i = 0; i < lost && i < 3; i++) {\n const silence = Buffer.alloc(OPUS_FRAME_SIZE * this.outputChannels * 2);\n this.emitFrame(silence);\n }\n\n // Decode the Opus frame\n if (opusFrame.length < 1) {\n return;\n }\n\n try {\n // Defensive copy — werift may reuse internal UDP buffers\n const opusCopy = Buffer.alloc(opusFrame.length);\n opusFrame.copy(opusCopy);\n const pcmBuffer = this.decoder.decode(opusCopy);\n this.emitFrame(pcmBuffer);\n } catch (err) {\n log.error(`Opus decode failed (${opusFrame.length} bytes)`, err);\n }\n }\n\n private emitFrame(pcm48k: Buffer): void {\n // Convert Buffer to Int16Array\n let samples = new Int16Array(\n pcm48k.buffer,\n pcm48k.byteOffset,\n pcm48k.byteLength / 2,\n );\n\n // Resample to desired output rate\n if (this.outputSampleRate !== OPUS_SAMPLE_RATE) {\n samples = downsample(samples, OPUS_SAMPLE_RATE, this.outputSampleRate, this.outputChannels);\n }\n\n const samplesPerChannel = samples.length / this.outputChannels;\n const frame = new AudioFrame(samples, this.outputSampleRate, this.outputChannels, samplesPerChannel);\n this.queue.push(frame);\n }\n}\n","/**\n * Participant classes — LocalParticipant and RemoteParticipant.\n *\n * Manages participant state, track publications, and data messaging.\n */\n\nimport { TypedEmitter } from './utils/events';\nimport { createLogger } from './utils/logger';\nimport { RTCEngine } from './engine';\nimport {\n LocalAudioTrack,\n RemoteAudioTrack,\n TrackPublication,\n LocalTrackPublication,\n RemoteTrackPublication,\n TrackPublishOptions,\n} from './track';\nimport {\n ParticipantInfo,\n ParticipantInfo_State,\n TrackInfo,\n TrackType,\n TrackSource,\n DataPacket,\n DataPacket_Kind,\n UserPacket,\n} from './proto/models';\nimport { TrackPublishedResponse } from './proto/signal';\nimport { MediaStreamTrack } from 'werift';\n\nconst log = createLogger('Participant');\n\n// ─── Base Participant ───────────────────────────────────────────────────────\n\nexport interface ParticipantEvents {\n [key: string]: (...args: any[]) => void;\n trackPublished: (publication: TrackPublication) => void;\n trackUnpublished: (publication: TrackPublication) => void;\n metadataChanged: (metadata: string) => void;\n}\n\nexport abstract class Participant extends TypedEmitter<ParticipantEvents> {\n sid: string;\n identity: string;\n name: string;\n metadata: string;\n state: ParticipantInfo_State;\n\n protected _trackPublications = new Map<string, TrackPublication>();\n\n constructor(sid: string, identity: string, name: string = '', metadata: string = '') {\n super();\n this.sid = sid;\n this.identity = identity;\n this.name = name;\n this.metadata = metadata;\n this.state = ParticipantInfo_State.JOINING;\n }\n\n get trackPublications(): Map<string, TrackPublication> {\n return this._trackPublications;\n }\n\n /** Update participant info from server */\n updateInfo(info: ParticipantInfo): void {\n const metadataChanged = this.metadata !== info.metadata;\n this.sid = info.sid;\n this.identity = info.identity;\n this.name = info.name;\n this.metadata = info.metadata;\n this.state = info.state;\n\n if (metadataChanged) {\n this.emit('metadataChanged', info.metadata);\n }\n }\n}\n\n// ─── Local Participant ──────────────────────────────────────────────────────\n\nexport interface DataPublishOptions {\n /** Data packet kind (default: RELIABLE) */\n kind?: DataPacket_Kind;\n /** Destination participant SIDs (empty = broadcast to all) */\n destinationSids?: string[];\n /** Topic for the data message */\n topic?: string;\n}\n\nexport class LocalParticipant extends Participant {\n private engine: RTCEngine;\n private publishedTracks = new Map<string, LocalAudioTrack>();\n\n constructor(engine: RTCEngine, sid: string, identity: string, name: string = '', metadata: string = '') {\n super(sid, identity, name, metadata);\n this.engine = engine;\n }\n\n /**\n * Publish an audio track to the room.\n *\n * Flow:\n * 1. Send AddTrackRequest to server\n * 2. Wait for TrackPublishedResponse (server assigns SID)\n * 3. Add transceiver to publisher PeerConnection\n * 4. Negotiate SDP\n */\n async publishTrack(track: LocalAudioTrack, options?: TrackPublishOptions): Promise<LocalTrackPublication> {\n const name = options?.name ?? track.name;\n const source = options?.source ?? TrackSource.MICROPHONE;\n const disableDtx = options?.disableDtx ?? false;\n\n log.info(`Publishing track \"${name}\" (cid=${track.cid})`);\n\n // Step 1: Request track publication from server\n const response = await this.engine.requestPublishTrack(\n track.cid,\n name,\n TrackType.AUDIO,\n source,\n { disableDtx },\n );\n\n if (!response.track) {\n throw new Error('Server did not return track info');\n }\n\n // Step 2: Set server-assigned SID\n track.sid = response.track.sid;\n log.debug(`Track published: cid=${track.cid}, sid=${track.sid}`);\n\n // Step 3: Add transceiver to publisher PC with the media track\n const transceiver = await this.engine.addTransceiver(track.mediaTrack);\n track.setTransceiver(transceiver);\n\n // Step 4: Negotiate\n await this.engine.negotiate();\n\n // Create publication\n const publication = new LocalTrackPublication(response.track, track);\n this._trackPublications.set(response.track.sid, publication);\n this.publishedTracks.set(track.cid, track);\n\n this.emit('trackPublished', publication);\n return publication;\n }\n\n /**\n * Unpublish an audio track from the room.\n */\n async unpublishTrack(track: LocalAudioTrack): Promise<void> {\n log.info(`Unpublishing track \"${track.name}\" (sid=${track.sid})`);\n\n track.stop();\n this._trackPublications.delete(track.sid);\n this.publishedTracks.delete(track.cid);\n\n // Re-negotiate to remove the track\n await this.engine.negotiate();\n\n this.emit('trackUnpublished', new TrackPublication({\n sid: track.sid,\n name: track.name,\n type: TrackType.AUDIO,\n source: TrackSource.MICROPHONE,\n muted: false,\n width: 0,\n height: 0,\n simulcast: false,\n disableDtx: false,\n layers: [],\n mimeType: 'audio/opus',\n mid: '',\n }));\n }\n\n /**\n * Publish data to the room.\n *\n * @param data The data payload\n * @param options Delivery options (kind, destinations, topic)\n */\n async publishData(data: Uint8Array, options: DataPublishOptions = {}): Promise<void> {\n const kind = options.kind ?? DataPacket_Kind.RELIABLE;\n const destinationSids = options.destinationSids ?? [];\n const topic = options.topic;\n\n const packet: DataPacket = {\n kind,\n user: {\n participantSid: this.sid,\n payload: data,\n destinationSids,\n topic,\n },\n };\n\n const encoded = DataPacket.encode(packet).finish();\n const channelKind = kind === DataPacket_Kind.RELIABLE ? 'reliable' : 'lossy';\n this.engine.sendData(new Uint8Array(encoded), channelKind);\n }\n}\n\n// ─── Remote Participant ─────────────────────────────────────────────────────\n\nexport interface RemoteParticipantEvents {\n [key: string]: (...args: any[]) => void;\n trackPublished: (publication: TrackPublication) => void;\n trackUnpublished: (publication: TrackPublication) => void;\n metadataChanged: (metadata: string) => void;\n trackSubscribed: (track: RemoteAudioTrack, publication: RemoteTrackPublication) => void;\n trackUnsubscribed: (track: RemoteAudioTrack, publication: RemoteTrackPublication) => void;\n}\n\nexport class RemoteParticipant extends TypedEmitter<RemoteParticipantEvents> {\n sid: string;\n identity: string;\n name: string;\n metadata: string;\n state: ParticipantInfo_State;\n\n private _trackPublications = new Map<string, RemoteTrackPublication>();\n private _audioTracks = new Map<string, RemoteAudioTrack>();\n\n constructor(info: ParticipantInfo) {\n super();\n this.sid = info.sid;\n this.identity = info.identity;\n this.name = info.name;\n this.metadata = info.metadata;\n this.state = info.state;\n\n // Initialize track publications from info\n for (const trackInfo of info.tracks) {\n const pub = new RemoteTrackPublication(trackInfo);\n this._trackPublications.set(trackInfo.sid, pub);\n }\n }\n\n get trackPublications(): Map<string, RemoteTrackPublication> {\n return this._trackPublications;\n }\n\n get audioTracks(): Map<string, RemoteAudioTrack> {\n return this._audioTracks;\n }\n\n /** Update participant info from server */\n updateInfo(info: ParticipantInfo): void {\n const metadataChanged = this.metadata !== info.metadata;\n this.sid = info.sid;\n this.identity = info.identity;\n this.name = info.name;\n this.metadata = info.metadata;\n this.state = info.state;\n\n // Update existing publications and add new ones\n const activeSids = new Set<string>();\n for (const trackInfo of info.tracks) {\n activeSids.add(trackInfo.sid);\n const existing = this._trackPublications.get(trackInfo.sid);\n if (existing) {\n existing.updateInfo(trackInfo);\n } else {\n const pub = new RemoteTrackPublication(trackInfo);\n this._trackPublications.set(trackInfo.sid, pub);\n this.emit('trackPublished', pub);\n }\n }\n\n // Remove publications that are no longer in the list\n for (const [sid, pub] of this._trackPublications) {\n if (!activeSids.has(sid)) {\n this._trackPublications.delete(sid);\n if (pub.track) {\n this.removeTrack(sid);\n }\n this.emit('trackUnpublished', pub);\n }\n }\n\n if (metadataChanged) {\n this.emit('metadataChanged', info.metadata);\n }\n }\n\n /**\n * Called when a remote media track is received on the subscriber PC.\n * Associates the media track with the correct publication.\n */\n addSubscribedTrack(\n mediaTrack: MediaStreamTrack,\n trackSid: string,\n trackName: string,\n ): RemoteAudioTrack | null {\n const publication = this._trackPublications.get(trackSid);\n if (!publication) {\n log.warn(`No publication found for track ${trackSid}`);\n // Create a temporary publication\n const tempPub = new RemoteTrackPublication({\n sid: trackSid,\n name: trackName,\n type: TrackType.AUDIO,\n source: TrackSource.MICROPHONE,\n muted: false,\n width: 0,\n height: 0,\n simulcast: false,\n disableDtx: false,\n layers: [],\n mimeType: 'audio/opus',\n mid: '',\n });\n this._trackPublications.set(trackSid, tempPub);\n }\n\n const pub = this._trackPublications.get(trackSid)!;\n const remoteTrack = new RemoteAudioTrack(trackSid, pub.name, mediaTrack);\n pub.setTrack(remoteTrack);\n this._audioTracks.set(trackSid, remoteTrack);\n\n log.debug(`Track subscribed: ${pub.name} (${trackSid}) from ${this.identity}`);\n this.emit('trackSubscribed', remoteTrack, pub);\n\n return remoteTrack;\n }\n\n /** Remove a subscribed track */\n removeTrack(trackSid: string): RemoteAudioTrack | null {\n const track = this._audioTracks.get(trackSid);\n if (!track) return null;\n\n track.stop();\n this._audioTracks.delete(trackSid);\n\n const pub = this._trackPublications.get(trackSid);\n if (pub) {\n pub.setTrack(null);\n this.emit('trackUnsubscribed', track, pub);\n }\n\n return track;\n }\n\n /** Clean up all tracks */\n destroy(): void {\n for (const [sid] of this._audioTracks) {\n this.removeTrack(sid);\n }\n this._trackPublications.clear();\n }\n}\n","/**\n * Room — the main entry point for connecting to a dTelecom room.\n *\n * Manages:\n * - Connection lifecycle (connect, disconnect, reconnect)\n * - Participant management (join, leave, track subscribe)\n * - Event dispatch\n */\n\nimport { TypedEmitter } from './utils/events';\nimport { createLogger } from './utils/logger';\nimport { RTCEngine } from './engine';\nimport {\n LocalParticipant,\n RemoteParticipant,\n Participant,\n DataPublishOptions,\n} from './participant';\nimport {\n RemoteAudioTrack,\n TrackPublication,\n RemoteTrackPublication,\n} from './track';\nimport {\n Room as RoomInfo,\n ParticipantInfo,\n ParticipantInfo_State,\n TrackType,\n DataPacket,\n DataPacket_Kind,\n UserPacket,\n SpeakerInfo,\n} from './proto/models';\nimport {\n JoinResponse,\n ParticipantUpdate,\n SpeakersChanged,\n} from './proto/signal';\n\nconst log = createLogger('Room');\n\n// ─── Room Options ───────────────────────────────────────────────────────────\n\nexport interface RoomOptions {\n /** Auto-subscribe to all published tracks (default: true) */\n autoSubscribe?: boolean;\n /** Connection timeout in ms (default: 10000) */\n connectTimeout?: number;\n}\n\n// ─── Room Events ────────────────────────────────────────────────────────────\n\nexport interface RoomEvents {\n [key: string]: (...args: any[]) => void;\n participantConnected: (participant: RemoteParticipant) => void;\n participantDisconnected: (participant: RemoteParticipant) => void;\n trackSubscribed: (track: RemoteAudioTrack, publication: RemoteTrackPublication, participant: RemoteParticipant) => void;\n trackUnsubscribed: (track: RemoteAudioTrack, publication: RemoteTrackPublication, participant: RemoteParticipant) => void;\n trackPublished: (publication: RemoteTrackPublication, participant: RemoteParticipant) => void;\n trackUnpublished: (publication: RemoteTrackPublication, participant: RemoteParticipant) => void;\n activeSpeakersChanged: (speakers: Array<LocalParticipant | RemoteParticipant>) => void;\n dataReceived: (data: Uint8Array, participant: RemoteParticipant | undefined, kind: DataPacket_Kind, topic?: string) => void;\n disconnected: (reason?: string) => void;\n reconnecting: () => void;\n reconnected: () => void;\n roomMetadataChanged: (metadata: string) => void;\n}\n\n// ─── Room Class ─────────────────────────────────────────────────────────────\n\nexport class Room extends TypedEmitter<RoomEvents> {\n /** Local participant (this bot) */\n localParticipant!: LocalParticipant;\n\n /** Remote participants indexed by SID */\n readonly remoteParticipants = new Map<string, RemoteParticipant>();\n\n /** Room name */\n name: string = '';\n /** Room SID */\n sid: string = '';\n /** Room metadata */\n metadata: string = '';\n\n private engine: RTCEngine;\n private _isConnected = false;\n private activeSpeakers: Array<LocalParticipant | RemoteParticipant> = [];\n private roomInfo: RoomInfo | null = null;\n\n constructor() {\n super();\n this.engine = new RTCEngine();\n }\n\n get isConnected(): boolean {\n return this._isConnected;\n }\n\n /**\n * Connect to a dTelecom room.\n *\n * @param url WebSocket URL of the dTelecom server (e.g. \"wss://my.dtelecom.org\")\n * @param token JWT access token (from AccessToken in @dtelecom/server-sdk-js)\n * @param options Room connection options\n */\n async connect(url: string, token: string, options: RoomOptions = {}): Promise<void> {\n log.info('Connecting to room...');\n\n // Connect via engine (signal + WebRTC)\n const joinResponse = await this.engine.connect(url, token, {\n autoSubscribe: options.autoSubscribe ?? true,\n connectTimeout: options.connectTimeout ?? 10000,\n });\n\n // Initialize room state from JoinResponse\n this.handleJoinResponse(joinResponse);\n\n // Set up engine event handlers\n this.setupEngineHandlers();\n\n // Set up signal event handlers (for participant updates)\n this.setupSignalHandlers();\n\n this._isConnected = true;\n log.info(`Connected to room \"${this.name}\" as \"${this.localParticipant.identity}\"`);\n }\n\n /**\n * Disconnect from the room.\n */\n async disconnect(): Promise<void> {\n if (!this._isConnected) return;\n\n log.info('Disconnecting from room...');\n this._isConnected = false;\n\n // Clean up remote participants\n for (const [sid, participant] of this.remoteParticipants) {\n participant.destroy();\n this.remoteParticipants.delete(sid);\n }\n\n await this.engine.disconnect();\n this.emit('disconnected', 'client_initiated');\n }\n\n /** Get a remote participant by SID */\n getParticipant(sid: string): RemoteParticipant | undefined {\n return this.remoteParticipants.get(sid);\n }\n\n /** Get a remote participant by identity */\n getParticipantByIdentity(identity: string): RemoteParticipant | undefined {\n for (const p of this.remoteParticipants.values()) {\n if (p.identity === identity) return p;\n }\n return undefined;\n }\n\n // ─── Private ────────────────────────────────────────────────────────────\n\n private handleJoinResponse(join: JoinResponse): void {\n // Room info\n if (join.room) {\n this.roomInfo = join.room;\n this.name = join.room.name;\n this.sid = join.room.sid;\n this.metadata = join.room.metadata;\n }\n\n // Local participant\n if (join.participant) {\n this.localParticipant = new LocalParticipant(\n this.engine,\n join.participant.sid,\n join.participant.identity,\n join.participant.name,\n join.participant.metadata,\n );\n }\n\n // Other participants\n for (const info of join.otherParticipants) {\n this.getOrCreateParticipant(info);\n }\n }\n\n private setupEngineHandlers(): void {\n // WebRTC connected\n this.engine.on('connected', () => {\n log.info('WebRTC connection established');\n });\n\n // WebRTC disconnected\n this.engine.on('disconnected', (reason) => {\n if (this._isConnected) {\n this._isConnected = false;\n this.emit('disconnected', reason);\n }\n });\n\n // Remote track received on subscriber\n this.engine.on('remoteTrack', (mediaTrack, transceiver) => {\n this.handleRemoteTrack(mediaTrack, transceiver);\n });\n\n // Data message received\n this.engine.on('dataMessage', (data, kind) => {\n this.handleDataMessage(data, kind);\n });\n }\n\n private setupSignalHandlers(): void {\n // Participant updates (join, leave, track changes)\n this.engine.signal.on('participantUpdate', (update) => {\n this.handleParticipantUpdate(update);\n });\n\n // Speakers changed\n this.engine.signal.on('speakersChanged', (changed) => {\n this.handleSpeakersChanged(changed);\n });\n\n // Room metadata update\n this.engine.signal.on('roomUpdate', (update) => {\n if (update.room) {\n this.roomInfo = update.room;\n const oldMetadata = this.metadata;\n this.metadata = update.room.metadata;\n if (oldMetadata !== this.metadata) {\n this.emit('roomMetadataChanged', this.metadata);\n }\n }\n });\n\n // Token refresh\n this.engine.signal.on('tokenRefresh', (token) => {\n log.debug('Token refreshed');\n });\n }\n\n private handleParticipantUpdate(update: ParticipantUpdate): void {\n for (const info of update.participants) {\n // Skip local participant (match by SID or identity)\n if (info.sid === this.localParticipant.sid || info.identity === this.localParticipant.identity) {\n this.localParticipant.updateInfo(info);\n continue;\n }\n\n if (info.state === ParticipantInfo_State.DISCONNECTED) {\n // Participant left\n const participant = this.remoteParticipants.get(info.sid);\n if (participant) {\n participant.destroy();\n this.remoteParticipants.delete(info.sid);\n log.info(`Participant disconnected: ${participant.identity}`);\n this.emit('participantDisconnected', participant);\n }\n } else {\n // Participant joined or updated\n const isNew = !this.remoteParticipants.has(info.sid);\n const participant = this.getOrCreateParticipant(info);\n\n if (isNew) {\n log.info(`Participant connected: ${participant.identity}`);\n this.emit('participantConnected', participant);\n }\n }\n }\n }\n\n private handleRemoteTrack(mediaTrack: any, transceiver: any): void {\n const mid = transceiver.mid;\n const mediaKind = mediaTrack?.kind; // 'audio' or 'video'\n\n // Map werift track kind to proto TrackType\n const expectedType = mediaKind === 'audio' ? TrackType.AUDIO : TrackType.VIDEO;\n\n // Search participants for an unassigned publication matching the track kind\n for (const participant of this.remoteParticipants.values()) {\n for (const [sid, pub] of participant.trackPublications) {\n if (!pub.track && pub.kind === expectedType) {\n // Only handle audio tracks (video not supported in this SDK)\n if (mediaKind !== 'audio') {\n log.debug(`Skipping ${mediaKind} track ${sid} (audio-only SDK)`);\n return;\n }\n\n // addSubscribedTrack emits 'trackSubscribed' on participant,\n // which bubbles up to Room via the listener in getOrCreateParticipant\n participant.addSubscribedTrack(mediaTrack, sid, pub.name);\n return;\n }\n }\n }\n\n log.warn(`Received remote track (mid=${mid}, kind=${mediaKind}) but couldn't match to a participant`);\n }\n\n private handleDataMessage(data: Uint8Array, kind: 'reliable' | 'lossy'): void {\n try {\n const packet = DataPacket.decode(data);\n if (packet.user) {\n const participant = this.remoteParticipants.get(packet.user.participantSid);\n const packetKind = kind === 'reliable' ? DataPacket_Kind.RELIABLE : DataPacket_Kind.LOSSY;\n this.emit('dataReceived', packet.user.payload, participant, packetKind, packet.user.topic);\n }\n } catch (err) {\n log.error('Failed to decode data message', err);\n }\n }\n\n private handleSpeakersChanged(changed: SpeakersChanged): void {\n const speakers: Array<LocalParticipant | RemoteParticipant> = [];\n for (const speaker of changed.speakers) {\n if (speaker.sid === this.localParticipant.sid) {\n speakers.push(this.localParticipant);\n } else {\n const p = this.remoteParticipants.get(speaker.sid);\n if (p) speakers.push(p);\n }\n }\n this.activeSpeakers = speakers;\n this.emit('activeSpeakersChanged', speakers);\n }\n\n private getOrCreateParticipant(info: ParticipantInfo): RemoteParticipant {\n let participant = this.remoteParticipants.get(info.sid);\n if (participant) {\n participant.updateInfo(info);\n } else {\n participant = new RemoteParticipant(info);\n this.remoteParticipants.set(info.sid, participant);\n\n // Wire up participant events to room events\n participant.on('trackSubscribed', (track, pub) => {\n this.emit('trackSubscribed', track, pub, participant!);\n });\n participant.on('trackUnsubscribed', (track, pub) => {\n this.emit('trackUnsubscribed', track, pub, participant!);\n });\n participant.on('trackPublished', (pub) => {\n this.emit('trackPublished', pub as RemoteTrackPublication, participant!);\n });\n participant.on('trackUnpublished', (pub) => {\n this.emit('trackUnpublished', pub as RemoteTrackPublication, participant!);\n });\n }\n return participant;\n }\n}\n","/**\n * AudioSource — feeds PCM16 audio into a local audio track.\n *\n * Handles:\n * - Resampling from user's sample rate (e.g. 16kHz) to Opus rate (48kHz)\n * - Opus encoding\n * - Frame buffering to ensure exact 20ms frame boundaries\n * - RTP packetization\n */\n\nimport { MediaStreamTrack } from 'werift';\nimport { AudioFrame } from './audio-frame';\nimport { OpusEncoder, OPUS_SAMPLE_RATE, OPUS_FRAME_SIZE } from './opus-encoder';\nimport { upsample } from './resampler';\nimport { createLogger } from '../utils/logger';\n\nconst log = createLogger('AudioSource');\n\nexport class AudioSource {\n readonly sampleRate: number;\n readonly channels: number;\n\n private encoder: OpusEncoder | null = null;\n private track: MediaStreamTrack | null = null;\n\n // Buffer for accumulating samples to form exact 20ms frames at 48kHz\n private sampleBuffer: Int16Array;\n private bufferOffset: number = 0;\n private readonly frameSizeAt48k: number;\n\n // Callback set by LocalAudioTrack to receive encoded Opus frames\n private _onEncodedFrame: ((opusData: Buffer) => void) | null = null;\n\n /**\n * @param sampleRate Input sample rate (e.g. 16000 for STT/TTS)\n * @param channels Number of channels (1 = mono)\n */\n constructor(sampleRate: number, channels: number = 1) {\n this.sampleRate = sampleRate;\n this.channels = channels;\n this.frameSizeAt48k = OPUS_FRAME_SIZE * channels; // 960 for mono\n this.sampleBuffer = new Int16Array(this.frameSizeAt48k);\n }\n\n /** Set the callback for encoded Opus frames. Used internally by LocalAudioTrack. */\n set onEncodedFrame(cb: ((opusData: Buffer) => void) | null) {\n this._onEncodedFrame = cb;\n }\n\n /** Associate this source with a werift MediaStreamTrack */\n setTrack(track: MediaStreamTrack): void {\n this.track = track;\n }\n\n /**\n * Feed a PCM16 audio frame into the source.\n *\n * The frame is resampled to 48kHz, buffered to 20ms boundaries,\n * Opus-encoded, and sent to the track for RTP transmission.\n */\n async captureFrame(frame: AudioFrame): Promise<void> {\n // Lazy-init encoder\n if (!this.encoder) {\n this.encoder = new OpusEncoder(OPUS_SAMPLE_RATE, this.channels);\n }\n\n // Resample to 48kHz if needed\n let samples = frame.data;\n if (frame.sampleRate !== OPUS_SAMPLE_RATE) {\n samples = upsample(frame.data, frame.sampleRate, OPUS_SAMPLE_RATE, this.channels);\n }\n\n // Buffer samples and encode in 20ms chunks\n let offset = 0;\n while (offset < samples.length) {\n const remaining = this.frameSizeAt48k - this.bufferOffset;\n const available = samples.length - offset;\n const toCopy = Math.min(remaining, available);\n\n this.sampleBuffer.set(samples.subarray(offset, offset + toCopy), this.bufferOffset);\n this.bufferOffset += toCopy;\n offset += toCopy;\n\n // Full 20ms frame? Encode and send\n if (this.bufferOffset >= this.frameSizeAt48k) {\n this.encodeAndSend(this.sampleBuffer);\n this.bufferOffset = 0;\n }\n }\n }\n\n /** Clear any buffered samples */\n flush(): void {\n // If there are buffered samples, pad with silence and encode\n if (this.bufferOffset > 0) {\n // Zero-fill remaining\n this.sampleBuffer.fill(0, this.bufferOffset);\n this.encodeAndSend(this.sampleBuffer);\n this.bufferOffset = 0;\n }\n }\n\n /** Release encoder resources */\n destroy(): void {\n if (this.encoder) {\n this.encoder.destroy();\n this.encoder = null;\n }\n this._onEncodedFrame = null;\n this.track = null;\n }\n\n private encodeAndSend(pcm: Int16Array): void {\n if (!this.encoder) return;\n\n try {\n const opusData = this.encoder.encode(pcm);\n\n if (this._onEncodedFrame) {\n this._onEncodedFrame(opusData);\n }\n } catch (err) {\n log.error('Opus encode failed', err);\n }\n }\n}\n","/**\n * Data channel utilities for sending/receiving protobuf-encoded\n * DataPacket messages over WebRTC data channels.\n */\n\nimport { DataPacket, DataPacket_Kind, UserPacket } from '../proto/models';\nimport { createLogger } from '../utils/logger';\n\nconst log = createLogger('DataChannel');\n\n/**\n * Encode a user data message into a DataPacket for transmission.\n */\nexport function encodeDataPacket(\n participantSid: string,\n payload: Uint8Array,\n kind: DataPacket_Kind = DataPacket_Kind.RELIABLE,\n options?: { destinationSids?: string[]; topic?: string },\n): Uint8Array {\n const packet: DataPacket = {\n kind,\n user: {\n participantSid,\n payload,\n destinationSids: options?.destinationSids ?? [],\n topic: options?.topic,\n },\n };\n\n return DataPacket.encode(packet).finish();\n}\n\n/**\n * Decode a DataPacket received from a data channel.\n */\nexport function decodeDataPacket(data: Uint8Array): DataPacket {\n return DataPacket.decode(data);\n}\n\n/**\n * Helper to create a text message DataPacket.\n */\nexport function createTextMessage(\n participantSid: string,\n text: string,\n options?: { destinationSids?: string[]; topic?: string },\n): Uint8Array {\n const payload = new TextEncoder().encode(text);\n return encodeDataPacket(participantSid, payload, DataPacket_Kind.RELIABLE, options);\n}\n"],"mappings":"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","names":["LogLevel","log","_m0","TrackType","TrackSource","ParticipantInfo_State","DataPacket_Kind","ConnectionQuality","DisconnectReason","WebSocket","log","import_werift","log","log","log","log","log","log","log","log","log","log"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/utils/events.ts","../src/utils/logger.ts","../src/engine.ts","../src/signal.ts","../src/proto/signal.ts","../src/proto/models.ts","../src/track.ts","../src/audio/audio-frame.ts","../src/audio/opus-encoder.ts","../src/audio/opus-decoder.ts","../src/audio/rtp-opus.ts","../src/audio/resampler.ts","../src/utils/queue.ts","../src/audio/audio-stream.ts","../src/participant.ts","../src/room.ts","../src/audio/audio-source.ts","../src/data/data-channel.ts"],"sourcesContent":["/**\n * @dtelecom/server-sdk-node\n *\n * Node.js RTC SDK for dTelecom — WebRTC participant for AI bots.\n *\n * Key classes:\n * - Room: Connect to a dTelecom room\n * - AudioSource: Feed PCM16 audio to publish\n * - AudioStream: Receive decoded PCM16 audio\n * - AudioFrame: PCM16 audio container\n * - LocalAudioTrack: Local audio track for publishing\n */\n\n// ─── Room ───────────────────────────────────────────────────────────────────\nexport { Room } from './room';\nexport type { RoomOptions, RoomEvents } from './room';\n\n// ─── Participants ───────────────────────────────────────────────────────────\nexport {\n Participant,\n LocalParticipant,\n RemoteParticipant,\n} from './participant';\nexport type { DataPublishOptions, ParticipantEvents, RemoteParticipantEvents } from './participant';\n\n// ─── Tracks ─────────────────────────────────────────────────────────────────\nexport {\n LocalAudioTrack,\n RemoteAudioTrack,\n TrackPublication,\n LocalTrackPublication,\n RemoteTrackPublication,\n} from './track';\nexport type { TrackPublishOptions } from './track';\n\n// ─── Audio ──────────────────────────────────────────────────────────────────\nexport { AudioFrame } from './audio/audio-frame';\nexport { AudioSource } from './audio/audio-source';\nexport { AudioStream } from './audio/audio-stream';\nexport { resample, downsample, upsample } from './audio/resampler';\n\n// ─── Data ───────────────────────────────────────────────────────────────────\nexport {\n encodeDataPacket,\n decodeDataPacket,\n createTextMessage,\n} from './data/data-channel';\n\n// ─── Proto types (for advanced usage) ───────────────────────────────────────\nexport {\n TrackType,\n TrackSource,\n DataPacket_Kind,\n ParticipantInfo_State,\n ConnectionQuality,\n DisconnectReason,\n} from './proto/models';\nexport type {\n Room as RoomInfo,\n ParticipantInfo,\n TrackInfo,\n DataPacket,\n UserPacket,\n ICEServer,\n SpeakerInfo,\n} from './proto/models';\n\n// ─── Utils ──────────────────────────────────────────────────────────────────\nexport { setLogLevel, LogLevel } from './utils/logger';\nexport type { Logger } from './utils/logger';\n","import { EventEmitter } from 'events';\n\n/**\n * A typed EventEmitter that provides type-safe event handling.\n * Usage:\n * interface MyEvents {\n * data: (payload: string) => void;\n * error: (err: Error) => void;\n * }\n * class MyClass extends TypedEmitter<MyEvents> {}\n */\nexport type EventMap = { [key: string]: (...args: any[]) => void };\n\nexport class TypedEmitter<T extends { [key: string]: (...args: any[]) => void }> {\n private emitter = new EventEmitter();\n\n constructor() {\n this.emitter.setMaxListeners(50);\n }\n\n on<K extends keyof T & string>(event: K, listener: T[K]): this {\n this.emitter.on(event, listener as (...args: any[]) => void);\n return this;\n }\n\n once<K extends keyof T & string>(event: K, listener: T[K]): this {\n this.emitter.once(event, listener as (...args: any[]) => void);\n return this;\n }\n\n off<K extends keyof T & string>(event: K, listener: T[K]): this {\n this.emitter.off(event, listener as (...args: any[]) => void);\n return this;\n }\n\n emit<K extends keyof T & string>(event: K, ...args: Parameters<T[K]>): boolean {\n return this.emitter.emit(event, ...args);\n }\n\n removeAllListeners<K extends keyof T & string>(event?: K): this {\n if (event) {\n this.emitter.removeAllListeners(event);\n } else {\n this.emitter.removeAllListeners();\n }\n return this;\n }\n\n listenerCount<K extends keyof T & string>(event: K): number {\n return this.emitter.listenerCount(event);\n }\n}\n","export enum LogLevel {\n TRACE = 0,\n DEBUG = 1,\n INFO = 2,\n WARN = 3,\n ERROR = 4,\n SILENT = 5,\n}\n\nconst levelNames: Record<LogLevel, string> = {\n [LogLevel.TRACE]: 'TRACE',\n [LogLevel.DEBUG]: 'DEBUG',\n [LogLevel.INFO]: 'INFO',\n [LogLevel.WARN]: 'WARN',\n [LogLevel.ERROR]: 'ERROR',\n [LogLevel.SILENT]: 'SILENT',\n};\n\nlet globalLevel: LogLevel = LogLevel.INFO;\n\nexport function setLogLevel(level: LogLevel): void {\n globalLevel = level;\n}\n\nexport function getLogLevel(): LogLevel {\n return globalLevel;\n}\n\nexport interface Logger {\n trace(msg: string, ...args: unknown[]): void;\n debug(msg: string, ...args: unknown[]): void;\n info(msg: string, ...args: unknown[]): void;\n warn(msg: string, ...args: unknown[]): void;\n error(msg: string, ...args: unknown[]): void;\n}\n\nexport function createLogger(component: string): Logger {\n const log = (level: LogLevel, msg: string, args: unknown[]) => {\n if (level < globalLevel) return;\n const ts = new Date().toISOString();\n const prefix = `${ts} [${levelNames[level]}] [${component}]`;\n if (args.length > 0) {\n console.log(prefix, msg, ...args);\n } else {\n console.log(prefix, msg);\n }\n };\n\n return {\n trace: (msg, ...args) => log(LogLevel.TRACE, msg, args),\n debug: (msg, ...args) => log(LogLevel.DEBUG, msg, args),\n info: (msg, ...args) => log(LogLevel.INFO, msg, args),\n warn: (msg, ...args) => log(LogLevel.WARN, msg, args),\n error: (msg, ...args) => log(LogLevel.ERROR, msg, args),\n };\n}\n","/**\n * RTCEngine — manages dual PeerConnections (publisher + subscriber)\n * for communication with the dTelecom SFU.\n *\n * Publisher PC: sends local audio + data channels\n * Subscriber PC: receives remote audio + data channels\n */\n\nimport {\n RTCPeerConnection,\n RTCSessionDescription,\n RTCIceCandidate,\n RTCDataChannel,\n MediaStreamTrack,\n RTCRtpTransceiver,\n} from 'werift';\nimport { TypedEmitter } from './utils/events';\nimport { createLogger } from './utils/logger';\nimport { SignalClient } from './signal';\nimport {\n SignalTarget,\n SessionDescription,\n JoinResponse,\n TrackPublishedResponse,\n AddTrackRequest,\n} from './proto/signal';\nimport { TrackType, TrackSource, ICEServer } from './proto/models';\n\nconst log = createLogger('RTCEngine');\n\nexport interface EngineEvents {\n [key: string]: (...args: any[]) => void;\n connected: () => void;\n disconnected: (reason?: string) => void;\n remoteTrack: (track: MediaStreamTrack, transceiver: RTCRtpTransceiver) => void;\n dataMessage: (data: Uint8Array, kind: 'reliable' | 'lossy') => void;\n dataChannelReady: () => void;\n trackPublished: (response: TrackPublishedResponse) => void;\n subscriberOffer: (sd: SessionDescription) => void;\n}\n\nexport interface EngineOptions {\n connectTimeout?: number;\n autoSubscribe?: boolean;\n}\n\nexport class RTCEngine extends TypedEmitter<EngineEvents> {\n readonly signal: SignalClient;\n\n private publisher: RTCPeerConnection | null = null;\n private subscriber: RTCPeerConnection | null = null;\n\n private reliableChannel: RTCDataChannel | null = null;\n private lossyChannel: RTCDataChannel | null = null;\n private subscriberReliableChannel: RTCDataChannel | null = null;\n private subscriberLossyChannel: RTCDataChannel | null = null;\n\n private subscriberPrimary = true;\n private _isConnected = false;\n private pendingCandidates: { candidate: RTCIceCandidate; target: SignalTarget }[] = [];\n private joinResponse: JoinResponse | null = null;\n\n private publishWaiters: Map<string, (response: TrackPublishedResponse) => void> = new Map();\n private _negotiateResolve: (() => void) | null = null;\n private _publisherConnectedResolve: (() => void) | null = null;\n\n get isConnected(): boolean {\n return this._isConnected;\n }\n\n get publisherPC(): RTCPeerConnection | null {\n return this.publisher;\n }\n\n get subscriberPC(): RTCPeerConnection | null {\n return this.subscriber;\n }\n\n get reliableDataChannel(): RTCDataChannel | null {\n return this.reliableChannel;\n }\n\n get lossyDataChannel(): RTCDataChannel | null {\n return this.lossyChannel;\n }\n\n constructor() {\n super();\n this.signal = new SignalClient();\n }\n\n async connect(url: string, token: string, options: EngineOptions = {}): Promise<JoinResponse> {\n const joinResponse = await this.signal.connect(url, token, {\n autoSubscribe: options.autoSubscribe ?? true,\n connectTimeout: options.connectTimeout ?? 10000,\n });\n this.joinResponse = joinResponse;\n this.subscriberPrimary = joinResponse.subscriberPrimary;\n\n log.info(`Joined room \"${joinResponse.room?.name}\", subscriber_primary=${this.subscriberPrimary}`);\n log.debug(`ICE servers: ${joinResponse.iceServers.length}, participants: ${joinResponse.otherParticipants.length}`);\n\n const iceServers = this.buildIceServers(joinResponse.iceServers);\n this.createPublisher(iceServers);\n this.createSubscriber(iceServers);\n this.setupSignalHandlers();\n this.createDataChannels();\n\n if (!this.subscriberPrimary) {\n await this.negotiate();\n }\n\n return joinResponse;\n }\n\n async addTransceiver(track: MediaStreamTrack): Promise<RTCRtpTransceiver> {\n if (!this.publisher) {\n throw new Error('Publisher PC not initialized');\n }\n const transceiver = this.publisher.addTransceiver(track, { direction: 'sendonly' });\n return transceiver;\n }\n\n async requestPublishTrack(\n cid: string,\n name: string,\n type: TrackType,\n source: TrackSource,\n options?: { disableDtx?: boolean; muted?: boolean },\n ): Promise<TrackPublishedResponse> {\n const request: AddTrackRequest = {\n cid,\n name,\n type,\n source,\n width: 0,\n height: 0,\n muted: options?.muted ?? false,\n disableDtx: options?.disableDtx ?? false,\n layers: [],\n sid: '',\n };\n\n return new Promise<TrackPublishedResponse>((resolve) => {\n this.publishWaiters.set(cid, resolve);\n this.signal.sendAddTrack(request);\n });\n }\n\n async negotiate(): Promise<void> {\n if (!this.publisher) {\n throw new Error('Publisher PC not initialized');\n }\n\n log.debug(`Publisher signaling state before negotiate: ${this.publisher.signalingState}`);\n const offer = await this.publisher.createOffer();\n await this.publisher.setLocalDescription(offer);\n\n // Create a promise that resolves when the answer is applied\n const answerPromise = new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error('Timed out waiting for publisher answer'));\n }, 10000);\n this._negotiateResolve = () => {\n clearTimeout(timeout);\n resolve();\n };\n });\n\n log.debug('Sending publisher offer');\n this.signal.sendOffer({\n type: offer.type,\n sdp: offer.sdp,\n });\n\n // Wait for the answer to be set on the publisher PC\n await answerPromise;\n log.debug('Negotiate complete (answer applied)');\n }\n\n /** Wait for publisher ICE to reach connected state (DTLS+SRTP ready). */\n async waitForPublisherConnected(timeoutMs: number = 10000): Promise<void> {\n if (!this.publisher) throw new Error('Publisher PC not initialized');\n\n const iceState = this.publisher.iceConnectionState;\n if (iceState === 'connected' || iceState === 'completed') {\n return; // Already connected\n }\n\n return new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(`Publisher ICE timed out (state: ${this.publisher?.iceConnectionState})`));\n }, timeoutMs);\n this._publisherConnectedResolve = () => {\n clearTimeout(timeout);\n resolve();\n };\n });\n }\n\n sendData(data: Uint8Array, kind: 'reliable' | 'lossy'): void {\n const channel = kind === 'reliable' ? this.reliableChannel : this.lossyChannel;\n if (!channel || channel.readyState !== 'open') {\n log.warn(`Data channel ${kind} not open`);\n return;\n }\n channel.send(Buffer.from(data));\n }\n\n async disconnect(): Promise<void> {\n this._isConnected = false;\n\n try {\n this.signal.sendLeave();\n } catch {\n // ignore\n }\n\n this.reliableChannel?.close();\n this.lossyChannel?.close();\n this.publisher?.close();\n this.subscriber?.close();\n this.signal.close();\n\n this.publisher = null;\n this.subscriber = null;\n this.reliableChannel = null;\n this.lossyChannel = null;\n this.subscriberReliableChannel = null;\n this.subscriberLossyChannel = null;\n this.publishWaiters.clear();\n\n log.info('Disconnected');\n this.emit('disconnected', 'client_initiated');\n }\n\n // ─── Private ────────────────────────────────────────────────────────────\n\n private buildIceServers(servers: ICEServer[]): { urls: string; username?: string; credential?: string }[] {\n const result: { urls: string; username?: string; credential?: string }[] = [];\n for (const s of servers) {\n for (const url of s.urls) {\n result.push({\n urls: url,\n username: s.username || undefined,\n credential: s.credential || undefined,\n });\n }\n }\n return result;\n }\n\n private createPublisher(iceServers: { urls: string; username?: string; credential?: string }[]): void {\n this.publisher = new RTCPeerConnection({\n iceServers,\n iceTransportPolicy: 'all',\n });\n\n this.publisher.onIceCandidate.subscribe((candidate) => {\n if (candidate) {\n const init = JSON.stringify(candidate.toJSON());\n this.signal.sendIceCandidate(init, SignalTarget.PUBLISHER);\n }\n });\n\n this.publisher.iceConnectionStateChange.subscribe((state) => {\n log.debug(`Publisher ICE state: ${state}`);\n if (state === 'connected' || state === 'completed') {\n if (this._publisherConnectedResolve) {\n this._publisherConnectedResolve();\n this._publisherConnectedResolve = null;\n }\n }\n });\n\n log.debug('Publisher PC created');\n }\n\n private createSubscriber(iceServers: { urls: string; username?: string; credential?: string }[]): void {\n this.subscriber = new RTCPeerConnection({\n iceServers,\n iceTransportPolicy: 'all',\n });\n\n this.subscriber.onIceCandidate.subscribe((candidate) => {\n if (candidate) {\n const init = JSON.stringify(candidate.toJSON());\n this.signal.sendIceCandidate(init, SignalTarget.SUBSCRIBER);\n }\n });\n\n // Remote track received on subscriber (fires after negotiation with actual track)\n this.subscriber.on('track', (event: any) => {\n const track = event.track as MediaStreamTrack;\n const transceiver = event.transceiver as RTCRtpTransceiver;\n log.debug(`Subscriber received track: mid=${transceiver?.mid}, kind=${track?.kind}`);\n if (track) {\n this.emit('remoteTrack', track, transceiver);\n }\n });\n\n // Data channels on subscriber (server creates them)\n this.subscriber.onDataChannel.subscribe((channel) => {\n log.debug(`Subscriber data channel: \"${channel.label}\"`);\n if (channel.label === '_reliable') {\n this.subscriberReliableChannel = channel;\n this.setupSubscriberDataChannel(channel, 'reliable');\n } else if (channel.label === '_lossy') {\n this.subscriberLossyChannel = channel;\n this.setupSubscriberDataChannel(channel, 'lossy');\n }\n });\n\n this.subscriber.iceConnectionStateChange.subscribe((state) => {\n log.debug(`Subscriber ICE state: ${state}`);\n if (state === 'connected') {\n if (!this._isConnected) {\n this._isConnected = true;\n this.emit('connected');\n }\n } else if (state === 'disconnected' || state === 'failed') {\n this._isConnected = false;\n this.emit('disconnected', `ICE ${state}`);\n }\n });\n\n log.debug('Subscriber PC created');\n }\n\n private createDataChannels(): void {\n if (!this.publisher) return;\n\n this.reliableChannel = this.publisher.createDataChannel('_reliable', {\n ordered: true,\n });\n\n this.lossyChannel = this.publisher.createDataChannel('_lossy', {\n ordered: true,\n maxRetransmits: 1,\n });\n\n let readyCount = 0;\n const checkReady = () => {\n readyCount++;\n if (readyCount >= 2) {\n log.debug('Publisher data channels ready');\n this.emit('dataChannelReady');\n }\n };\n\n this.reliableChannel.stateChanged.subscribe((state) => {\n if (state === 'open') {\n log.debug('Reliable data channel opened');\n checkReady();\n }\n });\n\n this.lossyChannel.stateChanged.subscribe((state) => {\n if (state === 'open') {\n log.debug('Lossy data channel opened');\n checkReady();\n }\n });\n\n log.debug('Data channels created on publisher');\n }\n\n private setupSubscriberDataChannel(channel: RTCDataChannel, kind: 'reliable' | 'lossy'): void {\n channel.onMessage.subscribe((event) => {\n let data: Uint8Array;\n if (event instanceof Buffer) {\n data = new Uint8Array(event);\n } else if (typeof event === 'string') {\n data = new TextEncoder().encode(event);\n } else {\n data = new Uint8Array(event as any);\n }\n this.emit('dataMessage', data, kind);\n });\n }\n\n private setupSignalHandlers(): void {\n this.signal.on('offer', async (sd) => {\n if (!this.subscriber) return;\n\n try {\n await this.subscriber.setRemoteDescription(\n new RTCSessionDescription(sd.sdp, sd.type as 'offer'),\n );\n\n const answer = await this.subscriber.createAnswer();\n await this.subscriber.setLocalDescription(answer);\n\n this.signal.sendAnswer({\n type: answer.type,\n sdp: answer.sdp,\n });\n log.debug('Sent subscriber answer');\n } catch (err) {\n log.error('Failed to handle subscriber offer', err);\n }\n });\n\n this.signal.on('answer', async (sd) => {\n if (!this.publisher) return;\n\n try {\n await this.publisher.setRemoteDescription(\n new RTCSessionDescription(sd.sdp, sd.type as 'answer'),\n );\n log.debug('Set publisher remote description');\n\n this.flushPendingCandidates(SignalTarget.PUBLISHER);\n\n // Resolve negotiate() promise\n if (this._negotiateResolve) {\n this._negotiateResolve();\n this._negotiateResolve = null;\n }\n } catch (err) {\n log.error('Failed to handle publisher answer', err);\n }\n });\n\n this.signal.on('trickle', async (trickle) => {\n try {\n const candidateInit = JSON.parse(trickle.candidateInit);\n const candidate = new RTCIceCandidate(candidateInit);\n const pc = trickle.target === SignalTarget.PUBLISHER ? this.publisher : this.subscriber;\n\n if (!pc) return;\n\n if (pc.remoteDescription) {\n await pc.addIceCandidate(candidate);\n } else {\n this.pendingCandidates.push({ candidate, target: trickle.target });\n }\n } catch (err) {\n log.error('Failed to add ICE candidate', err);\n }\n });\n\n this.signal.on('trackPublished', (response) => {\n const waiter = this.publishWaiters.get(response.cid);\n if (waiter) {\n this.publishWaiters.delete(response.cid);\n waiter(response);\n }\n this.emit('trackPublished', response);\n });\n\n this.signal.on('leave', () => {\n this.disconnect();\n });\n\n this.signal.on('close', (reason) => {\n if (this._isConnected) {\n this._isConnected = false;\n this.emit('disconnected', reason);\n }\n });\n }\n\n private flushPendingCandidates(target: SignalTarget): void {\n const pc = target === SignalTarget.PUBLISHER ? this.publisher : this.subscriber;\n if (!pc) return;\n\n const toFlush = this.pendingCandidates.filter((c) => c.target === target);\n this.pendingCandidates = this.pendingCandidates.filter((c) => c.target !== target);\n\n for (const { candidate } of toFlush) {\n pc.addIceCandidate(candidate).catch((err: any) => {\n log.error('Failed to flush ICE candidate', err);\n });\n }\n }\n}\n","/**\n * SignalClient — WebSocket connection to dTelecom SFU.\n *\n * Handles binary protobuf signaling: SignalRequest (client→server)\n * and SignalResponse (server→client).\n */\n\nimport WebSocket from 'ws';\nimport { TypedEmitter } from './utils/events';\nimport { createLogger } from './utils/logger';\nimport {\n SignalRequest,\n SignalResponse,\n SignalTarget,\n JoinResponse,\n SessionDescription,\n TrickleRequest,\n AddTrackRequest,\n MuteTrackRequest,\n UpdateSubscription,\n LeaveRequest,\n TrackPublishedResponse,\n ParticipantUpdate,\n SpeakersChanged,\n RoomUpdate,\n ConnectionQualityUpdate,\n StreamStateUpdate,\n TrackUnpublishedResponse,\n} from './proto/signal';\nimport { DisconnectReason } from './proto/models';\n\nconst log = createLogger('SignalClient');\n\nconst PROTOCOL_VERSION = 8;\nconst SDK_NAME = 'node';\nconst SDK_VERSION = '0.1.0';\n\nexport interface SignalOptions {\n /** Auto-subscribe to all tracks (default: true) */\n autoSubscribe?: boolean;\n /** WebSocket connection timeout in ms (default: 10000) */\n connectTimeout?: number;\n}\n\nexport interface SignalEvents {\n [key: string]: (...args: any[]) => void;\n join: (response: JoinResponse) => void;\n offer: (sd: SessionDescription) => void;\n answer: (sd: SessionDescription) => void;\n trickle: (request: TrickleRequest) => void;\n participantUpdate: (update: ParticipantUpdate) => void;\n trackPublished: (response: TrackPublishedResponse) => void;\n trackUnpublished: (response: TrackUnpublishedResponse) => void;\n speakersChanged: (update: SpeakersChanged) => void;\n roomUpdate: (update: RoomUpdate) => void;\n connectionQuality: (update: ConnectionQualityUpdate) => void;\n streamStateUpdate: (update: StreamStateUpdate) => void;\n leave: (request: LeaveRequest) => void;\n tokenRefresh: (token: string) => void;\n close: (reason: string) => void;\n error: (error: Error) => void;\n}\n\nexport class SignalClient extends TypedEmitter<SignalEvents> {\n private ws: WebSocket | null = null;\n private pingInterval: NodeJS.Timeout | null = null;\n private _isConnected = false;\n private joinResponse: JoinResponse | null = null;\n\n get isConnected(): boolean {\n return this._isConnected;\n }\n\n /**\n * Connect to the dTelecom SFU signaling server.\n * Returns JoinResponse on successful connection.\n */\n async connect(url: string, token: string, options: SignalOptions = {}): Promise<JoinResponse> {\n const autoSubscribe = options.autoSubscribe ?? true;\n const connectTimeout = options.connectTimeout ?? 10000;\n\n // Build WebSocket URL\n const wsUrl = this.buildUrl(url, token, autoSubscribe);\n log.info(`Connecting to ${wsUrl.replace(/access_token=[^&]+/, 'access_token=***')}`);\n\n return new Promise<JoinResponse>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.close();\n reject(new Error(`Signal connection timed out after ${connectTimeout}ms`));\n }, connectTimeout);\n\n try {\n this.ws = new WebSocket(wsUrl, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n this.ws.binaryType = 'arraybuffer';\n } catch (err) {\n clearTimeout(timeout);\n reject(err);\n return;\n }\n\n this.ws.on('open', () => {\n log.debug('WebSocket connected');\n });\n\n this.ws.on('message', (data: WebSocket.Data) => {\n try {\n const bytes = data instanceof ArrayBuffer\n ? new Uint8Array(data)\n : new Uint8Array(data as Buffer);\n\n const response = SignalResponse.decode(bytes);\n this.handleResponse(response);\n\n // First message should be JoinResponse\n if (response.join) {\n clearTimeout(timeout);\n this.joinResponse = response.join;\n this._isConnected = true;\n\n // Set up ping if configured\n if (response.join.pingInterval > 0) {\n this.startPing(response.join.pingInterval);\n }\n\n resolve(response.join);\n }\n } catch (err) {\n log.error('Failed to decode signal response', err);\n }\n });\n\n this.ws.on('error', (err) => {\n log.error('WebSocket error', err);\n clearTimeout(timeout);\n this.emit('error', err instanceof Error ? err : new Error(String(err)));\n reject(err);\n });\n\n this.ws.on('close', (code, reason) => {\n clearTimeout(timeout);\n this._isConnected = false;\n this.stopPing();\n const reasonStr = reason?.toString() || `code ${code}`;\n log.info(`WebSocket closed: ${reasonStr}`);\n this.emit('close', reasonStr);\n\n // If we haven't joined yet, reject\n if (!this.joinResponse) {\n reject(new Error(`WebSocket closed before join: ${reasonStr}`));\n }\n });\n });\n }\n\n /** Send an SDP offer (publisher → server) */\n sendOffer(sd: SessionDescription): void {\n this.sendRequest({ offer: sd });\n }\n\n /** Send an SDP answer (subscriber → server) */\n sendAnswer(sd: SessionDescription): void {\n this.sendRequest({ answer: sd });\n }\n\n /** Send an ICE candidate */\n sendIceCandidate(candidate: string, target: SignalTarget): void {\n this.sendRequest({\n trickle: { candidateInit: candidate, target },\n });\n }\n\n /** Request to add (publish) a track */\n sendAddTrack(request: AddTrackRequest): void {\n this.sendRequest({ addTrack: request });\n }\n\n /** Mute/unmute a track */\n sendMuteTrack(trackSid: string, muted: boolean): void {\n this.sendRequest({ mute: { sid: trackSid, muted } });\n }\n\n /** Update track subscription */\n sendSubscription(update: UpdateSubscription): void {\n this.sendRequest({ subscription: update });\n }\n\n /** Send leave request */\n sendLeave(): void {\n this.sendRequest({\n leave: { canReconnect: false, reason: DisconnectReason.CLIENT_INITIATED },\n });\n }\n\n /** Close the WebSocket connection */\n close(): void {\n this.stopPing();\n this._isConnected = false;\n if (this.ws) {\n this.ws.removeAllListeners();\n if (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) {\n this.ws.close();\n }\n this.ws = null;\n }\n }\n\n // ─── Private ────────────────────────────────────────────────────────────\n\n private buildUrl(url: string, token: string, autoSubscribe: boolean): string {\n // Normalize URL: ensure wss:// and /rtc path\n let wsUrl = url;\n if (wsUrl.startsWith('http://')) {\n wsUrl = wsUrl.replace('http://', 'ws://');\n } else if (wsUrl.startsWith('https://')) {\n wsUrl = wsUrl.replace('https://', 'wss://');\n } else if (!wsUrl.startsWith('ws://') && !wsUrl.startsWith('wss://')) {\n wsUrl = `wss://${wsUrl}`;\n }\n\n if (!wsUrl.includes('/rtc')) {\n wsUrl = wsUrl.replace(/\\/?$/, '/rtc');\n }\n\n const params = new URLSearchParams({\n protocol: String(PROTOCOL_VERSION),\n sdk: SDK_NAME,\n version: SDK_VERSION,\n auto_subscribe: autoSubscribe ? '1' : '0',\n access_token: token,\n });\n\n return `${wsUrl}?${params.toString()}`;\n }\n\n private sendRequest(request: SignalRequest): void {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n log.warn('Cannot send: WebSocket not open');\n return;\n }\n\n try {\n const bytes = SignalRequest.encode(request).finish();\n this.ws.send(bytes);\n } catch (err) {\n log.error('Failed to encode signal request', err);\n }\n }\n\n private handleResponse(response: SignalResponse): void {\n // join is handled in the connect() promise\n if (response.offer) {\n log.debug(`Received OFFER from server (type=${response.offer.type})`);\n this.emit('offer', response.offer);\n }\n if (response.answer) {\n log.debug(`Received ANSWER from server (type=${response.answer.type})`);\n this.emit('answer', response.answer);\n }\n if (response.trickle) {\n this.emit('trickle', response.trickle);\n }\n if (response.update) {\n this.emit('participantUpdate', response.update);\n }\n if (response.trackPublished) {\n log.debug('Track published confirmed:', response.trackPublished.cid);\n this.emit('trackPublished', response.trackPublished);\n }\n if (response.trackUnpublished) {\n this.emit('trackUnpublished', response.trackUnpublished);\n }\n if (response.speakersChanged) {\n this.emit('speakersChanged', response.speakersChanged);\n }\n if (response.roomUpdate) {\n this.emit('roomUpdate', response.roomUpdate);\n }\n if (response.connectionQuality) {\n this.emit('connectionQuality', response.connectionQuality);\n }\n if (response.streamStateUpdate) {\n this.emit('streamStateUpdate', response.streamStateUpdate);\n }\n if (response.leave) {\n log.info('Server requested leave', response.leave.reason);\n this.emit('leave', response.leave);\n }\n if (response.refreshToken) {\n this.emit('tokenRefresh', response.refreshToken);\n }\n if (response.mute) {\n // Server-initiated mute — handled via participant update\n }\n if (response.pong !== undefined) {\n // Pong received — connection alive\n }\n }\n\n private startPing(intervalSec: number): void {\n this.stopPing();\n const intervalMs = intervalSec * 1000;\n this.pingInterval = setInterval(() => {\n this.sendRequest({ ping: Date.now() });\n }, intervalMs);\n }\n\n private stopPing(): void {\n if (this.pingInterval) {\n clearInterval(this.pingInterval);\n this.pingInterval = null;\n }\n }\n}\n","/**\n * Signaling protocol types for dTelecom RTC.\n * Matches livekit_rtc.proto from github.com/dtelecom/protocol.\n *\n * These types define the WebSocket signaling messages between\n * client and SFU (Selective Forwarding Unit).\n */\n\nimport * as _m0 from 'protobufjs/minimal';\nimport {\n Room,\n Codec,\n ParticipantInfo,\n TrackInfo,\n TrackType,\n TrackSource,\n ICEServer,\n ClientInfo,\n SpeakerInfo,\n DataPacket_Kind,\n DisconnectReason,\n} from './models';\n\n// ─── Enums ──────────────────────────────────────────────────────────────────\n\nexport enum SignalTarget {\n PUBLISHER = 0,\n SUBSCRIBER = 1,\n}\n\nexport enum StreamState {\n ACTIVE = 0,\n PAUSED = 1,\n}\n\nexport enum CandidateProtocol {\n UDP = 0,\n TCP = 1,\n TLS = 2,\n}\n\n// ─── Session Description ────────────────────────────────────────────────────\n\nexport interface SessionDescription {\n /** SDP offer/answer string */\n type: string;\n sdp: string;\n}\n\n// ─── Signal Request (client → server) ───────────────────────────────────────\n\nexport interface SignalRequest {\n offer?: SessionDescription;\n answer?: SessionDescription;\n trickle?: TrickleRequest;\n addTrack?: AddTrackRequest;\n mute?: MuteTrackRequest;\n subscription?: UpdateSubscription;\n trackSetting?: UpdateTrackSettings;\n leave?: LeaveRequest;\n updateLayers?: UpdateVideoLayers;\n subscriptionPermission?: SubscriptionPermission;\n syncState?: SyncState;\n simulate?: SimulateScenario;\n ping?: number;\n}\n\n// ─── Signal Response (server → client) ──────────────────────────────────────\n\nexport interface SignalResponse {\n join?: JoinResponse;\n offer?: SessionDescription;\n answer?: SessionDescription;\n trickle?: TrickleRequest;\n update?: ParticipantUpdate;\n trackPublished?: TrackPublishedResponse;\n leave?: LeaveRequest;\n mute?: MuteTrackRequest;\n speakersChanged?: SpeakersChanged;\n roomUpdate?: RoomUpdate;\n connectionQuality?: ConnectionQualityUpdate;\n streamStateUpdate?: StreamStateUpdate;\n subscribedQualityUpdate?: SubscribedQualityUpdate;\n subscriptionPermissionUpdate?: SubscriptionPermissionUpdate;\n refreshToken?: string;\n trackUnpublished?: TrackUnpublishedResponse;\n pong?: number;\n}\n\n// ─── Sub-messages ───────────────────────────────────────────────────────────\n\nexport interface TrickleRequest {\n candidateInit: string;\n target: SignalTarget;\n}\n\nexport interface AddTrackRequest {\n cid: string;\n name: string;\n type: TrackType;\n width: number;\n height: number;\n muted: boolean;\n disableDtx: boolean;\n source: TrackSource;\n layers: SimulcastCodec[];\n sid: string;\n}\n\nexport interface SimulcastCodec {\n codec: string;\n cid: string;\n enableSimulcastLayers: boolean;\n}\n\nexport interface MuteTrackRequest {\n sid: string;\n muted: boolean;\n}\n\nexport interface UpdateSubscription {\n trackSids: string[];\n subscribe: boolean;\n participantTracks: ParticipantTrackInfo[];\n}\n\nexport interface ParticipantTrackInfo {\n participantSid: string;\n trackSids: string[];\n}\n\nexport interface UpdateTrackSettings {\n trackSids: string[];\n disabled: boolean;\n quality: number;\n width: number;\n height: number;\n fps: number;\n}\n\nexport interface LeaveRequest {\n canReconnect: boolean;\n reason: DisconnectReason;\n}\n\nexport interface UpdateVideoLayers {\n trackSid: string;\n layers: VideoLayerInfo[];\n}\n\nexport interface VideoLayerInfo {\n quality: number;\n width: number;\n height: number;\n bitrate: number;\n ssrc: number;\n}\n\nexport interface SubscriptionPermission {\n allParticipants: boolean;\n trackPermissions: TrackPermission[];\n}\n\nexport interface TrackPermission {\n participantSid: string;\n allTracks: boolean;\n trackSids: string[];\n}\n\nexport interface SyncState {\n answer?: SessionDescription;\n subscription?: UpdateSubscription;\n publishTracks: TrackPublishedResponse[];\n dataChannels: DataChannelInfo[];\n}\n\nexport interface DataChannelInfo {\n label: string;\n id: number;\n target: SignalTarget;\n}\n\nexport interface SimulateScenario {\n speakerUpdate?: number;\n nodeFailure?: boolean;\n migration?: boolean;\n serverLeave?: boolean;\n switchCandidateProtocol?: CandidateProtocol;\n}\n\n// ─── Response sub-messages ──────────────────────────────────────────────────\n\nexport interface JoinResponse {\n room?: Room;\n participant?: ParticipantInfo;\n otherParticipants: ParticipantInfo[];\n serverVersion: string;\n iceServers: ICEServer[];\n subscriberPrimary: boolean;\n alternativeUrl: string;\n clientConfiguration?: ClientConfiguration;\n serverRegion: string;\n pingTimeout: number;\n pingInterval: number;\n}\n\nexport interface ClientConfiguration {\n video?: VideoConfiguration;\n screen?: VideoConfiguration;\n resumeConnection: number;\n disabledCodecs?: DisabledCodecs;\n forceRelay: number;\n}\n\nexport interface VideoConfiguration {\n hardwareEncoder: number;\n}\n\nexport interface DisabledCodecs {\n codecs: CodecInfo[];\n}\n\nexport interface CodecInfo {\n mime: string;\n fmtpLine: string;\n}\n\nexport interface ParticipantUpdate {\n participants: ParticipantInfo[];\n}\n\nexport interface TrackPublishedResponse {\n cid: string;\n track?: TrackInfo;\n}\n\nexport interface TrackUnpublishedResponse {\n trackSid: string;\n}\n\nexport interface SpeakersChanged {\n speakers: SpeakerInfo[];\n}\n\nexport interface RoomUpdate {\n room?: Room;\n}\n\nexport interface ConnectionQualityInfo {\n participantSid: string;\n quality: number;\n score: number;\n}\n\nexport interface ConnectionQualityUpdate {\n updates: ConnectionQualityInfo[];\n}\n\nexport interface StreamStateInfo {\n participantSid: string;\n trackSid: string;\n state: StreamState;\n}\n\nexport interface StreamStateUpdate {\n streamStates: StreamStateInfo[];\n}\n\nexport interface SubscribedQualityUpdate {\n trackSid: string;\n subscribedQualities: SubscribedQuality[];\n subscribedCodecs: SubscribedCodec[];\n}\n\nexport interface SubscribedQuality {\n quality: number;\n enabled: boolean;\n}\n\nexport interface SubscribedCodec {\n codec: string;\n qualities: SubscribedQuality[];\n}\n\nexport interface SubscriptionPermissionUpdate {\n participantSid: string;\n trackSid: string;\n allowed: boolean;\n}\n\n// ─── Encode / Decode ────────────────────────────────────────────────────────\n\n// Helper to write a nested message\nfunction writeMessage(writer: _m0.Writer, fieldNumber: number, encodeFn: (w: _m0.Writer) => _m0.Writer): void {\n encodeFn(writer.uint32((fieldNumber << 3) | 2).fork()).ldelim();\n}\n\nfunction writeString(writer: _m0.Writer, fieldNumber: number, value: string): void {\n if (value !== '') {\n writer.uint32((fieldNumber << 3) | 2).string(value);\n }\n}\n\nfunction writeInt32(writer: _m0.Writer, fieldNumber: number, value: number): void {\n if (value !== 0) {\n writer.uint32((fieldNumber << 3) | 0).int32(value);\n }\n}\n\nfunction writeUint32(writer: _m0.Writer, fieldNumber: number, value: number): void {\n if (value !== 0) {\n writer.uint32((fieldNumber << 3) | 0).uint32(value);\n }\n}\n\nfunction writeBool(writer: _m0.Writer, fieldNumber: number, value: boolean): void {\n if (value) {\n writer.uint32((fieldNumber << 3) | 0).bool(value);\n }\n}\n\n// ─── SessionDescription encode/decode ───────────────────────────────────────\n\nexport const SessionDescription = {\n encode(message: SessionDescription, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n writeString(writer, 1, message.type);\n writeString(writer, 2, message.sdp);\n return writer;\n },\n\n decode(input: _m0.Reader | Uint8Array, length?: number): SessionDescription {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: SessionDescription = { type: '', sdp: '' };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.type = reader.string(); break;\n case 2: message.sdp = reader.string(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\n// ─── TrickleRequest encode/decode ───────────────────────────────────────────\n\nexport const TrickleRequest = {\n encode(message: TrickleRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n writeString(writer, 1, message.candidateInit);\n writeInt32(writer, 2, message.target);\n return writer;\n },\n\n decode(input: _m0.Reader | Uint8Array, length?: number): TrickleRequest {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: TrickleRequest = { candidateInit: '', target: 0 };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.candidateInit = reader.string(); break;\n case 2: message.target = reader.int32() as SignalTarget; break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\n// ─── AddTrackRequest encode/decode ──────────────────────────────────────────\n\nexport const AddTrackRequest = {\n encode(message: AddTrackRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n writeString(writer, 1, message.cid);\n writeString(writer, 2, message.name);\n writeInt32(writer, 3, message.type);\n writeUint32(writer, 4, message.width);\n writeUint32(writer, 5, message.height);\n writeBool(writer, 6, message.muted);\n writeBool(writer, 7, message.disableDtx);\n writeInt32(writer, 8, message.source);\n writeString(writer, 10, message.sid);\n return writer;\n },\n\n decode(input: _m0.Reader | Uint8Array, length?: number): AddTrackRequest {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: AddTrackRequest = {\n cid: '', name: '', type: 0, width: 0, height: 0,\n muted: false, disableDtx: false, source: 0, layers: [], sid: '',\n };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.cid = reader.string(); break;\n case 2: message.name = reader.string(); break;\n case 3: message.type = reader.int32() as TrackType; break;\n case 4: message.width = reader.uint32(); break;\n case 5: message.height = reader.uint32(); break;\n case 6: message.muted = reader.bool(); break;\n case 7: message.disableDtx = reader.bool(); break;\n case 8: message.source = reader.int32() as TrackSource; break;\n case 10: message.sid = reader.string(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\n// ─── MuteTrackRequest encode/decode ─────────────────────────────────────────\n\nexport const MuteTrackRequest = {\n encode(message: MuteTrackRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n writeString(writer, 1, message.sid);\n writeBool(writer, 2, message.muted);\n return writer;\n },\n\n decode(input: _m0.Reader | Uint8Array, length?: number): MuteTrackRequest {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: MuteTrackRequest = { sid: '', muted: false };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.sid = reader.string(); break;\n case 2: message.muted = reader.bool(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\n// ─── LeaveRequest encode/decode ─────────────────────────────────────────────\n\nexport const LeaveRequest = {\n encode(message: LeaveRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n writeBool(writer, 1, message.canReconnect);\n writeInt32(writer, 2, message.reason);\n return writer;\n },\n\n decode(input: _m0.Reader | Uint8Array, length?: number): LeaveRequest {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: LeaveRequest = { canReconnect: false, reason: 0 };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.canReconnect = reader.bool(); break;\n case 2: message.reason = reader.int32() as DisconnectReason; break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\n// ─── UpdateSubscription encode/decode ───────────────────────────────────────\n\nexport const UpdateSubscription = {\n encode(message: UpdateSubscription, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n for (const v of message.trackSids) {\n writeString(writer, 1, v);\n }\n writeBool(writer, 2, message.subscribe);\n return writer;\n },\n\n decode(input: _m0.Reader | Uint8Array, length?: number): UpdateSubscription {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: UpdateSubscription = { trackSids: [], subscribe: false, participantTracks: [] };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.trackSids.push(reader.string()); break;\n case 2: message.subscribe = reader.bool(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\n// ─── JoinResponse decode ────────────────────────────────────────────────────\n\nconst Room_decode = (reader: _m0.Reader, length: number): Room => {\n const end = reader.pos + length;\n const msg: Room = {\n sid: '', name: '', emptyTimeout: 0, maxParticipants: 0,\n creationTime: 0, turnPassword: '', enabledCodecs: [],\n metadata: '', numParticipants: 0, activeRecording: false,\n };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: msg.sid = reader.string(); break;\n case 2: msg.name = reader.string(); break;\n case 3: msg.emptyTimeout = reader.uint32(); break;\n case 4: msg.maxParticipants = reader.uint32(); break;\n case 5: msg.creationTime = reader.int64() as unknown as number; break;\n case 6: msg.turnPassword = reader.string(); break;\n case 7: {\n const codec: Codec = { mime: '', fmtpLine: '' };\n const cEnd = reader.pos + reader.uint32();\n while (reader.pos < cEnd) {\n const cTag = reader.uint32();\n switch (cTag >>> 3) {\n case 1: codec.mime = reader.string(); break;\n case 2: codec.fmtpLine = reader.string(); break;\n default: reader.skipType(cTag & 7); break;\n }\n }\n msg.enabledCodecs.push(codec);\n break;\n }\n case 8: msg.metadata = reader.string(); break;\n case 9: msg.numParticipants = reader.uint32(); break;\n case 10: msg.activeRecording = reader.bool(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return msg;\n};\n\nconst ICEServer_decode = (reader: _m0.Reader, length: number): ICEServer => {\n const end = reader.pos + length;\n const msg: ICEServer = { urls: [], username: '', credential: '' };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: msg.urls.push(reader.string()); break;\n case 2: msg.username = reader.string(); break;\n case 3: msg.credential = reader.string(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return msg;\n};\n\nconst TrackInfo_decode = (reader: _m0.Reader, length: number): TrackInfo => {\n const end = reader.pos + length;\n const msg: TrackInfo = {\n sid: '', type: 0, name: '', muted: false, width: 0, height: 0,\n simulcast: false, disableDtx: false, source: 0, layers: [],\n mimeType: '', mid: '',\n };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: msg.sid = reader.string(); break;\n case 2: msg.type = reader.int32() as TrackType; break;\n case 3: msg.name = reader.string(); break;\n case 4: msg.muted = reader.bool(); break;\n case 5: msg.width = reader.uint32(); break;\n case 6: msg.height = reader.uint32(); break;\n case 7: msg.simulcast = reader.bool(); break;\n case 8: msg.disableDtx = reader.bool(); break;\n case 9: msg.source = reader.int32() as TrackSource; break;\n case 11: msg.mimeType = reader.string(); break;\n case 12: msg.mid = reader.string(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return msg;\n};\n\nconst ParticipantInfo_decode = (reader: _m0.Reader, length: number): ParticipantInfo => {\n const end = reader.pos + length;\n const msg: ParticipantInfo = {\n sid: '', identity: '', state: 0, tracks: [], metadata: '',\n joinedAt: 0, name: '', version: 0, region: '', isPublisher: false,\n };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: msg.sid = reader.string(); break;\n case 2: msg.identity = reader.string(); break;\n case 3: msg.state = reader.int32(); break;\n case 4: msg.tracks.push(TrackInfo_decode(reader, reader.uint32())); break;\n case 5: msg.metadata = reader.string(); break;\n case 6: msg.joinedAt = reader.int64() as unknown as number; break;\n case 7: msg.name = reader.string(); break;\n case 10: msg.version = reader.uint32(); break;\n case 11: {\n const pEnd = reader.pos + reader.uint32();\n const perm: import('./models').ParticipantPermission = {\n canSubscribe: false, canPublish: false,\n canPublishData: false, hidden: false, recorder: false,\n };\n while (reader.pos < pEnd) {\n const pTag = reader.uint32();\n switch (pTag >>> 3) {\n case 1: perm.canSubscribe = reader.bool(); break;\n case 2: perm.canPublish = reader.bool(); break;\n case 3: perm.canPublishData = reader.bool(); break;\n case 7: perm.hidden = reader.bool(); break;\n case 8: perm.recorder = reader.bool(); break;\n default: reader.skipType(pTag & 7); break;\n }\n }\n msg.permission = perm;\n break;\n }\n case 12: msg.region = reader.string(); break;\n case 13: msg.isPublisher = reader.bool(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return msg;\n};\n\nconst SpeakerInfo_decode = (reader: _m0.Reader, length: number): SpeakerInfo => {\n const end = reader.pos + length;\n const msg: SpeakerInfo = { sid: '', level: 0, active: false };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: msg.sid = reader.string(); break;\n case 2: msg.level = reader.float(); break;\n case 3: msg.active = reader.bool(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return msg;\n};\n\nexport const JoinResponse = {\n decode(input: _m0.Reader | Uint8Array, length?: number): JoinResponse {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: JoinResponse = {\n otherParticipants: [], serverVersion: '', iceServers: [],\n subscriberPrimary: false, alternativeUrl: '', serverRegion: '',\n pingTimeout: 0, pingInterval: 0,\n };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.room = Room_decode(reader, reader.uint32()); break;\n case 2: message.participant = ParticipantInfo_decode(reader, reader.uint32()); break;\n case 3: message.otherParticipants.push(ParticipantInfo_decode(reader, reader.uint32())); break;\n case 4: message.serverVersion = reader.string(); break;\n case 5: message.iceServers.push(ICEServer_decode(reader, reader.uint32())); break;\n case 6: message.subscriberPrimary = reader.bool(); break;\n case 7: message.alternativeUrl = reader.string(); break;\n case 9: message.serverRegion = reader.string(); break;\n case 10: message.pingTimeout = reader.int32(); break;\n case 11: message.pingInterval = reader.int32(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\nexport const TrackPublishedResponse = {\n decode(input: _m0.Reader | Uint8Array, length?: number): TrackPublishedResponse {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: TrackPublishedResponse = { cid: '' };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.cid = reader.string(); break;\n case 2: message.track = TrackInfo_decode(reader, reader.uint32()); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\nexport const ParticipantUpdate = {\n decode(input: _m0.Reader | Uint8Array, length?: number): ParticipantUpdate {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: ParticipantUpdate = { participants: [] };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.participants.push(ParticipantInfo_decode(reader, reader.uint32())); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\nexport const SpeakersChanged = {\n decode(input: _m0.Reader | Uint8Array, length?: number): SpeakersChanged {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: SpeakersChanged = { speakers: [] };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.speakers.push(SpeakerInfo_decode(reader, reader.uint32())); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\nexport const RoomUpdate = {\n decode(input: _m0.Reader | Uint8Array, length?: number): RoomUpdate {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: RoomUpdate = {};\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.room = Room_decode(reader, reader.uint32()); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\nexport const TrackUnpublishedResponse = {\n decode(input: _m0.Reader | Uint8Array, length?: number): TrackUnpublishedResponse {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: TrackUnpublishedResponse = { trackSid: '' };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.trackSid = reader.string(); break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\nexport const ConnectionQualityUpdate = {\n decode(input: _m0.Reader | Uint8Array, length?: number): ConnectionQualityUpdate {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: ConnectionQualityUpdate = { updates: [] };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: {\n const cEnd = reader.pos + reader.uint32();\n const info: ConnectionQualityInfo = { participantSid: '', quality: 0, score: 0 };\n while (reader.pos < cEnd) {\n const cTag = reader.uint32();\n switch (cTag >>> 3) {\n case 1: info.participantSid = reader.string(); break;\n case 2: info.quality = reader.int32(); break;\n case 3: info.score = reader.float(); break;\n default: reader.skipType(cTag & 7); break;\n }\n }\n message.updates.push(info);\n break;\n }\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\nexport const StreamStateUpdate = {\n decode(input: _m0.Reader | Uint8Array, length?: number): StreamStateUpdate {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: StreamStateUpdate = { streamStates: [] };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: {\n const sEnd = reader.pos + reader.uint32();\n const info: StreamStateInfo = { participantSid: '', trackSid: '', state: 0 };\n while (reader.pos < sEnd) {\n const sTag = reader.uint32();\n switch (sTag >>> 3) {\n case 1: info.participantSid = reader.string(); break;\n case 2: info.trackSid = reader.string(); break;\n case 3: info.state = reader.int32(); break;\n default: reader.skipType(sTag & 7); break;\n }\n }\n message.streamStates.push(info);\n break;\n }\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n\n// ─── SignalRequest encode ───────────────────────────────────────────────────\n\nexport const SignalRequest = {\n encode(message: SignalRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n if (message.offer !== undefined) {\n writeMessage(writer, 1, (w) => SessionDescription.encode(message.offer!, w));\n }\n if (message.answer !== undefined) {\n writeMessage(writer, 2, (w) => SessionDescription.encode(message.answer!, w));\n }\n if (message.trickle !== undefined) {\n writeMessage(writer, 3, (w) => TrickleRequest.encode(message.trickle!, w));\n }\n if (message.addTrack !== undefined) {\n writeMessage(writer, 4, (w) => AddTrackRequest.encode(message.addTrack!, w));\n }\n if (message.mute !== undefined) {\n writeMessage(writer, 5, (w) => MuteTrackRequest.encode(message.mute!, w));\n }\n if (message.subscription !== undefined) {\n writeMessage(writer, 6, (w) => UpdateSubscription.encode(message.subscription!, w));\n }\n if (message.leave !== undefined) {\n writeMessage(writer, 8, (w) => LeaveRequest.encode(message.leave!, w));\n }\n if (message.ping !== undefined) {\n writer.uint32(72).int64(message.ping);\n }\n return writer;\n },\n};\n\n// ─── SignalResponse decode ──────────────────────────────────────────────────\n\nexport const SignalResponse = {\n decode(input: _m0.Reader | Uint8Array, length?: number): SignalResponse {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: SignalResponse = {};\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1: message.join = JoinResponse.decode(reader, reader.uint32()); break;\n case 2: message.answer = SessionDescription.decode(reader, reader.uint32()); break;\n case 3: message.offer = SessionDescription.decode(reader, reader.uint32()); break;\n case 4: message.trickle = TrickleRequest.decode(reader, reader.uint32()); break;\n case 5: message.update = ParticipantUpdate.decode(reader, reader.uint32()); break;\n case 6: message.trackPublished = TrackPublishedResponse.decode(reader, reader.uint32()); break;\n case 8: message.leave = LeaveRequest.decode(reader, reader.uint32()); break;\n case 9: message.mute = MuteTrackRequest.decode(reader, reader.uint32()); break;\n case 10: message.speakersChanged = SpeakersChanged.decode(reader, reader.uint32()); break;\n case 11: message.roomUpdate = RoomUpdate.decode(reader, reader.uint32()); break;\n case 12: message.connectionQuality = ConnectionQualityUpdate.decode(reader, reader.uint32()); break;\n case 13: message.streamStateUpdate = StreamStateUpdate.decode(reader, reader.uint32()); break;\n case 15: message.refreshToken = reader.string(); break;\n case 17: message.trackUnpublished = TrackUnpublishedResponse.decode(reader, reader.uint32()); break;\n case 18: message.pong = reader.int64() as unknown as number; break;\n default: reader.skipType(tag & 7); break;\n }\n }\n return message;\n },\n};\n","/**\n * Core protocol model types for dTelecom.\n * Manually defined to match github.com/dtelecom/protocol (dtelecom-db branch).\n * These mirror the types in livekit_models.proto.\n */\n\nimport * as _m0 from 'protobufjs/minimal';\n\n// ─── Enums ──────────────────────────────────────────────────────────────────\n\nexport enum TrackType {\n AUDIO = 0,\n VIDEO = 1,\n DATA = 2,\n}\n\nexport enum TrackSource {\n UNKNOWN = 0,\n CAMERA = 1,\n MICROPHONE = 2,\n SCREEN_SHARE = 3,\n SCREEN_SHARE_AUDIO = 4,\n}\n\nexport enum VideoQuality {\n LOW = 0,\n MEDIUM = 1,\n HIGH = 2,\n OFF = 3,\n}\n\nexport enum ParticipantInfo_State {\n JOINING = 0,\n JOINED = 1,\n ACTIVE = 2,\n DISCONNECTED = 3,\n}\n\nexport enum DataPacket_Kind {\n RELIABLE = 0,\n LOSSY = 1,\n}\n\nexport enum ConnectionQuality {\n POOR = 0,\n GOOD = 1,\n EXCELLENT = 2,\n}\n\nexport enum DisconnectReason {\n UNKNOWN_REASON = 0,\n CLIENT_INITIATED = 1,\n DUPLICATE_IDENTITY = 2,\n SERVER_SHUTDOWN = 3,\n PARTICIPANT_REMOVED = 4,\n ROOM_DELETED = 5,\n STATE_MISMATCH = 6,\n JOIN_FAILURE = 7,\n}\n\n// ─── Messages ───────────────────────────────────────────────────────────────\n\nexport interface Room {\n sid: string;\n name: string;\n emptyTimeout: number;\n maxParticipants: number;\n creationTime: number;\n turnPassword: string;\n enabledCodecs: Codec[];\n metadata: string;\n numParticipants: number;\n activeRecording: boolean;\n}\n\nexport interface Codec {\n mime: string;\n fmtpLine: string;\n}\n\nexport interface ParticipantPermission {\n canSubscribe: boolean;\n canPublish: boolean;\n canPublishData: boolean;\n hidden: boolean;\n recorder: boolean;\n}\n\nexport interface ParticipantInfo {\n sid: string;\n identity: string;\n state: ParticipantInfo_State;\n tracks: TrackInfo[];\n metadata: string;\n joinedAt: number;\n name: string;\n version: number;\n permission?: ParticipantPermission;\n region: string;\n isPublisher: boolean;\n}\n\nexport interface TrackInfo {\n sid: string;\n type: TrackType;\n name: string;\n muted: boolean;\n width: number;\n height: number;\n simulcast: boolean;\n disableDtx: boolean;\n source: TrackSource;\n layers: VideoLayer[];\n mimeType: string;\n mid: string;\n}\n\nexport interface VideoLayer {\n quality: VideoQuality;\n width: number;\n height: number;\n bitrate: number;\n ssrc: number;\n}\n\nexport interface DataPacket {\n kind: DataPacket_Kind;\n user?: UserPacket;\n speaker?: ActiveSpeakerUpdate;\n}\n\nexport interface UserPacket {\n participantSid: string;\n payload: Uint8Array;\n destinationSids: string[];\n topic?: string;\n}\n\nexport interface ActiveSpeakerUpdate {\n speakers: SpeakerInfo[];\n}\n\nexport interface SpeakerInfo {\n sid: string;\n level: number;\n active: boolean;\n}\n\nexport interface ParticipantTracks {\n participantSid: string;\n trackSids: string[];\n}\n\nexport interface ICEServer {\n urls: string[];\n username: string;\n credential: string;\n}\n\nexport interface ClientInfo {\n sdk: ClientInfo_SDK;\n version: string;\n protocol: number;\n os: string;\n osVersion: string;\n deviceModel: string;\n browser: string;\n browserVersion: string;\n address: string;\n network: string;\n}\n\nexport enum ClientInfo_SDK {\n UNKNOWN = 0,\n JS = 1,\n SWIFT = 2,\n ANDROID = 3,\n FLUTTER = 4,\n GO = 5,\n UNITY = 6,\n REACT_NATIVE = 7,\n RUST = 8,\n PYTHON = 9,\n CPP = 10,\n NODE = 11,\n}\n\n// ─── Encode / Decode helpers ────────────────────────────────────────────────\n\nexport const DataPacket = {\n encode(message: DataPacket, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n if (message.kind !== 0) {\n writer.uint32(8).int32(message.kind);\n }\n if (message.user !== undefined) {\n UserPacket.encode(message.user, writer.uint32(18).fork()).ldelim();\n }\n if (message.speaker !== undefined) {\n ActiveSpeakerUpdate.encode(message.speaker, writer.uint32(26).fork()).ldelim();\n }\n return writer;\n },\n\n decode(input: _m0.Reader | Uint8Array, length?: number): DataPacket {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: DataPacket = { kind: 0 };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1:\n message.kind = reader.int32() as DataPacket_Kind;\n break;\n case 2:\n message.user = UserPacket.decode(reader, reader.uint32());\n break;\n case 3:\n message.speaker = ActiveSpeakerUpdate.decode(reader, reader.uint32());\n break;\n default:\n reader.skipType(tag & 7);\n break;\n }\n }\n return message;\n },\n};\n\nexport const UserPacket = {\n encode(message: UserPacket, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n if (message.participantSid !== '') {\n writer.uint32(10).string(message.participantSid);\n }\n if (message.payload.length !== 0) {\n writer.uint32(18).bytes(message.payload);\n }\n for (const v of message.destinationSids) {\n writer.uint32(26).string(v);\n }\n if (message.topic !== undefined) {\n writer.uint32(34).string(message.topic);\n }\n return writer;\n },\n\n decode(input: _m0.Reader | Uint8Array, length?: number): UserPacket {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: UserPacket = {\n participantSid: '',\n payload: new Uint8Array(),\n destinationSids: [],\n };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1:\n message.participantSid = reader.string();\n break;\n case 2:\n message.payload = reader.bytes() as Uint8Array;\n break;\n case 3:\n message.destinationSids.push(reader.string());\n break;\n case 4:\n message.topic = reader.string();\n break;\n default:\n reader.skipType(tag & 7);\n break;\n }\n }\n return message;\n },\n};\n\nexport const ActiveSpeakerUpdate = {\n encode(message: ActiveSpeakerUpdate, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n for (const v of message.speakers) {\n SpeakerInfo.encode(v, writer.uint32(10).fork()).ldelim();\n }\n return writer;\n },\n\n decode(input: _m0.Reader | Uint8Array, length?: number): ActiveSpeakerUpdate {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: ActiveSpeakerUpdate = { speakers: [] };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1:\n message.speakers.push(SpeakerInfo.decode(reader, reader.uint32()));\n break;\n default:\n reader.skipType(tag & 7);\n break;\n }\n }\n return message;\n },\n};\n\nexport const SpeakerInfo = {\n encode(message: SpeakerInfo, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {\n if (message.sid !== '') {\n writer.uint32(10).string(message.sid);\n }\n if (message.level !== 0) {\n writer.uint32(21).float(message.level);\n }\n if (message.active) {\n writer.uint32(24).bool(message.active);\n }\n return writer;\n },\n\n decode(input: _m0.Reader | Uint8Array, length?: number): SpeakerInfo {\n const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);\n const end = length === undefined ? reader.len : reader.pos + length;\n const message: SpeakerInfo = { sid: '', level: 0, active: false };\n while (reader.pos < end) {\n const tag = reader.uint32();\n switch (tag >>> 3) {\n case 1:\n message.sid = reader.string();\n break;\n case 2:\n message.level = reader.float();\n break;\n case 3:\n message.active = reader.bool();\n break;\n default:\n reader.skipType(tag & 7);\n break;\n }\n }\n return message;\n },\n};\n","/**\n * Track classes — LocalAudioTrack, RemoteAudioTrack, TrackPublication.\n *\n * Tracks represent individual media streams within a room.\n */\n\nimport { MediaStreamTrack, RTCRtpTransceiver, RtpPacket, RtpHeader } from 'werift';\nimport { TypedEmitter } from './utils/events';\nimport { createLogger } from './utils/logger';\nimport { AudioSource } from './audio/audio-source';\nimport { AudioStream } from './audio/audio-stream';\nimport { TrackInfo, TrackType, TrackSource } from './proto/models';\nimport { OpusRtpPacketizer, OPUS_PAYLOAD_TYPE } from './audio/rtp-opus';\n\nconst log = createLogger('Track');\n\n// ─── Track Publication ──────────────────────────────────────────────────────\n\nexport interface TrackPublicationEvents {\n [key: string]: (...args: any[]) => void;\n muted: () => void;\n unmuted: () => void;\n}\n\nexport class TrackPublication extends TypedEmitter<TrackPublicationEvents> {\n sid: string;\n name: string;\n kind: TrackType;\n source: TrackSource;\n mimeType: string;\n muted: boolean;\n\n constructor(info: TrackInfo) {\n super();\n this.sid = info.sid;\n this.name = info.name;\n this.kind = info.type;\n this.source = info.source;\n this.mimeType = info.mimeType;\n this.muted = info.muted;\n }\n\n updateInfo(info: TrackInfo): void {\n const wasMuted = this.muted;\n this.sid = info.sid;\n this.name = info.name;\n this.kind = info.type;\n this.source = info.source;\n this.mimeType = info.mimeType;\n this.muted = info.muted;\n\n if (wasMuted !== info.muted) {\n this.emit(info.muted ? 'muted' : 'unmuted');\n }\n }\n}\n\nexport class LocalTrackPublication extends TrackPublication {\n track: LocalAudioTrack;\n\n constructor(info: TrackInfo, track: LocalAudioTrack) {\n super(info);\n this.track = track;\n }\n}\n\nexport class RemoteTrackPublication extends TrackPublication {\n track: RemoteAudioTrack | null = null;\n\n setTrack(track: RemoteAudioTrack | null): void {\n this.track = track;\n }\n}\n\n// ─── Local Audio Track ──────────────────────────────────────────────────────\n\nexport interface TrackPublishOptions {\n /** Track name (default: auto-generated) */\n name?: string;\n /** Audio source type (default: MICROPHONE) */\n source?: TrackSource;\n /** Disable DTX (Discontinuous Transmission) */\n disableDtx?: boolean;\n}\n\nexport class LocalAudioTrack {\n readonly name: string;\n readonly source: AudioSource;\n /** werift MediaStreamTrack used by the PeerConnection sender */\n readonly mediaTrack: MediaStreamTrack;\n private transceiver: RTCRtpTransceiver | null = null;\n private packetizer: OpusRtpPacketizer;\n private _cid: string;\n private _sid: string = '';\n\n private constructor(name: string, source: AudioSource) {\n this.name = name;\n this.source = source;\n this.mediaTrack = new MediaStreamTrack({ kind: 'audio' });\n this.packetizer = new OpusRtpPacketizer(0, OPUS_PAYLOAD_TYPE);\n this._cid = `track-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n }\n\n /** Create a local audio track from an AudioSource */\n static createAudioTrack(name: string, source: AudioSource): LocalAudioTrack {\n return new LocalAudioTrack(name, source);\n }\n\n /** Client-generated track ID (used before server assigns SID) */\n get cid(): string {\n return this._cid;\n }\n\n /** Server-assigned track SID */\n get sid(): string {\n return this._sid;\n }\n\n set sid(value: string) {\n this._sid = value;\n }\n\n /**\n * Set the RTP transceiver for sending audio.\n * Called internally by LocalParticipant after negotiation.\n */\n setTransceiver(transceiver: RTCRtpTransceiver): void {\n this.transceiver = transceiver;\n\n const sender = transceiver.sender as any;\n const dtlsState = sender?.dtlsTransport?.state;\n log.info(`setTransceiver: mid=${transceiver.mid}, codec=${sender?.codec?.name}, dtls=${dtlsState}`);\n\n // Wire up AudioSource → RTP, but only start sending once DTLS is connected\n const wireAudio = () => {\n let rtpWriteCount = 0;\n log.info(`Audio wired: dtls=${sender?.dtlsTransport?.state}, codec=${sender?.codec?.name}`);\n\n this.source.onEncodedFrame = (opusData: Buffer) => {\n if (this.mediaTrack.stopped) return;\n\n try {\n const info = this.packetizer.nextPacketInfo();\n const header = new RtpHeader();\n header.payloadType = OPUS_PAYLOAD_TYPE;\n header.sequenceNumber = info.sequenceNumber;\n header.timestamp = info.timestamp;\n header.ssrc = info.ssrc;\n header.marker = false;\n\n const packet = new RtpPacket(header, opusData);\n this.mediaTrack.writeRtp(packet);\n rtpWriteCount++;\n if (rtpWriteCount === 1) {\n log.info(`First RTP sent: dtls=${sender?.dtlsTransport?.state}`);\n }\n } catch (err) {\n log.error('Failed to send RTP via track', err);\n }\n };\n };\n\n if (dtlsState === 'connected') {\n wireAudio();\n } else {\n // Wait for DTLS to connect before sending any audio\n const dtls = sender?.dtlsTransport;\n if (dtls?.onStateChange) {\n const { unSubscribe } = dtls.onStateChange.subscribe((state: string) => {\n if (state === 'connected') {\n unSubscribe();\n wireAudio();\n }\n });\n } else {\n // Fallback: wire immediately if we can't subscribe to DTLS events\n log.warn('Cannot subscribe to DTLS state changes, wiring audio immediately');\n wireAudio();\n }\n }\n }\n\n /** Stop the track and release resources */\n stop(): void {\n this.source.flush();\n this.source.destroy();\n this.mediaTrack.stop();\n this.transceiver = null;\n }\n}\n\n// ─── Remote Audio Track ─────────────────────────────────────────────────────\n\nexport interface RemoteAudioTrackEvents {\n [key: string]: (...args: any[]) => void;\n audioFrame: () => void;\n ended: () => void;\n}\n\nexport class RemoteAudioTrack extends TypedEmitter<RemoteAudioTrackEvents> {\n readonly sid: string;\n readonly name: string;\n readonly mediaTrack: MediaStreamTrack;\n private _streams: AudioStream[] = [];\n\n constructor(sid: string, name: string, mediaTrack: MediaStreamTrack) {\n super();\n this.sid = sid;\n this.name = name;\n this.mediaTrack = mediaTrack;\n }\n\n /**\n * Create an AudioStream to consume decoded PCM16 frames from this track.\n * @param sampleRate Desired output sample rate (default: 16000 for STT)\n * @param channels Desired channels (default: 1)\n */\n createStream(sampleRate: number = 16000, channels: number = 1): AudioStream {\n const stream = new AudioStream(this.mediaTrack, sampleRate, channels);\n this._streams.push(stream);\n return stream;\n }\n\n /** Close all streams and release resources */\n stop(): void {\n for (const stream of this._streams) {\n stream.close();\n }\n this._streams = [];\n this.emit('ended');\n }\n}\n","/**\n * AudioFrame — PCM16 audio container.\n *\n * This is the primary audio type exposed to users.\n * All audio flowing in/out of the SDK uses this format.\n */\n\nexport class AudioFrame {\n /** PCM16 samples (interleaved if stereo) */\n readonly data: Int16Array;\n /** Sample rate in Hz (e.g. 16000, 48000) */\n readonly sampleRate: number;\n /** Number of channels (1 = mono, 2 = stereo) */\n readonly channels: number;\n /** Number of samples per channel */\n readonly samplesPerChannel: number;\n\n constructor(data: Int16Array, sampleRate: number, channels: number, samplesPerChannel: number) {\n this.data = data;\n this.sampleRate = sampleRate;\n this.channels = channels;\n this.samplesPerChannel = samplesPerChannel;\n }\n\n /** Create an empty (silent) AudioFrame */\n static create(sampleRate: number, channels: number, samplesPerChannel: number): AudioFrame {\n const data = new Int16Array(samplesPerChannel * channels);\n return new AudioFrame(data, sampleRate, channels, samplesPerChannel);\n }\n\n /** Duration of this frame in seconds */\n get duration(): number {\n return this.samplesPerChannel / this.sampleRate;\n }\n\n /** Duration of this frame in milliseconds */\n get durationMs(): number {\n return (this.samplesPerChannel / this.sampleRate) * 1000;\n }\n\n /** Total number of samples (channels * samplesPerChannel) */\n get totalSamples(): number {\n return this.data.length;\n }\n\n /** Convert to Buffer (for Opus encoder or file I/O) */\n toBuffer(): Buffer {\n return Buffer.from(this.data.buffer, this.data.byteOffset, this.data.byteLength);\n }\n\n /** Create AudioFrame from a Buffer of PCM16 data */\n static fromBuffer(buffer: Buffer, sampleRate: number, channels: number): AudioFrame {\n const data = new Int16Array(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength / 2,\n );\n const samplesPerChannel = data.length / channels;\n return new AudioFrame(data, sampleRate, channels, samplesPerChannel);\n }\n\n /** Clone this AudioFrame */\n clone(): AudioFrame {\n return new AudioFrame(\n new Int16Array(this.data),\n this.sampleRate,\n this.channels,\n this.samplesPerChannel,\n );\n }\n}\n","/**\n * Opus encoder wrapper around @discordjs/opus.\n *\n * Encodes PCM16 audio (48kHz) into Opus frames.\n */\n\nimport { createLogger } from '../utils/logger';\n\nconst log = createLogger('OpusEncoder');\n\n// Opus constants\nexport const OPUS_SAMPLE_RATE = 48000;\nexport const OPUS_FRAME_DURATION_MS = 20;\nexport const OPUS_FRAME_SIZE = OPUS_SAMPLE_RATE * OPUS_FRAME_DURATION_MS / 1000; // 960\n\nlet OpusEncoderClass: any = null;\n\nfunction getOpusEncoder(): any {\n if (!OpusEncoderClass) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const opus = require('@discordjs/opus');\n OpusEncoderClass = opus.OpusEncoder;\n } catch {\n try {\n // Fallback to opusscript (WASM)\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const OpusScript = require('opusscript');\n OpusEncoderClass = OpusScript;\n } catch {\n throw new Error(\n 'No Opus library found. Install @discordjs/opus (recommended) or opusscript (WASM fallback).',\n );\n }\n }\n }\n return OpusEncoderClass;\n}\n\nexport class OpusEncoder {\n private encoder: any;\n private readonly channels: number;\n\n /**\n * Create an Opus encoder.\n * @param sampleRate Must be 48000 (Opus native rate)\n * @param channels Number of channels (1 = mono, 2 = stereo)\n * @param bitrate Target bitrate in bps (default: 64000)\n */\n constructor(sampleRate: number = OPUS_SAMPLE_RATE, channels: number = 1, bitrate: number = 64000) {\n if (sampleRate !== OPUS_SAMPLE_RATE) {\n throw new Error(`Opus encoder requires ${OPUS_SAMPLE_RATE}Hz, got ${sampleRate}Hz. Resample first.`);\n }\n this.channels = channels;\n\n const Encoder = getOpusEncoder();\n this.encoder = new Encoder(sampleRate, channels);\n\n // Set bitrate if the encoder supports it\n if (typeof this.encoder.setBitrate === 'function') {\n this.encoder.setBitrate(bitrate);\n }\n\n log.debug(`Created Opus encoder: ${sampleRate}Hz, ${channels}ch, ${bitrate}bps`);\n }\n\n /**\n * Encode a PCM16 frame to Opus.\n * @param pcm PCM16 samples (Int16Array or Buffer). Must be exactly OPUS_FRAME_SIZE * channels samples.\n * @returns Opus-encoded bytes\n */\n encode(pcm: Buffer | Int16Array): Buffer {\n const buf = pcm instanceof Int16Array\n ? Buffer.from(pcm.buffer, pcm.byteOffset, pcm.byteLength)\n : pcm;\n return this.encoder.encode(buf, OPUS_FRAME_SIZE);\n }\n\n /** Clean up native resources */\n destroy(): void {\n if (this.encoder && typeof this.encoder.delete === 'function') {\n this.encoder.delete();\n }\n this.encoder = null;\n }\n}\n","/**\n * Opus decoder using opusscript (WASM).\n *\n * @discordjs/opus v0.9.0 segfaults when decoding SILK or hybrid mode\n * Opus frames (TOC configs < 16). WebRTC browsers switch to these modes\n * when bitrate estimation drops below ~52kbps. opusscript (WASM) handles\n * all Opus modes correctly and cannot segfault.\n *\n * @discordjs/opus is still used for encoding (CELT-only at 64kbps) where\n * it works reliably.\n */\n\nimport { createLogger } from '../utils/logger';\nimport { OPUS_SAMPLE_RATE, OPUS_FRAME_SIZE } from './opus-encoder';\n\nconst log = createLogger('OpusDecoder');\n\nlet OpusDecoderClass: any = null;\n\nfunction getOpusDecoder(): any {\n if (!OpusDecoderClass) {\n try {\n OpusDecoderClass = require('opusscript');\n } catch {\n throw new Error(\n 'opusscript is required for Opus decoding. Install it: npm install opusscript',\n );\n }\n }\n return OpusDecoderClass;\n}\n\nexport class OpusDecoder {\n private decoder: any;\n private readonly channels: number;\n\n /**\n * Create an Opus decoder.\n * @param sampleRate Must be 48000 (Opus native rate)\n * @param channels Number of channels (1 = mono, 2 = stereo)\n */\n constructor(sampleRate: number = OPUS_SAMPLE_RATE, channels: number = 1) {\n if (sampleRate !== OPUS_SAMPLE_RATE) {\n throw new Error(`Opus decoder requires ${OPUS_SAMPLE_RATE}Hz, got ${sampleRate}Hz`);\n }\n this.channels = channels;\n\n const Decoder = getOpusDecoder();\n this.decoder = new Decoder(sampleRate, channels);\n\n log.debug(`Created Opus decoder: ${sampleRate}Hz, ${channels}ch`);\n }\n\n /**\n * Decode an Opus frame to PCM16.\n * @param opus Opus-encoded bytes\n * @returns PCM16 samples as Buffer (OPUS_FRAME_SIZE * channels * 2 bytes)\n */\n decode(opus: Buffer): Buffer {\n return this.decoder.decode(opus);\n }\n\n /**\n * Decode an Opus frame to Int16Array.\n * @param opus Opus-encoded bytes\n * @returns PCM16 samples\n */\n decodeToInt16Array(opus: Buffer): Int16Array {\n const decoded = this.decode(opus);\n return new Int16Array(\n decoded.buffer,\n decoded.byteOffset,\n decoded.byteLength / 2,\n );\n }\n\n /** Generate a silence frame (packet loss concealment) */\n decodeMissing(): Buffer {\n return Buffer.alloc(OPUS_FRAME_SIZE * this.channels * 2);\n }\n\n /** Clean up resources */\n destroy(): void {\n if (this.decoder && typeof this.decoder.delete === 'function') {\n this.decoder.delete();\n }\n this.decoder = null;\n }\n}\n","/**\n * RTP packetizer and depacketizer for Opus audio.\n *\n * Opus in RTP follows RFC 7587:\n * - Payload type: dynamic (typically 111)\n * - Clock rate: 48000\n * - One Opus frame per RTP packet (no aggregation for 20ms frames)\n *\n * werift handles RTP framing and SRTP, but we need to:\n * - Set correct timestamps (increment by frame_size per packet)\n * - Set correct payload type\n * - Handle sequence numbers\n */\n\nimport { createLogger } from '../utils/logger';\nimport { OPUS_SAMPLE_RATE, OPUS_FRAME_SIZE } from './opus-encoder';\n\nconst log = createLogger('RTP-Opus');\n\n/** Standard Opus RTP payload type */\nexport const OPUS_PAYLOAD_TYPE = 111;\n\n/** RTP clock rate for Opus (always 48000) */\nexport const OPUS_CLOCK_RATE = OPUS_SAMPLE_RATE;\n\n/** RTP timestamp increment per 20ms Opus frame */\nexport const OPUS_TIMESTAMP_INCREMENT = OPUS_FRAME_SIZE; // 960\n\n/**\n * Tracks RTP sequence numbers and timestamps for an outgoing Opus stream.\n */\nexport class OpusRtpPacketizer {\n private sequenceNumber: number;\n private timestamp: number;\n private ssrc: number;\n readonly payloadType: number;\n\n constructor(ssrc: number = 0, payloadType: number = OPUS_PAYLOAD_TYPE) {\n // Start with random values per RFC 3550\n this.sequenceNumber = Math.floor(Math.random() * 0xFFFF);\n this.timestamp = Math.floor(Math.random() * 0xFFFFFFFF);\n this.ssrc = ssrc;\n this.payloadType = payloadType;\n }\n\n /**\n * Get the next RTP header values for an Opus frame.\n * Call this for each 20ms frame to get incrementing seq/ts.\n */\n nextPacketInfo(): { sequenceNumber: number; timestamp: number; ssrc: number } {\n const info = {\n sequenceNumber: this.sequenceNumber & 0xFFFF,\n timestamp: this.timestamp >>> 0,\n ssrc: this.ssrc,\n };\n\n this.sequenceNumber = (this.sequenceNumber + 1) & 0xFFFF;\n this.timestamp = (this.timestamp + OPUS_TIMESTAMP_INCREMENT) >>> 0;\n\n return info;\n }\n\n /** Reset the packetizer state */\n reset(): void {\n this.sequenceNumber = Math.floor(Math.random() * 0xFFFF);\n this.timestamp = Math.floor(Math.random() * 0xFFFFFFFF);\n }\n}\n\n/**\n * Tracks and reorders incoming Opus RTP packets.\n * Detects packet loss and provides frames in order.\n */\nexport class OpusRtpDepacketizer {\n private lastSequenceNumber: number = -1;\n private lastTimestamp: number = -1;\n private lostPackets: number = 0;\n\n /**\n * Process an incoming RTP packet containing an Opus frame.\n * Returns the Opus payload and metadata.\n */\n processPacket(payload: Buffer, sequenceNumber: number, timestamp: number): {\n opusFrame: Buffer;\n lost: number;\n isFirst: boolean;\n } {\n let lost = 0;\n const isFirst = this.lastSequenceNumber === -1;\n\n if (!isFirst) {\n const expectedSeq = (this.lastSequenceNumber + 1) & 0xFFFF;\n if (sequenceNumber !== expectedSeq) {\n // Calculate lost packets (handle wraparound)\n if (sequenceNumber > this.lastSequenceNumber) {\n lost = sequenceNumber - this.lastSequenceNumber - 1;\n } else {\n lost = (0xFFFF - this.lastSequenceNumber) + sequenceNumber;\n }\n this.lostPackets += lost;\n if (lost > 0) {\n log.debug(`Lost ${lost} packets (seq ${this.lastSequenceNumber} → ${sequenceNumber})`);\n }\n }\n }\n\n this.lastSequenceNumber = sequenceNumber;\n this.lastTimestamp = timestamp;\n\n return {\n opusFrame: payload,\n lost,\n isFirst,\n };\n }\n\n /** Total packets lost since creation */\n get totalLost(): number {\n return this.lostPackets;\n }\n\n /** Reset depacketizer state */\n reset(): void {\n this.lastSequenceNumber = -1;\n this.lastTimestamp = -1;\n this.lostPackets = 0;\n }\n}\n","/**\n * Audio resampler for converting between sample rates.\n *\n * Supports integer-ratio resampling (e.g. 48kHz ↔ 16kHz = 3:1).\n * Uses linear interpolation for downsampling and zero-fill + interpolation\n * for upsampling. Adequate quality for speech audio.\n */\n\n/**\n * Downsample PCM16 from a higher sample rate to a lower sample rate.\n * Supports integer-ratio downsampling (e.g. 48000 → 16000 = 3:1).\n *\n * Uses simple averaging of N samples → 1 output sample (anti-alias filter).\n */\nexport function downsample(\n input: Int16Array,\n fromRate: number,\n toRate: number,\n channels: number = 1,\n): Int16Array {\n if (fromRate === toRate) {\n return new Int16Array(input);\n }\n\n if (fromRate < toRate) {\n throw new Error(`downsample: fromRate (${fromRate}) must be >= toRate (${toRate})`);\n }\n\n const ratio = fromRate / toRate;\n if (!Number.isInteger(ratio)) {\n // Non-integer ratio — use linear interpolation\n return resampleLinear(input, fromRate, toRate, channels);\n }\n\n const inputSamplesPerChannel = input.length / channels;\n const outputSamplesPerChannel = Math.floor(inputSamplesPerChannel / ratio);\n const output = new Int16Array(outputSamplesPerChannel * channels);\n\n for (let ch = 0; ch < channels; ch++) {\n for (let i = 0; i < outputSamplesPerChannel; i++) {\n // Average `ratio` input samples to produce 1 output sample\n let sum = 0;\n for (let j = 0; j < ratio; j++) {\n sum += input[(i * ratio + j) * channels + ch];\n }\n output[i * channels + ch] = Math.round(sum / ratio);\n }\n }\n\n return output;\n}\n\n/**\n * Upsample PCM16 from a lower sample rate to a higher sample rate.\n * Supports integer-ratio upsampling (e.g. 16000 → 48000 = 1:3).\n *\n * Uses linear interpolation between samples.\n */\nexport function upsample(\n input: Int16Array,\n fromRate: number,\n toRate: number,\n channels: number = 1,\n): Int16Array {\n if (fromRate === toRate) {\n return new Int16Array(input);\n }\n\n if (fromRate > toRate) {\n throw new Error(`upsample: fromRate (${fromRate}) must be <= toRate (${toRate})`);\n }\n\n const ratio = toRate / fromRate;\n if (!Number.isInteger(ratio)) {\n return resampleLinear(input, fromRate, toRate, channels);\n }\n\n const inputSamplesPerChannel = input.length / channels;\n const outputSamplesPerChannel = inputSamplesPerChannel * ratio;\n const output = new Int16Array(outputSamplesPerChannel * channels);\n\n for (let ch = 0; ch < channels; ch++) {\n for (let i = 0; i < inputSamplesPerChannel; i++) {\n const currentSample = input[i * channels + ch];\n const nextSample = i + 1 < inputSamplesPerChannel\n ? input[(i + 1) * channels + ch]\n : currentSample;\n\n // Linear interpolation between current and next sample\n for (let j = 0; j < ratio; j++) {\n const t = j / ratio;\n const interpolated = currentSample + (nextSample - currentSample) * t;\n output[(i * ratio + j) * channels + ch] = Math.round(interpolated);\n }\n }\n }\n\n return output;\n}\n\n/**\n * General linear interpolation resampler for non-integer ratios.\n */\nfunction resampleLinear(\n input: Int16Array,\n fromRate: number,\n toRate: number,\n channels: number,\n): Int16Array {\n const inputSamplesPerChannel = input.length / channels;\n const outputSamplesPerChannel = Math.round(inputSamplesPerChannel * toRate / fromRate);\n const output = new Int16Array(outputSamplesPerChannel * channels);\n const ratio = fromRate / toRate;\n\n for (let ch = 0; ch < channels; ch++) {\n for (let i = 0; i < outputSamplesPerChannel; i++) {\n const srcPos = i * ratio;\n const srcIndex = Math.floor(srcPos);\n const frac = srcPos - srcIndex;\n\n const s0 = srcIndex < inputSamplesPerChannel\n ? input[srcIndex * channels + ch]\n : 0;\n const s1 = srcIndex + 1 < inputSamplesPerChannel\n ? input[(srcIndex + 1) * channels + ch]\n : s0;\n\n output[i * channels + ch] = Math.round(s0 + (s1 - s0) * frac);\n }\n }\n\n return output;\n}\n\n/**\n * Resample to any target rate (auto-detects up/downsample).\n */\nexport function resample(\n input: Int16Array,\n fromRate: number,\n toRate: number,\n channels: number = 1,\n): Int16Array {\n if (fromRate === toRate) return new Int16Array(input);\n if (fromRate > toRate) return downsample(input, fromRate, toRate, channels);\n return upsample(input, fromRate, toRate, channels);\n}\n","/**\n * Async queue for passing items between producer and consumer.\n * Implements AsyncIterable for for-await-of consumption.\n */\nexport class AsyncQueue<T> implements AsyncIterable<T> {\n private buffer: T[] = [];\n private resolvers: Array<(result: IteratorResult<T>) => void> = [];\n private closed = false;\n\n /** Push an item into the queue. */\n push(item: T): void {\n if (this.closed) return;\n\n if (this.resolvers.length > 0) {\n const resolve = this.resolvers.shift()!;\n resolve({ value: item, done: false });\n } else {\n this.buffer.push(item);\n }\n }\n\n /** Close the queue. Pending consumers receive done. */\n close(): void {\n this.closed = true;\n for (const resolve of this.resolvers) {\n resolve({ value: undefined as any, done: true });\n }\n this.resolvers.length = 0;\n }\n\n /** Number of buffered items. */\n get size(): number {\n return this.buffer.length;\n }\n\n /** Whether the queue is closed. */\n get isClosed(): boolean {\n return this.closed;\n }\n\n [Symbol.asyncIterator](): AsyncIterator<T> {\n return {\n next: (): Promise<IteratorResult<T>> => {\n if (this.buffer.length > 0) {\n return Promise.resolve({ value: this.buffer.shift()!, done: false });\n }\n\n if (this.closed) {\n return Promise.resolve({ value: undefined as any, done: true });\n }\n\n return new Promise<IteratorResult<T>>((resolve) => {\n this.resolvers.push(resolve);\n });\n },\n };\n }\n}\n","/**\n * AudioStream — async iterable stream of decoded audio frames\n * from a remote participant's audio track.\n *\n * Handles:\n * - RTP depacketization\n * - Opus decoding → PCM16 @ 48kHz\n * - Resampling to desired output rate (e.g. 16kHz for STT)\n * - Packet loss concealment\n */\n\nimport { MediaStreamTrack, RtpPacket } from 'werift';\nimport { AudioFrame } from './audio-frame';\nimport { OpusDecoder } from './opus-decoder';\nimport { OPUS_SAMPLE_RATE, OPUS_FRAME_SIZE } from './opus-encoder';\nimport { OpusRtpDepacketizer } from './rtp-opus';\nimport { downsample } from './resampler';\nimport { AsyncQueue } from '../utils/queue';\nimport { createLogger } from '../utils/logger';\n\nconst log = createLogger('AudioStream');\n\nexport class AudioStream implements AsyncIterable<AudioFrame> {\n private decoder: OpusDecoder | null = null;\n private depacketizer: OpusRtpDepacketizer;\n private queue: AsyncQueue<AudioFrame>;\n private readonly outputSampleRate: number;\n private readonly outputChannels: number;\n private track: MediaStreamTrack | null = null;\n private _closed = false;\n\n /**\n * @param track The remote audio track to stream from\n * @param sampleRate Desired output sample rate (default: 16000 for STT)\n * @param channels Desired output channels (default: 1 = mono)\n */\n constructor(track: MediaStreamTrack, sampleRate: number = 16000, channels: number = 1) {\n this.outputSampleRate = sampleRate;\n this.outputChannels = channels;\n this.depacketizer = new OpusRtpDepacketizer();\n this.queue = new AsyncQueue<AudioFrame>();\n this.track = track;\n this.start();\n }\n\n get closed(): boolean {\n return this._closed;\n }\n\n /** Close the stream and release resources */\n close(): void {\n if (this._closed) return;\n this._closed = true;\n this.queue.close();\n\n if (this.decoder) {\n this.decoder.destroy();\n this.decoder = null;\n }\n\n this.track = null;\n log.debug('AudioStream closed');\n }\n\n [Symbol.asyncIterator](): AsyncIterator<AudioFrame> {\n return this.queue[Symbol.asyncIterator]();\n }\n\n private start(): void {\n if (!this.track) return;\n\n // Listen for RTP packets on the track\n this.track.onReceiveRtp.subscribe((rtpPacket: RtpPacket) => {\n if (this._closed) return;\n\n try {\n this.processRtpPacket(rtpPacket);\n } catch (err) {\n log.error('Failed to process RTP packet', err);\n }\n });\n\n // Track ended\n this.track.onReceiveRtp.once(() => {\n // Note: werift doesn't have a clean \"track ended\" event,\n // we rely on the Room/Participant layer to call close()\n });\n\n log.debug(`AudioStream started, output: ${this.outputSampleRate}Hz ${this.outputChannels}ch`);\n }\n\n private processRtpPacket(rtp: RtpPacket): void {\n // Skip empty payloads\n if (!rtp.payload || rtp.payload.length === 0) {\n return;\n }\n\n // Ensure payload is a proper Buffer copy (werift may reuse internal buffers)\n const payloadCopy = Buffer.from(rtp.payload);\n\n // Skip suspiciously large payloads (not Opus)\n if (payloadCopy.length > 1500) {\n log.warn(`Skipping oversized RTP payload: ${payloadCopy.length} bytes`);\n return;\n }\n\n // Lazy init decoder\n if (!this.decoder) {\n this.decoder = new OpusDecoder(OPUS_SAMPLE_RATE, this.outputChannels);\n }\n\n const { opusFrame, lost } = this.depacketizer.processPacket(\n payloadCopy,\n rtp.header.sequenceNumber,\n rtp.header.timestamp,\n );\n\n // Handle packet loss — generate silence frames (PLC via null can segfault native addon)\n for (let i = 0; i < lost && i < 3; i++) {\n const silence = Buffer.alloc(OPUS_FRAME_SIZE * this.outputChannels * 2);\n this.emitFrame(silence);\n }\n\n // Decode the Opus frame\n if (opusFrame.length < 1) {\n return;\n }\n\n try {\n // Defensive copy — werift may reuse internal UDP buffers\n const opusCopy = Buffer.alloc(opusFrame.length);\n opusFrame.copy(opusCopy);\n const pcmBuffer = this.decoder.decode(opusCopy);\n this.emitFrame(pcmBuffer);\n } catch (err) {\n log.error(`Opus decode failed (${opusFrame.length} bytes)`, err);\n }\n }\n\n private emitFrame(pcm48k: Buffer): void {\n // Convert Buffer to Int16Array\n let samples = new Int16Array(\n pcm48k.buffer,\n pcm48k.byteOffset,\n pcm48k.byteLength / 2,\n );\n\n // Resample to desired output rate\n if (this.outputSampleRate !== OPUS_SAMPLE_RATE) {\n samples = downsample(samples, OPUS_SAMPLE_RATE, this.outputSampleRate, this.outputChannels);\n }\n\n const samplesPerChannel = samples.length / this.outputChannels;\n const frame = new AudioFrame(samples, this.outputSampleRate, this.outputChannels, samplesPerChannel);\n this.queue.push(frame);\n }\n}\n","/**\n * Participant classes — LocalParticipant and RemoteParticipant.\n *\n * Manages participant state, track publications, and data messaging.\n */\n\nimport { TypedEmitter } from './utils/events';\nimport { createLogger } from './utils/logger';\nimport { RTCEngine } from './engine';\nimport {\n LocalAudioTrack,\n RemoteAudioTrack,\n TrackPublication,\n LocalTrackPublication,\n RemoteTrackPublication,\n TrackPublishOptions,\n} from './track';\nimport {\n ParticipantInfo,\n ParticipantInfo_State,\n TrackInfo,\n TrackType,\n TrackSource,\n DataPacket,\n DataPacket_Kind,\n UserPacket,\n} from './proto/models';\nimport { TrackPublishedResponse } from './proto/signal';\nimport { MediaStreamTrack } from 'werift';\n\nconst log = createLogger('Participant');\n\n// ─── Base Participant ───────────────────────────────────────────────────────\n\nexport interface ParticipantEvents {\n [key: string]: (...args: any[]) => void;\n trackPublished: (publication: TrackPublication) => void;\n trackUnpublished: (publication: TrackPublication) => void;\n metadataChanged: (metadata: string) => void;\n}\n\nexport abstract class Participant extends TypedEmitter<ParticipantEvents> {\n sid: string;\n identity: string;\n name: string;\n metadata: string;\n state: ParticipantInfo_State;\n\n protected _trackPublications = new Map<string, TrackPublication>();\n\n constructor(sid: string, identity: string, name: string = '', metadata: string = '') {\n super();\n this.sid = sid;\n this.identity = identity;\n this.name = name;\n this.metadata = metadata;\n this.state = ParticipantInfo_State.JOINING;\n }\n\n get trackPublications(): Map<string, TrackPublication> {\n return this._trackPublications;\n }\n\n /** Update participant info from server */\n updateInfo(info: ParticipantInfo): void {\n const metadataChanged = this.metadata !== info.metadata;\n this.sid = info.sid;\n this.identity = info.identity;\n this.name = info.name;\n this.metadata = info.metadata;\n this.state = info.state;\n\n if (metadataChanged) {\n this.emit('metadataChanged', info.metadata);\n }\n }\n}\n\n// ─── Local Participant ──────────────────────────────────────────────────────\n\nexport interface DataPublishOptions {\n /** Data packet kind (default: RELIABLE) */\n kind?: DataPacket_Kind;\n /** Destination participant SIDs (empty = broadcast to all) */\n destinationSids?: string[];\n /** Topic for the data message */\n topic?: string;\n}\n\nexport class LocalParticipant extends Participant {\n private engine: RTCEngine;\n private publishedTracks = new Map<string, LocalAudioTrack>();\n\n constructor(engine: RTCEngine, sid: string, identity: string, name: string = '', metadata: string = '') {\n super(sid, identity, name, metadata);\n this.engine = engine;\n }\n\n /**\n * Publish an audio track to the room.\n *\n * Flow:\n * 1. Send AddTrackRequest to server\n * 2. Wait for TrackPublishedResponse (server assigns SID)\n * 3. Add transceiver to publisher PeerConnection\n * 4. Negotiate SDP\n */\n async publishTrack(track: LocalAudioTrack, options?: TrackPublishOptions): Promise<LocalTrackPublication> {\n const name = options?.name ?? track.name;\n const source = options?.source ?? TrackSource.MICROPHONE;\n const disableDtx = options?.disableDtx ?? false;\n\n log.info(`Publishing track \"${name}\" (cid=${track.cid})`);\n\n // Step 1: Request track publication from server\n const response = await this.engine.requestPublishTrack(\n track.cid,\n name,\n TrackType.AUDIO,\n source,\n { disableDtx },\n );\n\n if (!response.track) {\n throw new Error('Server did not return track info');\n }\n\n // Step 2: Set server-assigned SID\n track.sid = response.track.sid;\n log.debug(`Track published: cid=${track.cid}, sid=${track.sid}`);\n\n // Step 3: Add transceiver to publisher PC with the media track\n const transceiver = await this.engine.addTransceiver(track.mediaTrack);\n\n // Step 4: Negotiate (waits for SDP answer)\n await this.engine.negotiate();\n\n // Step 5: Wait for publisher ICE+DTLS to connect before wiring audio\n await this.engine.waitForPublisherConnected();\n\n // Step 6: Wire audio source to transceiver (only after media path is ready)\n track.setTransceiver(transceiver);\n\n // Create publication\n const publication = new LocalTrackPublication(response.track, track);\n this._trackPublications.set(response.track.sid, publication);\n this.publishedTracks.set(track.cid, track);\n\n this.emit('trackPublished', publication);\n return publication;\n }\n\n /**\n * Unpublish an audio track from the room.\n */\n async unpublishTrack(track: LocalAudioTrack): Promise<void> {\n log.info(`Unpublishing track \"${track.name}\" (sid=${track.sid})`);\n\n track.stop();\n this._trackPublications.delete(track.sid);\n this.publishedTracks.delete(track.cid);\n\n // Re-negotiate to remove the track\n await this.engine.negotiate();\n\n this.emit('trackUnpublished', new TrackPublication({\n sid: track.sid,\n name: track.name,\n type: TrackType.AUDIO,\n source: TrackSource.MICROPHONE,\n muted: false,\n width: 0,\n height: 0,\n simulcast: false,\n disableDtx: false,\n layers: [],\n mimeType: 'audio/opus',\n mid: '',\n }));\n }\n\n /**\n * Publish data to the room.\n *\n * @param data The data payload\n * @param options Delivery options (kind, destinations, topic)\n */\n async publishData(data: Uint8Array, options: DataPublishOptions = {}): Promise<void> {\n const kind = options.kind ?? DataPacket_Kind.RELIABLE;\n const destinationSids = options.destinationSids ?? [];\n const topic = options.topic;\n\n const packet: DataPacket = {\n kind,\n user: {\n participantSid: this.sid,\n payload: data,\n destinationSids,\n topic,\n },\n };\n\n const encoded = DataPacket.encode(packet).finish();\n const channelKind = kind === DataPacket_Kind.RELIABLE ? 'reliable' : 'lossy';\n this.engine.sendData(new Uint8Array(encoded), channelKind);\n }\n}\n\n// ─── Remote Participant ─────────────────────────────────────────────────────\n\nexport interface RemoteParticipantEvents {\n [key: string]: (...args: any[]) => void;\n trackPublished: (publication: TrackPublication) => void;\n trackUnpublished: (publication: TrackPublication) => void;\n metadataChanged: (metadata: string) => void;\n trackSubscribed: (track: RemoteAudioTrack, publication: RemoteTrackPublication) => void;\n trackUnsubscribed: (track: RemoteAudioTrack, publication: RemoteTrackPublication) => void;\n}\n\nexport class RemoteParticipant extends TypedEmitter<RemoteParticipantEvents> {\n sid: string;\n identity: string;\n name: string;\n metadata: string;\n state: ParticipantInfo_State;\n\n private _trackPublications = new Map<string, RemoteTrackPublication>();\n private _audioTracks = new Map<string, RemoteAudioTrack>();\n\n constructor(info: ParticipantInfo) {\n super();\n this.sid = info.sid;\n this.identity = info.identity;\n this.name = info.name;\n this.metadata = info.metadata;\n this.state = info.state;\n\n // Initialize track publications from info\n for (const trackInfo of info.tracks) {\n const pub = new RemoteTrackPublication(trackInfo);\n this._trackPublications.set(trackInfo.sid, pub);\n }\n }\n\n get trackPublications(): Map<string, RemoteTrackPublication> {\n return this._trackPublications;\n }\n\n get audioTracks(): Map<string, RemoteAudioTrack> {\n return this._audioTracks;\n }\n\n /** Update participant info from server */\n updateInfo(info: ParticipantInfo): void {\n const metadataChanged = this.metadata !== info.metadata;\n this.sid = info.sid;\n this.identity = info.identity;\n this.name = info.name;\n this.metadata = info.metadata;\n this.state = info.state;\n\n // Update existing publications and add new ones\n const activeSids = new Set<string>();\n for (const trackInfo of info.tracks) {\n activeSids.add(trackInfo.sid);\n const existing = this._trackPublications.get(trackInfo.sid);\n if (existing) {\n existing.updateInfo(trackInfo);\n } else {\n const pub = new RemoteTrackPublication(trackInfo);\n this._trackPublications.set(trackInfo.sid, pub);\n this.emit('trackPublished', pub);\n }\n }\n\n // Remove publications that are no longer in the list\n for (const [sid, pub] of this._trackPublications) {\n if (!activeSids.has(sid)) {\n this._trackPublications.delete(sid);\n if (pub.track) {\n this.removeTrack(sid);\n }\n this.emit('trackUnpublished', pub);\n }\n }\n\n if (metadataChanged) {\n this.emit('metadataChanged', info.metadata);\n }\n }\n\n /**\n * Called when a remote media track is received on the subscriber PC.\n * Associates the media track with the correct publication.\n */\n addSubscribedTrack(\n mediaTrack: MediaStreamTrack,\n trackSid: string,\n trackName: string,\n ): RemoteAudioTrack | null {\n const publication = this._trackPublications.get(trackSid);\n if (!publication) {\n log.warn(`No publication found for track ${trackSid}`);\n // Create a temporary publication\n const tempPub = new RemoteTrackPublication({\n sid: trackSid,\n name: trackName,\n type: TrackType.AUDIO,\n source: TrackSource.MICROPHONE,\n muted: false,\n width: 0,\n height: 0,\n simulcast: false,\n disableDtx: false,\n layers: [],\n mimeType: 'audio/opus',\n mid: '',\n });\n this._trackPublications.set(trackSid, tempPub);\n }\n\n const pub = this._trackPublications.get(trackSid)!;\n const remoteTrack = new RemoteAudioTrack(trackSid, pub.name, mediaTrack);\n pub.setTrack(remoteTrack);\n this._audioTracks.set(trackSid, remoteTrack);\n\n log.debug(`Track subscribed: ${pub.name} (${trackSid}) from ${this.identity}`);\n this.emit('trackSubscribed', remoteTrack, pub);\n\n return remoteTrack;\n }\n\n /** Remove a subscribed track */\n removeTrack(trackSid: string): RemoteAudioTrack | null {\n const track = this._audioTracks.get(trackSid);\n if (!track) return null;\n\n track.stop();\n this._audioTracks.delete(trackSid);\n\n const pub = this._trackPublications.get(trackSid);\n if (pub) {\n pub.setTrack(null);\n this.emit('trackUnsubscribed', track, pub);\n }\n\n return track;\n }\n\n /** Clean up all tracks */\n destroy(): void {\n for (const [sid] of this._audioTracks) {\n this.removeTrack(sid);\n }\n this._trackPublications.clear();\n }\n}\n","/**\n * Room — the main entry point for connecting to a dTelecom room.\n *\n * Manages:\n * - Connection lifecycle (connect, disconnect, reconnect)\n * - Participant management (join, leave, track subscribe)\n * - Event dispatch\n */\n\nimport { TypedEmitter } from './utils/events';\nimport { createLogger } from './utils/logger';\nimport { RTCEngine } from './engine';\nimport {\n LocalParticipant,\n RemoteParticipant,\n Participant,\n DataPublishOptions,\n} from './participant';\nimport {\n RemoteAudioTrack,\n TrackPublication,\n RemoteTrackPublication,\n} from './track';\nimport {\n Room as RoomInfo,\n ParticipantInfo,\n ParticipantInfo_State,\n TrackType,\n DataPacket,\n DataPacket_Kind,\n UserPacket,\n SpeakerInfo,\n} from './proto/models';\nimport {\n JoinResponse,\n ParticipantUpdate,\n SpeakersChanged,\n} from './proto/signal';\n\nconst log = createLogger('Room');\n\n// ─── Room Options ───────────────────────────────────────────────────────────\n\nexport interface RoomOptions {\n /** Auto-subscribe to all published tracks (default: true) */\n autoSubscribe?: boolean;\n /** Connection timeout in ms (default: 10000) */\n connectTimeout?: number;\n}\n\n// ─── Room Events ────────────────────────────────────────────────────────────\n\nexport interface RoomEvents {\n [key: string]: (...args: any[]) => void;\n participantConnected: (participant: RemoteParticipant) => void;\n participantDisconnected: (participant: RemoteParticipant) => void;\n trackSubscribed: (track: RemoteAudioTrack, publication: RemoteTrackPublication, participant: RemoteParticipant) => void;\n trackUnsubscribed: (track: RemoteAudioTrack, publication: RemoteTrackPublication, participant: RemoteParticipant) => void;\n trackPublished: (publication: RemoteTrackPublication, participant: RemoteParticipant) => void;\n trackUnpublished: (publication: RemoteTrackPublication, participant: RemoteParticipant) => void;\n activeSpeakersChanged: (speakers: Array<LocalParticipant | RemoteParticipant>) => void;\n dataReceived: (data: Uint8Array, participant: RemoteParticipant | undefined, kind: DataPacket_Kind, topic?: string) => void;\n disconnected: (reason?: string) => void;\n reconnecting: () => void;\n reconnected: () => void;\n roomMetadataChanged: (metadata: string) => void;\n}\n\n// ─── Room Class ─────────────────────────────────────────────────────────────\n\nexport class Room extends TypedEmitter<RoomEvents> {\n /** Local participant (this bot) */\n localParticipant!: LocalParticipant;\n\n /** Remote participants indexed by SID */\n readonly remoteParticipants = new Map<string, RemoteParticipant>();\n\n /** Room name */\n name: string = '';\n /** Room SID */\n sid: string = '';\n /** Room metadata */\n metadata: string = '';\n\n private engine: RTCEngine;\n private _isConnected = false;\n private activeSpeakers: Array<LocalParticipant | RemoteParticipant> = [];\n private roomInfo: RoomInfo | null = null;\n\n constructor() {\n super();\n this.engine = new RTCEngine();\n }\n\n get isConnected(): boolean {\n return this._isConnected;\n }\n\n /**\n * Connect to a dTelecom room.\n *\n * @param url WebSocket URL of the dTelecom server (e.g. \"wss://my.dtelecom.org\")\n * @param token JWT access token (from AccessToken in @dtelecom/server-sdk-js)\n * @param options Room connection options\n */\n async connect(url: string, token: string, options: RoomOptions = {}): Promise<void> {\n log.info('Connecting to room...');\n\n // Connect via engine (signal + WebRTC)\n const joinResponse = await this.engine.connect(url, token, {\n autoSubscribe: options.autoSubscribe ?? true,\n connectTimeout: options.connectTimeout ?? 10000,\n });\n\n // Initialize room state from JoinResponse\n this.handleJoinResponse(joinResponse);\n\n // Set up engine event handlers\n this.setupEngineHandlers();\n\n // Set up signal event handlers (for participant updates)\n this.setupSignalHandlers();\n\n this._isConnected = true;\n log.info(`Connected to room \"${this.name}\" as \"${this.localParticipant.identity}\"`);\n }\n\n /**\n * Disconnect from the room.\n */\n async disconnect(): Promise<void> {\n if (!this._isConnected) return;\n\n log.info('Disconnecting from room...');\n this._isConnected = false;\n\n // Clean up remote participants\n for (const [sid, participant] of this.remoteParticipants) {\n participant.destroy();\n this.remoteParticipants.delete(sid);\n }\n\n await this.engine.disconnect();\n this.emit('disconnected', 'client_initiated');\n }\n\n /** Get a remote participant by SID */\n getParticipant(sid: string): RemoteParticipant | undefined {\n return this.remoteParticipants.get(sid);\n }\n\n /** Get a remote participant by identity */\n getParticipantByIdentity(identity: string): RemoteParticipant | undefined {\n for (const p of this.remoteParticipants.values()) {\n if (p.identity === identity) return p;\n }\n return undefined;\n }\n\n // ─── Private ────────────────────────────────────────────────────────────\n\n private handleJoinResponse(join: JoinResponse): void {\n // Room info\n if (join.room) {\n this.roomInfo = join.room;\n this.name = join.room.name;\n this.sid = join.room.sid;\n this.metadata = join.room.metadata;\n }\n\n // Local participant\n if (join.participant) {\n this.localParticipant = new LocalParticipant(\n this.engine,\n join.participant.sid,\n join.participant.identity,\n join.participant.name,\n join.participant.metadata,\n );\n }\n\n // Other participants\n for (const info of join.otherParticipants) {\n this.getOrCreateParticipant(info);\n }\n }\n\n private setupEngineHandlers(): void {\n // WebRTC connected\n this.engine.on('connected', () => {\n log.info('WebRTC connection established');\n });\n\n // WebRTC disconnected\n this.engine.on('disconnected', (reason) => {\n if (this._isConnected) {\n this._isConnected = false;\n this.emit('disconnected', reason);\n }\n });\n\n // Remote track received on subscriber\n this.engine.on('remoteTrack', (mediaTrack, transceiver) => {\n this.handleRemoteTrack(mediaTrack, transceiver);\n });\n\n // Data message received\n this.engine.on('dataMessage', (data, kind) => {\n this.handleDataMessage(data, kind);\n });\n }\n\n private setupSignalHandlers(): void {\n // Participant updates (join, leave, track changes)\n this.engine.signal.on('participantUpdate', (update) => {\n this.handleParticipantUpdate(update);\n });\n\n // Speakers changed\n this.engine.signal.on('speakersChanged', (changed) => {\n this.handleSpeakersChanged(changed);\n });\n\n // Room metadata update\n this.engine.signal.on('roomUpdate', (update) => {\n if (update.room) {\n this.roomInfo = update.room;\n const oldMetadata = this.metadata;\n this.metadata = update.room.metadata;\n if (oldMetadata !== this.metadata) {\n this.emit('roomMetadataChanged', this.metadata);\n }\n }\n });\n\n // Token refresh\n this.engine.signal.on('tokenRefresh', (token) => {\n log.debug('Token refreshed');\n });\n }\n\n private handleParticipantUpdate(update: ParticipantUpdate): void {\n for (const info of update.participants) {\n // Skip local participant (match by SID or identity)\n if (info.sid === this.localParticipant.sid || info.identity === this.localParticipant.identity) {\n this.localParticipant.updateInfo(info);\n continue;\n }\n\n if (info.state === ParticipantInfo_State.DISCONNECTED) {\n // Participant left\n const participant = this.remoteParticipants.get(info.sid);\n if (participant) {\n participant.destroy();\n this.remoteParticipants.delete(info.sid);\n log.info(`Participant disconnected: ${participant.identity}`);\n this.emit('participantDisconnected', participant);\n }\n } else {\n // Participant joined or updated\n const isNew = !this.remoteParticipants.has(info.sid);\n const participant = this.getOrCreateParticipant(info);\n\n if (isNew) {\n log.info(`Participant connected: ${participant.identity}`);\n this.emit('participantConnected', participant);\n }\n }\n }\n }\n\n private handleRemoteTrack(mediaTrack: any, transceiver: any): void {\n const mid = transceiver.mid;\n const mediaKind = mediaTrack?.kind; // 'audio' or 'video'\n\n // Map werift track kind to proto TrackType\n const expectedType = mediaKind === 'audio' ? TrackType.AUDIO : TrackType.VIDEO;\n\n // Search participants for an unassigned publication matching the track kind\n for (const participant of this.remoteParticipants.values()) {\n for (const [sid, pub] of participant.trackPublications) {\n if (!pub.track && pub.kind === expectedType) {\n // Only handle audio tracks (video not supported in this SDK)\n if (mediaKind !== 'audio') {\n log.debug(`Skipping ${mediaKind} track ${sid} (audio-only SDK)`);\n return;\n }\n\n // addSubscribedTrack emits 'trackSubscribed' on participant,\n // which bubbles up to Room via the listener in getOrCreateParticipant\n participant.addSubscribedTrack(mediaTrack, sid, pub.name);\n return;\n }\n }\n }\n\n log.warn(`Received remote track (mid=${mid}, kind=${mediaKind}) but couldn't match to a participant`);\n }\n\n private handleDataMessage(data: Uint8Array, kind: 'reliable' | 'lossy'): void {\n try {\n const packet = DataPacket.decode(data);\n if (packet.user) {\n const participant = this.remoteParticipants.get(packet.user.participantSid);\n const packetKind = kind === 'reliable' ? DataPacket_Kind.RELIABLE : DataPacket_Kind.LOSSY;\n this.emit('dataReceived', packet.user.payload, participant, packetKind, packet.user.topic);\n }\n } catch (err) {\n log.error('Failed to decode data message', err);\n }\n }\n\n private handleSpeakersChanged(changed: SpeakersChanged): void {\n const speakers: Array<LocalParticipant | RemoteParticipant> = [];\n for (const speaker of changed.speakers) {\n if (speaker.sid === this.localParticipant.sid) {\n speakers.push(this.localParticipant);\n } else {\n const p = this.remoteParticipants.get(speaker.sid);\n if (p) speakers.push(p);\n }\n }\n this.activeSpeakers = speakers;\n this.emit('activeSpeakersChanged', speakers);\n }\n\n private getOrCreateParticipant(info: ParticipantInfo): RemoteParticipant {\n let participant = this.remoteParticipants.get(info.sid);\n if (participant) {\n participant.updateInfo(info);\n } else {\n participant = new RemoteParticipant(info);\n this.remoteParticipants.set(info.sid, participant);\n\n // Wire up participant events to room events\n participant.on('trackSubscribed', (track, pub) => {\n this.emit('trackSubscribed', track, pub, participant!);\n });\n participant.on('trackUnsubscribed', (track, pub) => {\n this.emit('trackUnsubscribed', track, pub, participant!);\n });\n participant.on('trackPublished', (pub) => {\n this.emit('trackPublished', pub as RemoteTrackPublication, participant!);\n });\n participant.on('trackUnpublished', (pub) => {\n this.emit('trackUnpublished', pub as RemoteTrackPublication, participant!);\n });\n }\n return participant;\n }\n}\n","/**\n * AudioSource — feeds PCM16 audio into a local audio track.\n *\n * Handles:\n * - Resampling from user's sample rate (e.g. 16kHz) to Opus rate (48kHz)\n * - Opus encoding\n * - Frame buffering to ensure exact 20ms frame boundaries\n * - RTP packetization\n */\n\nimport { MediaStreamTrack } from 'werift';\nimport { AudioFrame } from './audio-frame';\nimport { OpusEncoder, OPUS_SAMPLE_RATE, OPUS_FRAME_SIZE } from './opus-encoder';\nimport { upsample } from './resampler';\nimport { createLogger } from '../utils/logger';\n\nconst log = createLogger('AudioSource');\n\nexport class AudioSource {\n readonly sampleRate: number;\n readonly channels: number;\n\n private encoder: OpusEncoder | null = null;\n private track: MediaStreamTrack | null = null;\n\n // Buffer for accumulating samples to form exact 20ms frames at 48kHz\n private sampleBuffer: Int16Array;\n private bufferOffset: number = 0;\n private readonly frameSizeAt48k: number;\n\n // Callback set by LocalAudioTrack to receive encoded Opus frames\n private _onEncodedFrame: ((opusData: Buffer) => void) | null = null;\n\n /**\n * @param sampleRate Input sample rate (e.g. 16000 for STT/TTS)\n * @param channels Number of channels (1 = mono)\n */\n constructor(sampleRate: number, channels: number = 1) {\n this.sampleRate = sampleRate;\n this.channels = channels;\n this.frameSizeAt48k = OPUS_FRAME_SIZE * channels; // 960 for mono\n this.sampleBuffer = new Int16Array(this.frameSizeAt48k);\n }\n\n /** Set the callback for encoded Opus frames. Used internally by LocalAudioTrack. */\n set onEncodedFrame(cb: ((opusData: Buffer) => void) | null) {\n this._onEncodedFrame = cb;\n }\n\n /** Associate this source with a werift MediaStreamTrack */\n setTrack(track: MediaStreamTrack): void {\n this.track = track;\n }\n\n /**\n * Feed a PCM16 audio frame into the source.\n *\n * The frame is resampled to 48kHz, buffered to 20ms boundaries,\n * Opus-encoded, and sent to the track for RTP transmission.\n */\n async captureFrame(frame: AudioFrame): Promise<void> {\n // Lazy-init encoder\n if (!this.encoder) {\n this.encoder = new OpusEncoder(OPUS_SAMPLE_RATE, this.channels);\n }\n\n // Resample to 48kHz if needed\n let samples = frame.data;\n if (frame.sampleRate !== OPUS_SAMPLE_RATE) {\n samples = upsample(frame.data, frame.sampleRate, OPUS_SAMPLE_RATE, this.channels);\n }\n\n // Buffer samples and encode in 20ms chunks\n let offset = 0;\n while (offset < samples.length) {\n const remaining = this.frameSizeAt48k - this.bufferOffset;\n const available = samples.length - offset;\n const toCopy = Math.min(remaining, available);\n\n this.sampleBuffer.set(samples.subarray(offset, offset + toCopy), this.bufferOffset);\n this.bufferOffset += toCopy;\n offset += toCopy;\n\n // Full 20ms frame? Encode and send\n if (this.bufferOffset >= this.frameSizeAt48k) {\n this.encodeAndSend(this.sampleBuffer);\n this.bufferOffset = 0;\n }\n }\n }\n\n /** Clear any buffered samples */\n flush(): void {\n // If there are buffered samples, pad with silence and encode\n if (this.bufferOffset > 0) {\n // Zero-fill remaining\n this.sampleBuffer.fill(0, this.bufferOffset);\n this.encodeAndSend(this.sampleBuffer);\n this.bufferOffset = 0;\n }\n }\n\n /** Release encoder resources */\n destroy(): void {\n if (this.encoder) {\n this.encoder.destroy();\n this.encoder = null;\n }\n this._onEncodedFrame = null;\n this.track = null;\n }\n\n private _rtpCount = 0;\n private _warnedNoCallback = false;\n\n private encodeAndSend(pcm: Int16Array): void {\n if (!this.encoder) return;\n\n try {\n const opusData = this.encoder.encode(pcm);\n\n if (this._onEncodedFrame) {\n this._onEncodedFrame(opusData);\n this._rtpCount++;\n if (this._rtpCount === 1) {\n log.info(`First RTP packet sent (${opusData.byteLength} bytes)`);\n }\n } else if (!this._warnedNoCallback) {\n this._warnedNoCallback = true;\n log.debug('Waiting for DTLS — buffered audio will be dropped');\n }\n } catch (err) {\n log.error('Opus encode failed', err);\n }\n }\n}\n","/**\n * Data channel utilities for sending/receiving protobuf-encoded\n * DataPacket messages over WebRTC data channels.\n */\n\nimport { DataPacket, DataPacket_Kind, UserPacket } from '../proto/models';\nimport { createLogger } from '../utils/logger';\n\nconst log = createLogger('DataChannel');\n\n/**\n * Encode a user data message into a DataPacket for transmission.\n */\nexport function encodeDataPacket(\n participantSid: string,\n payload: Uint8Array,\n kind: DataPacket_Kind = DataPacket_Kind.RELIABLE,\n options?: { destinationSids?: string[]; topic?: string },\n): Uint8Array {\n const packet: DataPacket = {\n kind,\n user: {\n participantSid,\n payload,\n destinationSids: options?.destinationSids ?? [],\n topic: options?.topic,\n },\n };\n\n return DataPacket.encode(packet).finish();\n}\n\n/**\n * Decode a DataPacket received from a data channel.\n */\nexport function decodeDataPacket(data: Uint8Array): DataPacket {\n return DataPacket.decode(data);\n}\n\n/**\n * Helper to create a text message DataPacket.\n */\nexport function createTextMessage(\n participantSid: string,\n text: string,\n options?: { destinationSids?: string[]; topic?: string },\n): Uint8Array {\n const payload = new TextEncoder().encode(text);\n return encodeDataPacket(participantSid, payload, DataPacket_Kind.RELIABLE, options);\n}\n"],"mappings":"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","names":["LogLevel","log","_m0","TrackType","TrackSource","ParticipantInfo_State","DataPacket_Kind","ConnectionQuality","DisconnectReason","WebSocket","log","import_werift","log","log","log","log","log","log","log","log","log","log"]}
|