Upload local file
Sometimes, you may need to upload a local file instead of capturing audio.
Find example source code here.
Install dependencies
yarn install
Start application
yarn start
How it works
- Ensure your file has a sample rate of 16000 Hz and is in LINEAR16 format. Otherwise convert it manually.
ffmpeg -i test.mp3 -ar 16000 -sample_fmt s16 test.wav
-
Split the file into chunks by specifying the
highWaterMark
parameter when callingcreateReadStream
. The size of each chunk should not be too large. -
Send
sendAudioSessionStart
event. -
Send chunks one by one using timeout.
-
Send
sendAudioSessionEnd
event.
import {
InworldClient,
InworldPacket,
ServiceError,
} from '@inworld/nodejs-sdk';
import * as fs from 'fs';
import { exit } from 'process';
const timeout = 200;
const highWaterMark = 1024 * 5;
const run = async function () {
const stream = fs.createReadStream('test.wav', { highWaterMark });
const connection = new InworldClient()
.setApiKey({
key: process.env.INWORLD_KEY!,
secret: process.env.INWORLD_SECRET!,
})
.setScene(process.env.INWORLD_SCENE!)
.setOnError((err: ServiceError) => {
console.error(`Error: ${err.message}`);
exit(1);
})
.setOnDisconnect(() => {
console.log('Disconnected');
})
.setOnMessage((packet: InworldPacket) => {
if (packet.isText() && packet.routing.source.isCharacter) {
console.log(`Answer: ${packet.text.text}`);
}
if (packet.isInteractionEnd()) {
connection.close();
process.exit(0);
}
})
.build();
await connection.sendAudioSessionStart();
let i = 0;
stream.on('data', async (chunk: string) => {
setTimeout(() => {
connection.sendAudio(chunk);
}, timeout * i);
i++;
});
stream.on('end', async () => {
setTimeout(() => {
connection.sendAudioSessionEnd();
}, timeout * (i - 1));
stream.close();
});
};
if (!process.env.INWORLD_KEY) {
throw new Error('INWORLD_KEY env variable is required');
}
if (!process.env.INWORLD_SECRET) {
throw new Error('INWORLD_SECRET env variable is required');
}
run();
process.on('unhandledRejection', (err: Error) => {
console.error(err.message);
process.exit(1);
});