/
mikopbx
/
ModulePhraseStudio
Обзор
Документация
Войти
/
mikopbx
/
ModulePhraseStudio
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
Lib/RestAPI/Phrases/Actions/GeneratePhraseAction.php
83 строки
3 KB
Nikolay Beketov
feat: async voice install + UI status polling
05 май 2026, 06:32
05 май 2026, 06:32
8b826c8
Код
Авторство
О чём код?
<?php declare(strict_types=1); /* * MikoPBX - free phone system for small business * Copyright © 2017-2026 Alexey Portnov and Nikolay Beketov */ namespace Modules\ModulePhraseStudio\Lib\RestAPI\Phrases\Actions; use MikoPBX\PBXCoreREST\Lib\PBXApiResult; use Modules\ModulePhraseStudio\Lib\Engines\PiperEngine; use Modules\ModulePhraseStudio\Lib\PhraseStudioMain; /** * Generates (or returns a cached) phrase audio file. * * Runs entirely inside the standard `WorkerApiCommands` request thread — * Piper synthesis takes 1–3 s on a healthy box, which fits comfortably * in WorkerApiCommands' 30-second sync timeout. Cache hits return * without invoking Piper at all. There is no persistent module worker: * the rare slow op (voice download) is detached separately via * `Processes::mwExecBg` from `PhraseStudioMain::installVoice`. * * Validation order: * 1. text non-empty + length <= max_text_length * 2. voice_id present * 3. engine binary installed * 4. voice model installed (and not in 'installing' / 'failed' state) * 5. delegate to PhraseStudioMain (cache lookup → Piper → optional sox) * * @package Modules\ModulePhraseStudio\Lib\RestAPI\Phrases\Actions */ class GeneratePhraseAction { public static function main(array $data): PBXApiResult { $res = new PBXApiResult(); $res->processor = __METHOD__; $text = (string)($data['text'] ?? ''); $voiceId = trim((string)($data['voice_id'] ?? '')); $sampleRate = (string)($data['sample_rate'] ?? 'native'); if (trim($text) === '') { $res->messages['error'][] = 'text is required'; $res->httpCode = 400; return $res; } if ($voiceId === '') { $res->messages['error'][] = 'voice_id is required'; $res->httpCode = 400; return $res; } $engine = new PiperEngine(); if (!$engine->isInstalled()) { $res->messages['error'][] = 'Engine is not installed'; $res->httpCode = 409; return $res; } $main = new PhraseStudioMain(); $result = $main->generatePhrase($text, $voiceId, $sampleRate); $res->success = (bool)($result['success'] ?? false); $res->httpCode = $res->success ? 200 : 500; $res->data = [ 'phrase_id' => (int)($result['phrase_id'] ?? 0), 'cache_key' => (string)($result['cache_key'] ?? ''), 'cached' => (bool)($result['cached'] ?? false), 'voice_id' => $voiceId, 'sample_rate' => $sampleRate, 'message' => (string)($result['message'] ?? ''), ]; if (!$res->success) { $res->messages['error'][] = (string)($result['message'] ?? 'Generation failed'); } return $res; } }