Esempio n. 1
0
        private async Task AddToQueueAsync(Song song)
        {
            if (QueueSongs.Any(p => p.SongId == song.Id))
            {
                return;
            }

            var prev = QueueSongs.LastOrDefault();

            // Create the new queue entry
            var newQueue = new QueueSong
            {
                SongId = song.Id,
                PrevId = prev == null ? 0 : prev.Id,
                Song   = song
            };

            using (var bg = _bgFunc())
            {
                await bg.InsertAsync(newQueue);

                if (prev != null)
                {
                    prev.NextId = newQueue.Id;
                    await bg.UpdateItemAsync(prev);
                }

                QueueSongsLookup.Add(newQueue.Id, newQueue);
                QueueSongs.Add(newQueue);
            }
        }
Esempio n. 2
0
        private void LoadQueue()
        {
            var       queue = _sqlService.SelectAll <QueueSong>();
            QueueSong head  = null;

            foreach (var queueSong in queue)
            {
                queueSong.Song = Songs.FirstOrDefault(p => p.Id == queueSong.SongId);

                _lookupMap.Add(queueSong.Id, queueSong);
                if (queueSong.PrevId == 0)
                {
                    head = queueSong;
                }
            }

            if (head == null)
            {
                return;
            }

            for (var i = 0; i < queue.Count; i++)
            {
                PlaybackQueue.Add(head);

                if (head.NextId != 0)
                {
                    head = _lookupMap[head.NextId];
                }
            }
        }
Esempio n. 3
0
        public async Task AddToQueueAsync(Song song)
        {
            var tail = PlaybackQueue.LastOrDefault();

            //Create the new queue entry
            var newQueue = new QueueSong
            {
                SongId = song.Id,
                NextId = 0,
                PrevId = tail == null ? 0 : tail.Id,
                Song   = song
            };

            //Add it to the database
            await _sqlService.InsertAsync(newQueue);

            if (tail != null)
            {
                //Update the next id of the previous tail
                tail.NextId = newQueue.Id;
                await _sqlService.UpdateItemAsync(tail);
            }

            //Add the new queue entry to the collection and map
            PlaybackQueue.Add(newQueue);
            _lookupMap.Add(newQueue.Id, newQueue);
        }
Esempio n. 4
0
        public async void PlaySong(QueueSong queue)
        {
            _appSettingsHelper.Write(PlayerConstants.CurrentTrack, queue.Id);
            if (_alreadyStarted)
            {
                _player.Reset();
            }
            else
            {
                StartForeground(NotificationId, BuildNotification());
            }
            _alreadyStarted = true;

            try
            {
                await _player.SetDataSourceAsync(ApplicationContext, Uri.Parse(queue.Song.AudioUrl));

                MediaPlayerState = MediaPlayerState.Buffering;
                _player.PrepareAsync();
            }
            catch (Exception e)
            {
                MediaPlayerState = MediaPlayerState.None;
                Log.Error("MUSIC SERVICE", "Player error", e);
            }
        }
Esempio n. 5
0
        public async void PlaySong(QueueSong song)
        {
            if (song == null || song.Song == null)
            {
                CurtainPrompt.ShowError("Song seems to be empty...");
                return;
            }

            Insights.Track(
                "Play Song",
                new Dictionary <string, string>
            {
                { "Name", song.Song.Name },
                { "ArtistName", song.Song.ArtistName },
                { "ProviderId", song.Song.ProviderId }
            });

            if (_isShutdown)
            {
                await AddMediaPlayerEventHandlers();
            }

            _appSettings.Write("RadioId", null);
            _appSettings.Write("RadioMode", false);
            _appSettings.Write(PlayerConstants.CurrentTrack, song.Id);

            var message = new ValueSet {
                { PlayerConstants.StartPlayback, null }
            };

            BackgroundMediaPlayer.SendMessageToBackground(message);

            RaiseEvent(TrackChanged);
        }
