2015-01-02 08:16:54 +00:00
|
|
|
<?php
|
2020-10-14 22:19:31 +00:00
|
|
|
|
2020-12-08 18:40:33 +00:00
|
|
|
/** @noinspection PhpMissingFieldTypeInspection */
|
|
|
|
|
2018-08-04 22:05:14 +00:00
|
|
|
namespace App\Entity;
|
2015-01-02 08:16:54 +00:00
|
|
|
|
2021-05-30 18:55:26 +00:00
|
|
|
use App\Entity\Interfaces\PathAwareInterface;
|
|
|
|
use App\Entity\Interfaces\ProcessableMediaInterface;
|
|
|
|
use App\Entity\Interfaces\SongInterface;
|
2021-05-31 21:30:40 +00:00
|
|
|
use App\Normalizer\Attributes\DeepNormalize;
|
2017-01-24 00:35:16 +00:00
|
|
|
use Doctrine\Common\Collections\ArrayCollection;
|
2017-08-17 18:28:48 +00:00
|
|
|
use Doctrine\Common\Collections\Collection;
|
2018-12-22 00:01:04 +00:00
|
|
|
use Doctrine\ORM\Mapping as ORM;
|
2021-05-30 18:55:26 +00:00
|
|
|
use Exception;
|
2019-04-22 11:19:21 +00:00
|
|
|
use OpenApi\Annotations as OA;
|
2021-06-10 03:22:13 +00:00
|
|
|
use RuntimeException;
|
2019-08-07 04:33:55 +00:00
|
|
|
use Symfony\Component\Serializer\Annotation as Serializer;
|
2015-01-02 08:16:54 +00:00
|
|
|
|
2021-05-30 18:55:26 +00:00
|
|
|
/** @OA\Schema(type="object") */
|
|
|
|
#[
|
|
|
|
ORM\Entity,
|
|
|
|
ORM\Table(name: 'station_media'),
|
|
|
|
ORM\Index(columns: ['title', 'artist', 'album'], name: 'search_idx'),
|
|
|
|
ORM\UniqueConstraint(name: 'path_unique_idx', columns: ['path', 'storage_location_id'])
|
|
|
|
]
|
2020-12-31 01:39:50 +00:00
|
|
|
class StationMedia implements SongInterface, ProcessableMediaInterface, PathAwareInterface
|
2015-01-02 08:16:54 +00:00
|
|
|
{
|
2021-05-30 18:55:26 +00:00
|
|
|
use Traits\HasAutoIncrementId;
|
2020-10-14 22:19:31 +00:00
|
|
|
use Traits\TruncateStrings;
|
|
|
|
use Traits\HasSongFields;
|
2017-11-04 02:13:41 +00:00
|
|
|
|
2019-10-11 01:22:02 +00:00
|
|
|
public const UNIQUE_ID_LENGTH = 24;
|
|
|
|
|
2020-11-10 03:06:48 +00:00
|
|
|
public const DIR_ALBUM_ART = '.albumart';
|
|
|
|
public const DIR_WAVEFORMS = '.waveforms';
|
|
|
|
|
2015-01-02 08:16:54 +00:00
|
|
|
/**
|
2021-05-30 18:55:26 +00:00
|
|
|
* @OA\Property(
|
|
|
|
* description="A unique identifier associated with this record.",
|
|
|
|
* example="69b536afc7ebbf16457b8645"
|
|
|
|
* )
|
2015-01-02 08:16:54 +00:00
|
|
|
*/
|
2021-06-09 01:38:18 +00:00
|
|
|
#[ORM\Column(length: 25, nullable: true)]
|
2021-05-30 18:55:26 +00:00
|
|
|
protected ?string $unique_id = null;
|
2015-01-02 08:16:54 +00:00
|
|
|
|
2021-06-09 01:38:18 +00:00
|
|
|
#[ORM\Column(nullable: false)]
|
2021-05-30 18:55:26 +00:00
|
|
|
protected int $storage_location_id;
|
2015-01-02 08:16:54 +00:00
|
|
|
|
2021-05-30 18:55:26 +00:00
|
|
|
#[ORM\ManyToOne(inversedBy: 'media')]
|
2021-06-09 01:38:18 +00:00
|
|
|
#[ORM\JoinColumn(name: 'storage_location_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
|
2021-05-30 18:55:26 +00:00
|
|
|
protected StorageLocation $storage_location;
|
2017-08-17 18:28:48 +00:00
|
|
|
|
|
|
|
/**
|
2021-05-30 18:55:26 +00:00
|
|
|
* @OA\Property(
|
|
|
|
* description="The name of the media file's album.",
|
|
|
|
* example="Test Album"
|
|
|
|
* )
|
2017-08-17 18:28:48 +00:00
|
|
|
*/
|
2021-06-09 01:38:18 +00:00
|
|
|
#[ORM\Column(length: 200, nullable: true)]
|
2021-05-30 18:55:26 +00:00
|
|
|
protected ?string $album = null;
|
2015-01-02 08:16:54 +00:00
|
|
|
|
2020-10-17 01:22:36 +00:00
|
|
|
/**
|
2021-05-30 18:55:26 +00:00
|
|
|
* @OA\Property(
|
|
|
|
* description="The genre of the media file.",
|
|
|
|
* example="Rock"
|
|
|
|
* )
|
2020-10-17 01:22:36 +00:00
|
|
|
*/
|
2021-06-09 01:38:18 +00:00
|
|
|
#[ORM\Column(length: 30, nullable: true)]
|
2021-05-30 18:55:26 +00:00
|
|
|
protected ?string $genre = null;
|
2020-10-17 01:22:36 +00:00
|
|
|
|
2017-11-04 02:13:41 +00:00
|
|
|
/**
|
2021-05-30 18:55:26 +00:00
|
|
|
* @OA\Property(
|
|
|
|
* description="Full lyrics of the track, if available.",
|
|
|
|
* example="...Never gonna give you up..."
|
|
|
|
* )
|
2017-11-04 02:13:41 +00:00
|
|
|
*/
|
2021-06-09 01:38:18 +00:00
|
|
|
#[ORM\Column(type: 'text', nullable: true)]
|
2021-05-30 18:55:26 +00:00
|
|
|
protected ?string $lyrics = null;
|
2017-11-04 02:13:41 +00:00
|
|
|
|
2017-05-24 09:21:11 +00:00
|
|
|
/**
|
2021-05-30 18:55:26 +00:00
|
|
|
* @OA\Property(
|
|
|
|
* description="The track ISRC (International Standard Recording Code), used for licensing purposes.",
|
|
|
|
* example="GBARL0600786"
|
|
|
|
* )
|
2017-05-24 09:21:11 +00:00
|
|
|
*/
|
2021-06-09 01:38:18 +00:00
|
|
|
#[ORM\Column(length: 15, nullable: true)]
|
2021-05-30 18:55:26 +00:00
|
|
|
protected ?string $isrc = null;
|
2017-05-24 09:21:11 +00:00
|
|
|
|
2017-08-17 18:28:48 +00:00
|
|
|
/**
|
2021-05-30 18:55:26 +00:00
|
|
|
* @OA\Property(
|
|
|
|
* description="The song duration in seconds.",
|
|
|
|
* example=240.00
|
|
|
|
* )
|
2017-08-17 18:28:48 +00:00
|
|
|
*/
|
2021-06-09 01:38:18 +00:00
|
|
|
#[ORM\Column(type: 'decimal', precision: 7, scale: 2, nullable: true)]
|
2021-05-30 18:55:26 +00:00
|
|
|
protected ?float $length = 0.00;
|
2015-01-02 08:16:54 +00:00
|
|
|
|
2017-08-17 18:28:48 +00:00
|
|
|
/**
|
2021-05-30 18:55:26 +00:00
|
|
|
* @OA\Property(
|
|
|
|
* description="The formatted song duration (in mm:ss format)",
|
|
|
|
* example="4:00"
|
|
|
|
* )
|
2017-08-17 18:28:48 +00:00
|
|
|
*/
|
2021-06-09 01:38:18 +00:00
|
|
|
#[ORM\Column(length: 10, nullable: true)]
|
2021-05-30 18:55:26 +00:00
|
|
|
protected ?string $length_text = '0:00';
|
2017-08-17 18:28:48 +00:00
|
|
|
|
|
|
|
/**
|
2021-05-30 18:55:26 +00:00
|
|
|
* @OA\Property(
|
|
|
|
* description="The relative path of the media file.",
|
|
|
|
* example="test.mp3"
|
|
|
|
* )
|
2017-08-17 18:28:48 +00:00
|
|
|
*/
|
2021-05-30 18:55:26 +00:00
|
|
|
#[ORM\Column(length: 500)]
|
|
|
|
protected string $path;
|
2017-08-17 18:28:48 +00:00
|
|
|
|
|
|
|
/**
|
2021-05-30 18:55:26 +00:00
|
|
|
* @OA\Property(
|
|
|
|
* description="The UNIX timestamp when the database was last modified.",
|
|
|
|
* example=SAMPLE_TIMESTAMP
|
|
|
|
* )
|
2017-08-17 18:28:48 +00:00
|
|
|
*/
|
2021-06-09 01:38:18 +00:00
|
|
|
#[ORM\Column(nullable: true)]
|
2021-05-30 18:55:26 +00:00
|
|
|
protected ?int $mtime = 0;
|
2017-08-17 18:28:48 +00:00
|
|
|
|
2020-01-24 22:33:34 +00:00
|
|
|
/**
|
2021-05-30 18:55:26 +00:00
|
|
|
* @OA\Property(
|
|
|
|
* description="The amount of amplification (in dB) to be applied to the radio source (liq_amplify)",
|
|
|
|
* example=-14.00
|
|
|
|
* )
|
2020-01-24 22:33:34 +00:00
|
|
|
*/
|
2021-06-09 01:38:18 +00:00
|
|
|
#[ORM\Column(type: 'decimal', precision: 6, scale: 1, nullable: true)]
|
2021-05-30 18:55:26 +00:00
|
|
|
protected ?float $amplify = null;
|
2020-01-24 22:33:34 +00:00
|
|
|
|
2017-08-17 18:28:48 +00:00
|
|
|
/**
|
2021-05-30 18:55:26 +00:00
|
|
|
* @OA\Property(
|
|
|
|
* description="The length of time (in seconds) before the next song starts in the fade (liq_start_next)",
|
|
|
|
* example=2.00
|
|
|
|
* )
|
2017-08-17 18:28:48 +00:00
|
|
|
*/
|
2021-06-09 01:38:18 +00:00
|
|
|
#[ORM\Column(type: 'decimal', precision: 6, scale: 1, nullable: true)]
|
2021-05-30 18:55:26 +00:00
|
|
|
protected ?float $fade_overlap = null;
|
2017-08-17 18:28:48 +00:00
|
|
|
|
|
|
|
/**
|
2021-05-30 18:55:26 +00:00
|
|
|
* @OA\Property(
|
|
|
|
* description="The length of time (in seconds) to fade in the next track (liq_fade_in)",
|
|
|
|
* example=3.00
|
|
|
|
* )
|
2017-08-17 18:28:48 +00:00
|
|
|
*/
|
2021-06-09 01:38:18 +00:00
|
|
|
#[ORM\Column(type: 'decimal', precision: 6, scale: 1, nullable: true)]
|
2021-05-30 18:55:26 +00:00
|
|
|
protected ?float $fade_in = null;
|
2017-08-17 18:28:48 +00:00
|
|
|
|
|
|
|
/**
|
2021-05-30 18:55:26 +00:00
|
|
|
* @OA\Property(
|
|
|
|
* description="The length of time (in seconds) to fade out the previous track (liq_fade_out)",
|
|
|
|
* example=3.00
|
|
|
|
* )
|
2017-08-17 18:28:48 +00:00
|
|
|
*/
|
2021-06-09 01:38:18 +00:00
|
|
|
#[ORM\Column(type: 'decimal', precision: 6, scale: 1, nullable: true)]
|
2021-05-30 18:55:26 +00:00
|
|
|
protected ?float $fade_out = null;
|
2017-08-17 18:28:48 +00:00
|
|
|
|
|
|
|
/**
|
2021-05-30 18:55:26 +00:00
|
|
|
* @OA\Property(
|
|
|
|
* description="The length of time (in seconds) from the start of the track to start playing (liq_cue_in)",
|
|
|
|
* example=30.00
|
|
|
|
* )
|
2017-08-17 18:28:48 +00:00
|
|
|
*/
|
2021-06-09 01:38:18 +00:00
|
|
|
#[ORM\Column(type: 'decimal', precision: 6, scale: 1, nullable: true)]
|
2021-05-30 18:55:26 +00:00
|
|
|
protected ?float $cue_in = null;
|
2017-08-17 18:28:48 +00:00
|
|
|
|
|
|
|
/**
|
2021-05-30 18:55:26 +00:00
|
|
|
* @OA\Property(
|
|
|
|
* description="The length of time (in seconds) from the CUE-IN of the track to stop playing (liq_cue_out)",
|
|
|
|
* example=30.00
|
|
|
|
* )
|
2017-08-17 18:28:48 +00:00
|
|
|
*/
|
2021-06-09 01:38:18 +00:00
|
|
|
#[ORM\Column(type: 'decimal', precision: 6, scale: 1, nullable: true)]
|
2021-05-30 18:55:26 +00:00
|
|
|
protected ?float $cue_out = null;
|
2017-08-17 18:28:48 +00:00
|
|
|
|
2019-10-24 19:37:27 +00:00
|
|
|
/**
|
2021-05-30 18:55:26 +00:00
|
|
|
* @OA\Property(
|
|
|
|
* description="The latest time (UNIX timestamp) when album art was updated.",
|
|
|
|
* example=SAMPLE_TIMESTAMP
|
|
|
|
* )
|
2019-10-24 19:37:27 +00:00
|
|
|
*/
|
2021-05-30 18:55:26 +00:00
|
|
|
#[ORM\Column]
|
|
|
|
protected int $art_updated_at = 0;
|
2019-10-24 19:37:27 +00:00
|
|
|
|
2021-05-30 18:55:26 +00:00
|
|
|
/** @OA\Property(type="array", @OA\Items()) */
|
|
|
|
#[ORM\OneToMany(mappedBy: 'media', targetEntity: StationPlaylistMedia::class)]
|
|
|
|
#[DeepNormalize(true)]
|
|
|
|
#[Serializer\MaxDepth(1)]
|
|
|
|
protected Collection $playlists;
|
2017-08-17 18:28:48 +00:00
|
|
|
|
2021-05-30 18:55:26 +00:00
|
|
|
#[ORM\OneToMany(mappedBy: 'media', targetEntity: StationMediaCustomField::class)]
|
|
|
|
protected Collection $custom_fields;
|
2018-04-15 23:53:46 +00:00
|
|
|
|
2020-11-10 03:06:48 +00:00
|
|
|
public function __construct(StorageLocation $storageLocation, string $path)
|
2017-08-17 18:28:48 +00:00
|
|
|
{
|
2020-11-10 03:06:48 +00:00
|
|
|
$this->storage_location = $storageLocation;
|
2017-08-17 18:28:48 +00:00
|
|
|
|
2020-10-14 22:19:31 +00:00
|
|
|
$this->playlists = new ArrayCollection();
|
|
|
|
$this->custom_fields = new ArrayCollection();
|
2018-12-05 07:15:51 +00:00
|
|
|
|
|
|
|
$this->setPath($path);
|
|
|
|
$this->generateUniqueId();
|
2017-08-17 18:28:48 +00:00
|
|
|
}
|
|
|
|
|
2021-05-30 18:55:26 +00:00
|
|
|
public function getUniqueId(): string
|
|
|
|
{
|
|
|
|
if (!isset($this->unique_id)) {
|
2021-06-10 03:22:13 +00:00
|
|
|
throw new RuntimeException('Unique ID has not been generated yet.');
|
2021-05-30 18:55:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return $this->unique_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generate a new unique ID for this item.
|
|
|
|
*
|
|
|
|
* @param bool $force_new
|
|
|
|
*
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
public function generateUniqueId($force_new = false): void
|
2017-08-17 18:28:48 +00:00
|
|
|
{
|
2021-05-30 18:55:26 +00:00
|
|
|
if (!isset($this->unique_id) || $force_new) {
|
|
|
|
$this->unique_id = bin2hex(random_bytes(12));
|
|
|
|
}
|
2017-08-17 18:28:48 +00:00
|
|
|
}
|
|
|
|
|
2020-11-10 03:06:48 +00:00
|
|
|
public function getStorageLocation(): StorageLocation
|
2017-08-17 18:28:48 +00:00
|
|
|
{
|
2020-11-10 03:06:48 +00:00
|
|
|
return $this->storage_location;
|
2017-08-17 18:28:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getAlbum(): ?string
|
|
|
|
{
|
|
|
|
return $this->album;
|
|
|
|
}
|
|
|
|
|
2020-03-29 07:16:41 +00:00
|
|
|
public function setAlbum(?string $album = null): void
|
2017-08-17 18:28:48 +00:00
|
|
|
{
|
2021-05-30 18:55:26 +00:00
|
|
|
$this->album = $this->truncateNullableString($album, 200);
|
2017-08-17 18:28:48 +00:00
|
|
|
}
|
|
|
|
|
2020-10-17 01:22:36 +00:00
|
|
|
public function getGenre(): ?string
|
|
|
|
{
|
|
|
|
return $this->genre;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setGenre(?string $genre = null): void
|
|
|
|
{
|
2021-05-30 18:55:26 +00:00
|
|
|
$this->genre = $this->truncateNullableString($genre, 30);
|
2020-10-17 01:22:36 +00:00
|
|
|
}
|
|
|
|
|
2019-01-31 17:54:17 +00:00
|
|
|
public function getLyrics(): ?string
|
2017-11-04 02:13:41 +00:00
|
|
|
{
|
|
|
|
return $this->lyrics;
|
|
|
|
}
|
|
|
|
|
2020-03-29 07:16:41 +00:00
|
|
|
public function setLyrics(?string $lyrics = null): void
|
2017-11-04 02:13:41 +00:00
|
|
|
{
|
|
|
|
$this->lyrics = $lyrics;
|
|
|
|
}
|
|
|
|
|
2020-10-14 22:19:31 +00:00
|
|
|
/**
|
|
|
|
* @return string[]
|
|
|
|
*/
|
2020-09-29 16:59:05 +00:00
|
|
|
public function getRelatedFilePaths(): array
|
|
|
|
{
|
|
|
|
return [
|
2020-11-10 03:06:48 +00:00
|
|
|
self::getArtPath($this->getUniqueId()),
|
|
|
|
self::getWaveformPath($this->getUniqueId()),
|
2020-09-29 16:59:05 +00:00
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2017-08-17 18:28:48 +00:00
|
|
|
public function getIsrc(): ?string
|
|
|
|
{
|
|
|
|
return $this->isrc;
|
|
|
|
}
|
|
|
|
|
2020-03-29 07:16:41 +00:00
|
|
|
public function setIsrc(?string $isrc = null): void
|
2017-08-17 18:28:48 +00:00
|
|
|
{
|
2021-05-30 18:55:26 +00:00
|
|
|
$this->isrc = $this->truncateNullableString($isrc, 15);
|
2017-08-17 18:28:48 +00:00
|
|
|
}
|
|
|
|
|
2020-08-26 16:36:37 +00:00
|
|
|
public function getLength(): float
|
2017-08-17 18:28:48 +00:00
|
|
|
{
|
|
|
|
return $this->length;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-01-31 17:54:17 +00:00
|
|
|
* @param int $length
|
2017-08-17 18:28:48 +00:00
|
|
|
*/
|
2021-04-23 22:12:47 +00:00
|
|
|
public function setLength(int $length): void
|
2017-01-24 00:17:50 +00:00
|
|
|
{
|
|
|
|
$length_min = floor($length / 60);
|
|
|
|
$length_sec = $length % 60;
|
|
|
|
|
2020-08-25 21:17:53 +00:00
|
|
|
$this->length = (float)$length;
|
2020-08-31 22:32:30 +00:00
|
|
|
$this->length_text = $length_min . ':' . str_pad((string)$length_sec, 2, '0', STR_PAD_LEFT);
|
2017-01-24 00:17:50 +00:00
|
|
|
}
|
|
|
|
|
2017-08-17 18:28:48 +00:00
|
|
|
public function getLengthText(): ?string
|
|
|
|
{
|
|
|
|
return $this->length_text;
|
|
|
|
}
|
|
|
|
|
2020-03-29 07:16:41 +00:00
|
|
|
public function setLengthText(?string $length_text = null): void
|
2017-08-17 18:28:48 +00:00
|
|
|
{
|
|
|
|
$this->length_text = $length_text;
|
|
|
|
}
|
|
|
|
|
2020-12-31 01:39:50 +00:00
|
|
|
public function getPath(): string
|
2017-08-17 18:28:48 +00:00
|
|
|
{
|
|
|
|
return $this->path;
|
|
|
|
}
|
|
|
|
|
2020-12-31 01:39:50 +00:00
|
|
|
public function setPath(string $path): void
|
2017-08-17 18:28:48 +00:00
|
|
|
{
|
|
|
|
$this->path = $path;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getMtime(): ?int
|
|
|
|
{
|
|
|
|
return $this->mtime;
|
|
|
|
}
|
|
|
|
|
2020-03-29 07:16:41 +00:00
|
|
|
public function setMtime(?int $mtime = null): void
|
2017-08-17 18:28:48 +00:00
|
|
|
{
|
|
|
|
$this->mtime = $mtime;
|
|
|
|
}
|
|
|
|
|
2020-01-24 22:33:34 +00:00
|
|
|
public function getAmplify(): ?float
|
|
|
|
{
|
|
|
|
return $this->amplify;
|
|
|
|
}
|
|
|
|
|
2020-03-29 07:16:41 +00:00
|
|
|
public function setAmplify(?float $amplify = null): void
|
2020-01-24 22:33:34 +00:00
|
|
|
{
|
2020-08-31 22:32:30 +00:00
|
|
|
$this->amplify = $amplify;
|
2020-01-24 22:33:34 +00:00
|
|
|
}
|
|
|
|
|
2017-08-17 18:28:48 +00:00
|
|
|
public function getFadeOverlap(): ?float
|
|
|
|
{
|
|
|
|
return $this->fade_overlap;
|
|
|
|
}
|
|
|
|
|
2020-03-29 07:16:41 +00:00
|
|
|
public function setFadeOverlap(?float $fade_overlap = null): void
|
2017-08-17 18:28:48 +00:00
|
|
|
{
|
|
|
|
$this->fade_overlap = $fade_overlap;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getFadeIn(): ?float
|
|
|
|
{
|
|
|
|
return $this->fade_in;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-11-07 06:06:59 +00:00
|
|
|
* @param string|float|null $fade_in
|
2017-08-17 18:28:48 +00:00
|
|
|
*/
|
2019-01-30 05:25:46 +00:00
|
|
|
public function setFadeIn($fade_in = null): void
|
2017-08-17 18:28:48 +00:00
|
|
|
{
|
2019-11-07 06:06:59 +00:00
|
|
|
$this->fade_in = $this->parseSeconds($fade_in);
|
2017-08-17 18:28:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getFadeOut(): ?float
|
|
|
|
{
|
|
|
|
return $this->fade_out;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-11-07 06:06:59 +00:00
|
|
|
* @param string|float|null $fade_out
|
2017-08-17 18:28:48 +00:00
|
|
|
*/
|
2019-01-30 05:25:46 +00:00
|
|
|
public function setFadeOut($fade_out = null): void
|
2017-08-17 18:28:48 +00:00
|
|
|
{
|
2019-11-07 06:06:59 +00:00
|
|
|
$this->fade_out = $this->parseSeconds($fade_out);
|
2017-08-17 18:28:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getCueIn(): ?float
|
|
|
|
{
|
|
|
|
return $this->cue_in;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-11-07 06:06:59 +00:00
|
|
|
* @param string|float|null $cue_in
|
2017-08-17 18:28:48 +00:00
|
|
|
*/
|
2019-01-31 17:54:17 +00:00
|
|
|
public function setCueIn($cue_in = null): void
|
2017-08-17 18:28:48 +00:00
|
|
|
{
|
2019-11-07 06:06:59 +00:00
|
|
|
$this->cue_in = $this->parseSeconds($cue_in);
|
2017-08-17 18:28:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getCueOut(): ?float
|
|
|
|
{
|
|
|
|
return $this->cue_out;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-11-07 06:06:59 +00:00
|
|
|
* @param string|float|null $cue_out
|
2017-08-17 18:28:48 +00:00
|
|
|
*/
|
2019-01-31 17:54:17 +00:00
|
|
|
public function setCueOut($cue_out = null): void
|
2017-08-17 18:28:48 +00:00
|
|
|
{
|
2019-11-07 06:06:59 +00:00
|
|
|
$this->cue_out = $this->parseSeconds($cue_out);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string|float|null $seconds
|
|
|
|
*/
|
2019-11-07 07:07:12 +00:00
|
|
|
protected function parseSeconds($seconds = null): ?float
|
2019-11-07 06:06:59 +00:00
|
|
|
{
|
|
|
|
if ($seconds === '') {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2021-04-23 22:12:47 +00:00
|
|
|
if (str_contains($seconds, ':')) {
|
2019-11-07 06:06:59 +00:00
|
|
|
$sec = 0;
|
|
|
|
foreach (array_reverse(explode(':', $seconds)) as $k => $v) {
|
2019-11-07 07:20:09 +00:00
|
|
|
$sec += (60 ** (int)$k) * (int)$v;
|
2019-11-07 06:06:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return $sec;
|
2019-01-30 05:25:46 +00:00
|
|
|
}
|
|
|
|
|
2019-11-07 06:06:59 +00:00
|
|
|
return $seconds;
|
2017-08-17 18:28:48 +00:00
|
|
|
}
|
|
|
|
|
2017-06-19 17:15:57 +00:00
|
|
|
/**
|
|
|
|
* Get the length with cue-in and cue-out points included.
|
|
|
|
*/
|
2019-01-30 05:25:46 +00:00
|
|
|
public function getCalculatedLength(): int
|
2017-06-19 17:15:57 +00:00
|
|
|
{
|
|
|
|
$length = (int)$this->length;
|
|
|
|
|
|
|
|
if ((int)$this->cue_out > 0) {
|
|
|
|
$length_removed = $length - (int)$this->cue_out;
|
|
|
|
$length -= $length_removed;
|
|
|
|
}
|
|
|
|
if ((int)$this->cue_in > 0) {
|
|
|
|
$length -= $this->cue_in;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $length;
|
|
|
|
}
|
|
|
|
|
2019-10-24 19:37:27 +00:00
|
|
|
public function getArtUpdatedAt(): int
|
|
|
|
{
|
|
|
|
return $this->art_updated_at;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setArtUpdatedAt(int $art_updated_at): void
|
|
|
|
{
|
|
|
|
$this->art_updated_at = $art_updated_at;
|
|
|
|
}
|
|
|
|
|
2018-04-16 00:53:27 +00:00
|
|
|
public function getCustomFields(): Collection
|
2018-04-15 23:53:46 +00:00
|
|
|
{
|
2018-04-16 00:53:27 +00:00
|
|
|
return $this->custom_fields;
|
2018-04-15 23:53:46 +00:00
|
|
|
}
|
|
|
|
|
2018-04-16 00:53:27 +00:00
|
|
|
public function setCustomFields(Collection $custom_fields): void
|
2018-04-15 23:53:46 +00:00
|
|
|
{
|
2018-04-16 00:53:27 +00:00
|
|
|
$this->custom_fields = $custom_fields;
|
2018-04-15 23:53:46 +00:00
|
|
|
}
|
|
|
|
|
2021-04-10 01:25:35 +00:00
|
|
|
public static function needsReprocessing(int $fileModifiedTime = 0, int $dbModifiedTime = 0): bool
|
2018-12-30 10:18:48 +00:00
|
|
|
{
|
2021-04-10 01:25:35 +00:00
|
|
|
return $fileModifiedTime > $dbModifiedTime;
|
2019-09-04 18:00:51 +00:00
|
|
|
}
|
|
|
|
|
2018-04-12 22:43:58 +00:00
|
|
|
/**
|
|
|
|
* Indicates whether this media is a part of any "requestable" playlists.
|
|
|
|
*/
|
|
|
|
public function isRequestable(): bool
|
|
|
|
{
|
2021-06-08 06:40:49 +00:00
|
|
|
foreach ($this->getPlaylists() as $playlist_item) {
|
2018-04-29 23:48:48 +00:00
|
|
|
$playlist = $playlist_item->getPlaylist();
|
2018-04-12 22:43:58 +00:00
|
|
|
/** @var StationPlaylist $playlist */
|
|
|
|
if ($playlist->isRequestable()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-10-08 08:52:09 +00:00
|
|
|
/**
|
2020-10-08 09:00:23 +00:00
|
|
|
* @return StationPlaylistMedia[]|Collection
|
2020-10-08 08:52:09 +00:00
|
|
|
*/
|
2019-09-04 18:00:51 +00:00
|
|
|
public function getPlaylists(): Collection
|
|
|
|
{
|
|
|
|
return $this->playlists;
|
|
|
|
}
|
|
|
|
|
2020-10-21 10:04:58 +00:00
|
|
|
public function fromMetadata(Metadata $metadata): void
|
|
|
|
{
|
|
|
|
$this->setLength($metadata->getDuration());
|
|
|
|
|
|
|
|
$tags = $metadata->getTags();
|
|
|
|
|
|
|
|
if (isset($tags['title'])) {
|
|
|
|
$this->setTitle($tags['title']);
|
|
|
|
}
|
|
|
|
if (isset($tags['artist'])) {
|
|
|
|
$this->setArtist($tags['artist']);
|
|
|
|
}
|
|
|
|
if (isset($tags['album'])) {
|
|
|
|
$this->setAlbum($tags['album']);
|
|
|
|
}
|
|
|
|
if (isset($tags['genre'])) {
|
|
|
|
$this->setGenre($tags['genre']);
|
|
|
|
}
|
|
|
|
if (isset($tags['unsynchronised_lyric'])) {
|
|
|
|
$this->setLyrics($tags['unsynchronised_lyric']);
|
|
|
|
}
|
|
|
|
if (isset($tags['isrc'])) {
|
|
|
|
$this->setIsrc($tags['isrc']);
|
|
|
|
}
|
2021-01-19 15:57:12 +00:00
|
|
|
|
|
|
|
$this->updateSongId();
|
2020-10-21 10:04:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function toMetadata(): Metadata
|
|
|
|
{
|
|
|
|
$metadata = new Metadata();
|
|
|
|
$metadata->setDuration($this->getLength());
|
|
|
|
|
2020-12-08 18:40:33 +00:00
|
|
|
$tagsToSet = array_filter(
|
|
|
|
[
|
|
|
|
'title' => $this->getTitle(),
|
|
|
|
'artist' => $this->getArtist(),
|
|
|
|
'album' => $this->getAlbum(),
|
|
|
|
'genre' => $this->getGenre(),
|
|
|
|
'unsynchronised_lyric' => $this->getLyrics(),
|
|
|
|
'isrc' => $this->getIsrc(),
|
|
|
|
]
|
|
|
|
);
|
2020-10-21 10:04:58 +00:00
|
|
|
|
|
|
|
$tags = $metadata->getTags();
|
|
|
|
foreach ($tagsToSet as $tagKey => $tagValue) {
|
|
|
|
$tags->set($tagKey, $tagValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $metadata;
|
|
|
|
}
|
|
|
|
|
2019-09-07 00:24:42 +00:00
|
|
|
public function __toString(): string
|
|
|
|
{
|
2020-03-08 19:35:19 +00:00
|
|
|
return 'StationMedia ' . $this->unique_id . ': ' . $this->artist . ' - ' . $this->title;
|
2019-09-07 00:24:42 +00:00
|
|
|
}
|
2020-11-10 03:06:48 +00:00
|
|
|
|
|
|
|
public static function getArtPath(string $uniqueId): string
|
|
|
|
{
|
|
|
|
return self::DIR_ALBUM_ART . '/' . $uniqueId . '.jpg';
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function getWaveformPath(string $uniqueId): string
|
|
|
|
{
|
|
|
|
return self::DIR_WAVEFORMS . '/' . $uniqueId . '.json';
|
|
|
|
}
|
2018-07-16 18:59:08 +00:00
|
|
|
}
|