@linkbox/mediasoup-translate-client
Version:
156 lines (131 loc) • 4.08 kB
text/typescript
import axios from 'axios';
import { Device } from 'mediasoup-client';
import { createTransport } from './mediasoup-api-client';
/**
* in sync with live-translate-service
*/
export const supportedLanguages = [
'German',
'English',
'Spanish',
'French',
'Russian',
'Italian',
'Ukrainian',
] as const;
export type Language = typeof supportedLanguages[number];
export const translateTrack = async (options: {
device: Device;
sourceTrack: MediaStreamTrack;
sourceLanguage: Language;
targetLanguage: Language;
apiToken: string;
apiUrl?: string;
}) =>
new Promise<{ translatedTrack: MediaStreamTrack }>(async (resolve) => {
const {
device,
sourceTrack,
sourceLanguage,
targetLanguage,
apiToken,
apiUrl = 'http://live-translate-api.cloud-services.linkbox.de:8000',
} = options;
console.log('client: starting');
const routerRtpCapabilities = await axios
.get(`${apiUrl}/rtp-capabilities`)
.then((res) => res.data);
if (!device.loaded) {
await device.load({
routerRtpCapabilities,
});
}
console.log(
'client: loaded device, can produce audio:',
device.canProduce('audio'),
);
const sendTransport = await createTransport(
device,
'send',
apiUrl,
apiToken,
);
console.log('client: created send transport on server', sendTransport.id);
// "produce" is emitted upon each call to transport.produce()
sendTransport.on('produce', async (data, callback, errback) => {
console.log('client: producing', data.rtpParameters);
console.log(
`[POST] "${apiUrl}/transports/${sendTransport.id}/translation-producer"`,
);
const producer: { producerId: string } = await axios
.post(`${apiUrl}/transports/${sendTransport.id}/translation-producer`, {
kind: 'audio',
rtpParameters: data.rtpParameters,
apiToken,
sourceLanguage,
targetLanguage,
})
.then((res) => {
return res.data;
})
.catch((err) => {
console.error('client: error creating producer', err);
errback(err);
});
console.log('client: produced', producer);
callback({ id: producer.producerId });
});
if (!device.canProduce('audio')) {
console.error('client: cannot produce audio');
return;
}
sendTransport.observer.on('newproducer', (producer) => {
console.log('new producer created [id:%s]', producer.id);
});
const producer = await sendTransport.produce({
track: sourceTrack,
});
console.log('GOT PRODUCER', producer.id);
producer.on('trackended', () => {
console.log('TRACK ENDED');
});
producer.on('transportclose', () => {
console.log('TRANSPORT CLOSED!');
});
/////////////// CONSUME ////////////////
const recvTransport = await createTransport(
device,
'recv',
apiUrl,
apiToken,
);
recvTransport.observer.on('newconsumer', (consumer) => {
console.log('new consumer created [id:%s]', consumer.id);
});
const serverConsumer: { id: string; rtpParameters: any } = await axios
.post(`${apiUrl}/transports/${recvTransport.id}/consume`, {
producerId: producer.id,
apiToken,
})
.then((res) => res.data);
console.log('serverConsumer', serverConsumer);
const consumer = await recvTransport.consume({
id: serverConsumer.id,
producerId: producer.id,
rtpParameters: serverConsumer.rtpParameters,
kind: 'audio',
});
consumer.on('transportclose', () => {
console.log('CONSUMER TRANS CLOSED');
});
consumer.on('trackended', () => {
console.log('TRACK ENDED');
});
resolve({ translatedTrack: consumer.track });
recvTransport.on('connectionstatechange', async (state) => {
console.log('client: recv transport connection state', state);
if (state === 'connected') {
console.log('client: connected');
}
});
});