public void SavePosition() { try { var position = _mbApiInterface.Player_GetPosition(); File.WriteAllText(_currentTrackUrl + ".position.txt", position.ToString()); } catch (Exception) { // ignored } }
/// <inheritdoc/> public TrackTemporalInformation GetTemporalInformation() { var position = _api.Player_GetPosition(); var duration = _api.NowPlaying_GetDuration(); return(new TrackTemporalInformation(position, duration)); }
// 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; } }
/// <summary> /// Run every time the timer has fired this off. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { // Update the track time via the websocket. TrackTimeMessage msg; msg.time = (int)Math.Round(api.Player_GetPosition() / 1000.0); ws.Send("track.time", msg); }
private void updateTaskbarProgress() { float currentPos = mbApiInterface.Player_GetPosition(); float totalTime = mbApiInterface.NowPlaying_GetDuration(); completedPercentage = currentPos / totalTime * 100; TaskbarProgress.SetValue(mbApiInterface.MB_GetWindowHandle(), completedPercentage, 100); }
private void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { if (_track.ChapterList.Count == 0) { return; } int playerPosition = mbApiInterface.Player_GetPosition(); Chapter currentChapter = _track.ChapterList.GetCurrentChapterFromPosition(playerPosition); if (!currentChapter.Equals(_currentChapter)) { _mainForm?.Invoke(_mainForm.SetCurrentChapterDelegate, currentChapter); _currentChapter = currentChapter; } // Repeat section if (RepeatSection.RepeatCheck(playerPosition)) { mbApiInterface.Player_SetPosition(RepeatSection.A.Position); } }
public void ReceiveNotification(string sourceFileUrl, NotificationType type) { // musicbee api stuff string artist = mbApiInterface.NowPlaying_GetFileTag(MetaDataType.Artist); string trackTitle = mbApiInterface.NowPlaying_GetFileTag(MetaDataType.TrackTitle); string duration = mbApiInterface.NowPlaying_GetFileProperty(FilePropertyType.Duration); bool getSongLength = mbApiInterface.Player_GetShowTimeRemaining(); string songLength = getSongLength.ToString(); int position = mbApiInterface.Player_GetPosition(); // create new variables so we can modify them for certain situations string songName = trackTitle; string songArtist = artist; // check if there is no artist so we can replace it with Unknown if (string.IsNullOrEmpty(artist)) { songName = trackTitle; songArtist = "Unknown"; } // perform some action depending on the notification type switch (type) { case NotificationType.PluginStartup: // perform startup initialization case NotificationType.PlayStateChanged: switch (mbApiInterface.Player_GetPlayState()) { case PlayState.Playing: UpdatePlayedPresence(songName, songArtist, duration, position / 1000); break; case PlayState.Paused: UpdatePausedPresence(); break; } break; case NotificationType.TrackChanged: UpdatePlayedPresence(songName, songArtist, duration, 0); break; } }
public void ReceiveNotification(string sourceFileUrl, NotificationType type) { string artist = MbApiInterface.NowPlaying_GetFileTag(MetaDataType.AlbumArtist); string trackArtist = MbApiInterface.NowPlaying_GetFileTag(MetaDataType.Artist); string trackTitle = MbApiInterface.NowPlaying_GetFileTag(MetaDataType.TrackTitle); string album = MbApiInterface.NowPlaying_GetFileTag(MetaDataType.Album); string duration = MbApiInterface.NowPlaying_GetFileProperty(FilePropertyType.Duration); int volume = Convert.ToInt32(MbApiInterface.Player_GetVolume() * 100.0f); int position = MbApiInterface.Player_GetPosition() / 1000; if (string.IsNullOrEmpty(artist)) { artist = "[artist empty]"; } switch (type) { case NotificationType.PlayStateChanged: switch (MbApiInterface.Player_GetPlayState()) { case PlayState.Playing: UpdatePresence(artist, trackArtist, trackTitle, album, duration, true, position, volume); break; case PlayState.Paused: UpdatePresence(artist, trackArtist, trackTitle, album, duration, false, 0, volume); break; } break; case NotificationType.TrackChanged: UpdatePresence(artist, trackArtist, trackTitle, album, duration, true, 0, volume, true); break; case NotificationType.VolumeLevelChanged: if (MbApiInterface.Player_GetPlayState() == PlayState.Playing) { UpdatePresence(artist, trackArtist, trackTitle, album, duration, true, position, volume); } break; } }
// receive event notifications from MusicBee // you need to set about.ReceiveNotificationFlags = PlayerEvents to receive all notifications, and not just the startup event public void ReceiveNotification(string sourceFileUrl, NotificationType type) { string artist = mbApiInterface.NowPlaying_GetFileTag(MetaDataType.Artist); string trackTitle = mbApiInterface.NowPlaying_GetFileTag(MetaDataType.TrackTitle); string duration = mbApiInterface.NowPlaying_GetFileProperty(FilePropertyType.Duration); // mbApiInterface.NowPlaying_GetDuration(); int position = mbApiInterface.Player_GetPosition(); string song = artist + " - " + trackTitle; if (string.IsNullOrEmpty(artist)) { song = trackTitle; } // perform some action depending on the notification type PlayState state = mbApiInterface.Player_GetPlayState(); switch (type) { case NotificationType.PluginStartup: // perform startup initialisation case NotificationType.PlayStateChanged: switch (state) { case PlayState.Playing: UpdatePresence(song, duration, position / 1000, state); break; case PlayState.Paused: UpdatePresence(song, duration, 0, state: state); break; case PlayState.Stopped: UpdatePresence(song, duration, 0, state); break; } break; case NotificationType.TrackChanged: UpdatePresence(song, duration, 0, state); break; } }
// Draw the Seekbar on Timer Ticks private void onTime(object sender, ElapsedEventArgs e) { if (!_seekbar) { LogMessageToFile("Timer disabled."); timer.Stop(); timer.Dispose(); } else { if (panel.InvokeRequired) { panel.BeginInvoke((MethodInvoker)delegate () { Graphics myGraphics = panel.CreateGraphics(); SolidBrush blackFill = new SolidBrush(Color.Black); float currentPos = mbApiInterface.Player_GetPosition(); float totalTime = mbApiInterface.NowPlaying_GetDuration(); float totalLength = this.panel.Width; if (currentPos < _lastPos) { panel.Invalidate(); } _lastPos = currentPos; float currentCompletion = (currentPos / totalTime) * (totalLength - (_seekMin * 2)); Rectangle rect = new Rectangle(_seekMin, panel.Height - 10, (int)currentCompletion, 10); myGraphics.FillRectangle(blackFill, rect); blackFill.Dispose(); myGraphics.Dispose(); }); } } }
// receive event notifications from MusicBee // you need to set about.ReceiveNotificationFlags = PlayerEvents to receive all notifications, and not just the startup event public void ReceiveNotification(string sourceFileUrl, NotificationType type) { string artist = mbApiInterface.NowPlaying_GetFileTag(MetaDataType.Artist); string trackTitle = mbApiInterface.NowPlaying_GetFileTag(MetaDataType.TrackTitle); string album = mbApiInterface.NowPlaying_GetFileTag(MetaDataType.Album); string duration = mbApiInterface.NowPlaying_GetFileProperty(FilePropertyType.Duration); // mbApiInterface.NowPlaying_GetDuration(); int position = mbApiInterface.Player_GetPosition(); // Check if there isn't an artist for the current song. If so, replace it with "(unknown artist)". if (string.IsNullOrEmpty(artist)) { artist = "(unknown artist)"; } // perform some action depending on the notification type switch (type) { case NotificationType.PluginStartup: // perform startup initialisation case NotificationType.PlayStateChanged: switch (mbApiInterface.Player_GetPlayState()) { case PlayState.Playing: UpdatePresence(artist, trackTitle, album, duration, true); break; case PlayState.Paused: UpdatePresence(artist, trackTitle, album, duration, false); break; } break; case NotificationType.TrackChanged: UpdatePresence(artist, trackTitle, album, duration, true); break; } }
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 string padString(string input) { if (!string.IsNullOrEmpty(input) && input.Length < 2) { return(input + "\u180E"); } return(input); } void SetImage(string name) { _discordPresence.Assets.LargeImageKey = "logo"; _discordPresence.Assets.LargeImageText = padString(_layoutHandler.Render(_settings.ImageText, metaDataDict, _settings.Seperator)); _discordPresence.Assets.SmallImageKey = padString(name); _discordPresence.Assets.SmallImageText = padString(name); } _discordPresence.State = padString(_layoutHandler.Render(_settings.PresenceState, metaDataDict, _settings.Seperator)); var t = DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)); _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; break; case PlayState.Paused: SetImage("pause"); _discordPresence.Timestamps.Start = null; break; case PlayState.Undefined: case PlayState.Loading: break; } _discordPresence.Details = padString(_layoutHandler.Render(_settings.PresenceDetails, metaDataDict, _settings.Seperator)); _discordPresence.Party.ID = "aaaa"; var trackcnt = 0; var trackno = 0; try { trackcnt = int.Parse(_layoutHandler.Render(_settings.PresenceTrackCnt, metaDataDict, _settings.Seperator)); trackno = int.Parse(_layoutHandler.Render(_settings.PresenceTrackNo, metaDataDict, _settings.Seperator)); } catch (Exception) { // ignored } _discordPresence.Party.Max = trackcnt; _discordPresence.Party.Size = trackno; if (!_settings.UpdatePresenceWhenStopped && (playerGetPlayState == PlayState.Paused || playerGetPlayState == PlayState.Stopped)) { _discordClient.ClearPresence(); } else { _discordClient.SetPresence(_discordPresence); } }
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 int charsUsed, bytesUsed: out int bytesUsed, completed: out bool completed); return(Encoding.UTF8.GetString(buffer, 0, bytesUsed)); } } return(input); } void SetImage(string name) { _discordPresence.Assets.LargeImageKey = "logo"; _discordPresence.Assets.LargeImageText = padString(_layoutHandler.Render(_settings.ImageText, metaDataDict, _settings.Seperator)); _discordPresence.Assets.SmallImageKey = padString(name); _discordPresence.Assets.SmallImageText = padString(name); } _discordPresence.State = padString(_layoutHandler.Render(_settings.PresenceState, metaDataDict, _settings.Seperator)); var t = DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)); _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; break; case PlayState.Paused: SetImage("pause"); _discordPresence.Timestamps.Start = 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))); } }
// receive event notifications from MusicBee // you need to set about.ReceiveNotificationFlags = PlayerEvents to receive all notifications, and not just the startup event public void ReceiveNotification(string sourceFileUrl, NotificationType type) { // activate video only if valid extention string[] ext = extConf.Split(' '); bool tmpFlag = false; foreach (string i in ext) { if (sourceFileUrl.EndsWith(i)) { tmpFlag = true; } } // perform some action depending on the notification type switch (type) { case NotificationType.PlayStateChanged: if (tmpFlag) { switch (mbApiInterface.Player_GetPlayState()) { case PlayState.Playing: int tmp = mbApiInterface.Player_GetPosition(); double sec = tmp / 1000.0; Program.MpvLoadFile2(sec.ToString(), 0); break; case PlayState.Paused: Program.MpvLoadFile2("", 1); break; } } else { // clear MPV but still keep open Program.MpvLoadFile2("", 2); } break; case NotificationType.PluginStartup: // perform startup initialisation break; case NotificationType.TrackChanged: switch (mbApiInterface.Player_GetPlayState()) { case PlayState.Playing: if (tmpFlag) { Program.MainHack(sourceFileUrl); var t = Task.Factory.StartNew(() => { return(Task.Factory.StartNew(() => { Task.Delay(3000).Wait(); Program.MpvLoadFile2((mbApiInterface.Player_GetPosition() / 1000.0).ToString(), 0); })); }); t.Wait(); } else { Program.MpvLoadFile2("", 2); } break; case PlayState.Paused: break; } break; } }
// receive event notifications from MusicBee // you need to set about.ReceiveNotificationFlags = PlayerEvents to receive all notifications, and not just the startup event public void ReceiveNotification(string sourceFileUrl, NotificationType type) { // perform some action depending on the notification type switch (type) { case NotificationType.PluginStartup: if (device_ == null) { settings_ = new Settings(mbApiInterface_.Setting_GetPersistentStoragePath(), this); connectDevice(); settings_.openSettings(); pluginObject_ = this; //Create an event to signal the timeout count threshold in the // timer callback. autoEvent = new AutoResetEvent(false); // Create an inferred delegate that invokes methods for the timer. TimerCallback tcb = refreshLoop; // Create a timer that signals the delegate to invoke // CheckStatus after one second, and every 1/4 second // thereafter. timer_ = new System.Threading.Timer(tcb, autoEvent, 1000, 100); } eventHappened_ = true; break; case NotificationType.PlayStateChanged: if (lcdScreenList_.Count > 0 && lcdScreenList_[0].getName() == "StartupScreen") { openScreens(); } stateChanged(mbApiInterface_.Player_GetPlayState()); getSongData(); getVolume(); getSettings(); eventHappened_ = true; timerTime_ = mbApiInterface_.Player_GetPosition(); break; case NotificationType.NowPlayingListChanged: case NotificationType.PlayerEqualiserOnOffChanged: case NotificationType.PlayerRepeatChanged: case NotificationType.PlayerShuffleChanged: case NotificationType.AutoDjStarted: case NotificationType.AutoDjStopped: case NotificationType.NowPlayingArtworkReady: case NotificationType.RatingChanged: case NotificationType.TrackChanged: case NotificationType.VolumeLevelChanged: case NotificationType.VolumeMuteChanged: case NotificationType.NowPlayingLyricsReady: if (lcdScreenList_.Count > 0 && lcdScreenList_[0].getName() == "StartupScreen") { openScreens(); } getVolume(); getSongData(); getSettings(); eventHappened_ = true; timerTime_ = mbApiInterface_.Player_GetPosition(); break; } }