// 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;
     }
 }
Example #2
0
        /// <inheritdoc/>
        public TrackTemporalInformation GetTemporalInformation()
        {
            var position = _api.Player_GetPosition();
            var duration = _api.NowPlaying_GetDuration();

            return(new TrackTemporalInformation(position, duration));
        }
Example #3
0
        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());
        }
Example #4
0
        private void updateTaskbarProgress()
        {
            float currentPos = mbApiInterface.Player_GetPosition();
            float totalTime  = mbApiInterface.NowPlaying_GetDuration();

            completedPercentage = currentPos / totalTime * 100;


            TaskbarProgress.SetValue(mbApiInterface.MB_GetWindowHandle(), completedPercentage, 100);
        }
Example #5
0
        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;
            }
        }
Example #6
0
        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);
            }
        }
Example #9
0
        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);
            }
        }
Example #10
0
        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);
        }