UNPKG

sonix-speech-recognition

Version:

A library that produces audio transcriptions and translations using the Sonix.AI service.

185 lines (184 loc) 8.3 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SonixSpeechRecognitionService = void 0; const axios_1 = require("axios"); const fs = require("fs"); const FormData = require("form-data"); const constants_1 = require("./constants"); class SonixSpeechRecognitionService { constructor(authKey) { this.authKey = authKey; } uploadFileForTranscription({ audioUrl, audioFilePath, fileName, language, }) { return __awaiter(this, void 0, void 0, function* () { if (!audioUrl && !audioFilePath) { throw new Error('Either audioUrl or audioFilePath must be provided'); } const form = new FormData(); if (audioUrl) { form.append('file_url', audioUrl); } if (audioFilePath) { const fileStream = fs.createReadStream(audioFilePath); form.append('file', fileStream, fileName); } form.append('language', language); if (fileName) { form.append('name', fileName); } const response = yield axios_1.default.post(constants_1.SPEECH_BASE_URL, form, { headers: { Authorization: `Bearer ${this.authKey}`, }, }); return response.data; }); } getTranscriptionStatus(uploadAudioResponse) { return __awaiter(this, void 0, void 0, function* () { const response = yield axios_1.default.request({ method: 'get', maxBodyLength: Infinity, url: `${constants_1.SPEECH_BASE_URL}/${uploadAudioResponse.id}`, headers: { Authorization: `Bearer ${this.authKey}`, }, }); return response.data; }); } getTranscriptionResult(transcriptionId, language) { return __awaiter(this, void 0, void 0, function* () { const form = new FormData(); form.append('language', language); const response = yield axios_1.default.get(`${constants_1.SPEECH_BASE_URL}/${transcriptionId}/transcript`, { headers: { Authorization: `Bearer ${this.authKey}`, }, data: form, }); return response.data; }); } queueTranslation({ transcriptionJobId, language, }) { return __awaiter(this, void 0, void 0, function* () { const form = new FormData(); form.append('language', language); const response = yield axios_1.default.post(`${constants_1.SPEECH_BASE_URL}/${transcriptionJobId}/translations`, form, { headers: { Authorization: `Bearer ${this.authKey}`, }, }); return response.data; }); } getTranslationStatus({ transcriptionJobId, language, }) { return __awaiter(this, void 0, void 0, function* () { const response = yield axios_1.default.request({ method: 'get', maxBodyLength: Infinity, url: `${constants_1.SPEECH_BASE_URL}/${transcriptionJobId}/translations/${language}`, headers: { Authorization: `Bearer ${this.authKey}`, }, }); return response.data; }); } delay(ms) { return __awaiter(this, void 0, void 0, function* () { return new Promise(resolve => setTimeout(resolve, ms)); }); } speechToText({ audioUrl, fileName, language, audioFilePath, }) { return __awaiter(this, void 0, void 0, function* () { let jobId = ''; try { const fileUploadResponse = yield this.uploadFileForTranscription({ audioUrl, fileName, language, audioFilePath, }); jobId = fileUploadResponse.id; const startTime = Date.now(); let transcriptionStatus = yield this.getTranscriptionStatus(fileUploadResponse); while (transcriptionStatus.status !== 'completed') { if (Date.now() - startTime > constants_1.MAX_WAIT_TIME) { throw new Error('Transcription timeout'); } yield this.delay(constants_1.RECOGNITION_POLLING_DELAY); transcriptionStatus = yield this.getTranscriptionStatus(fileUploadResponse); if (transcriptionStatus.status === 'duplicate') { if (!transcriptionStatus.duplicate_media_id) { throw new Error('Sonix returned failed status and duplicate media id is not provided. Please check portal https://my.sonix.ai/ for more details'); } const duplicateMediaId = transcriptionStatus.duplicate_media_id; transcriptionStatus = Object.assign(Object.assign({}, transcriptionStatus), { id: duplicateMediaId }); break; } if (transcriptionStatus.status === 'failed') { throw new Error('Sonix returned failed status. Please check portal https://my.sonix.ai/ for more details'); } } const transcription = yield this.getTranscriptionResult(transcriptionStatus.id, language); return { jobId: transcriptionStatus.id, text: transcription, status: 'completed', }; } catch (error) { return { jobId, text: '', status: 'failed', error: error.message, }; } }); } translateTranscription(request) { return __awaiter(this, void 0, void 0, function* () { try { yield this.queueTranslation(request); const startTime = Date.now(); let translationStatus = yield this.getTranslationStatus(request); while (translationStatus.status !== 'completed') { if (Date.now() - startTime > constants_1.MAX_WAIT_TIME) { throw new Error('Transcription timeout'); } yield this.delay(constants_1.RECOGNITION_POLLING_DELAY); translationStatus = yield this.getTranslationStatus(request); if (translationStatus.status === 'failed') { throw new Error('Sonix returned failed status. Please check portal https://my.sonix.ai/ for more details'); } } const transcriptionEnglish = yield this.getTranscriptionResult(request.transcriptionJobId, request.language); return { jobId: request.transcriptionJobId, text: transcriptionEnglish, status: 'completed', }; } catch (error) { return { jobId: request.transcriptionJobId, text: '', status: 'failed', error: error.message, }; } }); } } exports.SonixSpeechRecognitionService = SonixSpeechRecognitionService;