agent-twitter-summary
Version:
A twitter client for agents
86 lines (74 loc) • 2.14 kB
text/typescript
// src/core/JanusAudio.ts
import { EventEmitter } from 'events';
import wrtc from '@roamhq/wrtc';
const { nonstandard } = wrtc;
const { RTCAudioSource, RTCAudioSink } = nonstandard;
import { Logger } from '../logger';
interface AudioSourceOptions {
logger?: Logger;
}
interface AudioSinkOptions {
logger?: Logger;
}
export class JanusAudioSource extends EventEmitter {
private source: any;
private readonly track: MediaStreamTrack;
private logger?: Logger;
constructor(options?: AudioSourceOptions) {
super();
this.logger = options?.logger;
this.source = new RTCAudioSource();
this.track = this.source.createTrack();
}
getTrack() {
return this.track;
}
pushPcmData(samples: Int16Array, sampleRate: number, channels = 1) {
if (this.logger?.isDebugEnabled()) {
this.logger?.debug(
`[JanusAudioSource] pushPcmData => sampleRate=${sampleRate}, channels=${channels}`,
);
}
this.source.onData({
samples,
sampleRate,
bitsPerSample: 16,
channelCount: channels,
numberOfFrames: samples.length / channels,
});
}
}
export class JanusAudioSink extends EventEmitter {
private sink: any;
private active = true;
private logger?: Logger;
constructor(track: MediaStreamTrack, options?: AudioSinkOptions) {
super();
this.logger = options?.logger;
if (track.kind !== 'audio') {
throw new Error('JanusAudioSink must be an audio track');
}
this.sink = new RTCAudioSink(track);
this.sink.ondata = (frame: {
samples: Int16Array;
sampleRate: number;
bitsPerSample: number;
channelCount: number;
}) => {
if (!this.active) return;
if (this.logger?.isDebugEnabled()) {
this.logger?.debug(
`[JanusAudioSink] ondata => sampleRate=${frame.sampleRate}, bitsPerSample=${frame.bitsPerSample}, channelCount=${frame.channelCount}`,
);
}
this.emit('audioData', frame);
};
}
stop() {
this.active = false;
if (this.logger?.isDebugEnabled()) {
this.logger?.debug('[JanusAudioSink] stop');
}
this.sink?.stop();
}
}