Esempio n. 6
0
        /// <summary>
        ///     Starts a given track
        /// </summary>
        public void StartTrack(QueueSong song)
        {
            var source = song.Song.AudioUrl;

            _currentTrackIndex    = tracks.FindIndex(p => p.SongId == song.SongId);
            _mediaPlayer.AutoPlay = false;
            _mediaPlayer.SetUriSource(new Uri(source));
        }
        public async Task QueueSongAsync(QueueSong song)
        {
            this.SongQueue.Enqueue(song);

            if (SongQueue.Count() == 1)
            {
                await NextSongAsync();
            }
            await server.sendRoomUpdate(this);
        }
Esempio n. 8
0
        private async void SetTrackUri(QueueSong track)
        {
            try
            {
                if (!track.Song.IsStreaming)
                {
                    var file = await StorageFile.GetFileFromPathAsync(track.Song.AudioUrl);

                    if (file != null)
                    {
                        try
                        {
                            BackgroundMediaPlayer.Current.SetFileSource(file);
                            BackgroundMediaPlayer.Current.Play();
                        }
                        catch
                        {
                            SkipToNext();
                        }
                    }
                }

                else if (track.Song.IsStreaming)
                {
                    try
                    {
                        BackgroundMediaPlayer.Current.SetUriSource(new Uri(track.Song.AudioUrl));
                        BackgroundMediaPlayer.Current.Play();
                    }
                    catch
                    {
                        SkipToNext();
                    }
                }

                else
                {
                    return;
                }
            }

            catch (UnauthorizedAccessException UnAuth)
            {
                ErrorHandler?.Invoke(this, UnAuth);
                return;
            }

            catch
            {
                return;
            }

            LoadAndSetTile();
        }
Esempio n. 9
0
 public async Task UpdateNowPlaying(QueueSong queue)
 {
     try
     {
         await _service.ScrobbleNowPlayingAsync(queue.Song.Name, queue.Song.Artist.Name,
                                                DateTime.UtcNow, queue.Song.Duration);
     }
     catch
     {
     }
 }
Esempio n. 10
0
        public static QueueSong GetQueueSong(Func <QueueSong, bool> expression)
        {
            QueueSong queueSong = Sql.GetFirstQueueTrack(expression, Path.Combine(DbMainPath, PlayerConstants.BgDataBasePath));

            if (queueSong != null)
            {
                Song song = Sql.GetFirstTrack(p => p.Id == queueSong.SongId, Path.Combine(DbMainPath, PlayerConstants.DataBasePath));
                queueSong.Song = song;
                return(queueSong);
            }
            return(null);
        }
Esempio n. 11
0
        public void StartMusicInternal(QueueSong track)
        {
            if (track == null)
            {
                SkipToNext();
                return;
            }

            _currentTrack = track;
            SetTrackUri(track);
            TrackChanged?.Invoke(this, _currentTrack.Id);
        }
Esempio n. 12
0
        public async void PlaySong(QueueSong queueSong)
        {
            try
            {
                var song = App.Locator.CollectionService.GetSongById(queueSong.SongId);
                await Task.Factory.StartNew(() =>
                {
                    if (song.IsDownload && !App.Locator.Network.IsActive)
                    {
                        MessageHelpers.ShowError("Problem while streaming.", "No internet connection");
                        NextSong();
                        return;
                    }
                });
                await CompletePlayAsync(queueSong);
            }
            catch
            {
                //ignore
            }

            //await Task.Run(() =>
            //{
            //    if (song == null && !song.IsDownload)
            //    {
            //        if (!File.Exists(song.AudioUrl) || string.IsNullOrEmpty(song.AudioUrl))
            //        {
            //            MessageHelpers.DeleteRequestAsync("File doesn't exists at given url.", "Delete", song);
            //            if (App.Locator.CollectionService.CurrentPlaybackQueue.Count > 0)
            //                NextSong();
            //            return;
            //        }
            //    }

            //    else if (song.IsDownload &&  !App.Locator.Network.IsActive)
            //    {
            //        MessageHelpers.ShowError("Problem while streaming.", "No internet connection");
            //        NextSong();
            //        return;
            //    }


            //    //if (song.IsDownload)
            //    //{
            //    //    if (!await IsValid(song.AudioUrl))
            //    //    {
            //    //        MessageHelpers.ShowError("Audio url is not responding we suggest rematch.", "Re match", song: song, IsRematchError: true);
            //    //        NextSong();
            //    //        return;
            //    //    }
            //    //}
            //});
        }
