adapter ??= $this->resolveAdapter(); } private function resolveAdapter(): StreamerAdapter { throw_unless($this->song->storage->supported(), KoelPlusRequiredException::class); if ($this->song->isEpisode()) { return app(PodcastStreamerAdapter::class); } if ($this->shouldTranscode()) { return app(TranscodingStreamerAdapter::class); } return match ($this->song->storage) { SongStorageType::LOCAL => app(LocalStreamerAdapter::class), SongStorageType::SFTP => app(SftpStreamerAdapter::class), SongStorageType::S3, SongStorageType::S3_LAMBDA => app(S3CompatibleStreamerAdapter::class), SongStorageType::DROPBOX => app(DropboxStreamerAdapter::class), }; } 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. if ($this->song->storage !== SongStorageType::LOCAL) { return false; } if (Arr::get($this->config, 'transcode', false)) { return true; } return Str::endsWith(File::mimeType($this->song->storage_metadata->getPath()), 'flac') && config('koel.streaming.transcode_flac') && is_executable(config('koel.streaming.ffmpeg_path')); } public function getAdapter(): StreamerAdapter { return $this->adapter; } }