HEX
Server: LiteSpeed
System: Linux houston.panomity.com 6.8.0-100-generic #100-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan 13 16:40:06 UTC 2026 x86_64
User: nudepix (1011)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: //home/panomity.de/vr.panomity.com/api/gpuq-stt-exec.php
<?php
/**
 * GPUQ STT-Exec: wird vom GPUQ-Worker aufgerufen (job_type vr_stt).
 * POST { _gpuq_secret, audio_path, language } → Transkription via vrstt (127.0.0.1:8032).
 */

header('Content-Type: application/json; charset=utf-8');

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['ok' => false, 'message' => 'Method not allowed']);
    exit;
}

$config = require __DIR__ . '/config.gpuq.php';

$raw = file_get_contents('php://input') ?: '';
$body = json_decode($raw, true);
if (!is_array($body)) {
    http_response_code(400);
    echo json_encode(['ok' => false, 'message' => 'Invalid JSON payload']);
    exit;
}

$secret = (string)($body['_gpuq_secret'] ?? '');
if ($secret === '' || !hash_equals((string)($config['self_exec_secret'] ?? ''), $secret)) {
    http_response_code(403);
    echo json_encode(['ok' => false, 'message' => 'Forbidden']);
    exit;
}

$audioPath = (string)($body['audio_path'] ?? '');
$language = strtolower(trim((string)($body['language'] ?? '')));

// Nur Dateien aus dem dafür vorgesehenen Cache-Verzeichnis zulassen.
$sttDir = realpath(__DIR__ . '/../admin/data/cache/stt');
$real = $audioPath !== '' ? realpath($audioPath) : false;
if ($sttDir === false || $real === false || strpos($real, $sttDir . '/') !== 0 || !is_file($real)) {
    http_response_code(400);
    echo json_encode(['ok' => false, 'message' => 'Invalid audio_path']);
    exit;
}

$sttUrl = rtrim((string)($config['stt_url'] ?? 'http://127.0.0.1:8032'), '/') . '/transcribe';

$post = ['file' => new CURLFile($real, null, basename($real))];
if (preg_match('/^[a-z]{2}$/', $language)) {
    $post['language'] = $language;
}

$ch = curl_init($sttUrl);
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $post,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 90,
]);
$response = curl_exec($ch);
$error = curl_error($ch);
$httpCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($response === false || $httpCode !== 200) {
    http_response_code(502);
    echo json_encode(['ok' => false, 'message' => 'STT service error: ' . ($error ?: ('HTTP ' . $httpCode))]);
    exit;
}

$decoded = json_decode((string)$response, true);
if (!is_array($decoded) || empty($decoded['ok'])) {
    http_response_code(502);
    echo json_encode(['ok' => false, 'message' => 'STT service invalid response']);
    exit;
}

echo json_encode([
    'ok' => true,
    'text' => (string)($decoded['text'] ?? ''),
    'language' => (string)($decoded['language'] ?? ''),
    'duration' => $decoded['duration'] ?? null,
], JSON_UNESCAPED_UNICODE);