mirror of
https://github.com/Vateron-Media/XC_VM.git
synced 2026-10-20 12:02:58 +02:00
fix(streaming): import and map all VOD subtitles, not just the first
buildSubtitleImport nested the metadata loop inside the import loop and reused the outer counter $i. The inner loop advanced $i to count(files), so the outer import loop exited after its first iteration: only the first subtitle was imported (-sub_charenc -i), while -map/-metadata was still emitted for every file — mapping ffmpeg inputs that were never added. Multi-subtitle movies got a single imported track plus dangling -map references (broken output). Split the nested loop into two siblings — import every file, then map every file — and cache the count. All configured subtitles are now imported and mapped to the correct input index. Add tests/Unit/StreamProcessSubtitleTest.php covering empty input, a single local subtitle, remote-server fetch, and the multi-subtitle case that reproduces the defect (import count was 1, must equal N). Verified red→green against the pre-fix code. Verified: php -l clean, make gates green, phpunit 336/336 green.
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use XcVm\Domain\Stream\StreamProcess;
|
||||
|
||||
/**
|
||||
* Unit tests for StreamProcess::buildSubtitleImport() — the VOD subtitle
|
||||
* import/metadata builder extracted from startMovie.
|
||||
*
|
||||
* Guards the fix for the nested-loop $i reuse that imported only the first
|
||||
* subtitle while emitting -map metadata for every file.
|
||||
*/
|
||||
final class StreamProcessSubtitleTest extends TestCase {
|
||||
|
||||
public static function setUpBeforeClass(): void {
|
||||
if (!defined('SERVER_ID')) {
|
||||
define('SERVER_ID', 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the private static buildSubtitleImport() via reflection.
|
||||
*
|
||||
* @return array{0:string,1:string} [$import, $metadata]
|
||||
*/
|
||||
private function build(string $json, array $servers = []): array {
|
||||
$m = new ReflectionMethod(StreamProcess::class, 'buildSubtitleImport');
|
||||
$m->setAccessible(true);
|
||||
return $m->invoke(null, $json, $servers);
|
||||
}
|
||||
|
||||
public function testNoSubtitlesReturnsEmptyStrings(): void {
|
||||
[$import, $meta] = $this->build('');
|
||||
$this->assertSame('', $import);
|
||||
$this->assertSame('', $meta);
|
||||
|
||||
[$import, $meta] = $this->build('{"files":[]}');
|
||||
$this->assertSame('', $import);
|
||||
$this->assertSame('', $meta);
|
||||
}
|
||||
|
||||
public function testSingleLocalSubtitleImportedAndMapped(): void {
|
||||
$json = json_encode([
|
||||
'location' => SERVER_ID,
|
||||
'files' => ['/subs/en.srt'],
|
||||
'charset' => ['UTF-8'],
|
||||
'names' => ['English'],
|
||||
]);
|
||||
[$import, $meta] = $this->build($json);
|
||||
|
||||
$this->assertSame(1, substr_count($import, '-sub_charenc'));
|
||||
$this->assertStringContainsString('/subs/en.srt', $import);
|
||||
$this->assertSame(1, substr_count($meta, '-map '));
|
||||
$this->assertStringContainsString('-map 1 ', $meta);
|
||||
$this->assertStringContainsString('title=English', $meta);
|
||||
}
|
||||
|
||||
/**
|
||||
* The bug fix: every subtitle must be imported AND mapped. The old nested
|
||||
* loop imported only the first file while mapping all of them, so this
|
||||
* previously failed (import count was 1, not 3).
|
||||
*/
|
||||
public function testAllSubtitlesAreImportedAndMapped(): void {
|
||||
$json = json_encode([
|
||||
'location' => SERVER_ID,
|
||||
'files' => ['/subs/en.srt', '/subs/fr.srt', '/subs/de.srt'],
|
||||
'charset' => ['UTF-8', 'UTF-8', 'UTF-8'],
|
||||
'names' => ['English', 'French', 'German'],
|
||||
]);
|
||||
[$import, $meta] = $this->build($json);
|
||||
|
||||
// All three imported (the old nested-loop code produced only one).
|
||||
$this->assertSame(3, substr_count($import, '-sub_charenc'), 'all subtitles imported');
|
||||
$this->assertStringContainsString('/subs/en.srt', $import);
|
||||
$this->assertStringContainsString('/subs/fr.srt', $import);
|
||||
$this->assertStringContainsString('/subs/de.srt', $import);
|
||||
|
||||
// Each mapped to its own input index 1..N.
|
||||
$this->assertSame(3, substr_count($meta, '-map '));
|
||||
$this->assertStringContainsString('-map 1 ', $meta);
|
||||
$this->assertStringContainsString('-map 2 ', $meta);
|
||||
$this->assertStringContainsString('-map 3 ', $meta);
|
||||
}
|
||||
|
||||
public function testRemoteSubtitleUsesServerApiUrl(): void {
|
||||
$servers = [2 => ['api_url' => 'http://node2/api?key=abc']];
|
||||
$json = json_encode([
|
||||
'location' => 2,
|
||||
'files' => ['remote.srt'],
|
||||
'charset' => ['UTF-8'],
|
||||
'names' => ['Remote'],
|
||||
]);
|
||||
[$import] = $this->build($json, $servers);
|
||||
|
||||
$this->assertStringContainsString('http://node2/api?key=abc', $import);
|
||||
$this->assertStringContainsString('action=getFile', $import);
|
||||
$this->assertStringContainsString('filename=', $import);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user