#1281 #1282 -- Add remotes/mount point API.

This commit is contained in:
Buster Neece 2019-04-09 23:46:51 -05:00
parent 9f4d548953
commit 4f68512b43
No known key found for this signature in database
GPG key ID: 6D9E12FF03411F4E
10 changed files with 717 additions and 11 deletions

View file

@ -32,9 +32,9 @@ return [
'label' => __('Remote Station Type'),
'required' => true,
'choices' => [
'shoutcast1' => 'SHOUTcast v1',
'shoutcast2' => 'SHOUTcast v2',
'icecast' => 'Icecast v2.4+',
StationRemote::TYPE_SHOUTCAST1 => 'SHOUTcast v1',
StationRemote::TYPE_SHOUTCAST2 => 'SHOUTcast v2',
StationRemote::TYPE_ICECAST => 'Icecast v2.4+',
],
]
],

View file

@ -301,6 +301,30 @@ return function(App $app)
$this->get('/art/{media_id:[a-zA-Z0-9]+}', Controller\Api\Stations\MediaController::class.':artAction');
$this->group('', function() {
/** @var App $this */
$this->get('/mounts', Controller\Api\Stations\MountsController::class.':listAction')
->setName('api:stations:mounts');
$this->post('/mounts', Controller\Api\Stations\MountsController::class.':createAction');
$this->get('/mount/{id}', Controller\Api\Stations\MountsController::class.':getAction')
->setName('api:stations:mount');
$this->put('/mount/{id}', Controller\Api\Stations\MountsController::class.':editAction');
$this->delete('/mount/{id}', Controller\Api\Stations\MountsController::class.':deleteAction');
})->add([Middleware\Permissions::class, Acl::STATION_MOUNTS, true]);
$this->group('', function() {
/** @var App $this */
$this->get('/remotes', Controller\Api\Stations\RemotesController::class.':listAction')
->setName('api:stations:remotes');
$this->post('/remotes', Controller\Api\Stations\RemotesController::class.':createAction');
$this->get('/remote/{id}', Controller\Api\Stations\RemotesController::class.':getAction')
->setName('api:stations:remote');
$this->put('/remote/{id}', Controller\Api\Stations\RemotesController::class.':editAction');
$this->delete('/remote/{id}', Controller\Api\Stations\RemotesController::class.':deleteAction');
})->add([Middleware\Permissions::class, Acl::STATION_REMOTES, true]);
$this->group('', function() {
/** @var App $this */
$this->get('/streamers', Controller\Api\Stations\StreamersController::class.':listAction')

View file

@ -0,0 +1,114 @@
<?php
namespace App\Controller\Api\Stations;
use App\Entity;
use App\Http\Request;
use OpenApi\Annotations as OA;
/**
* @see \App\Provider\ApiProvider
*/
class MountsController extends AbstractStationCrudController
{
protected $entityClass = Entity\StationMount::class;
protected $resourceRouteName = 'api:stations:mount';
/**
* @OA\Get(path="/station/{station_id}/mounts",
* tags={"Stations: Mounts"},
* description="List all current mount points.",
* @OA\Parameter(ref="#/components/parameters/station_id_required"),
* @OA\Response(response=200, description="Success",
* @OA\JsonContent(type="array", @OA\Items(ref="#/components/schemas/StationMount"))
* ),
* @OA\Response(response=403, description="Access denied"),
* security={{"api_key": {}}},
* )
*
* @OA\Post(path="/station/{station_id}/mounts",
* tags={"Stations: Mounts"},
* description="Create a new mount point.",
* @OA\Parameter(ref="#/components/parameters/station_id_required"),
* @OA\RequestBody(
* @OA\JsonContent(ref="#/components/schemas/StationMount")
* ),
* @OA\Response(response=200, description="Success",
* @OA\JsonContent(ref="#/components/schemas/StationMount")
* ),
* @OA\Response(response=403, description="Access denied"),
* security={{"api_key": {}}},
* )
*
* @OA\Get(path="/station/{station_id}/mount/{id}",
* tags={"Stations: Mounts"},
* description="Retrieve details for a single mount point.",
* @OA\Parameter(ref="#/components/parameters/station_id_required"),
* @OA\Parameter(
* name="id",
* in="path",
* description="Streamer ID",
* required=true,
* @OA\Schema(type="integer", format="int64")
* ),
* @OA\Response(response=200, description="Success",
* @OA\JsonContent(ref="#/components/schemas/StationMount")
* ),
* @OA\Response(response=403, description="Access denied"),
* security={{"api_key": {}}},
* )
*
* @OA\Put(path="/station/{station_id}/mount/{id}",
* tags={"Stations: Mounts"},
* description="Update details of a single mount point.",
* @OA\RequestBody(
* @OA\JsonContent(ref="#/components/schemas/StationMount")
* ),
* @OA\Parameter(ref="#/components/parameters/station_id_required"),
* @OA\Parameter(
* name="id",
* in="path",
* description="Streamer ID",
* required=true,
* @OA\Schema(type="integer", format="int64")
* ),
* @OA\Response(response=200, description="Success",
* @OA\JsonContent(ref="#/components/schemas/Api_Status")
* ),
* @OA\Response(response=403, description="Access denied"),
* security={{"api_key": {}}},
* )
*
* @OA\Delete(path="/station/{station_id}/mount/{id}",
* tags={"Stations: Mounts"},
* description="Delete a single mount point.",
* @OA\Parameter(ref="#/components/parameters/station_id_required"),
* @OA\Parameter(
* name="id",
* in="path",
* description="StationMount ID",
* required=true,
* @OA\Schema(type="integer", format="int64")
* ),
* @OA\Response(response=200, description="Success",
* @OA\JsonContent(ref="#/components/schemas/Api_Status")
* ),
* @OA\Response(response=403, description="Access denied"),
* security={{"api_key": {}}},
* )
*/
/**
* @inheritDoc
*/
protected function _getStation(Request $request): Entity\Station
{
$station = parent::_getStation($request);
$frontend = $request->getStationFrontend();
if (!$frontend::supportsMounts()) {
throw new \App\Exception\StationUnsupported;
}
return $station;
}
}

View file

@ -0,0 +1,99 @@
<?php
namespace App\Controller\Api\Stations;
use App\Entity;
use App\Http\Request;
use OpenApi\Annotations as OA;
/**
* @see \App\Provider\ApiProvider
*/
class RemotesController extends AbstractStationCrudController
{
protected $entityClass = Entity\StationRemote::class;
protected $resourceRouteName = 'api:stations:remote';
/**
* @OA\Get(path="/station/{station_id}/remotes",
* tags={"Stations: Remote Relays"},
* description="List all current remote relays.",
* @OA\Parameter(ref="#/components/parameters/station_id_required"),
* @OA\Response(response=200, description="Success",
* @OA\JsonContent(type="array", @OA\Items(ref="#/components/schemas/StationRemote"))
* ),
* @OA\Response(response=403, description="Access denied"),
* security={{"api_key": {}}},
* )
*
* @OA\Post(path="/station/{station_id}/remotes",
* tags={"Stations: Remote Relays"},
* description="Create a new remote relay.",
* @OA\Parameter(ref="#/components/parameters/station_id_required"),
* @OA\RequestBody(
* @OA\JsonContent(ref="#/components/schemas/StationRemote")
* ),
* @OA\Response(response=200, description="Success",
* @OA\JsonContent(ref="#/components/schemas/StationRemote")
* ),
* @OA\Response(response=403, description="Access denied"),
* security={{"api_key": {}}},
* )
*
* @OA\Get(path="/station/{station_id}/remote/{id}",
* tags={"Stations: Remote Relays"},
* description="Retrieve details for a single remote relay.",
* @OA\Parameter(ref="#/components/parameters/station_id_required"),
* @OA\Parameter(
* name="id",
* in="path",
* description="Streamer ID",
* required=true,
* @OA\Schema(type="integer", format="int64")
* ),
* @OA\Response(response=200, description="Success",
* @OA\JsonContent(ref="#/components/schemas/StationRemote")
* ),
* @OA\Response(response=403, description="Access denied"),
* security={{"api_key": {}}},
* )
*
* @OA\Put(path="/station/{station_id}/remote/{id}",
* tags={"Stations: Remote Relays"},
* description="Update details of a single remote relay.",
* @OA\RequestBody(
* @OA\JsonContent(ref="#/components/schemas/StationRemote")
* ),
* @OA\Parameter(ref="#/components/parameters/station_id_required"),
* @OA\Parameter(
* name="id",
* in="path",
* description="Streamer ID",
* required=true,
* @OA\Schema(type="integer", format="int64")
* ),
* @OA\Response(response=200, description="Success",
* @OA\JsonContent(ref="#/components/schemas/Api_Status")
* ),
* @OA\Response(response=403, description="Access denied"),
* security={{"api_key": {}}},
* )
*
* @OA\Delete(path="/station/{station_id}/remote/{id}",
* tags={"Stations: Remote Relays"},
* description="Delete a single remote relay.",
* @OA\Parameter(ref="#/components/parameters/station_id_required"),
* @OA\Parameter(
* name="id",
* in="path",
* description="StationRemote ID",
* required=true,
* @OA\Schema(type="integer", format="int64")
* ),
* @OA\Response(response=200, description="Success",
* @OA\JsonContent(ref="#/components/schemas/Api_Status")
* ),
* @OA\Response(response=403, description="Access denied"),
* security={{"api_key": {}}},
* )
*/
}

View file

@ -10,7 +10,9 @@ use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use OpenApi\Annotations as OA;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
use App\Validator\Constraints as AppAssert;
use App\Radio\Adapters;
use App\Radio\Frontend\AbstractFrontend;
use App\Radio\Remote\AdapterProxy;
@ -51,6 +53,8 @@ class Station
* @ORM\Column(name="name", type="string", length=100, nullable=true)
*
* @OA\Property(example="AzuraTest Radio")
*
* @Assert\NotBlank()
* @var string|null The full display name of the station.
*/
protected $name;
@ -59,6 +63,8 @@ class Station
* @ORM\Column(name="short_name", type="string", length=100, nullable=true)
*
* @OA\Property(example="azuratest_radio")
*
* @Assert\NotBlank()
* @var string|null The URL-friendly name for the station, typically auto-generated from the full station name.
*/
protected $short_name;
@ -75,6 +81,8 @@ class Station
* @ORM\Column(name="frontend_type", type="string", length=100, nullable=true)
*
* @OA\Property(example="icecast")
*
* @Assert\Choice(choices={Adapters::FRONTEND_ICECAST, Adapters::FRONTEND_REMOTE, Adapters::FRONTEND_SHOUTCAST})
* @var string|null The frontend adapter (icecast,shoutcast,remote,etc)
*/
protected $frontend_type;
@ -90,6 +98,7 @@ class Station
/**
* @ORM\Column(name="backend_type", type="string", length=100, nullable=true)
*
* @Assert\Choice(choices={Adapters::BACKEND_LIQUIDSOAP, Adapters::BACKEND_NONE})
* @OA\Property(example="liquidsoap")
* @var string|null The backend adapter (liquidsoap,etc)
*/

View file

@ -2,6 +2,8 @@
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use OpenApi\Annotations as OA;
use Symfony\Component\Validator\Constraints as Assert;
use App\Radio\Adapters;
use App\Radio\Frontend\AbstractFrontend;
@ -11,6 +13,8 @@ use Psr\Http\Message\UriInterface;
* @ORM\Table(name="station_mounts")
* @ORM\Entity(repositoryClass="App\Entity\Repository\StationMountRepository")
* @ORM\HasLifecycleCallbacks
*
* @OA\Schema(type="object")
*/
class StationMount implements StationMountInterface
{
@ -20,6 +24,8 @@ class StationMount implements StationMountInterface
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*
* @OA\Property(example=1)
* @var int
*/
protected $id;
@ -41,78 +47,118 @@ class StationMount implements StationMountInterface
/**
* @ORM\Column(name="name", type="string", length=100)
*
* @OA\Property(example="/radio.mp3")
* @Assert\NotBlank()
*
* @var string
*/
protected $name = '';
/**
* @ORM\Column(name="display_name", type="string", length=255, nullable=true)
*
* @OA\Property(example="128kbps MP3")
*
* @var string|null
*/
protected $display_name;
/**
* @ORM\Column(name="is_visible_on_public_pages", type="boolean")
*
* @OA\Property(example=true)
*
* @var bool
*/
protected $is_visible_on_public_pages = true;
/**
* @ORM\Column(name="is_default", type="boolean")
*
* @OA\Property(example=false)
*
* @var bool
*/
protected $is_default = false;
/**
* @ORM\Column(name="is_public", type="boolean")
*
* @OA\Property(example=false)
*
* @var bool
*/
protected $is_public = false;
/**
* @ORM\Column(name="fallback_mount", type="string", length=100, nullable=true)
*
* @OA\Property(example="/error.mp3")
*
* @var string|null
*/
protected $fallback_mount;
/**
* @ORM\Column(name="relay_url", type="string", length=255, nullable=true)
*
* @OA\Property(example="http://radio.example.com:8000/radio.mp3")
*
* @var string|null
*/
protected $relay_url;
/**
* @ORM\Column(name="authhash", type="string", length=255, nullable=true)
*
* @OA\Property(example="")
*
* @var string|null
*/
protected $authhash;
/**
* @ORM\Column(name="enable_autodj", type="boolean")
*
* @OA\Property(example=true)
*
* @var bool
*/
protected $enable_autodj = true;
/**
* @ORM\Column(name="autodj_format", type="string", length=10, nullable=true)
*
* @OA\Property(example="mp3")
*
* @var string|null
*/
protected $autodj_format = 'mp3';
/**
* @ORM\Column(name="autodj_bitrate", type="smallint", nullable=true)
*
* @OA\Property(example=128)
*
* @var int|null
*/
protected $autodj_bitrate = 128;
/**
* @ORM\Column(name="custom_listen_url", type="string", length=255, nullable=true)
*
* @OA\Property(example="https://custom-listen-url.example.com/stream.mp3")
*
* @var string|null
*/
protected $custom_listen_url;
/**
* @ORM\Column(name="frontend_config", type="text", nullable=true)
*
* @OA\Property(@OA\Items())
*
* @var string|null
*/
protected $frontend_config;

View file

@ -2,6 +2,8 @@
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use OpenApi\Annotations as OA;
use Symfony\Component\Validator\Constraints as Assert;
use App\Radio\Adapters;
use App\Radio\Remote\AbstractRemote;
@ -10,15 +12,23 @@ use App\Radio\Remote\AbstractRemote;
* @ORM\Table(name="station_remotes")
* @ORM\Entity()
* @ORM\HasLifecycleCallbacks
*
* @OA\Schema(type="object")
*/
class StationRemote implements StationMountInterface
{
public const TYPE_SHOUTCAST1 = 'shoutcast1';
public const TYPE_SHOUTCAST2 = 'shoutcast2';
public const TYPE_ICECAST = 'icecast';
use Traits\TruncateStrings;
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*
* @OA\Property(example=1)
* @var int
*/
protected $id;
@ -40,84 +50,127 @@ class StationRemote implements StationMountInterface
/**
* @ORM\Column(name="display_name", type="string", length=255, nullable=true)
*
* @OA\Property(example="128kbps MP3")
*
* @var string|null
*/
protected $display_name;
/**
* @ORM\Column(name="is_visible_on_public_pages", type="boolean")
*
* @OA\Property(example=true)
*
* @var bool
*/
protected $is_visible_on_public_pages = true;
/**
* @ORM\Column(name="type", type="string", length=50)
*
* @OA\Property(example="icecast")
* @Assert\Choice(choices={StationRemote::TYPE_ICECAST, StationRemote::TYPE_SHOUTCAST1, StationRemote::TYPE_SHOUTCAST2})
*
* @var string
*/
protected $type;
/**
* @ORM\Column(name="enable_autodj", type="boolean")
*
* @OA\Property(example=false)
*
* @var bool
*/
protected $enable_autodj = false;
/**
* @ORM\Column(name="autodj_format", type="string", length=10, nullable=true)
*
* @OA\Property(example="mp3")
*
* @var string|null
*/
protected $autodj_format;
/**
* @ORM\Column(name="autodj_bitrate", type="smallint", nullable=true)
*
* @OA\Property(example=128)
*
* @var int|null
*/
protected $autodj_bitrate;
/**
* @ORM\Column(name="custom_listen_url", type="string", length=255, nullable=true)
*
* @OA\Property(example="https://custom-listen-url.example.com/stream.mp3")
*
* @var string|null
*/
protected $custom_listen_url;
/**
* @ORM\Column(name="url", type="string", length=255, nullable=true)
*
* @OA\Property(example="http://custom-url.example.com")
*
* @var string|null
*/
protected $url;
/**
* @ORM\Column(name="mount", type="string", length=150, nullable=true)
*
* @OA\Property(example="/stream.mp3")
*
* @var string|null
*/
protected $mount;
/**
* @ORM\Column(name="source_port", type="smallint", nullable=true)
*
* @OA\Property(example=8000)
*
* @var int|null
*/
protected $source_port;
/**
* @ORM\Column(name="source_mount", type="string", length=150, nullable=true)
*
* @OA\Property(example="/")
*
* @var string|null
*/
protected $source_mount;
/**
* @ORM\Column(name="source_username", type="string", length=100, nullable=true)
*
* @OA\Property(example="source")
*
* @var string|null
*/
protected $source_username;
/**
* @ORM\Column(name="source_password", type="string", length=100, nullable=true)
*
* @OA\Property(example="password")
*
* @var string|null
*/
protected $source_password;
/**
* @ORM\Column(name="is_public", type="boolean")
*
* @OA\Property(example=false)
*
* @var bool
*/
protected $is_public = false;

View file

@ -48,7 +48,7 @@ class StationStreamer
* @ORM\Column(name="streamer_username", type="string", length=50, nullable=false)
*
* @OA\Property(example="dj_test")
* @Assert\NotBlank
* @Assert\NotBlank()
* @var string
*/
protected $streamer_username;

View file

@ -101,6 +101,8 @@ class ApiProvider implements ServiceProviderInterface
Api\Admin\RolesController::class,
Api\Admin\SettingsController::class,
Api\Admin\StationsController::class,
Api\Stations\MountsController::class,
Api\Stations\RemotesController::class,
Api\Stations\StreamersController::class,
];

View file

@ -718,6 +718,139 @@ paths:
description: 'The requested album artwork'
'404':
description: 'Image not found; generic filler image.'
'/station/{station_id}/mounts':
get:
tags:
- 'Stations: Mounts'
description: 'List all current mount points.'
parameters:
-
$ref: '#/components/parameters/station_id_required'
responses:
'200':
description: Success
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/StationMount'
'403':
description: 'Access denied'
security:
-
api_key: []
post:
tags:
- 'Stations: Mounts'
description: 'Create a new mount point.'
parameters:
-
$ref: '#/components/parameters/station_id_required'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/StationMount'
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/StationMount'
'403':
description: 'Access denied'
security:
-
api_key: []
'/station/{station_id}/mount/{id}':
get:
tags:
- 'Stations: Mounts'
description: 'Retrieve details for a single mount point.'
parameters:
-
$ref: '#/components/parameters/station_id_required'
-
name: id
in: path
description: 'Streamer ID'
required: true
schema:
type: integer
format: int64
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/StationMount'
'403':
description: 'Access denied'
security:
-
api_key: []
put:
tags:
- 'Stations: Mounts'
description: 'Update details of a single mount point.'
parameters:
-
$ref: '#/components/parameters/station_id_required'
-
name: id
in: path
description: 'Streamer ID'
required: true
schema:
type: integer
format: int64
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/StationMount'
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/Api_Status'
'403':
description: 'Access denied'
security:
-
api_key: []
delete:
tags:
- 'Stations: Mounts'
description: 'Delete a single mount point.'
parameters:
-
$ref: '#/components/parameters/station_id_required'
-
name: id
in: path
description: 'StationMount ID'
required: true
schema:
type: integer
format: int64
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/Api_Status'
'403':
description: 'Access denied'
security:
-
api_key: []
'/station/{station_id}/queue':
get:
tags:
@ -798,6 +931,139 @@ paths:
security:
-
api_key: []
'/station/{station_id}/remotes':
get:
tags:
- 'Stations: Remote Relays'
description: 'List all current remote relays.'
parameters:
-
$ref: '#/components/parameters/station_id_required'
responses:
'200':
description: Success
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/StationRemote'
'403':
description: 'Access denied'
security:
-
api_key: []
post:
tags:
- 'Stations: Remote Relays'
description: 'Create a new remote relay.'
parameters:
-
$ref: '#/components/parameters/station_id_required'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/StationRemote'
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/StationRemote'
'403':
description: 'Access denied'
security:
-
api_key: []
'/station/{station_id}/remote/{id}':
get:
tags:
- 'Stations: Remote Relays'
description: 'Retrieve details for a single remote relay.'
parameters:
-
$ref: '#/components/parameters/station_id_required'
-
name: id
in: path
description: 'Streamer ID'
required: true
schema:
type: integer
format: int64
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/StationRemote'
'403':
description: 'Access denied'
security:
-
api_key: []
put:
tags:
- 'Stations: Remote Relays'
description: 'Update details of a single remote relay.'
parameters:
-
$ref: '#/components/parameters/station_id_required'
-
name: id
in: path
description: 'Streamer ID'
required: true
schema:
type: integer
format: int64
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/StationRemote'
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/Api_Status'
'403':
description: 'Access denied'
security:
-
api_key: []
delete:
tags:
- 'Stations: Remote Relays'
description: 'Delete a single remote relay.'
parameters:
-
$ref: '#/components/parameters/station_id_required'
-
name: id
in: path
description: 'StationRemote ID'
required: true
schema:
type: integer
format: int64
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/Api_Status'
'403':
description: 'Access denied'
security:
-
api_key: []
'/station/{station_id}/requests':
get:
tags:
@ -1172,7 +1438,7 @@ components:
connected_on:
description: 'UNIX timestamp that the user first connected.'
type: integer
example: 1554636757
example: 1554805409
connected_time:
description: 'Number of seconds that the user has been connected.'
type: integer
@ -1268,7 +1534,7 @@ components:
cued_at:
description: 'UNIX timestamp when the item was cued for playback.'
type: integer
example: 1554636757
example: 1554805409
autodj_custom_uri:
description: 'Custom AutoDJ playback URI, if it exists.'
type: string
@ -1323,7 +1589,7 @@ components:
played_at:
description: 'UNIX timestamp when playback started.'
type: integer
example: 1554636757
example: 1554805409
duration:
description: 'Duration of the song in seconds'
type: integer
@ -1454,7 +1720,7 @@ components:
timestamp:
description: 'The current UNIX timestamp'
type: integer
example: 1554636757
example: 1554805409
type: object
Api_Time:
properties:
@ -1601,6 +1867,99 @@ components:
type: string
example: 1048576
type: object
StationMount:
properties:
id:
type: integer
example: 1
name:
type: string
example: /radio.mp3
display_name:
type: string
example: '128kbps MP3'
is_visible_on_public_pages:
type: boolean
example: true
is_default:
type: boolean
example: false
is_public:
type: boolean
example: false
fallback_mount:
type: string
example: /error.mp3
relay_url:
type: string
example: 'http://radio.example.com:8000/radio.mp3'
authhash:
type: string
example: ''
enable_autodj:
type: boolean
example: true
autodj_format:
type: string
example: mp3
autodj_bitrate:
type: integer
example: 128
custom_listen_url:
type: string
example: 'https://custom-listen-url.example.com/stream.mp3'
frontend_config:
type: string
items: { }
type: object
StationRemote:
properties:
id:
type: integer
example: 1
display_name:
type: string
example: '128kbps MP3'
is_visible_on_public_pages:
type: boolean
example: true
type:
type: string
example: icecast
enable_autodj:
type: boolean
example: false
autodj_format:
type: string
example: mp3
autodj_bitrate:
type: integer
example: 128
custom_listen_url:
type: string
example: 'https://custom-listen-url.example.com/stream.mp3'
url:
type: string
example: 'http://custom-url.example.com'
mount:
type: string
example: /stream.mp3
source_port:
type: integer
example: 8000
source_mount:
type: string
example: /
source_username:
type: string
example: source
source_password:
type: string
example: password
is_public:
type: boolean
example: false
type: object
StationStreamer:
properties:
id:
@ -1623,7 +1982,7 @@ components:
example: true
reactivate_at:
type: integer
example: 1554636757
example: 1554805409
type: object
User:
properties:
@ -1653,10 +2012,10 @@ components:
example: A1B2C3D4
created_at:
type: integer
example: 1554636757
example: 1554805409
updated_at:
type: integer
example: 1554636757
example: 1554805409
roles:
items: { }
type: object