tutoring/app/View/Components/VideoPlayer.php

73 lines
1.9 KiB
PHP

<?php
namespace App\View\Components;
use Closure;
use Illuminate\Contracts\View\View;
use Illuminate\View\Component;
class VideoPlayer extends Component
{
public string $url;
public ?string $title;
public function __construct(?string $url = null, ?string $title = null)
{
// Coerce null → "" then trim so downstream code is safe
$this->url = trim((string) $url);
$this->title = $title ?: 'Video';
}
public function provider(): ?string
{
if ($this->url === '') return null;
$u = $this->url;
if (stripos($u, '<iframe') !== false && preg_match('/src=["\']([^"\']+)["\']/', $u, $m)) {
$u = $m[1];
}
if (preg_match('~(youtube\.com|youtu\.be)~i', $u)) return 'youtube';
if (preg_match('~vimeo\.com~i', $u)) return 'vimeo';
return null;
}
public function videoId(): ?string
{
if ($this->url === '') return null;
$u = $this->url;
if (stripos($u, '<iframe') !== false && preg_match('/src=["\']([^"\']+)["\']/', $u, $m)) {
$u = $m[1];
}
if (preg_match('~(youtube\.com|youtu\.be)~i', $u) &&
preg_match('~(?:v=|/embed/|youtu\.be/)([0-9A-Za-z_-]{11})~', $u, $m)) {
return $m[1];
}
if (preg_match('~vimeo\.com~i', $u)) {
if (preg_match('~vimeo\.com/(?:video/)?(\d+)~', $u, $m)) return $m[1];
if (preg_match('~player\.vimeo\.com/video/(\d+)~', $u, $m)) return $m[1];
}
return null;
}
public function embedSrc(): ?string
{
$provider = $this->provider();
$id = $this->videoId();
if (!$provider || !$id) return null;
return match ($provider) {
'youtube' => "https://www.youtube.com/embed/{$id}",
'vimeo' => "https://player.vimeo.com/video/{$id}?title=0&byline=0&portrait=0",
default => null,
};
}
public function render(): View|Closure|string
{
return view('components.video-player', [
'embedSrc' => $this->embedSrc(),
'provider' => $this->provider(),
]);
}
}