Esempio n. 13
0
        private async void InternalStartTrack(QueueSong track)
        {
            _transportControls.IsPreviousEnabled = !IsRadioMode;

            // If the flac media source adapter is not null, disposed of it
            // since we won't be using it

            if (_currentMediaSourceAdapter != null)
            {
                _currentMediaSourceAdapter.Dispose();
                _currentMediaSourceAdapter = null;
            }

            if (track.Song.IsStreaming)
            {
                _mediaPlayer.SetUriSource(new Uri(track.Song.AudioUrl));
            }
            else
            {
                var file = await StorageFile.GetFileFromPathAsync(track.Song.AudioUrl);

                if (file != null)
                {
                    try
                    {
                        if (file.FileType != ".flac")
                        {
                            _mediaPlayer.SetFileSource(file);
                        }
                        else
                        {
                            // Use custom media source for FLAC support
                            _currentMediaSourceAdapter =
                                await FlacMediaSourceAdapter.CreateAsync(file);

                            BackgroundMediaPlayer.Current.SetMediaSource(_currentMediaSourceAdapter.MediaSource);
                        }
                    }
                    catch
                    {
                        SkipToNext();
                    }
                }
                else if (CurrentTrack.NextId != 0 && CurrentTrack.PrevId != 0)
                {
                    SkipToNext();
                }
            }
            _mediaPlayer.Play();
        }
Esempio n. 14
0
        public async Task DeleteFromQueueAsync(QueueSong songToRemove)
        {
            QueueSong previousModel;

            if (songToRemove == null)
            {
                return;
            }

            if (_lookupMap.TryGetValue(songToRemove.PrevId, out previousModel))
            {
                previousModel.NextId = songToRemove.NextId;
                await _bgSqlService.UpdateItemAsync(previousModel);
            }

            if (_lookupMap.TryGetValue(songToRemove.ShufflePrevId, out previousModel))
            {
                previousModel.ShuffleNextId = songToRemove.ShuffleNextId;
                await _bgSqlService.UpdateItemAsync(previousModel);
            }

            QueueSong nextModel;

            if (_lookupMap.TryGetValue(songToRemove.NextId, out nextModel))
            {
                nextModel.PrevId = songToRemove.PrevId;
                await _bgSqlService.UpdateItemAsync(nextModel);
            }

            if (_lookupMap.TryGetValue(songToRemove.ShuffleNextId, out nextModel))
            {
                nextModel.ShufflePrevId = songToRemove.ShufflePrevId;
                await _bgSqlService.UpdateItemAsync(nextModel);
            }

            await _dispatcher.RunAsync(
                () =>
            {
                PlaybackQueue.Remove(songToRemove);
                ShufflePlaybackQueue.Remove(songToRemove);
            });

            _lookupMap.TryRemove(songToRemove.Id, out songToRemove);

            // Delete from database
            await _bgSqlService.DeleteItemAsync(songToRemove);
        }
Esempio n. 15
0
        private void RemoveFlyoutClicked(object sender, RoutedEventArgs e)
        {
            var queueList = CurrentQueueView.Items.Cast <QueueSong>().ToList();

            if (queueList.Count == 1)
            {
                ToastManager.ShowError("Something went wrong.");
                return;
            }
            QueueSong song = (sender as MenuFlyoutItem).DataContext as QueueSong;

            if (App.Locator.Player.CurrentSong.Id == song.SongId)
            {
                ToastManager.ShowError("Cannot remove.");
                return;
            }
            App.Locator.CollectionService.DeleteFromQueueAsync(song);
        }
