141 lines
4.9 KiB
TypeScript
141 lines
4.9 KiB
TypeScript
|
import {_connection} from "./ServerConnection";
|
||
|
import {_audio as _recorder} from "../audio/AudioRecorder";
|
||
|
|
||
|
import {
|
||
|
NativeVoiceConnection,
|
||
|
NativeVoiceClient
|
||
|
} from "teaclient_connection";
|
||
|
|
||
|
export namespace _audio {
|
||
|
export namespace native {
|
||
|
import ServerConnection = _connection.native.ServerConnection;
|
||
|
|
||
|
export class VoiceConnection extends connection.voice.AbstractVoiceConnection {
|
||
|
readonly connection: ServerConnection;
|
||
|
readonly handle: NativeVoiceConnection;
|
||
|
|
||
|
private _audio_source: RecorderProfile;
|
||
|
|
||
|
constructor(connection: ServerConnection, voice: NativeVoiceConnection) {
|
||
|
super(connection);
|
||
|
this.connection = connection;
|
||
|
this.handle = voice;
|
||
|
}
|
||
|
|
||
|
setup() { }
|
||
|
|
||
|
async acquire_voice_recorder(recorder: RecorderProfile | undefined, enforce?: boolean) {
|
||
|
if(this._audio_source === recorder && !enforce)
|
||
|
return;
|
||
|
|
||
|
if(this._audio_source)
|
||
|
await this._audio_source.unmount();
|
||
|
|
||
|
if(recorder) {
|
||
|
if(!(recorder.input instanceof _recorder.recorder.NativeInput))
|
||
|
throw "Recorder input must be an instance of NativeInput!";
|
||
|
await recorder.unmount();
|
||
|
}
|
||
|
|
||
|
this.handleVoiceEnded();
|
||
|
this._audio_source = recorder;
|
||
|
|
||
|
if(recorder) {
|
||
|
recorder.current_handler = this.connection.client;
|
||
|
|
||
|
recorder.callback_unmount = () => {
|
||
|
this._audio_source = undefined;
|
||
|
this.handle.set_audio_source(undefined);
|
||
|
this.connection.client.update_voice_status(undefined);
|
||
|
};
|
||
|
|
||
|
recorder.callback_start = this.handleVoiceStarted.bind(this);
|
||
|
recorder.callback_stop = this.handleVoiceEnded.bind(this);
|
||
|
|
||
|
recorder.callback_support_change = () => {
|
||
|
this.connection.client.update_voice_status(undefined);
|
||
|
};
|
||
|
|
||
|
this.handle.set_audio_source((recorder.input as _recorder.recorder.NativeInput).consumer);
|
||
|
}
|
||
|
this.connection.client.update_voice_status(undefined);
|
||
|
}
|
||
|
|
||
|
voice_playback_support() : boolean {
|
||
|
return this.connection.connected();
|
||
|
}
|
||
|
|
||
|
voice_send_support() : boolean {
|
||
|
return this.connection.connected();
|
||
|
}
|
||
|
|
||
|
private current_channel_codec() : number {
|
||
|
const chandler = this.connection.client;
|
||
|
return (chandler.getClient().currentChannel() || {properties: { channel_codec: 4}}).properties.channel_codec;
|
||
|
}
|
||
|
|
||
|
private handleVoiceEnded() {
|
||
|
const chandler = this.connection.client;
|
||
|
chandler.getClient().speaking = false;
|
||
|
|
||
|
if(!chandler.connected)
|
||
|
return false;
|
||
|
|
||
|
if(chandler.client_status.input_muted)
|
||
|
return false;
|
||
|
|
||
|
console.log(tr("Local voice ended"));
|
||
|
//TODO
|
||
|
}
|
||
|
|
||
|
private handleVoiceStarted() {
|
||
|
const chandler = this.connection.client;
|
||
|
console.log(tr("Local voice started"));
|
||
|
chandler.getClient().speaking = true;
|
||
|
}
|
||
|
|
||
|
connected(): boolean {
|
||
|
return true; /* we cant be disconnected at any time! */
|
||
|
}
|
||
|
|
||
|
voice_recorder(): RecorderProfile {
|
||
|
return this._audio_source;
|
||
|
}
|
||
|
|
||
|
available_clients(): connection.voice.VoiceClient[] {
|
||
|
return this.handle.available_clients();
|
||
|
}
|
||
|
|
||
|
find_client(client_id: number) : connection.voice.VoiceClient | undefined {
|
||
|
for(const client of this.available_clients())
|
||
|
if(client.client_id === client_id)
|
||
|
return client;
|
||
|
return undefined;
|
||
|
}
|
||
|
|
||
|
unregister_client(client: connection.voice.VoiceClient): Promise<void> {
|
||
|
this.handle.unregister_client(client.client_id);
|
||
|
return Promise.resolve();
|
||
|
}
|
||
|
|
||
|
register_client(client_id: number): connection.voice.VoiceClient {
|
||
|
const client = this.handle.register_client(client_id);
|
||
|
if(!client)
|
||
|
return client;
|
||
|
|
||
|
const stream = client.get_stream();
|
||
|
stream.set_buffer_latency(0.02);
|
||
|
stream.set_buffer_max_latency(0.2);
|
||
|
return client;
|
||
|
}
|
||
|
|
||
|
decoding_supported(codec: number): boolean {
|
||
|
return this.handle.decoding_supported(codec);
|
||
|
}
|
||
|
|
||
|
encoding_supported(codec: number): boolean {
|
||
|
return this.handle.encoding_supported(codec);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|