public void Run() { Console.WriteLine("Trying to connect to : " + myConfiguration.GetSONOSHTTPAPIURL()); while (!shutdown) { try{ // get the update from the SONOS system... List <SONOSZone> Zones = ZonesUpdater.UpdateSONOSZones(myConfiguration.GetSONOSHTTPAPIURL()); // save before state... NowPlayingBefore = NowPlaying; // get new State... NowPlaying = PlayingNow(Zones); /* if (NowPlaying.Count == 0) * Console.WriteLine ("Nothing playing"); * * // go through all zones and find what is being played... * foreach(String coordinator in NowPlaying.Keys) * { * State Playing = NowPlaying [coordinator]; * * // we have these information at hand now: title, album, artist, duration * // and from the State elapsedTime * // from the track information we build a hash * String Track = Playing.currentTrack.title + Playing.currentTrack.album + Playing.currentTrack.artist + Convert.ToString(Playing.currentTrack.duration); * String TrackHash = GetHashString (Track); * double TrackDonePercentage = (float)Playing.elapsedTime / (float)Playing.currentTrack.duration * 100; * * Console.WriteLine (coordinator+" - "+Playing.currentTrack.artist+" - "+Playing.currentTrack.title+" - "+Playing.elapsedTime+" - "+Playing.currentTrack.duration+" - "+String.Format("{0:0}%", TrackDonePercentage)+" ("+TrackHash+")"); * } */ // check what changed from the last update... if (NowPlayingBefore != null) { // Check for Transitions TManager.CalculateTransitions(NowPlayingBefore, NowPlaying); } } catch (Exception e) { // pokemon handling, catching them all, because we want this to run "unlimitedly" Console.WriteLine("Pokemon: " + e.Message); } Thread.Sleep(myConfiguration.GetUpdateIntervalSeconds() * 1000); } }
/// <summary> /// Calculates the transitions. /// </summary> /// <param name="OldPlayingState">Old playing state.</param> /// <param name="NewPlayingState">New playing state.</param> public void CalculateTransitions(Dictionary <String, State> OldPlayingState, Dictionary <String, State> NewPlayingState) { // merge all the zones and handle conflicts... Dictionary <String, Bookmark> OldPlayingTitles = MergeCoordinatorsAndHandleConflicts(OldPlayingState); Dictionary <String, Bookmark> NewPlayingTitles = MergeCoordinatorsAndHandleConflicts(NewPlayingState); // now we have all previous and updated play states... let's find which ones stopped and started // stopped = in OldPlayingTitles but not in NewPlayingTitles // started = in NewPlayingTitles but not in OldPlayingTitles List <Bookmark> Stopped = StoppedTitles(OldPlayingTitles, NewPlayingTitles); List <Bookmark> Started = StartedTitles(OldPlayingTitles, NewPlayingTitles); foreach (Bookmark bookmark in Stopped) { // output Stopped Information... Console.WriteLine(DateTime.Now.ToShortTimeString() + " - " + DateTime.Now.ToShortDateString() + " - Stopped: " + bookmark.Artist + " - " + bookmark.Title + " - " + bookmark.Position + "/" + bookmark.Duration); // check if this track qualifies to be saved... // these are the requirements: // - the track that stopped is longer than the configured number of seconds (BookmarkOnlyLongerThanSeconds in configuration.json) // - the position within the track is not within the last seconds (number of seconds configurable in configuration.json by UpdateIntervalSeconds) if (bookmark.Duration >= myConfiguration.GetBookmarkOnlyLongerThanSeconds()) { bool matchesTitlePattern = false; // further check if this one matches any pattern #region Regular Expression Check for the title of the track foreach (String RegExpPattern in myConfiguration.GetIgnoreTitleNamePatterns()) { Match match = Regex.Match(bookmark.Title, RegExpPattern, RegexOptions.IgnoreCase); // Here we check the Match instance. if (match.Success) { Console.WriteLine(DateTime.Now.ToShortTimeString() + " - " + DateTime.Now.ToShortDateString() + " - not saving since title matches ignore pattern: " + RegExpPattern); matchesTitlePattern = true; break; } } #endregion if (!matchesTitlePattern) { // check if this bookmark is within the last UpdateIntervalSeconds of the track - then we do not save but we delete the bookmark if ((bookmark.Position != 0) && (bookmark.Position <= (bookmark.Duration - myConfiguration.GetUpdateIntervalSeconds()))) { // yes it does...so save it! Console.WriteLine(DateTime.Now.ToShortTimeString() + " - " + DateTime.Now.ToShortDateString() + " - Saving Bookmark: " + bookmark.Position + "@" + bookmark.Hash); myConfiguration.AddOrUpdateKnownPosition(bookmark); myConfiguration.Save(); } else { // no it does not...so delete it! myConfiguration.GetBookmarkForHash(bookmark.Hash); } } } } foreach (Bookmark bookmark in Started) { // output Started Information... Console.WriteLine(DateTime.Now.ToShortTimeString() + " - " + DateTime.Now.ToShortDateString() + " - Started: " + bookmark.Artist + " - " + bookmark.Title + " - " + bookmark.Position + "/" + bookmark.Duration); if (bookmark.Position < 10) { Bookmark storedBookmark = myConfiguration.GetBookmarkForHash(bookmark.Hash); if (storedBookmark != null) { // only seek when the current position leads us to believe that the track has been restarted... // we've found a play position, seek there! Console.WriteLine(DateTime.Now.ToShortTimeString() + " - " + DateTime.Now.ToShortDateString() + " - Found Bookmark, now seeking: " + storedBookmark.Position + "@" + bookmark.Hash); SONOSTrackSeek.SeekTrack(myConfiguration.GetSONOSHTTPAPIURL(), storedBookmark.Position, bookmark.Coordinator); myConfiguration.Save(); } } } // decide wether we save or not }