Esempio n. 16
0
        public void PlaySong(QueueSong song)
        {
            if (_isShutdown)
            {
                AddMediaPlayerEventHandlers();
            }

            AppSettingsHelper.Write(PlayerConstants.CurrentTrack, song.Id);

            var message = new ValueSet {
                { PlayerConstants.StartPlayback, null }
            };

            BackgroundMediaPlayer.SendMessageToBackground(message);

            song.Song.PlayCount++;
            song.Song.LastPlayed = DateTime.Now;
        }
Esempio n. 17
0
        private async Task CompletePlayAsync(QueueSong song)
        {
            if (_isShutdown)
            {
                await AddMediaPlayerEventHandlers();
            }
            _appSettings.Write(PlayerConstants.CurrentTrack, song.SongId);
            _appSettings.Write(PlayerConstants.CurrentQueueTrackIndex, song.Id);

            Debug.WriteLine(_appSettings.Read <int>(PlayerConstants.CurrentTrack));
            try
            {
                var message = new ValueSet {
                    { PlayerConstants.StartPlayback, null }
                };
                BackgroundMediaPlayer.SendMessageToBackground(message);
            }
            catch
            {
                ShowError("Error restart device!!!");
            }
        }
Esempio n. 18
0
        public async void StartRadioTrack(QueueSong track)
        {
            if (track == null)
            {
                return;
            }

            switch (track.Song.SongState)
            {
            case SongState.BackgroundMatching:
                _transportControls.IsPlayEnabled     = false;
                _transportControls.IsNextEnabled     = false;
                _transportControls.IsPreviousEnabled = false;
                OnEvent(MatchingTrack);

                // Create the station manager
                var radioStationManager = new RadioStationManager(_station.GracenoteId, _station.Id,
                                                                  CreateCollectionSqlService,
                                                                  CreatePlayerSqlService);

                var matched = await radioStationManager.MatchSongAsync(track.Song);

                _transportControls.IsNextEnabled = true;

                if (!matched)
                {
                    SkipToNext();
                    return;
                }
                break;

            case SongState.NoMatch:
                SkipToNext();
                break;
            }

            InternalStartTrack(track);
        }
Esempio n. 19
0
        public static async void PlaySong(QueueSong queueSong)
        {
            if (queueSong == null)
            {
                return;
            }

//            Insights.Track("Play Song", new Dictionary<string, string>
//            {
//                {"Name",queueSong.Song.Name},
//                {"ArtistName",queueSong.Song.ArtistName},
//                {"ProviderId",queueSong.Song.ProviderId}
//            });

            if (!App.Current.AudioServiceConnection.IsPlayerBound)
            {
                if (!await App.Current.StartPlaybackServiceAsync())
                {
                    return;
                }
            }

            App.Current.AudioServiceConnection.GetPlaybackService().PlaySong(queueSong);
        }
        private async Task handlePacketAsync(Packet packet) // TODO add behavior
        {
            object data = null;

            switch (packet.Type)
            {
            default:
                throw new NotImplementedException("Packet type has no suitable handler!");

            case PacketType.ChatMessage:
                data = packet.Data.ToObject <ChatMessageData>();
                await room.HandleChatAsync($"{user.DisplayName}: {((ChatMessageData)data).Message}");

                break;

            case PacketType.RoomList:
                await SendRoomList();

                break;

            case PacketType.JoinRoom:
                await server.JoinRoom(this, packet.Data.ToObject <JoinRoomData>());

                break;

            case PacketType.LeaveRoom:
                // Has no data
                room.Users.Remove(this.user);
                await server.sendRoomUpdate(room);

                break;

            case PacketType.RoomUpdate:
                data = packet.Data.ToObject <RoomUpdateData>();
                break;

            case PacketType.KeepAlive:
                // Just a keepalive, needs no data
                this.MissedKeepalives = 0;
                Console.WriteLine($"Kept alive user {user.Id}");
                break;

            case PacketType.PlayMusic:
                // Just indicates a play command
                break;

            case PacketType.PauseMusic:
                // Just indicates pause command
                break;

            case PacketType.ClearQueue:
                // Just indicates clear queue command
                await room.ClearQueueAsync();

                break;

            case PacketType.CreateRoom:
                await server.CreateRoomAndJoin(this, packet.Data.ToObject <CreateRoomData>());

                break;

            case PacketType.SetUserData:
                data = packet.Data.ToObject <SetUserData>();    // Just in case the server can for some reason change the user's data
                handleUserData((SetUserData)data);
                break;

            case PacketType.SkipSong:
            case PacketType.Done:
                if (this.room.HostUserId == this.user.Id)
                {
                    room.SongQueue.Dequeue();
                    await room.NextSongAsync();
                }
                break;

            case PacketType.EncodingData:
                await this.SendPacketAsync(packet);

                //await this.Room.BroadcastPacketAsync(packet);
                break;

            case PacketType.QueueSong:
                var song = new QueueSong()
                {
                    Path   = packet.Data.ToObject <QueueSongData>().Song,
                    UserId = this.user.Id
                };

                await room.QueueSongAsync(song);

                break;
            }
        }
