// Updates player state and time in rich presence private void UpdatePresencePlayState(string smallImageKey, bool displayTime, bool showRemaining) { presence.Assets.SmallImageKey = smallImageKey; presence.Assets.SmallImageText = smallImageKey; if (displayTime) { presence.Timestamps = new Timestamps(); int playerPositionMillis = mbApiInterface.Player_GetPosition(); if (showRemaining) { int songLengthMillis = mbApiInterface.NowPlaying_GetDuration(); presence.Timestamps.Start = null; presence.Timestamps.End = DateTime.UtcNow.AddMilliseconds(songLengthMillis - playerPositionMillis); } else { presence.Timestamps.Start = DateTime.UtcNow.AddMilliseconds(-playerPositionMillis); presence.Timestamps.End = null; } } else { presence.Timestamps = null; } }
/// <inheritdoc/> public TrackTemporalInformation GetTemporalInformation() { var position = _api.Player_GetPosition(); var duration = _api.NowPlaying_GetDuration(); return(new TrackTemporalInformation(position, duration)); }
private void TryScrobble(string title, string artist, string album, int duration) { if (hasScrobbled) { return; } played += (int)DateTime.UtcNow.Subtract(started).TotalMilliseconds; if (played < Api.NowPlaying_GetDuration() / 2 && played < 240000) { return; } hasScrobbled = true; played = 0; LastFM.Scrobble(title, artist, album, (duration / 1000).ToString()); }
private void updateTaskbarProgress() { float currentPos = mbApiInterface.Player_GetPosition(); float totalTime = mbApiInterface.NowPlaying_GetDuration(); completedPercentage = currentPos / totalTime * 100; TaskbarProgress.SetValue(mbApiInterface.MB_GetWindowHandle(), completedPercentage, 100); }
public void ReceiveNotification(string src, NotificationType type) { if (type == NotificationType.PlayerScrobbleChanged) { if (Api.Player_GetScrobbleEnabled()) { Api.Player_SetScrobbleEnabled(false); } return; } if (type != NotificationType.TrackChanged && type != NotificationType.PlayStateChanged) { return; } var title = Api.NowPlaying_GetFileTag(Settings.GetTag("ScrobbleBee-Title", MetaDataType.TrackTitle)); var artist = Api.NowPlaying_GetFileTag(Settings.GetTag("ScrobbleBee-Artist", MetaDataType.Artist)); var album = Api.NowPlaying_GetFileTag(Settings.GetTag("ScrobbleBee-Album", MetaDataType.Album)); var albumArtist = Api.NowPlaying_GetFileTag(Settings.GetTag("ScrobbleBee-AlbumArtist", MetaDataType.AlbumArtist)); var duration = Api.NowPlaying_GetDuration(); switch (type) { case NotificationType.TrackChanged: TryScrobble(lastTitle, lastArtist, lastAlbum, lastAlbumArtist, lastDuration); LastFm.Update(title, artist, album, albumArtist, duration); hasScrobbled = duration < 30000; started = DateTime.UtcNow; played = 0; lastTitle = title; lastArtist = artist; lastAlbum = album; lastAlbumArtist = albumArtist; lastDuration = duration; break; case NotificationType.PlayStateChanged: switch (Api.Player_GetPlayState()) { case PlayState.Playing: started = DateTime.UtcNow; break; case PlayState.Paused: case PlayState.Stopped: TryScrobble(title, artist, album, albumArtist, duration); break; } break; } }
private Track GetTrack() { var trackInfo = new NowPlayingTrackInfo( mbApiInterface.NowPlaying_GetFileTag(MetaDataType.TrackTitle), mbApiInterface.NowPlaying_GetFileTag(MetaDataType.Artist), mbApiInterface.NowPlaying_GetFileTag(MetaDataType.Album), new TimeSpan(0, 0, 0, 0, mbApiInterface.NowPlaying_GetDuration()), new Uri(mbApiInterface.NowPlaying_GetFileProperty( FilePropertyType.Url), UriKind.Absolute) ); Track track = new Track(trackInfo); return(track); }
internal void getSongData() { string artist = mbApiInterface_.NowPlaying_GetFileTag(MetaDataType.Artist); string album = mbApiInterface_.NowPlaying_GetFileTag(MetaDataType.Album); string title = mbApiInterface_.NowPlaying_GetFileTag(MetaDataType.TrackTitle); string artwork = mbApiInterface_.NowPlaying_GetArtwork(); string ratingString = mbApiInterface_.NowPlaying_GetFileTag(MetaDataType.Rating); string lyrics = mbApiInterface_.NowPlaying_GetLyrics(); float rating = 0; if (ratingString != "") { rating = Convert.ToSingle(ratingString); } foreach (Screen screen in lcdScreenList_) { screen.songChanged(artist, album, title, rating, artwork, mbApiInterface_.NowPlaying_GetDuration(), mbApiInterface_.Player_GetPosition(), lyrics); } }
public async Task LoadSong(string hashed, string songFileExt) { string filetype = mbApiInterface.NowPlaying_GetFileProperty(FilePropertyType.Kind).Replace(" audio file", ""); string samplerate = mbApiInterface.NowPlaying_GetFileProperty(FilePropertyType.SampleRate); string bitrate = mbApiInterface.NowPlaying_GetFileProperty(FilePropertyType.Bitrate); string channels = mbApiInterface.NowPlaying_GetFileProperty(FilePropertyType.Channels); string properties = ""; string nextSong = mbApiInterface.NowPlayingList_GetFileTag(mbApiInterface.NowPlayingList_GetNextIndex(1), MetaDataType.TrackTitle) + " by " + mbApiInterface.NowPlayingList_GetFileTag(mbApiInterface.NowPlayingList_GetNextIndex(1), MetaDataType.Artist); nextSong = nextSong == " by " || nextSong == null ? "End of List" : nextSong; if (filetype == "FLAC") { using (FlacFile file = new FlacFile(mbApiInterface.NowPlaying_GetFileUrl())) { properties = filetype + " " + file.StreamInfo.BitsPerSample.ToString() + " bit, " + samplerate + ", " + bitrate + ", " + channels; } } else { properties = filetype + " " + samplerate + ", " + bitrate + ", " + channels; } string[] temp = null; mbApiInterface.NowPlayingList_QueryFilesEx("", ref temp); int size = temp.Count(); try { await mediaChannel.LoadAsync( new MediaInformation() { ContentId = HttpUtility.UrlPathEncode(mediaContentURL + hashed + songFileExt), StreamType = StreamType.Buffered, Duration = mbApiInterface.NowPlaying_GetDuration() / 1000, Metadata = new MusicTrackMediaMetadata { Artist = mbApiInterface.NowPlaying_GetFileTag(MetaDataType.Artist), Title = mbApiInterface.NowPlaying_GetFileTag(MetaDataType.TrackTitle), AlbumName = mbApiInterface.NowPlaying_GetFileTag(MetaDataType.Album), Images = new[] { new GoogleCast.Models.Image { Url = mediaContentURL + hashed + ".jpg" } }, }, CustomData = new Dictionary <string, string>() { { "Properties", properties }, { "Position", (mbApiInterface.NowPlayingList_GetCurrentIndex() + 1).ToString() + " / " + size.ToString() }, { "Next", nextSong } } }); filenameStack.Push(hashed.ToString()); } catch (OperationCanceledException) { Debug.WriteLine("Requested to close"); } catch (Exception e) { Debug.WriteLine(e.Message); } }
private void UpdateDiscordPresence(PlayState playerGetPlayState) { var metaDataDict = GenerateMetaDataDictionary(); // Discord allows only strings with a min length of 2 or the update fails // so add some exotic space (Mongolian vovel seperator) to the string if it is smaller // Discord also disallows strings bigger than 128bytes so handle that as well string padString(string input) { if (!string.IsNullOrEmpty(input)) { if (input.Length < 2) { return(input + "\u180E"); } if (Encoding.UTF8.GetBytes(input).Length > 128) { byte[] buffer = new byte[128]; char[] inputChars = input.ToCharArray(); Encoding.UTF8.GetEncoder().Convert( chars: inputChars, charIndex: 0, charCount: inputChars.Length, bytes: buffer, byteIndex: 0, byteCount: buffer.Length, flush: false, charsUsed: out _, bytesUsed: out int bytesUsed, completed: out _); return(Encoding.UTF8.GetString(buffer, 0, bytesUsed)); } } return(input); } void SetImage(string name) { if (_settings.TextOnly) { _discordPresence.Assets.LargeImageKey = null; _discordPresence.Assets.LargeImageText = null; _discordPresence.Assets.SmallImageKey = null; _discordPresence.Assets.SmallImageText = null; return; } _discordPresence.Assets.LargeImageKey = "logo"; _discordPresence.Assets.LargeImageText = padString(_layoutHandler.Render(_settings.LargeImageText, metaDataDict, _settings.Seperator)); _discordPresence.Assets.SmallImageKey = padString(name); _discordPresence.Assets.SmallImageText = padString(_layoutHandler.Render(_settings.SmallImageText, metaDataDict, _settings.Seperator));; } _discordPresence.State = padString(_layoutHandler.Render(_settings.PresenceState, metaDataDict, _settings.Seperator)); var t = DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)); if (_settings.ShowRemainingTime) { // show remaining time // subtract current track position from total duration for position seeking var totalRemainingDuration = _mbApiInterface.NowPlaying_GetDuration() - _mbApiInterface.Player_GetPosition(); _discordPresence.Timestamps.EndUnixMilliseconds = (ulong)(Math.Round(t.TotalSeconds) + Math.Round(totalRemainingDuration / 1000.0)); } else { // show elapsed time _discordPresence.Timestamps.StartUnixMilliseconds = (ulong)(Math.Round(t.TotalSeconds) - Math.Round(_mbApiInterface.Player_GetPosition() / 1000.0)); } switch (playerGetPlayState) { case PlayState.Playing: SetImage("play"); break; case PlayState.Stopped: SetImage("stop"); _discordPresence.Timestamps.Start = null; _discordPresence.Timestamps.End = null; break; case PlayState.Paused: SetImage("pause"); _discordPresence.Timestamps.Start = null; _discordPresence.Timestamps.End = null; break; case PlayState.Undefined: case PlayState.Loading: break; } _discordPresence.Details = padString(_layoutHandler.Render(_settings.PresenceDetails, metaDataDict, _settings.Seperator)); var trackcnt = -1; var trackno = -1; try { trackcnt = int.Parse(_layoutHandler.Render(_settings.PresenceTrackCnt, metaDataDict, _settings.Seperator)); trackno = int.Parse(_layoutHandler.Render(_settings.PresenceTrackNo, metaDataDict, _settings.Seperator)); } catch (Exception) { // ignored } if (trackcnt < trackno || trackcnt <= 0 || trackno <= 0) { _discordPresence.Party = null; } else { _discordPresence.Party = new Party { ID = "aaaa", Max = trackcnt, Size = trackno }; } if (!_settings.UpdatePresenceWhenStopped && (playerGetPlayState == PlayState.Paused || playerGetPlayState == PlayState.Stopped)) { _discordClient.ClearPresence(); } else { _discordClient.SetPresence(_discordPresence); } }
private void UpdateDiscordPresence(PlayState playerGetPlayState) { Debug.WriteLine("DiscordBee: Updating Presence with PlayState {0}...", playerGetPlayState); var metaDataDict = GenerateMetaDataDictionary(); RichPresence _discordPresence = new RichPresence { Assets = new Assets(), Party = new Party(), Timestamps = new Timestamps() }; // Discord allows only strings with a min length of 2 or the update fails // so add some exotic space (Mongolian vowel separator) to the string if it is smaller // Discord also disallows strings bigger than 128bytes so handle that as well string padString(string input) { if (!string.IsNullOrEmpty(input)) { if (input.Length < 2) { return(input + "\u180E"); } if (Encoding.UTF8.GetBytes(input).Length > 128) { byte[] buffer = new byte[128]; char[] inputChars = input.ToCharArray(); Encoding.UTF8.GetEncoder().Convert( chars: inputChars, charIndex: 0, charCount: inputChars.Length, bytes: buffer, byteIndex: 0, byteCount: buffer.Length, flush: false, charsUsed: out _, bytesUsed: out int bytesUsed, completed: out _); return(Encoding.UTF8.GetString(buffer, 0, bytesUsed)); } } return(input); } // Button Functionality if (_settings.ShowButton) { var uri = _layoutHandler.RenderUrl(_settings.ButtonUrl, metaDataDict); Debug.WriteLine($"Url: {uri}"); // Validate the URL again. if (ValidationHelpers.ValidateUri(uri)) { _discordPresence.Buttons = new Button[] { new Button { Label = padString(_settings.ButtonLabel), Url = uri } }; } } void SetImage(string name, bool forceHideSmallImage = false) { if (_settings.TextOnly) { _discordPresence.Assets.LargeImageKey = null; _discordPresence.Assets.LargeImageText = null; _discordPresence.Assets.SmallImageKey = null; _discordPresence.Assets.SmallImageText = null; } else { _discordPresence.Assets.LargeImageKey = AssetManager.ASSET_LOGO; _discordPresence.Assets.LargeImageText = padString(_layoutHandler.Render(_settings.LargeImageText, metaDataDict, _settings.Separator)); if (_settings.ShowPlayState && !forceHideSmallImage) { _discordPresence.Assets.SmallImageKey = padString(name); _discordPresence.Assets.SmallImageText = padString(_layoutHandler.Render(_settings.SmallImageText, metaDataDict, _settings.Separator)); } else { _discordPresence.Assets.SmallImageKey = null; _discordPresence.Assets.SmallImageText = null; } } } _discordPresence.State = padString(_layoutHandler.Render(_settings.PresenceState, metaDataDict, _settings.Separator)); var t = DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)); if (_settings.ShowTime) { if (_settings.ShowRemainingTime) { // show remaining time // subtract current track position from total duration for position seeking var totalRemainingDuration = _mbApiInterface.NowPlaying_GetDuration() - _mbApiInterface.Player_GetPosition(); _discordPresence.Timestamps.EndUnixMilliseconds = (ulong)(Math.Round(t.TotalSeconds) + Math.Round(totalRemainingDuration / 1000.0)); } else { // show elapsed time _discordPresence.Timestamps.StartUnixMilliseconds = (ulong)(Math.Round(t.TotalSeconds) - Math.Round(_mbApiInterface.Player_GetPosition() / 1000.0)); } } switch (playerGetPlayState) { case PlayState.Playing: SetImage(AssetManager.ASSET_PLAY, _settings.ShowOnlyNonPlayingState); break; case PlayState.Stopped: SetImage(AssetManager.ASSET_STOP); _discordPresence.Timestamps.Start = null; _discordPresence.Timestamps.End = null; break; case PlayState.Paused: SetImage(AssetManager.ASSET_PAUSE); _discordPresence.Timestamps.Start = null; _discordPresence.Timestamps.End = null; break; case PlayState.Undefined: case PlayState.Loading: break; } _discordPresence.Details = padString(_layoutHandler.Render(_settings.PresenceDetails, metaDataDict, _settings.Separator)); var trackcnt = -1; var trackno = -1; try { trackcnt = int.Parse(_layoutHandler.Render(_settings.PresenceTrackCnt, metaDataDict, _settings.Separator)); trackno = int.Parse(_layoutHandler.Render(_settings.PresenceTrackNo, metaDataDict, _settings.Separator)); } #pragma warning disable RCS1075 // Avoid empty catch clause that catches System.Exception. catch (Exception) #pragma warning restore RCS1075 // Avoid empty catch clause that catches System.Exception. { // ignored } if (trackcnt < trackno || trackcnt <= 0 || trackno <= 0) { _discordPresence.Party = null; } else { _discordPresence.Party = new Party { ID = "aaaa", Max = trackcnt, Size = trackno }; } if (!_settings.UpdatePresenceWhenStopped && (playerGetPlayState == PlayState.Paused || playerGetPlayState == PlayState.Stopped)) { Debug.WriteLine("Clearing Presence...", "DiscordBee"); _discordClient.ClearPresence(); } else { Debug.WriteLine("Setting new Presence...", "DiscordBee"); Task.Run(() => _discordClient.SetPresence(_discordPresence, GetAlbumCoverData(_mbApiInterface.NowPlaying_GetArtwork(), metaDataDict))); } }
// The duration of the current track. Used to determine if the file is a stream. public void CurrentDuration() { _duration = mbApiInterface.NowPlaying_GetDuration(); LogMessageToFile("Current Song Duration: " + _duration); }