#757 -- Refactor the AzuraCast AutoDJ into its own class, employ new shuffle method.
This commit is contained in:
parent
77541fc276
commit
f19a114881
7 changed files with 420 additions and 149 deletions
|
@ -159,6 +159,15 @@ services:
|
|||
- "8888:8888"
|
||||
command: "chronograf --influxdb-url=http://influxdb:8086"
|
||||
|
||||
redis-commander:
|
||||
image: rediscommander/redis-commander:latest
|
||||
depends_on:
|
||||
- redis
|
||||
environment:
|
||||
REDIS_HOSTS: "local-app:redis:6379:0,local-sessions:redis:6379:1,local-doctrine:redis:6379:2"
|
||||
ports:
|
||||
- "127.0.0.1:8081:8081"
|
||||
|
||||
volumes:
|
||||
nginx_letsencrypt_certs: {}
|
||||
nginx_letsencrypt_www: {}
|
||||
|
|
|
@ -343,143 +343,4 @@ class SongHistoryRepository extends BaseRepository
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function _playSongFromRequest(Entity\StationRequest $request)
|
||||
{
|
||||
// Log in history
|
||||
$sh = new Entity\SongHistory($request->getTrack()->getSong(), $request->getStation());
|
||||
$sh->setRequest($request);
|
||||
$sh->setMedia($request->getTrack());
|
||||
|
||||
$sh->setDuration($request->getTrack()->getCalculatedLength());
|
||||
$sh->setTimestampCued(time());
|
||||
$this->_em->persist($sh);
|
||||
|
||||
$request->setPlayedAt(time());
|
||||
$this->_em->persist($request);
|
||||
|
||||
$this->_em->flush();
|
||||
|
||||
return $sh;
|
||||
}
|
||||
|
||||
protected function _playSongFromPlaylist(Entity\StationPlaylist $playlist)
|
||||
{
|
||||
if ($playlist->getOrder() === Entity\StationPlaylist::ORDER_SEQUENTIAL) {
|
||||
$media_to_play = $this->_playSequentialSongFromPlaylist($playlist);
|
||||
} else {
|
||||
$media_to_play = $this->_playRandomSongFromPlaylist($playlist);
|
||||
}
|
||||
|
||||
if ($media_to_play instanceof Entity\StationMedia) {
|
||||
$spm = $media_to_play->getItemForPlaylist($playlist);
|
||||
$spm->played();
|
||||
$this->_em->persist($spm);
|
||||
|
||||
// Log in history
|
||||
$sh = new Entity\SongHistory($media_to_play->getSong(), $playlist->getStation());
|
||||
$sh->setPlaylist($playlist);
|
||||
$sh->setMedia($media_to_play);
|
||||
|
||||
$sh->setDuration($media_to_play->getCalculatedLength());
|
||||
$sh->setTimestampCued(time());
|
||||
|
||||
$this->_em->persist($sh);
|
||||
$this->_em->flush();
|
||||
|
||||
return $sh;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function _playRandomSongFromPlaylist(Entity\StationPlaylist $playlist)
|
||||
{
|
||||
// Get some random songs from playlist.
|
||||
$random_songs = $this->_em->createQuery('SELECT sm, spm, s, st FROM '.Entity\StationMedia::class.' sm
|
||||
JOIN sm.song s
|
||||
JOIN sm.station st
|
||||
JOIN sm.playlist_items spm
|
||||
JOIN spm.playlist sp
|
||||
WHERE spm.playlist_id = :playlist_id
|
||||
GROUP BY sm.id ORDER BY RAND()')
|
||||
->setParameter('playlist_id', $playlist->getId())
|
||||
->setMaxResults(15)
|
||||
->execute();
|
||||
|
||||
/** @var bool Whether to use "last song ID played" or "genuine random shuffle" mode. */
|
||||
$use_song_ids = true;
|
||||
|
||||
// Get all song IDs from the random songs.
|
||||
$song_timestamps = [];
|
||||
$songs_by_id = [];
|
||||
foreach($random_songs as $media_row) {
|
||||
/** @var Entity\StationMedia $media_row */
|
||||
|
||||
if ($media_row->getLength() == 0) {
|
||||
$use_song_ids = false;
|
||||
break;
|
||||
} else {
|
||||
$playlist_item = $media_row->getItemForPlaylist($playlist);
|
||||
|
||||
$song_timestamps[$media_row->getSong()->getId()] = $playlist_item->getLastPlayed();
|
||||
$songs_by_id[$media_row->getSong()->getId()] = $media_row;
|
||||
}
|
||||
}
|
||||
|
||||
if ($use_song_ids) {
|
||||
asort($song_timestamps);
|
||||
reset($song_timestamps);
|
||||
$id_to_play = key($song_timestamps);
|
||||
|
||||
$random_song = $songs_by_id[$id_to_play];
|
||||
} else {
|
||||
shuffle($random_songs);
|
||||
$random_song = array_pop($random_songs);
|
||||
}
|
||||
|
||||
return $random_song;
|
||||
}
|
||||
|
||||
protected function _playSequentialSongFromPlaylist(Entity\StationPlaylist $playlist)
|
||||
{
|
||||
// Fetch the most recently played song
|
||||
try {
|
||||
/** @var Entity\StationPlaylistMedia $last_played_media */
|
||||
$last_played_media = $this->_em->createQuery('SELECT spm FROM '.Entity\StationPlaylistMedia::class.' spm
|
||||
WHERE spm.playlist_id = :playlist_id
|
||||
ORDER BY spm.last_played DESC')
|
||||
->setParameter('playlist_id', $playlist->getId())
|
||||
->setMaxResults(1)
|
||||
->getSingleResult();
|
||||
} catch(NoResultException $e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$last_weight = (int)$last_played_media->getWeight();
|
||||
|
||||
// Try to find a song of greater weight. If none exists, start back with zero.
|
||||
$next_song_query = $this->_em->createQuery('SELECT spm, sm, s, st FROM '.Entity\StationPlaylistMedia::class.' spm
|
||||
JOIN spm.media sm
|
||||
JOIN sm.song s
|
||||
JOIN sm.station st
|
||||
WHERE spm.playlist_id = :playlist_id
|
||||
AND spm.weight >= :weight
|
||||
ORDER BY spm.weight ASC')
|
||||
->setParameter('playlist_id', $playlist->getId())
|
||||
->setMaxResults(1);
|
||||
|
||||
try {
|
||||
$next_song = $next_song_query
|
||||
->setParameter('weight', $last_weight+1)
|
||||
->getSingleResult();
|
||||
} catch(NoResultException $e) {
|
||||
$next_song = $next_song_query
|
||||
->setParameter('weight', 0)
|
||||
->getSingleResult();
|
||||
}
|
||||
|
||||
/** @var Entity\StationPlaylistMedia $next_song */
|
||||
return $next_song->getMedia();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
namespace App\Provider;
|
||||
|
||||
use App\Radio\Adapters;
|
||||
use App\Radio\AutoDJ;
|
||||
use App\Radio\Backend;
|
||||
use App\Radio\Configuration;
|
||||
use App\Radio\Frontend;
|
||||
|
@ -22,6 +23,13 @@ class RadioProvider implements ServiceProviderInterface
|
|||
]));
|
||||
};
|
||||
|
||||
$di[AutoDJ::class] = function($di) {
|
||||
return new AutoDJ(
|
||||
$di[\Doctrine\ORM\EntityManager::class],
|
||||
$di[\App\Cache::class]
|
||||
);
|
||||
};
|
||||
|
||||
$di[Configuration::class] = function($di) {
|
||||
return new Configuration(
|
||||
$di[\Doctrine\ORM\EntityManager::class],
|
||||
|
@ -34,7 +42,8 @@ class RadioProvider implements ServiceProviderInterface
|
|||
return new Backend\Liquidsoap(
|
||||
$di[\Doctrine\ORM\EntityManager::class],
|
||||
$di[\Supervisor\Supervisor::class],
|
||||
$di[\Monolog\Logger::class]
|
||||
$di[\Monolog\Logger::class],
|
||||
$di[AutoDJ::class]
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
@ -57,7 +57,8 @@ class SyncProvider implements ServiceProviderInterface
|
|||
$di[\App\Cache::class],
|
||||
$di[\App\Radio\Adapters::class],
|
||||
$di[\App\Webhook\Dispatcher::class],
|
||||
$di[\App\ApiUtilities::class]
|
||||
$di[\App\ApiUtilities::class],
|
||||
$di[\App\Radio\AutoDJ::class]
|
||||
);
|
||||
};
|
||||
|
||||
|
|
360
src/Radio/AutoDJ.php
Normal file
360
src/Radio/AutoDJ.php
Normal file
|
@ -0,0 +1,360 @@
|
|||
<?php
|
||||
namespace App\Radio;
|
||||
|
||||
use App\Entity;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use App\Cache;
|
||||
|
||||
class AutoDJ
|
||||
{
|
||||
/** @var int The time to live (in seconds) of cached playlist queues. */
|
||||
const CACHE_TTL = 43200;
|
||||
|
||||
/** @var EntityManager */
|
||||
protected $em;
|
||||
|
||||
/** @var Cache */
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* @param EntityManager $em
|
||||
* @param Cache $cache
|
||||
* @see \App\Provider\RadioProvider
|
||||
*/
|
||||
public function __construct(EntityManager $em, Cache $cache)
|
||||
{
|
||||
$this->em = $em;
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the next song for a station has already been calculated, return the calculated result; otherwise,
|
||||
* calculate the next playing song.
|
||||
*
|
||||
* @param Entity\Station $station
|
||||
* @param bool $is_autodj
|
||||
* @return Entity\SongHistory|null
|
||||
*/
|
||||
public function getNextSong(Entity\Station $station, $is_autodj = false): ?Entity\SongHistory
|
||||
{
|
||||
if ($station->useManualAutoDJ()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$next_song = $this->em->createQuery('SELECT sh, s, sm
|
||||
FROM ' . Entity\SongHistory::class . ' sh JOIN sh.song s JOIN sh.media sm
|
||||
WHERE sh.station_id = :station_id
|
||||
AND sh.timestamp_cued >= :threshold
|
||||
AND sh.sent_to_autodj = 0
|
||||
AND sh.timestamp_start = 0
|
||||
AND sh.timestamp_end = 0
|
||||
ORDER BY sh.id DESC')
|
||||
->setParameter('station_id', $station->getId())
|
||||
->setParameter('threshold', time() - 60 * 15)
|
||||
->setMaxResults(1)
|
||||
->getOneOrNullResult();
|
||||
|
||||
if (!($next_song instanceof Entity\SongHistory)) {
|
||||
$next_song = $this->calculateNextSong($station);
|
||||
}
|
||||
|
||||
if ($next_song instanceof Entity\SongHistory && $is_autodj) {
|
||||
$next_song->sentToAutodj();
|
||||
$this->em->persist($next_song);
|
||||
|
||||
// The "get next song" function is only called when a streamer is not live
|
||||
$station->setIsStreamerLive(false);
|
||||
$this->em->persist($station);
|
||||
|
||||
$this->em->flush();
|
||||
}
|
||||
|
||||
return $next_song;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the next-playing song for this station based on its playlist rotation rules.
|
||||
*
|
||||
* @param Entity\Station $station
|
||||
* @return Entity\SongHistory|null
|
||||
*/
|
||||
public function calculateNextSong(Entity\Station $station)
|
||||
{
|
||||
// Process requests first (if applicable)
|
||||
if ($station->getEnableRequests()) {
|
||||
|
||||
$min_minutes = (int)$station->getRequestDelay();
|
||||
$threshold_minutes = $min_minutes + mt_rand(0, $min_minutes);
|
||||
|
||||
$threshold = time() - ($threshold_minutes * 60);
|
||||
|
||||
// Look up all requests that have at least waited as long as the threshold.
|
||||
$request = $this->em->createQuery('SELECT sr, sm
|
||||
FROM '.Entity\StationRequest::class.' sr JOIN sr.track sm
|
||||
WHERE sr.played_at = 0 AND sr.station_id = :station_id AND sr.timestamp <= :threshold
|
||||
ORDER BY sr.id ASC')
|
||||
->setParameter('station_id', $station->getId())
|
||||
->setParameter('threshold', $threshold)
|
||||
->setMaxResults(1)
|
||||
->getOneOrNullResult();
|
||||
|
||||
if ($request instanceof Entity\StationRequest) {
|
||||
return $this->_playSongFromRequest($request);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Pull all active, non-empty playlists and sort by type.
|
||||
$playlists_by_type = [];
|
||||
foreach($station->getPlaylists() as $playlist) {
|
||||
/** @var Entity\StationPlaylist $playlist */
|
||||
|
||||
// Don't include empty playlists or nonstandard ones
|
||||
if ($playlist->getIsEnabled()
|
||||
&& $playlist->getSource() === Entity\StationPlaylist::SOURCE_SONGS
|
||||
&& $playlist->getMediaItems()->count() > 0) {
|
||||
$playlists_by_type[$playlist->getType()][$playlist->getId()] = $playlist;
|
||||
}
|
||||
}
|
||||
|
||||
// Pull all recent cued songs for easy referencing below.
|
||||
$cued_song_history = $this->em->createQuery('SELECT sh FROM '.Entity\SongHistory::class.' sh
|
||||
WHERE sh.station_id = :station_id
|
||||
AND (sh.timestamp_cued != 0 AND sh.timestamp_cued IS NOT NULL)
|
||||
AND sh.timestamp_cued >= :threshold
|
||||
ORDER BY sh.timestamp_cued DESC')
|
||||
->setParameter('station_id', $station->getId())
|
||||
->setParameter('threshold', time()-86399)
|
||||
->getArrayResult();
|
||||
|
||||
// Once per day playlists
|
||||
if (!empty($playlists_by_type['once_per_day'])) {
|
||||
foreach ($playlists_by_type['once_per_day'] as $playlist) {
|
||||
/** @var Entity\StationPlaylist $playlist */
|
||||
if ($playlist->canPlayOnce()) {
|
||||
// Check if already played
|
||||
$relevant_song_history = array_slice($cued_song_history, 0, 15);
|
||||
|
||||
$was_played = false;
|
||||
foreach($relevant_song_history as $sh_row) {
|
||||
if ($sh_row['playlist_id'] == $playlist->getId()) {
|
||||
$was_played = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$was_played) {
|
||||
$sh = $this->_playSongFromPlaylist($playlist);
|
||||
if ($sh) {
|
||||
return $sh;
|
||||
}
|
||||
}
|
||||
|
||||
reset($cued_song_history);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Once per X songs playlists
|
||||
if (!empty($playlists_by_type['once_per_x_songs'])) {
|
||||
foreach($playlists_by_type['once_per_x_songs'] as $playlist) {
|
||||
/** @var Entity\StationPlaylist $playlist */
|
||||
|
||||
$relevant_song_history = array_slice($cued_song_history, 0, $playlist->getPlayPerSongs());
|
||||
|
||||
$was_played = false;
|
||||
foreach($relevant_song_history as $sh_row) {
|
||||
if ($sh_row['playlist_id'] == $playlist->getId()) {
|
||||
$was_played = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$was_played) {
|
||||
$sh = $this->_playSongFromPlaylist($playlist);
|
||||
if ($sh) {
|
||||
return $sh;
|
||||
}
|
||||
}
|
||||
|
||||
reset($cued_song_history);
|
||||
}
|
||||
}
|
||||
|
||||
// Once per X minutes playlists
|
||||
if (!empty($playlists_by_type['once_per_x_minutes'])) {
|
||||
foreach($playlists_by_type['once_per_x_minutes'] as $playlist) {
|
||||
/** @var Entity\StationPlaylist $playlist */
|
||||
|
||||
$threshold = time() - ($playlist->getPlayPerMinutes() * 60);
|
||||
|
||||
$was_played = false;
|
||||
foreach($cued_song_history as $sh_row) {
|
||||
if ($sh_row['timestamp_cued'] < $threshold) {
|
||||
break;
|
||||
} else if ($sh_row['playlist_id'] == $playlist->getId()) {
|
||||
$was_played = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$was_played) {
|
||||
$sh = $this->_playSongFromPlaylist($playlist);
|
||||
if ($sh) {
|
||||
return $sh;
|
||||
}
|
||||
}
|
||||
|
||||
reset($cued_song_history);
|
||||
}
|
||||
}
|
||||
|
||||
// Time-block scheduled playlists
|
||||
if (!empty($playlists_by_type['scheduled'])) {
|
||||
foreach ($playlists_by_type['scheduled'] as $playlist) {
|
||||
/** @var Entity\StationPlaylist $playlist */
|
||||
if ($playlist->canPlayScheduled()) {
|
||||
$sh = $this->_playSongFromPlaylist($playlist);
|
||||
if ($sh) {
|
||||
return $sh;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Default rotation playlists
|
||||
if (!empty($playlists_by_type['default'])) {
|
||||
$playlist_weights = [];
|
||||
foreach($playlists_by_type['default'] as $playlist_id => $playlist) {
|
||||
/** @var Entity\StationPlaylist $playlist */
|
||||
$playlist_weights[$playlist_id] = $playlist->getWeight();
|
||||
}
|
||||
|
||||
$rand = random_int(1, (int)array_sum($playlist_weights));
|
||||
foreach ($playlist_weights as $playlist_id => $weight) {
|
||||
$rand -= $weight;
|
||||
if ($rand <= 0) {
|
||||
$playlist = $playlists_by_type['default'][$playlist_id];
|
||||
|
||||
$sh = $this->_playSongFromPlaylist($playlist);
|
||||
if ($sh) {
|
||||
return $sh;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a playlist's cache as invalidated and force regeneration on the next "next song" call.
|
||||
*
|
||||
* @param Entity\StationPlaylist $playlist
|
||||
*/
|
||||
public function clearPlaybackCache(Entity\StationPlaylist $playlist): void
|
||||
{
|
||||
$this->cache->remove($this->_getCacheName($playlist));
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a StationRequest object, create a new SongHistory entry that cues the requested song to play next.
|
||||
*
|
||||
* @param Entity\StationRequest $request
|
||||
* @return Entity\SongHistory
|
||||
* @throws \Doctrine\ORM\ORMException
|
||||
* @throws \Doctrine\ORM\OptimisticLockException
|
||||
*/
|
||||
protected function _playSongFromRequest(Entity\StationRequest $request)
|
||||
{
|
||||
// Log in history
|
||||
$sh = new Entity\SongHistory($request->getTrack()->getSong(), $request->getStation());
|
||||
$sh->setRequest($request);
|
||||
$sh->setMedia($request->getTrack());
|
||||
|
||||
$sh->setDuration($request->getTrack()->getCalculatedLength());
|
||||
$sh->setTimestampCued(time());
|
||||
$this->em->persist($sh);
|
||||
|
||||
$request->setPlayedAt(time());
|
||||
$this->em->persist($request);
|
||||
|
||||
$this->em->flush();
|
||||
|
||||
return $sh;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a specified (sequential or shuffled) playlist, choose a song from the playlist to play and return it.
|
||||
*
|
||||
* @param Entity\StationPlaylist $playlist
|
||||
* @return Entity\SongHistory|null
|
||||
* @throws \Doctrine\ORM\ORMException
|
||||
* @throws \Doctrine\ORM\OptimisticLockException
|
||||
*/
|
||||
protected function _playSongFromPlaylist(Entity\StationPlaylist $playlist)
|
||||
{
|
||||
$cache_name = $this->_getCacheName($playlist);
|
||||
$media_queue = (array)$this->cache->get($cache_name);
|
||||
|
||||
if (empty($media_queue)) {
|
||||
$all_media = $this->em->createQuery('SELECT sm.id FROM '.Entity\StationMedia::class.' sm
|
||||
JOIN sm.playlist_items spm
|
||||
WHERE spm.playlist_id = :playlist_id
|
||||
ORDER BY spm.weight ASC')
|
||||
->setParameter('playlist_id', $playlist->getId())
|
||||
->getArrayResult();
|
||||
|
||||
$media_queue = [];
|
||||
foreach($all_media as $media_row) {
|
||||
$media_queue[] = $media_row['id'];
|
||||
}
|
||||
|
||||
if ($playlist->getOrder() === Entity\StationPlaylist::ORDER_RANDOM) {
|
||||
shuffle($media_queue);
|
||||
}
|
||||
}
|
||||
|
||||
$media_id = array_shift($media_queue);
|
||||
|
||||
// Save the modified cache, sans the now-missing entry.
|
||||
$this->cache->set($media_queue, $cache_name, self::CACHE_TTL);
|
||||
|
||||
/** @var Entity\Repository\StationMediaRepository $media_repo */
|
||||
$media_repo = $this->em->getRepository(Entity\StationMedia::class);
|
||||
|
||||
$media_to_play = $media_repo->find($media_id);
|
||||
|
||||
if ($media_to_play instanceof Entity\StationMedia) {
|
||||
$spm = $media_to_play->getItemForPlaylist($playlist);
|
||||
$spm->played();
|
||||
$this->em->persist($spm);
|
||||
|
||||
// Log in history
|
||||
$sh = new Entity\SongHistory($media_to_play->getSong(), $playlist->getStation());
|
||||
$sh->setPlaylist($playlist);
|
||||
$sh->setMedia($media_to_play);
|
||||
|
||||
$sh->setDuration($media_to_play->getCalculatedLength());
|
||||
$sh->setTimestampCued(time());
|
||||
|
||||
$this->em->persist($sh);
|
||||
$this->em->flush();
|
||||
|
||||
return $sh;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cache name for the given playlist.
|
||||
*
|
||||
* @param Entity\StationPlaylist $playlist
|
||||
* @return string
|
||||
*/
|
||||
protected function _getCacheName(Entity\StationPlaylist $playlist): string
|
||||
{
|
||||
return 'autodj/playlist_'.$playlist->getId().'_'.$playlist->getOrder().'_'.$playlist->getType();
|
||||
}
|
||||
}
|
|
@ -1,11 +1,31 @@
|
|||
<?php
|
||||
namespace App\Radio\Backend;
|
||||
|
||||
use App\Radio\AutoDJ;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use App\Entity;
|
||||
use Monolog\Logger;
|
||||
use Supervisor\Supervisor;
|
||||
|
||||
class Liquidsoap extends BackendAbstract
|
||||
{
|
||||
/** @var AutoDJ */
|
||||
protected $autodj;
|
||||
|
||||
/**
|
||||
* @param EntityManager $em
|
||||
* @param Supervisor $supervisor
|
||||
* @param Logger $logger
|
||||
* @param AutoDJ $autodj
|
||||
* @see \App\Provider\RadioProvider
|
||||
*/
|
||||
public function __construct(EntityManager $em, Supervisor $supervisor, Logger $logger, AutoDJ $autodj)
|
||||
{
|
||||
parent::__construct($em, $supervisor, $logger);
|
||||
|
||||
$this->autodj = $autodj;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
|
@ -715,11 +735,8 @@ class Liquidsoap extends BackendAbstract
|
|||
|
||||
public function getNextSong($as_autodj = false)
|
||||
{
|
||||
/** @var Entity\Repository\SongHistoryRepository $history_repo */
|
||||
$history_repo = $this->em->getRepository(Entity\SongHistory::class);
|
||||
|
||||
/** @var Entity\SongHistory|null $sh */
|
||||
$sh = $history_repo->getNextSongForStation($this->station, $as_autodj);
|
||||
$sh = $this->autodj->getNextSong($this->station, $as_autodj);
|
||||
|
||||
if ($sh instanceof Entity\SongHistory) {
|
||||
$media = $sh->getMedia();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
namespace App\Sync\Task;
|
||||
|
||||
use App\Cache;
|
||||
use App\Url;
|
||||
use App\Radio\AutoDJ;
|
||||
use App\ApiUtilities;
|
||||
use App\Radio\Adapters;
|
||||
use App\Webhook\Dispatcher;
|
||||
|
@ -24,6 +24,9 @@ class NowPlaying extends TaskAbstract
|
|||
/** @var Adapters */
|
||||
protected $adapters;
|
||||
|
||||
/** @var AutoDJ */
|
||||
protected $autodj;
|
||||
|
||||
/** @var Dispatcher */
|
||||
protected $webhook_dispatcher;
|
||||
|
||||
|
@ -45,8 +48,18 @@ class NowPlaying extends TaskAbstract
|
|||
/** @var string */
|
||||
protected $analytics_level;
|
||||
|
||||
/**
|
||||
* @param EntityManager $em
|
||||
* @param Database $influx
|
||||
* @param Cache $cache
|
||||
* @param Adapters $adapters
|
||||
* @param Dispatcher $webhook_dispatcher
|
||||
* @param ApiUtilities $api_utils
|
||||
* @param AutoDJ $autodj
|
||||
* @see \App\Provider\SyncProvider
|
||||
*/
|
||||
public function __construct(EntityManager $em, Database $influx, Cache $cache, Adapters $adapters,
|
||||
Dispatcher $webhook_dispatcher, ApiUtilities $api_utils)
|
||||
Dispatcher $webhook_dispatcher, ApiUtilities $api_utils, AutoDJ $autodj)
|
||||
{
|
||||
$this->em = $em;
|
||||
$this->influx = $influx;
|
||||
|
@ -54,6 +67,7 @@ class NowPlaying extends TaskAbstract
|
|||
$this->adapters = $adapters;
|
||||
$this->webhook_dispatcher = $webhook_dispatcher;
|
||||
$this->api_utils = $api_utils;
|
||||
$this->autodj = $autodj;
|
||||
|
||||
$this->history_repo = $this->em->getRepository(Entity\SongHistory::class);
|
||||
$this->song_repo = $this->em->getRepository(Entity\Song::class);
|
||||
|
@ -178,7 +192,7 @@ class NowPlaying extends TaskAbstract
|
|||
|
||||
$np->song_history = $this->history_repo->getHistoryForStation($station, $this->api_utils);
|
||||
|
||||
$next_song = $this->history_repo->getNextSongForStation($station);
|
||||
$next_song = $this->autodj->getNextSong($station);
|
||||
if ($next_song instanceof Entity\SongHistory) {
|
||||
$np->playing_next = $next_song->api(new Entity\Api\SongHistory, $this->api_utils);
|
||||
} else {
|
||||
|
@ -206,7 +220,7 @@ class NowPlaying extends TaskAbstract
|
|||
|
||||
$np->song_history = $this->history_repo->getHistoryForStation($station, $this->api_utils);
|
||||
|
||||
$next_song = $this->history_repo->getNextSongForStation($station);
|
||||
$next_song = $this->autodj->getNextSong($station);
|
||||
|
||||
if ($next_song instanceof Entity\SongHistory) {
|
||||
$np->playing_next = $next_song->api(new Entity\Api\SongHistory, $this->api_utils);
|
||||
|
|
Loading…
Reference in a new issue