/** * OpenAI: prepis nahravky na text. * * Sluzba: https://api.openai.com/v1 * Endpoint: POST /audio/transcriptions (multipart/form-data) * * Rozdil proti sluzbe Prepis hovoru: tam bezi dva enginy naraz a jejich * vysledky se slucuji, coz je presnejsi a drazsi. Tohle je jeden pruchod * pod vlastnim klicem, kdyz staci obycejny prepis. */ export const manifest = { id: 'openai.transcribe-audio', name: 'Přepsat zvuk', description: 'Přepíše nahrávku na text jedním přepisovacím modelem OpenAI.', inputs: [ { id: 'fileName', label: 'Název nahrávky', type: 'string', required: true, hint: 'Včetně přípony, například hovor.mp3. Podle ní se pozná formát.', }, { id: 'contentBase64', label: 'Nahrávka (Base64)', type: 'string', required: true, multiline: true, hint: 'Obsah zakódovaný v Base64. Formáty mp3, mp4, m4a, wav, webm, ogg a flac.', }, { id: 'model', label: 'Model', type: 'string', required: false, default: 'gpt-4o-mini-transcribe', hint: 'Například gpt-4o-mini-transcribe, gpt-4o-transcribe nebo whisper-1.', }, { id: 'language', label: 'Jazyk nahrávky', type: 'string', required: false, pattern: '^[a-zA-Z]{2}$', hint: 'Dvoupísmenný kód, například cs. Vyplněný jazyk přepis zpřesní i zrychlí.', }, { id: 'prompt', label: 'Nápověda k přepisu', type: 'string', required: false, multiline: true, hint: 'Vlastní jména, zkratky a názvy produktů, které se v nahrávce objeví.', }, ], outputs: [ { id: 'text', label: 'Přepis', type: 'string', required: true }, { id: 'model', label: 'Použitý model', type: 'string', required: true }, { id: 'length', label: 'Délka přepisu ve znacích', type: 'number', required: true }, ], // Prepis je nejpomalejsi operace v katalogu, delsi zaznam trva minuty. timeoutMs: 120000, }; /** Typ obsahu podle pripony. Zaroven seznam toho, co OpenAI prijme. */ const byExtension = { mp3: 'audio/mpeg', mpga: 'audio/mpeg', mpeg: 'audio/mpeg', mp4: 'audio/mp4', m4a: 'audio/mp4', wav: 'audio/wav', webm: 'audio/webm', ogg: 'audio/ogg', oga: 'audio/ogg', flac: 'audio/flac', }; export async function run(inputs, ctx) { const { pick, text, need } = ctx.util; const parts = inputs.fileName.split('.'); const extension = parts.length > 1 ? parts[parts.length - 1].toLowerCase() : ''; const contentType = byExtension[extension]; if (!contentType) { ctx.fail( `Přípona "${extension}" není podporovaný formát zvuku. ` + 'Použijte mp3, mp4, m4a, wav, webm, ogg nebo flac.', ); } const { body } = await ctx.http.postForm('/audio/transcriptions', { model: inputs.model, language: inputs.language, prompt: inputs.prompt, response_format: 'json', file: { filename: inputs.fileName, base64: inputs.contentBase64.trim(), contentType, }, }); const transcript = need(text(pick(body, 'text')), 'přepis'); return { text: transcript, model: inputs.model, length: transcript.length }; }