Files
zyt/server/tests/FollowupAudioPipelineLongMediaTest.php
T

33 lines
2.7 KiB
PHP

<?php
declare(strict_types=1);
require dirname(__DIR__) . '/vendor/autoload.php';
use app\common\service\followupaudio\FollowupAudioPipelineCheckpoint as Checkpoint;
use app\common\service\followupaudio\FollowupAudioPipelineMedia as Media;
$directory = sys_get_temp_dir() . '/fa-pipeline-hour-' . bin2hex(random_bytes(6)); mkdir($directory, 0700);
$source = $directory . '/hour.mp3'; $chunk = $directory . '/chunk.wav';
$checks = 0;
$expect = static function (bool $value, string $message) use (&$checks): void { if (!$value) { throw new RuntimeException($message); } $checks++; };
try {
$process = proc_open(['ffmpeg', '-nostdin', '-hide_banner', '-v', 'error', '-f', 'lavfi', '-i', 'anullsrc=r=16000:cl=mono',
'-t', '3599', '-c:a', 'libmp3lame', '-b:a', '32k', '-threads', '1', $source],
[0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']], $pipes);
fclose($pipes[0]); $stdout = stream_get_contents($pipes[1]); $stderr = stream_get_contents($pipes[2]); fclose($pipes[1]); fclose($pipes[2]);
$expect(proc_close($process) === 0 && $stdout === '' && $stderr === '', 'bounded generated mono near-hour synthetic source'); chmod($source, 0600);
$hash = hash_file('sha256', $source); $media = new Media([]); $audio = $media->inspect($source, $hash);
$expect($audio['channels'] === 1 && $audio['duration'] >= 3599 && $audio['duration'] <= 3600, 'source mono and true encoded duration: ' . json_encode([$audio['channels'], $audio['duration']]));
$task = ['sha256' => $hash, 'duration_seconds' => $audio['duration']];
$plan = Checkpoint::initial($task, str_repeat('a', 64), 120000);
$expect(count($plan['chunks']) === 30, '30 bounded chunks cover entire original'); $covered = 0;
foreach ($plan['chunks'] as $segment) {
$media->chunk($audio, $segment, $chunk, static fn (): bool => true);
$metadata = $media->inspect($chunk, hash_file('sha256', $chunk), true);
$expect($segment['start_ms'] === $covered && abs($metadata['duration'] * 1000 - ($segment['end_ms'] - $segment['start_ms'])) <= 80, 'contiguous real decoded coverage');
$expect($metadata['duration'] <= 120 && $metadata['channels'] === 1 && filesize($chunk) <= 4194304, 'bounded mono ASR copy');
$covered = $segment['end_ms']; unlink($chunk);
}
$expect($covered === (int) ceil($audio['duration'] * 1000) && hash_file('sha256', $source) === $hash, 'tail covered and original immutable');
echo 'FOLLOWUP_AUDIO_PIPELINE_LONG_MEDIA assertions=' . $checks . ' PASS real_near_hour=1 chunks=30 contiguous_coverage=1 bounded_pcm=1 mono_source_retained=1 network_calls=0' . PHP_EOL;
} finally { foreach (glob($directory . '/*') as $file) { unlink($file); } rmdir($directory); }