using System; using System.Collections.Generic; using Crosstales.Radio.Model; using Crosstales.Radio.Model.Enum; using Crosstales.Radio.Util; using UnityEngine; namespace Crosstales.Radio { [HelpURLAttribute("https://www.crosstales.com/media/data/assets/radio/api/class_crosstales_1_1_radio_1_1_simple_player.html")] [ExecuteInEditMode] public class SimplePlayer : BasePlayer { public delegate void StationChange(RadioStation newStation); [Tooltip("'RadioPlayer' from the scene.")] [Header("General Settings")] public RadioPlayer Player; [Tooltip("'RadioManager' from the scene.")] public RadioManager Manager; [Tooltip("Global RadioFilter (active if no explicit filter is given).")] public RadioFilter Filter; [Header("Retry Settings")] [Tooltip("Retry to start the radio on an error (default: false).")] public bool RetryOnError; [Tooltip("How many times should the radio station restart after an error before giving up (default: 3).")] public int Retries = 3; [Tooltip("Play a radio on start (default: false).")] [Header("Behaviour Settings")] public bool PlayOnStart; [Tooltip("Play the radio stations in random order (default: false).")] public bool PlayRandom; private int invokeDelayCounter = 1; private bool started; private float lastPlaytime = float.MinValue; private FilterChange _filterChange; private ProviderReady _providerReady; private StationChange _stationChange; public bool isRetryOnError { get { return RetryOnError; } set { RetryOnError = value; } } public bool isPlayRandom { get { return PlayRandom; } set { PlayRandom = value; } } public override RadioStation RadioStation { get { if (Player != null) { return Player.Station; } return null; } set { if (Player != null) { Player.Station = value; } } } public override AudioSource Source { get { if (Player != null) { return Player.Source; } return null; } protected set { } } public override AudioCodec Codec { get { if (Player != null) { return Player.Codec; } return AudioCodec.MP3_NLayer; } protected set { } } public override float PlayTime { get { if (Player != null) { return Player.PlayTime; } return 0f; } protected set { } } public override float BufferProgress { get { if (Player != null) { return Player.BufferProgress; } return 0f; } protected set { } } public override bool isPlayback { get { if (Player != null) { return Player.isPlayback; } return false; } } public override bool isAudioPlaying { get { if (Player != null) { return Player.isAudioPlaying; } return false; } } public override bool isBuffering { get { if (Player != null) { return Player.isBuffering; } return false; } } public override float RecordPlayTime { get { if (Player != null) { return Player.RecordPlayTime; } return 0f; } protected set { } } public override RecordInfo RecordInfo { get { if (Player != null) { return Player.RecordInfo; } return new RecordInfo(); } } public override bool isLegacyMode { get { if (Player != null) { return Player.isLegacyMode; } return false; } set { if (Player != null) { Player.isLegacyMode = value; } } } public override bool isCaptureDataStream { get { if (Player != null) { return Player.isCaptureDataStream; } return false; } set { if (Player != null) { Player.isCaptureDataStream = value; } } } public override RecordInfo NextRecordInfo { get { if (Player != null) { return Player.RecordInfo; } return new RecordInfo(); } } public override float NextRecordDelay { get { if (Player != null) { return Player.NextRecordDelay; } return 0f; } } public override long CurrentBufferSize { get { if (Player != null) { return Player.CurrentBufferSize; } return Config.DEFAULT_BUFFERSIZE; } } public override long CurrentDownloadSpeed { get { if (Player != null) { return Player.CurrentDownloadSpeed; } return 0L; } } public override MemoryCacheStream DataStream { get { if (Player != null) { return Player.DataStream; } return null; } protected set { } } public override int Channels { get { if (Player != null) { return Player.Channels; } return 2; } protected set { } } public override int SampleRate { get { if (Player != null) { return Player.SampleRate; } return 44100; } protected set { } } public List Stations { get { if (Manager != null) { if (Filter.isFiltering) { return Manager.StationsByName(false, Filter); } return Manager.StationsByName(); } return new List(); } } public List Players { get { if (Manager != null) { if (Filter.isFiltering) { return Manager.PlayersByName(false, Filter); } return Manager.PlayersByName(); } return new List(); } } public bool isReady { get { if (Manager != null) { return Manager.isReady; } return false; } } public event FilterChange OnFilterChange { add { _filterChange = (FilterChange)Delegate.Combine(_filterChange, value); } remove { _filterChange = (FilterChange)Delegate.Remove(_filterChange, value); } } public event ProviderReady OnProviderReady { add { _providerReady = (ProviderReady)Delegate.Combine(_providerReady, value); } remove { _providerReady = (ProviderReady)Delegate.Remove(_providerReady, value); } } public event StationChange OnStationChange { add { _stationChange = (StationChange)Delegate.Combine(_stationChange, value); } remove { _stationChange = (StationChange)Delegate.Remove(_stationChange, value); } } public void OnEnable() { if (Player != null && Manager != null) { Player.OnPlaybackStart += onPlaybackStart; Player.OnPlaybackEnd += onPlaybackEnd; Player.OnAudioStart += onAudioStart; Player.OnAudioEnd += onAudioEnd; Player.OnAudioPlayTimeUpdate += onAudioPlayTimeUpdate; Player.OnBufferingStart += onBufferingStart; Player.OnBufferingEnd += onBufferingEnd; Player.OnBufferingProgressUpdate += onBufferingProgressUpdate; Player.OnErrorInfo += onErrorInfo; Player.OnRecordChange += onRecordChange; Player.OnRecordPlayTimeUpdate += onRecordPlayTimeUpdate; Player.OnNextRecordChange += onNextRecordChange; Player.OnNextRecordDelayUpdate += onNextRecordDelayUpdate; Manager.OnProviderReady += onProviderReady; Manager.OnFilterChange += onFilterChange; } else if (!Helper.isEditorMode) { Debug.LogError("'Player' or 'Manager' are null!"); } } public void OnDisable() { if (Player != null && Manager != null) { Player.OnPlaybackStart -= onPlaybackStart; Player.OnPlaybackEnd -= onPlaybackEnd; Player.OnAudioStart += onAudioStart; Player.OnAudioEnd += onAudioEnd; Player.OnAudioPlayTimeUpdate -= onAudioPlayTimeUpdate; Player.OnBufferingStart -= onBufferingStart; Player.OnBufferingEnd -= onBufferingEnd; Player.OnBufferingProgressUpdate -= onBufferingProgressUpdate; Player.OnErrorInfo -= onErrorInfo; Player.OnRecordChange -= onRecordChange; Player.OnRecordPlayTimeUpdate -= onRecordPlayTimeUpdate; Player.OnNextRecordChange -= onNextRecordChange; Player.OnNextRecordDelayUpdate -= onNextRecordDelayUpdate; Manager.OnProviderReady -= onProviderReady; Manager.OnFilterChange -= onFilterChange; } } public override void Play() { if (!(Player != null)) { return; } if (lastPlaytime + Constants.PLAY_CALL_SPEED < Time.realtimeSinceStartup) { lastPlaytime = Time.realtimeSinceStartup; Stop(); if (!Helper.isEditorMode) { LeanTween.delayedCall(0.4f, play).setIgnoreTimeScale(true); } } else { Debug.LogWarning("Play called to fast - please slow down!"); } } public void Next() { Next(PlayRandom); } public void Next(bool random, RadioFilter filter = null) { if (Player != null && Manager != null) { Player.Station = Manager.NextStation(random, getFilter(filter)); Play(); } } public void Previous() { Previous(PlayRandom); } public void Previous(bool random, RadioFilter filter = null) { if (Player != null && Manager != null) { Player.Station = Manager.PreviousStation(random, getFilter(filter)); Play(); } } public override void Stop() { if (Player != null) { Player.Stop(); } } public override void Silence() { if (Player != null) { Player.Silence(); } } public override void Restart(float invokeDelay = 0.4f) { if (Player != null) { Player.Restart(invokeDelay); } } private void play() { Player.Play(); onStationChange(Player.Station); } private void playInvoker() { if (started) { Play(); } } private RadioFilter getFilter(RadioFilter filter) { if (filter != null && filter.isFiltering) { return filter; } if (Filter.isFiltering) { return Filter; } return null; } private void onPlaybackStart(RadioStation station) { if (_playbackStart != null) { _playbackStart(station); } } private void onPlaybackEnd(RadioStation station) { if (_playbackEnd != null) { _playbackEnd(station); } } private void onAudioStart(RadioStation station) { started = true; if (_audioStart != null) { _audioStart(station); } } private void onAudioEnd(RadioStation station) { started = false; if (_audioEnd != null) { _audioEnd(station); } } private void onAudioPlayTimeUpdate(RadioStation station, float _playtime) { if (_playtime > 30f) { invokeDelayCounter = 1; } if (_audioPlayTimeUpdate != null) { _audioPlayTimeUpdate(station, _playtime); } } private void onBufferingStart(RadioStation station) { if (_bufferingStart != null) { _bufferingStart(station); } } private void onBufferingEnd(RadioStation station) { if (_bufferingEnd != null) { _bufferingEnd(station); } } private void onBufferingProgressUpdate(RadioStation station, float progress) { if (_bufferingProgressUpdate != null) { _bufferingProgressUpdate(station, progress); } } private void onErrorInfo(RadioStation station, string info) { Stop(); if (RetryOnError && Helper.isInternetAvailable) { if (started) { if (invokeDelayCounter < Retries) { Debug.LogWarning("Error occoured -> Restarting station." + Environment.NewLine + info); Invoke("playInvoker", 0.4f * (float)invokeDelayCounter); invokeDelayCounter++; } else { Debug.LogError("Restarting station failed more than " + Retries + " times - giving up!" + Environment.NewLine + info); } } else { Debug.LogError("Could not start the station '" + station.Name + "'! Please try another station. " + Environment.NewLine + info); } } if (_errorInfo != null) { _errorInfo(station, info); } } private void onProviderReady() { if (Config.DEBUG) { Debug.Log("Provider ready - all stations loaded."); } Player.Station = Manager.NextStation(PlayRandom, Filter); if (!Helper.isEditorMode && PlayOnStart) { Play(); } if (_providerReady != null) { _providerReady(); } } private void onFilterChange() { if (_filterChange != null) { _filterChange(); } } private void onStationChange(RadioStation newStation) { if (_stationChange != null) { _stationChange(newStation); } } private void onRecordChange(RadioStation station, RecordInfo newRecord) { if (_recordChange != null) { _recordChange(station, newRecord); } } private void onRecordPlayTimeUpdate(RadioStation station, RecordInfo record, float playtime) { if (_recordPlayTimeUpdate != null) { _recordPlayTimeUpdate(station, record, playtime); } } private void onNextRecordChange(RadioStation station, RecordInfo nextRecord, float delay) { if (_nextRecordChange != null) { _nextRecordChange(station, nextRecord, delay); } } private void onNextRecordDelayUpdate(RadioStation station, RecordInfo nextRecord, float delay) { if (_nextRecordDelayUpdate != null) { _nextRecordDelayUpdate(station, nextRecord, delay); } } } }