AzuraCast/src/Radio/Adapters.php

218 lines
5.9 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Radio;
use App\Entity;
use App\Exception\NotFoundException;
use Psr\Container\ContainerInterface;
/**
* Manager class for radio adapters.
*/
class Adapters
{
public const FRONTEND_ICECAST = 'icecast';
public const FRONTEND_SHOUTCAST = 'shoutcast2';
public const FRONTEND_REMOTE = 'remote';
public const BACKEND_LIQUIDSOAP = 'liquidsoap';
public const BACKEND_NONE = 'none';
public const REMOTE_SHOUTCAST1 = 'shoutcast1';
public const REMOTE_SHOUTCAST2 = 'shoutcast2';
public const REMOTE_ICECAST = 'icecast';
public const REMOTE_AZURARELAY = 'azurarelay';
public function __construct(
protected ContainerInterface $adapters
) {
}
/**
* @param Entity\Station $station
*
* @throws NotFoundException
*/
public function getFrontendAdapter(Entity\Station $station): Frontend\AbstractFrontend
{
$adapters = $this->listFrontendAdapters();
$frontend_type = $station->getFrontendType();
if (!isset($adapters[$frontend_type])) {
throw new NotFoundException('Adapter not found: ' . $frontend_type);
}
$class_name = $adapters[$frontend_type]['class'];
if ($this->adapters->has($class_name)) {
return $this->adapters->get($class_name);
}
throw new NotFoundException('Adapter not found: ' . $class_name);
}
/**
* @param bool $check_installed
*
* @return mixed[]
*/
public function listFrontendAdapters(bool $check_installed = false): array
{
$adapters = [
self::FRONTEND_ICECAST => [
'name' => 'Icecast 2.4',
'class' => Frontend\Icecast::class,
],
self::FRONTEND_SHOUTCAST => [
'name' => 'SHOUTcast DNAS 2',
'class' => Frontend\SHOUTcast::class,
],
self::FRONTEND_REMOTE => [
'name' => 'Remote',
'class' => Frontend\Remote::class,
],
];
if ($check_installed) {
return array_filter(
$adapters,
function ($adapter_info) {
/** @var AbstractAdapter $adapter */
$adapter = $this->adapters->get($adapter_info['class']);
return $adapter->isInstalled();
}
);
}
return $adapters;
}
/**
* @param Entity\Station $station
*
* @throws NotFoundException
*/
public function getBackendAdapter(Entity\Station $station): Backend\AbstractBackend
{
$adapters = $this->listBackendAdapters();
$backend_type = $station->getBackendType();
if (!isset($adapters[$backend_type])) {
throw new NotFoundException('Adapter not found: ' . $backend_type);
}
$class_name = $adapters[$backend_type]['class'];
if ($this->adapters->has($class_name)) {
return $this->adapters->get($class_name);
}
throw new NotFoundException('Adapter not found: ' . $class_name);
}
/**
* @param bool $check_installed
*
* @return mixed[]
*/
public function listBackendAdapters(bool $check_installed = false): array
{
$adapters = [
self::BACKEND_LIQUIDSOAP => [
'name' => 'Liquidsoap',
'class' => Backend\Liquidsoap::class,
],
self::BACKEND_NONE => [
'name' => 'Disabled',
'class' => Backend\None::class,
],
];
if ($check_installed) {
return array_filter(
$adapters,
function ($adapter_info) {
/** @var AbstractAdapter $adapter */
$adapter = $this->adapters->get($adapter_info['class']);
return $adapter->isInstalled();
}
);
}
return $adapters;
}
/**
* @param Entity\Station $station
*
* @return Remote\AdapterProxy[]
* @throws NotFoundException
*/
public function getRemoteAdapters(Entity\Station $station): array
{
$remote_adapters = [];
foreach ($station->getRemotes() as $remote) {
$remote_adapters[] = new Remote\AdapterProxy($this->getRemoteAdapter($station, $remote), $remote);
}
return $remote_adapters;
}
/**
* Assemble an array of ready-to-operate
*
* @param Entity\Station $station
* @param Entity\StationRemote $remote
*
* @throws NotFoundException
*/
public function getRemoteAdapter(Entity\Station $station, Entity\StationRemote $remote): Remote\AbstractRemote
{
$adapters = $this->listRemoteAdapters();
$remote_type = $remote->getType();
if (!isset($adapters[$remote_type])) {
throw new NotFoundException('Adapter not found: ' . $remote_type);
}
$class_name = $adapters[$remote_type]['class'];
if ($this->adapters->has($class_name)) {
return $this->adapters->get($class_name);
}
throw new NotFoundException('Adapter not found: ' . $class_name);
}
/**
* @return mixed[]
*/
public function listRemoteAdapters(): array
{
return [
self::REMOTE_SHOUTCAST1 => [
'name' => 'SHOUTcast 1',
'class' => Remote\SHOUTcast1::class,
],
self::REMOTE_SHOUTCAST2 => [
'name' => 'SHOUTcast 2',
'class' => Remote\SHOUTcast2::class,
],
self::REMOTE_ICECAST => [
'name' => 'Icecast',
'class' => Remote\Icecast::class,
],
self::REMOTE_AZURARELAY => [
'name' => 'AzuraRelay',
'class' => Remote\AzuraRelay::class,
],
];
}
}