Esempio n. 21
0
        public async void StartTrack(QueueSong track, bool ended = false)
        {
            if (track == null)
            {
                return;
            }

            try
            {
                ScrobbleOnMediaEnded();
            }
            catch { }

            if (IsRadioMode && _station != null && _currentTrack != null && _currentTrack.Song.ProviderId.Contains("gn."))
            {
                // Create the station manager
                var radioStationManager = new RadioStationManager(_station.GracenoteId, _station.Id,
                                                                  CreateCollectionSqlService,
                                                                  CreatePlayerSqlService);

                var trackId = _currentTrack.Song.ProviderId.Replace("gn.", "");

                if (!ended)
                {
                    await radioStationManager.SkippedAsync(trackId);
                }
                else
                {
                    await radioStationManager.PlayedAsync(trackId);
                }

                await radioStationManager.UpdateQueueAsync();

                track = radioStationManager.QueueSongs[0];
                _appSettingsHelper.Write(PlayerConstants.CurrentTrack, track.Id);
                OnEvent(QueueUpdated);
            }

            _currentTrack = track;
            UpdateTile();

            if (TrackChanged != null)
            {
                OnTrackChanged(_currentTrack.SongId);
            }

            _mediaPlayer.Pause();
            if (_mediaPlayer.Position > TimeSpan.Zero)
            {
                _mediaPlayer.Position = TimeSpan.Zero;
            }
            _transportControls.PlaybackStatus = MediaPlaybackStatus.Changing;

            if (IsRadioMode)
            {
                StartRadioTrack(track);
            }
            else
            {
                InternalStartTrack(track);
            }
        }
