private async Task <bool> GetPlayStatusUpdateAsync(CancellationToken cancellationToken) { // Do not pass the cancellation token to the HTTP request since canceling a request will cause iTunes to close the current session. DacpRequest request = new DacpRequest("/ctrl-int/1/playstatusupdate"); request.QueryParameters["revision-number"] = _playStatusRevisionNumber.ToString(); try { var response = await SendRequestAsync(request).ConfigureAwait(false); // Do we still need to process this response? if (cancellationToken.IsCancellationRequested) { return(false); } // Process response var nodes = DacpNodeDictionary.Parse(response.Nodes); _playStatusRevisionNumber = nodes.GetInt("cmsr"); // Current item and container IDs if (nodes.ContainsKey("canp")) { byte[] value = nodes["canp"]; byte[] dbID = { value[0], value[1], value[2], value[3] }; byte[] containerID = { value[4], value[5], value[6], value[7] }; byte[] containerItemID = { value[8], value[9], value[10], value[11] }; byte[] itemID = { value[12], value[13], value[14], value[15] }; CurrentDatabaseID = dbID.GetInt32Value(); CurrentContainerID = containerID.GetInt32Value(); CurrentContainerItemID = containerItemID.GetInt32Value(); CurrentItemID = itemID.GetInt32Value(); } else { CurrentDatabaseID = 0; CurrentContainerID = 0; CurrentContainerItemID = 0; CurrentItemID = 0; } CurrentItemSignature = string.Format("{0}|{1}|{2}|{3}", CurrentDatabaseID, CurrentContainerID, CurrentContainerItemID, CurrentItemID); // Current item info CurrentArtistName = nodes.GetString("cana"); CurrentAlbumName = nodes.GetString("canl"); CurrentSongName = nodes.GetString("cann"); CurrentAlbumPersistentID = (UInt64)nodes.GetLong("asai"); // Play state CurrentPlayState = (PlayState)nodes.GetByte("caps"); // Track time UpdateTrackTime(nodes.GetInt("cast"), nodes.GetNullableInt("cant")); // Shuffle int caas = nodes.GetInt("caas"); IsShuffleAvailable = (caas & (1 << 1)) != 0; CurrentShuffleMode = nodes.GetBool("cash"); // Repeat int caar = nodes.GetInt("caar"); IsRepeatOneAvailable = (caar & (1 << 1)) != 0; IsRepeatAllAvailable = (caar & (1 << 2)) != 0; IsRepeatAvailable = (IsRepeatOneAvailable || IsRepeatAllAvailable); CurrentRepeatMode = (RepeatMode)nodes.GetByte("carp"); //CurrentMediaKind = nodes.GetInt("cmmk"); //ShowUserRating = nodes.GetBool("casu"); // dacp.visualizer IsVisualizerEnabled = nodes.GetBool("cavs"); // dacp.visualizerenabled IsVisualizerAvailable = nodes.GetBool("cave"); // dacp.fullscreen IsFullScreenModeEnabled = nodes.GetBool("cafs"); // dacp.fullscreenenabled IsFullScreenModeAvailable = nodes.GetBool("cafe"); // iTunes Radio iTunesRadioControlState newiTunesRadioControlState = 0; if (iTunesRadioDatabase != null && iTunesRadioDatabase.ID == CurrentDatabaseID) { IsPlayingiTunesRadio = true; CurrentiTunesRadioStationName = nodes.GetString("ceNR"); // caks = 1 when the next button is disabled, and 2 when it's enabled if (nodes.GetByte("caks") != 1) { newiTunesRadioControlState |= iTunesRadioControlState.NextButtonEnabled; } // "aelb" indicates whether the star button (iTunes Radio menu) should be enabled, but this only seems to be set to true // when connected via Home Sharing. This parameter is missing when an ad is playing, so use this to determine whether // the menu should be enabled. if (nodes.ContainsKey("aelb")) { newiTunesRadioControlState |= iTunesRadioControlState.MenuEnabled; } if (nodes.GetByte("aels") == 2) { newiTunesRadioControlState |= iTunesRadioControlState.CurrentSongFavorited; } } else { IsPlayingiTunesRadio = false; } CurrentiTunesRadioControlState = newiTunesRadioControlState; IsTrackTimePositionBarEnabled = nodes.GetBool("casc", true); // Genius Shuffle IsPlayingGeniusShuffle = nodes.GetBool("ceGs"); // There are two other nodes related to Genius Shuffle, "ceGS" and "aeGs" (currently unknown) if (CurrentPlayState == PlayState.FastForward || CurrentPlayState == PlayState.Rewind) { BeginRepeatedTrackTimeRequests(); } await GetVolumeLevelAsync().ConfigureAwait(false); await GetSpeakersAsync().ConfigureAwait(false); //var volumeTask = UpdateCurrentVolumeLevelAsync(); //var userRatingTask = UpdateCurrentSongUserRatingAsync(); //var playQueueTask = UpdatePlayQueueContentsAsync(); //Task[] tasks = new[] { volumeTask, userRatingTask, playQueueTask }; #if WP7 //await TaskEx.WhenAll(tasks).ConfigureAwait(false); #else //await Task.WhenAll(tasks).ConfigureAwait(false); #endif //SubmitGetSpeakersRequest(); PlayStatusUpdated.RaiseOnUIThread(this, new EventArgs()); } catch { return(false); } return(true); }
private async Task <bool> GetSpeakersAsync() { DacpRequest request = new DacpRequest("/ctrl-int/1/getspeakers"); try { var response = await SendRequestAsync(request).ConfigureAwait(false); var speakerNodes = response.Nodes.Where(n => n.Key == "mdcl").Select(n => DacpNodeDictionary.Parse(n.Value)).ToList(); var speakers = Speakers; // Determine whether we need to replace the list of speakers bool replaceSpeakers = false; if (speakers == null || speakers.Count != speakerNodes.Count) { replaceSpeakers = true; } else { // Determine whether we still have the same speaker IDs for (int i = 0; i < speakers.Count; i++) { if (speakers[i].ID != (UInt64)speakerNodes[i].GetLong("msma")) { replaceSpeakers = true; break; } } } // Create the new list of speakers or update the existing speakers if (replaceSpeakers) { Speakers = speakerNodes.Select(n => new AirPlaySpeaker(this, n)).ToList(); } else { for (int i = 0; i < speakers.Count; i++) { speakers[i].ProcessNodes(speakerNodes[i]); } } } catch { return(false); } return(true); }
public AirPlaySpeaker(DacpClient client, DacpNodeDictionary nodes) { _client = client; ProcessNodes(nodes); }
internal Task <IDacpList> GetAlphaGroupedListAsync <T>(DacpRequest request, Func <DacpNodeDictionary, T> itemGenerator, string listKey = DacpUtility.DefaultListKey) { return(GetAlphaGroupedListAsync(request, b => itemGenerator(DacpNodeDictionary.Parse(b)), listKey)); }
protected virtual void ProcessNodes(DacpNodeDictionary nodes) { ID = nodes.GetInt("miid"); PersistentID = (UInt64)nodes.GetLong("mper"); Name = nodes.GetString("minm"); }
public DacpElement(DacpClient client, DacpNodeDictionary nodes) { Client = client; ProcessNodes(nodes); }
public static IEnumerable <T> GetItemsFromNodes <T>(IEnumerable <DacpNode> nodes, Func <DacpNodeDictionary, T> itemGenerator, string listKey = DefaultListKey) { return(GetItemsFromNodes(nodes, d => itemGenerator(DacpNodeDictionary.Parse(d)), listKey)); }
public static IEnumerable <T> GetItemsFromNodes <T>(byte[] data, Func <DacpNodeDictionary, T> itemGenerator, string listKey = DefaultListKey) { return(GetItemsFromNodes(GetResponseNodes(data), d => itemGenerator(DacpNodeDictionary.Parse(d)), listKey)); }
public static IDacpList GetAlphaGroupedDacpList <T>(IEnumerable <DacpNode> nodes, Func <DacpNodeDictionary, T> itemGenerator, out List <T> items, string listKey = DefaultListKey, bool useGroupMinimums = true) { return(GetAlphaGroupedDacpList(nodes, d => itemGenerator(DacpNodeDictionary.Parse(d)), out items, listKey, useGroupMinimums)); }