private static string FindToastLogo(ExtendedSongMetadata metaData) { //try and find a nice image to set for the toast string toastLogo = null; if (!string.IsNullOrWhiteSpace(metaData.Album?.AlbumCoverUrl)) { toastLogo = metaData.Album?.AlbumCoverUrl; } else { if (!string.IsNullOrWhiteSpace(metaData.ArtistInfo?.ArtistImage)) { toastLogo = metaData.ArtistInfo?.ArtistImage; } else { if (metaData.JPopAsiaArtistInfo != null) { if (metaData.JPopAsiaArtistInfo.ArtistImageUrl != null) { toastLogo = metaData.JPopAsiaArtistInfo.ArtistImageUrl.ToString(); } } } } if (string.IsNullOrWhiteSpace(toastLogo)) { toastLogo = metaData.StationLogo.ToString(); } return(toastLogo); }
public async Task <ExtendedSongMetadata> Populate(ExtendedSongMetadata songMetadata) { var track = $"{songMetadata.Artist}-{songMetadata.Title}"; var trackSearchResult = await _lastFmClient.Track.SearchAsync(track); // Nothing to add if (!trackSearchResult.Success || !trackSearchResult.Content.Any()) { return(songMetadata); } var trackResultItem = trackSearchResult.Content.First(); var trackInfo = await _lastFmClient.Track.GetInfoAsync(trackResultItem.Name, trackResultItem.ArtistName); if (trackInfo.Success && trackInfo.Content != null) { songMetadata.Url = trackInfo.Content.Url?.AbsoluteUri; songMetadata.PlayCount = trackInfo.Content.PlayCount ?? 0; } var albumInfo = await _lastFmClient.Album.SearchAsync(track); if (albumInfo.Success && albumInfo.Content.Any()) { songMetadata.Album = albumInfo.Content.First().Name; } return(songMetadata); }
internal void UpdateSongToastNotification(ExtendedSongMetadata metaData) { string toastLogo = FindToastLogo(metaData); ToastContent content = new ToastContent() { Launch = "now-playing", Audio = new ToastAudio() { Silent = true, }, Visual = new ToastVisual() { BindingGeneric = new ToastBindingGeneric() { Children = { new AdaptiveText() { Text = metaData.Track, HintStyle = AdaptiveTextStyle.Title }, new AdaptiveText() { Text = metaData.Artist, HintStyle = AdaptiveTextStyle.Subtitle }, new AdaptiveText() { Text = metaData.StationPlayedOn, HintStyle = AdaptiveTextStyle.Caption }, }, AppLogoOverride = new ToastGenericAppLogo() { Source = toastLogo } } } }; var notification = new ToastNotification(content.GetXml()); notification.Tag = SongNotificationTag; notification.NotificationMirroring = NotificationMirroring.Disabled; // notification.SuppressPopup = true; // toastNotifier.Show(notification); }
private async System.Threading.Tasks.Task HandleStationSongMetadataStage2Async(SongMetadata songMetadata) { ExtendedSongMetadata newMetadata = new ExtendedSongMetadata(songMetadata); bool hasMoreMetadata = await NepApp.MetadataManager.FindAdditionalMetadataAsync(newMetadata); CurrentSong = newMetadata; CurrentSong.SongLength = newMetadata.SongLength; RaisePropertyChanged(nameof(CurrentSong)); await History.AddSongAsync(CurrentSong); SongChanged.Invoke(this, new NepAppSongChangedEventArgs(CurrentSong)); if (hasMoreMetadata) { ArtworkProcessor.UpdateArtworkMetadata(); } else { ArtworkProcessor.ResetArtwork(); } }
/// <summary> /// Start the stream /// </summary> /// <param name="id"></param> /// <returns></returns> public async Task <bool> Start(int id) { Stream stream; // Stream does not exist if ((stream = await _streamLogic.For(_user).Get(id)) == null) { return(false); } // Stream already started if (_state.StreamItems.ContainsKey(id) && _state.StreamItems[id].State == StreamStatusEnum.Started) { return(false); } var streamRipperInstance = _streamRipperProxy.Proxy(new Uri(stream.Url)); streamRipperInstance.SongChangedEventHandlers += async(_, arg) => { var songMetaData = arg.SongInfo.SongMetadata; var track = $"{songMetaData.Artist}-{songMetaData.Title}"; var filename = $"{track}.mp3"; if (_filterSongLogic.ShouldInclude(arg.SongInfo.Stream, track, stream.Filter, out var duration)) { var aggregatedSink = await _sinkService.ResolveStreamSink(stream); // Upload the stream await aggregatedSink(arg.SongInfo.Stream.Reset(), filename); var extendedSongMetadata = await _songMetaDataExtract.Populate(ExtendedSongMetadata.Extend( arg.SongInfo.SongMetadata, x => { x.Duration = duration; })); // Invoke socket await _hub.Clients.User(_user.Id.ToString()).SendAsync("download", filename, extendedSongMetadata, arg.SongInfo.Stream.Reset().ConvertToBase64(), new { stream.Name, stream.Id } ); } else { await _hub.Clients.User(_user.Id.ToString()) .SendAsync("log", $"Stream {id} with name {filename} skipped"); } }; streamRipperInstance.StreamEndedEventHandlers += async(sender, arg) => { await _hub.Clients.User(_user.Id.ToString()).SendAsync("log", $"Stream {id} ended"); _state.StreamItems[id].State = StreamStatusEnum.Stopped; }; streamRipperInstance.StreamFailedHandlers += async(sender, arg) => { await _hub.Clients.User(_user.Id.ToString()).SendAsync("log", $"Stream {id} failed", arg.Exception?.Message); _state.StreamItems[id].State = StreamStatusEnum.Fail; _logger.LogError($"Failed to start {id}", arg.Exception); }; streamRipperInstance.StreamStartedEventHandlers += async(sender, arg) => { await _hub.Clients.User(_user.Id.ToString()).SendAsync("log", $"Stream {id} started"); }; streamRipperInstance.StreamUpdateEventHandlers += async(sender, arg) => { await _hub.Clients.User(_user.Id.ToString()).SendAsync("log", $"Stream {id} updated with {arg.SongRawPartial.Length} bytes"); }; // Start the ripper streamRipperInstance.Start(); // Add to the dictionary _state.StreamItems[id] = new StreamItem { User = _user, StreamRipper = streamRipperInstance, State = StreamStatusEnum.Started }; await _configLogic.UpdateGlobalConfig(c => new GlobalConfigViewModel(c) { StartedStreams = c.StartedStreams.Add(id) }); return(true); }