Esempio n. 22
0
        private void LoadQueue(List <Song> songs)
        {
            var       queue       = _bgSqlService.SelectAll <QueueSong>();
            QueueSong head        = null;
            QueueSong shuffleHead = null;

            foreach (var queueSong in queue)
            {
                queueSong.Song = songs.FirstOrDefault(p => p.Id == queueSong.SongId);

                _lookupMap.TryAdd(queueSong.Id, queueSong);

                if (queueSong.ShufflePrevId == 0)
                {
                    shuffleHead = queueSong;
                }

                if (queueSong.PrevId == 0)
                {
                    head = queueSong;
                }
            }

            if (head != null)
            {
                for (var i = 0; i < queue.Count; i++)
                {
                    if (_dispatcher != null)
                    {
                        _dispatcher.RunAsync(() => PlaybackQueue.Add(head)).Wait();
                    }
                    else
                    {
                        PlaybackQueue.Add(head);
                    }

                    QueueSong value;
                    if (head.NextId != 0 && _lookupMap.TryGetValue(head.NextId, out value))
                    {
                        head = value;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            if (shuffleHead != null)
            {
                for (var i = 0; i < queue.Count; i++)
                {
                    if (_dispatcher != null)
                    {
                        _dispatcher.RunAsync(() => ShufflePlaybackQueue.Add(shuffleHead)).Wait();
                    }
                    else
                    {
                        ShufflePlaybackQueue.Add(shuffleHead);
                    }

                    QueueSong value;
                    if (shuffleHead.ShuffleNextId != 0 && _lookupMap.TryGetValue(shuffleHead.ShuffleNextId, out value))
                    {
                        shuffleHead = value;
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
Esempio n. 23
0
        private void LoadAndSetTile()
        {
            QueueSong track = CurrentTrack;

            if (track == null)
            {
                TileUpdateManager.CreateTileUpdaterForApplication("App").Clear();
                return;
            }

            var artworkUrl = AppConstant.MissingArtworkAppPath;

            try
            {
                artworkUrl = BackgroundQueueHelper.IsValidPathForAlbum(track.Song.AlbumId)
                 ? AppConstant.LocalStorageAppPath +
                             string.Format(AppConstant.ArtworkPath, track.Song.AlbumId)
                 : AppConstant.MissingArtworkAppPath;
            }
            catch
            {
                artworkUrl = AppConstant.MissingArtworkAppPath;
            }

            string trackName  = track.Song.Name;
            string artistName = track.Song.ArtistName;

            string tileXmlString = "<tile>"
                                   + "<visual branding='nameAndLogo'>"

                                   + "<binding template='TileSmall' hint-textStacking='top'>"
                                   + "<image src='" + artworkUrl + "'" + " placement='peek'/>"
                                   + "<text hint-wrap='true' hint-maxLines='2' hint-style='body' hint-align='left'>" + artistName + "</text>"
                                   + "</binding>"

                                   + "<binding template='TileMedium' hint-textStacking='top'>"
                                   + "<image src='" + artworkUrl + "'" + " placement='peek'/>"
                                   + "<text hint-style='base' hint-align='left'>" + artistName + "</text>"
                                   + "<text hint-style='captionSubtle' hint-align='left'>" + trackName + "</text>"
                                   + "</binding>"

                                   + "<binding template='TileWide' hint-textStacking='left'>"
                                   + "<image src='" + artworkUrl + "'" + " placement='peek'/>"
                                   + "<text hint-style='base' hint-align='left'>" + artistName + "</text>"
                                   + "<text hint-style='captionSubtle' hint-align='left'>" + trackName + "</text>"
                                   + "</binding>"


                                   + "<binding template='TileLarge' hint-textStacking='left'>"
                                   + "<image src='" + artworkUrl + "'" + " placement='peek'/>"
                                   + "<text hint-style='base' hint-align='left'>" + artistName + "</text>"
                                   + "<text hint-style='captionSubtle' hint-align='left'>" + trackName + "</text>"
                                   + "</binding>"


                                   + "</visual>"
                                   + "</tile>";


            Windows.Data.Xml.Dom.XmlDocument toastDOM = new Windows.Data.Xml.Dom.XmlDocument();
            toastDOM.LoadXml(tileXmlString);

            try
            {
                TileNotification toast = new TileNotification(toastDOM);
                TileUpdateManager.CreateTileUpdaterForApplication("App").Update(toast);
            }
            catch (Exception)
            {
            }
        }
Esempio n. 24
0
        public async Task <QueueSong> AddToQueueAsync(Song song, QueueSong position = null, bool shuffleInsert = true)
        {
            if (song == null)
            {
                return(null);
            }

            var       rnd          = new Random(DateTime.Now.Millisecond);
            QueueSong prev         = null;
            QueueSong shufflePrev  = null;
            QueueSong next         = null;
            QueueSong shuffleNext  = null;
            var       shuffleIndex = -1;
            var       normalIndex  = -1;

            if (position != null)
            {
                shuffleIndex = ShufflePlaybackQueue.IndexOf(position) + 1;
                normalIndex  = PlaybackQueue.IndexOf(position) + 1;
            }

            var insert         = normalIndex > -1 && normalIndex < PlaybackQueue.Count;
            var insertShuffle  = shuffleIndex > -1 && shuffleInsert;
            var shuffleLastAdd = shuffleIndex == ShufflePlaybackQueue.Count;

            if (insert)
            {
                next = PlaybackQueue.ElementAtOrDefault(normalIndex);
                if (next != null)
                {
                    _lookupMap.TryGetValue(next.PrevId, out prev);
                }
            }
            else
            {
                prev = PlaybackQueue.LastOrDefault();
            }

            if (insertShuffle)
            {
                if (shuffleLastAdd)
                {
                    shufflePrev = ShufflePlaybackQueue.ElementAtOrDefault(ShufflePlaybackQueue.Count - 1);
                }
                else
                {
                    shuffleNext = ShufflePlaybackQueue.ElementAtOrDefault(shuffleIndex);
                    if (shuffleNext != null)
                    {
                        _lookupMap.TryGetValue(shuffleNext.ShufflePrevId, out shufflePrev);
                    }
                }
            }
            else
            {
                if (ShufflePlaybackQueue.Count > 1)
                {
                    shuffleIndex = rnd.Next(1, ShufflePlaybackQueue.Count - 1);
                    shuffleNext  = ShufflePlaybackQueue.ElementAt(shuffleIndex);

                    _lookupMap.TryGetValue(shuffleNext.ShufflePrevId, out shufflePrev);
                }
                else
                {
                    shuffleLastAdd = true;
                    shufflePrev    = prev;
                }
            }

            // Create the new queue entry
            var newQueue = new QueueSong
            {
                SongId        = song.Id,
                NextId        = next == null ? 0 : next.Id,
                PrevId        = prev == null ? 0 : prev.Id,
                ShuffleNextId = shuffleNext == null ? 0 : shuffleNext.Id,
                ShufflePrevId = shufflePrev == null ? 0 : shufflePrev.Id,
                Song          = song
            };

            // Add it to the database
            await _bgSqlService.InsertAsync(newQueue).ConfigureAwait(false);

            if (next != null)
            {
                // Update the prev id of the queue that was replaced
                next.PrevId = newQueue.Id;
                await _bgSqlService.UpdateItemAsync(next).ConfigureAwait(false);
            }

            if (prev != null)
            {
                // Update the next id of the previous tail
                prev.NextId = newQueue.Id;
                await _bgSqlService.UpdateItemAsync(prev).ConfigureAwait(false);
            }

            if (shuffleNext != null)
            {
                shuffleNext.ShufflePrevId = newQueue.Id;
                await _bgSqlService.UpdateItemAsync(shuffleNext).ConfigureAwait(false);
            }

            if (shufflePrev != null)
            {
                shufflePrev.ShuffleNextId = newQueue.Id;
                await _bgSqlService.UpdateItemAsync(shufflePrev).ConfigureAwait(false);
            }

            // Add the new queue entry to the collection and map
            await _dispatcher.RunAsync(
                () =>
            {
                if (insert)
                {
                    try
                    {
                        PlaybackQueue.Insert(normalIndex, newQueue);
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        PlaybackQueue.Add(newQueue);
                    }
                }
                else
                {
                    PlaybackQueue.Add(newQueue);
                }

                if (shuffleLastAdd || !shuffleInsert)
                {
                    ShufflePlaybackQueue.Add(newQueue);
                }
                else
                {
                    try
                    {
                        ShufflePlaybackQueue.Insert(shuffleIndex, newQueue);
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        ShufflePlaybackQueue.Add(newQueue);
                    }
                }
            }).ConfigureAwait(false);

            _lookupMap.TryAdd(newQueue.Id, newQueue);

            return(newQueue);
        }
 public Task DeleteFromQueueAsync(QueueSong songToRemove)
 {
     throw new NotImplementedException();
 }
 public Task <QueueSong> AddToQueueAsync(Song song, QueueSong position = null, bool shuffleInsert = true)
 {
     throw new NotImplementedException();
 }