Detect local audio URLs in MediaUrlResolver

Recognizes mp3/wav/ogg/m4a and emits <audio controls class="kb-audio">.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Yutaka Kurosaki
2026-05-09 10:44:35 +09:00
parent 7e445eb2fe
commit bb9843fd47
2 changed files with 33 additions and 1 deletions
+13 -1
View File
@@ -6,12 +6,15 @@ class MediaUrlResolver
{ {
private const VIDEO_EXT = ['mp4', 'webm', 'ogv', 'mov', 'm4v']; private const VIDEO_EXT = ['mp4', 'webm', 'ogv', 'mov', 'm4v'];
private const AUDIO_EXT = ['mp3', 'wav', 'ogg', 'm4a'];
public function resolve(string $url): ?string public function resolve(string $url): ?string
{ {
if ($url === '') { if ($url === '') {
return null; return null;
} }
return $this->detectVideo($url); return $this->detectVideo($url)
?? $this->detectAudio($url);
} }
private function detectVideo(string $url): ?string private function detectVideo(string $url): ?string
@@ -23,6 +26,15 @@ private function detectVideo(string $url): ?string
return "<video src=\"{$safe}\" controls class=\"kb-video\"></video>"; return "<video src=\"{$safe}\" controls class=\"kb-video\"></video>";
} }
private function detectAudio(string $url): ?string
{
if (!in_array($this->getPathExtension($url), self::AUDIO_EXT, true)) {
return null;
}
$safe = htmlspecialchars($url, ENT_QUOTES, 'UTF-8');
return "<audio src=\"{$safe}\" controls class=\"kb-audio\"></audio>";
}
private function getPathExtension(string $url): string private function getPathExtension(string $url): string
{ {
$path = parse_url($url, PHP_URL_PATH); $path = parse_url($url, PHP_URL_PATH);
@@ -67,4 +67,24 @@ public function test_video_url_is_html_escaped(): void
$this->assertStringNotContainsString('"quote.mp4"', $html); $this->assertStringNotContainsString('"quote.mp4"', $html);
$this->assertStringContainsString('&quot;', $html); $this->assertStringContainsString('&quot;', $html);
} }
#[DataProvider('audioUrls')]
public function test_audio_urls_produce_audio_tag(string $url): void
{
$html = $this->resolver->resolve($url);
$this->assertNotNull($html);
$this->assertStringStartsWith('<audio', $html);
$this->assertStringContainsString('controls', $html);
$this->assertStringContainsString('class="kb-audio"', $html);
}
public static function audioUrls(): array
{
return [
'mp3' => ['/clip.mp3'],
'wav' => ['/clip.wav'],
'ogg' => ['/clip.ogg'],
'm4a' => ['/clip.m4a'],
];
}
} }