koel/app/Services/Streamer/Streamer.php

73 lines
2.3 KiB
PHP
Raw Normal View History

2024-02-24 07:28:49 +00:00
<?php
namespace App\Services\Streamer;
2024-04-18 17:20:14 +00:00
use App\Enums\SongStorageType;
2024-02-24 07:28:49 +00:00
use App\Exceptions\KoelPlusRequiredException;
use App\Models\Song;
use App\Services\Streamer\Adapters\DropboxStreamerAdapter;
use App\Services\Streamer\Adapters\LocalStreamerAdapter;
use App\Services\Streamer\Adapters\S3CompatibleStreamerAdapter;
2024-04-26 13:35:26 +00:00
use App\Services\Streamer\Adapters\SftpStreamerAdapter;
2024-02-24 07:28:49 +00:00
use App\Services\Streamer\Adapters\StreamerAdapter;
use App\Services\Streamer\Adapters\TranscodingStreamerAdapter;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
class Streamer
{
2024-04-18 14:36:28 +00:00
public function __construct(
private readonly Song $song,
2024-04-26 13:35:26 +00:00
private ?StreamerAdapter $adapter = null,
2024-04-18 14:36:28 +00:00
private readonly array $config = []
) {
2024-02-24 07:28:49 +00:00
// Turn off error reporting to make sure our stream isn't interfered.
@error_reporting(0);
2024-04-26 13:35:26 +00:00
$this->adapter ??= $this->resolveAdapter();
2024-02-24 07:28:49 +00:00
}
private function resolveAdapter(): StreamerAdapter
{
2024-04-18 17:20:14 +00:00
throw_unless($this->song->storage->supported(), KoelPlusRequiredException::class);
2024-02-24 07:28:49 +00:00
if ($this->shouldTranscode()) {
return app(TranscodingStreamerAdapter::class);
}
return match ($this->song->storage) {
2024-04-18 17:20:14 +00:00
SongStorageType::LOCAL => app(LocalStreamerAdapter::class),
2024-04-26 13:35:26 +00:00
SongStorageType::SFTP => app(SftpStreamerAdapter::class),
2024-04-18 17:20:14 +00:00
SongStorageType::S3, SongStorageType::S3_LAMBDA => app(S3CompatibleStreamerAdapter::class),
SongStorageType::DROPBOX => app(DropboxStreamerAdapter::class),
2024-02-24 07:28:49 +00:00
};
}
public function stream(): mixed
{
return $this->adapter->stream($this->song, $this->config);
}
private function shouldTranscode(): bool
{
// We only transcode local files. "Remote" transcoding (e.g., from Dropbox) is not supported.
2024-04-18 17:20:14 +00:00
if ($this->song->storage !== SongStorageType::LOCAL) {
2024-02-24 07:28:49 +00:00
return false;
}
if (Arr::get($this->config, 'transcode', false)) {
return true;
}
2024-04-18 17:20:14 +00:00
return Str::endsWith(File::mimeType($this->song->storage_metadata->getPath()), 'flac')
&& config('koel.streaming.transcode_flac')
&& is_executable(config('koel.streaming.ffmpeg_path'));
2024-02-24 07:28:49 +00:00
}
public function getAdapter(): StreamerAdapter
{
return $this->adapter;
}
}