Rewrite frontend as single self-contained HTML file — all CSS/JS inline, no external files to fail loading
This commit is contained in:
75
dist/providers/tts/openAITTSProvider.js
vendored
Normal file
75
dist/providers/tts/openAITTSProvider.js
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.OpenAITTSProvider = void 0;
|
||||
const fs_1 = __importDefault(require("fs"));
|
||||
const child_process_1 = require("child_process");
|
||||
const openai_1 = require("openai");
|
||||
const mediaUtils_1 = require("../../utils/mediaUtils");
|
||||
/**
|
||||
* OpenAI TTS Provider Implementation
|
||||
*/
|
||||
class OpenAITTSProvider {
|
||||
constructor(config) {
|
||||
this.config = config;
|
||||
this.openai = new openai_1.OpenAI({
|
||||
apiKey: config.apiKey,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Convert text to speech
|
||||
* @param text - Text to convert to speech
|
||||
* @param outputPath - Output path for the audio file
|
||||
* @param options - Additional options
|
||||
* @returns Duration of the generated audio in seconds and cost
|
||||
*/
|
||||
async textToSpeech(text, outputPath, options = {}) {
|
||||
try {
|
||||
// Get the options, with defaults from config
|
||||
const voice = options.voice || this.config.voice;
|
||||
const model = options.model || this.config.model;
|
||||
const speedFactor = options.speedFactor || 1.0;
|
||||
// Generate the initial TTS output
|
||||
const tempOutputPath = outputPath.replace(/\.\w+$/, '_temp$&');
|
||||
const mp3 = await this.openai.audio.speech.create({
|
||||
model: model,
|
||||
voice: voice,
|
||||
input: text,
|
||||
...(options.instructions ? { instructions: options.instructions } : {})
|
||||
});
|
||||
// Cost calculation is based on character count
|
||||
const cost = text.length;
|
||||
const buffer = Buffer.from(await mp3.arrayBuffer());
|
||||
fs_1.default.writeFileSync(tempOutputPath, buffer);
|
||||
// Speed up the audio using FFmpeg if needed
|
||||
if (speedFactor !== 1.0) {
|
||||
(0, child_process_1.execSync)(`ffmpeg -v error -i "${tempOutputPath}" -filter:a "atempo=${speedFactor}" -c:a libmp3lame -q:a 2 "${outputPath}" -y`);
|
||||
// Clean up temporary file
|
||||
fs_1.default.unlinkSync(tempOutputPath);
|
||||
}
|
||||
else {
|
||||
// Just use the file as is
|
||||
fs_1.default.renameSync(tempOutputPath, outputPath);
|
||||
}
|
||||
// Get actual audio duration for accurate timing
|
||||
const audioDuration = (0, mediaUtils_1.getAudioDuration)(outputPath);
|
||||
return {
|
||||
duration: audioDuration,
|
||||
cost: cost
|
||||
};
|
||||
}
|
||||
catch (error) {
|
||||
console.error("Error generating speech:", error);
|
||||
// Create a silent audio file if TTS fails
|
||||
(0, child_process_1.execSync)(`ffmpeg -v error -f lavfi -i anullsrc=r=24000:cl=mono -t 1 -q:a 9 -acodec libmp3lame "${outputPath}" -y`);
|
||||
return {
|
||||
duration: 1,
|
||||
cost: 0
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.OpenAITTSProvider = OpenAITTSProvider;
|
||||
//# sourceMappingURL=openAITTSProvider.js.map
|
||||
Reference in New Issue
Block a user