private void UpdateAutoRating(string file) { string playCountString = _mbApiInterface.Library_GetFileProperty(file, FilePropertyType.PlayCount); string skipCountString = _mbApiInterface.Library_GetFileProperty(file, FilePropertyType.SkipCount); int playCount = 0; int skipCount = 0; if (playCountString.Length > 0) { playCount = int.Parse(playCountString); } if (skipCountString.Length > 0) { skipCount = int.Parse(skipCountString); } int playDelta = playCount - skipCount; int newRating = -1; if (playDelta < -5) { newRating = 1; } else if (playDelta < -1) { newRating = 2; } else if (playDelta < 2) { newRating = 3; } else if (playDelta < 6) { newRating = 4; } else { newRating = 5; } _mbApiInterface.Library_SetFileTag(file, MetaDataType.Rating, newRating.ToString()); _mbApiInterface.Library_CommitTagsToFile(file); }
private Album[] GetAlbums(string artist) { MetaDataType[] meta = new MetaDataType[] { MetaDataType.TrackTitle, MetaDataType.TrackNo, MetaDataType.DiscNo, MetaDataType.Album, MetaDataType.Year, MetaDataType.AlbumArtist, MetaDataType.Artist }; MetaDataType[] albumMeta = new MetaDataType[] { MetaDataType.Album, MetaDataType.Year, MetaDataType.AlbumArtist }; List <Album> albums = new List <Album>(); string[] albumInfo = null; string[] tracks = null; string[] trackInfo = null; // Get all Tracks that belong to an artist mbApi.Library_QueryFilesEx($"Artist={artist}", ref tracks); List <string> albumTitles = new List <string>(); // Use list of tracks to find all albums that belong to an artist foreach (var track in tracks.Select((value, index) => new { value, index })) { mbApi.Library_GetFileTags(track.value, albumMeta, ref albumInfo); if (!albumTitles.Contains(albumInfo[0])) { albumTitles.Add(albumInfo[0]); } } // Use list of albums to get tracks for each album foreach (var singleAlbum in albumTitles.Select((value, index) => new { value, index })) { mbApi.Library_QueryFilesEx($"Artist={artist}\0Album={singleAlbum.value}", ref tracks); mbApi.Library_GetFileTags(tracks[0], albumMeta, ref albumInfo); List <Track> albumTracks = new List <Track>(); // Use the list of tracks to get information for each track foreach (var albumTrack in tracks.Select((value, index) => new { value, index })) { mbApi.Library_GetFileTags(albumTrack.value, meta, ref trackInfo); string length = mbApi.Library_GetFileProperty(albumTrack.value, FilePropertyType.Duration); // not all tracks have a disk number if (trackInfo[2] != "") { albumTracks.Add(new Track { Artist = trackInfo[6], Disk = Convert.ToInt16(trackInfo[2]), Length = length, Name = trackInfo[0], Number = Convert.ToInt16(trackInfo[1]), Path = albumTrack.value }); } else { albumTracks.Add(new Track { Artist = trackInfo[6], Disk = null, Length = length, Name = trackInfo[0], Number = Convert.ToInt16(trackInfo[1]), Path = albumTrack.value }); } } // Sort to ensure correct order of disks and tracks albumTracks.Sort((x, y) => x.Disk == y.Disk ? x.Number.CompareTo(y.Number) : (x.Disk < y.Disk ? -1 : 1)); albums.Add(new Album { Artist = albumInfo[2], Title = albumInfo[0], Tracks = albumTracks.ToArray(), Year = albumInfo[1] }); } return(albums.ToArray()); }
// Receive event notifications from MusicBee. public void ReceiveNotification(string sourceFileUrl, NotificationType type) { // Get the MusicBee settings path for later. string dataPath = mbApiInterface.Setting_GetPersistentStoragePath(); // Prepare the HTTP client instance for later. HttpClient httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Token", userToken); // Set the authorization headers. System.Threading.Tasks.Task <HttpResponseMessage> submitListenResponse; // Perform some action depending on the notification type. switch (type) { case NotificationType.PluginStartup: // Perform startup initialisation. // Get the metadata of the track selected by MusicBee on startup to know what to scrobble. artist = HttpUtility.JavaScriptStringEncode(mbApiInterface.NowPlaying_GetFileTag(MetaDataType.Artist)); track = HttpUtility.JavaScriptStringEncode(mbApiInterface.NowPlaying_GetFileTag(MetaDataType.TrackTitle)); release = HttpUtility.JavaScriptStringEncode(mbApiInterface.NowPlaying_GetFileTag(MetaDataType.Album)); // Get the current playcount to see if it changes or if the song was skipped. previousPlaycount = mbApiInterface.NowPlaying_GetFileProperty(FilePropertyType.PlayCount); // Re-scrobble any offline scrobbles. try { string[] offlineScrobbles = Directory.GetFiles(String.Concat(dataPath, settingsSubfolder, "scrobbles")); for (int i = 0; i < offlineScrobbles.Length; i++) { if (!String.IsNullOrEmpty(userToken)) // But only if the user token is configured. { try { submitListenResponse = httpClient.PostAsync("https://api.listenbrainz.org/1/submit-listens", new StringContent(File.ReadAllText(offlineScrobbles[i]), Encoding.UTF8, "application/json")); if (submitListenResponse.Result.IsSuccessStatusCode) // If the re-scrobble succeedes, remove the file. { try { File.Delete(offlineScrobbles[i]); } catch (IOException) // Handle the case where the saved scrobble is opened. { // Do nothing, the file will be removed on the next run. } } } catch // Handle the connectivity issues exception. { // Do nothing, the file will be re-scrobbled on the next run. } } } } catch (DirectoryNotFoundException) // Handle the "no offline scroble directory" exception. { // Do nothing, there's just nothing to re-scrobble. } //switch (mbApiInterface.Player_GetPlayState()) //{ // case PlayState.Playing: // case PlayState.Paused: // artist = mbApiInterface.NowPlaying_GetFileTag(MetaDataType.Artist); // break; //} break; case NotificationType.TrackChanged: // Update the metadata on track change. artist = HttpUtility.JavaScriptStringEncode(mbApiInterface.NowPlaying_GetFileTag(MetaDataType.Artist)); track = HttpUtility.JavaScriptStringEncode(mbApiInterface.NowPlaying_GetFileTag(MetaDataType.TrackTitle)); release = HttpUtility.JavaScriptStringEncode(mbApiInterface.NowPlaying_GetFileTag(MetaDataType.Album)); // Get the current playcount to see if it changes or if the song was skipped. previousPlaycount = mbApiInterface.NowPlaying_GetFileProperty(FilePropertyType.PlayCount); break; case NotificationType.PlayCountersChanged: // This is emitted each time either a play count OR a skip count increases. // Scrobble the track but only if the user token is configured and the song wasn't skipped. if (!String.IsNullOrEmpty(userToken) && !(previousPlaycount == mbApiInterface.Library_GetFileProperty(sourceFileUrl, FilePropertyType.PlayCount))) { timestamp = DateTime.UtcNow - new DateTime(1970, 1, 1); // Get the timestamp in epoch. // Prepare the scrobble. string submitListenJson = "{\"listen_type\": \"single\", \"payload\": [ { \"listened_at\": " + (int)timestamp.TotalSeconds + ",\"track_metadata\": {\"artist_name\": \"" + artist + "\", \"track_name\": \"" + track + "\", \"release_name\": \"" + release + "\", \"additional_info\": {\"listening_from\": \"MusicBee\"} } } ] }"; // Set the scrobble JSON. // Post the scrobble. for (int i = 0; i < 5; i++) // In case of temporary errors do up to 5 retries. { try { submitListenResponse = httpClient.PostAsync("https://api.listenbrainz.org/1/submit-listens", new StringContent(submitListenJson, Encoding.UTF8, "application/json")); if (submitListenResponse.Result.IsSuccessStatusCode) // If the scrobble succeedes, exit the loop. { break; } else // If the scrobble fails save it for a later resubmission and log the error. { // Log the timestamp, the failed scrobble and the error message in the error file. string errorTimestamp = DateTime.Now.ToString(); // Create the folder where the error log will be stored. Directory.CreateDirectory(String.Concat(dataPath, settingsSubfolder)); File.AppendAllText(String.Concat(dataPath, settingsSubfolder, "error.log"), errorTimestamp + " " + submitListenJson + Environment.NewLine); File.AppendAllText(String.Concat(dataPath, settingsSubfolder, "error.log"), errorTimestamp + " " + submitListenResponse.Result.Content.ReadAsStringAsync().Result + Environment.NewLine); // In case there's a problem with the scrobble JSON, the error is permanent so do not retry. if (submitListenResponse.Result.StatusCode.ToString() == "BadRequest") { // Save the scrobble to a file and exit the loop. SaveScrobble(timestamp.TotalSeconds.ToString(), submitListenJson); break; } // If this is the last retry save the scrobble. if (i == 4) { SaveScrobble(timestamp.TotalSeconds.ToString(), submitListenJson); } } } catch // When offline, save the scrobble for a later resubmission and exit the loop. { SaveScrobble(timestamp.TotalSeconds.ToString(), submitListenJson); break; } } } break; } }
public void GetCurrentLoudness() { //string tempculture = Thread.CurrentThread.CurrentCulture.Name; //Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US"); //Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("en-US"); string temp, check = null; MetaDataType tag, tag2; configMgr = new ConfigMgr(); Dictionary <int, string> DeserializedDict = configMgr.DeserializeIntoDict(_workingDirectory + @"\DRconfig.xml", new Dictionary <int, string>()); DeserializedDict.TryGetValue(0, out temp); DeserializedDict.TryGetValue(8, out check); if ((check == "None") || (temp == "None")) { MessageBox.Show("Please configure tag in EBU R128 Settings."); return; } tagsDictionary.TryGetValue(temp, out tag); tagsDictionary.TryGetValue(check, out tag2); if (!mbApiInterface.Library_QueryFilesEx("domain=SelectedFiles", ref files)) { files = new string[0]; } if (files.Length == 0) { MessageBox.Show("No files selected."); return; } for (int i = 0; i < files.Length; i++) { // Add regex to remove non-numeric characters from tags. string taggedVal = Regex.Replace(mbApiInterface.Library_GetFileTag(files[i], tag), @"[a-zA-Z /\s/g :]", ""); string gainVal = Regex.Replace(mbApiInterface.Library_GetFileProperty(files[i], FilePropertyType.ReplayGainTrack), @"[a-zA-Z /\s/g :]", ""); Convert.ToString(gainVal, CultureInfo.GetCultureInfo("en-us")); //gainVal = Regex.Replace(gainVal, ",", "."); //MessageBox.Show("Tagged Value: " + taggedVal + "\nGain Value: " + gainVal); try { double cur = Convert.ToDouble(taggedVal, CultureInfo.GetCultureInfo("en-us")) + Convert.ToDouble(gainVal); //MessageBox.Show("CUR: " + cur); mbApiInterface.Library_SetFileTag(files[i], tag2, Math.Round(cur, 2) + " LUFS"); mbApiInterface.Library_CommitTagsToFile(files[i]); } catch (System.FormatException e) { MessageBox.Show("Please tag all of the files first! \n "); return; } } mbApiInterface.MB_RefreshPanels(); MessageBox.Show("Files tagged."); //Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(tempculture); //Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(tempculture); return; }
public Dictionary <string, string> GenerateMetaDataDictionary(string fileUrl = null) { var ret = new Dictionary <string, string>(Enum.GetNames(typeof(MetaDataType)).Length + Enum.GetNames(typeof(FilePropertyType)).Length); foreach (MetaDataType elem in Enum.GetValues(typeof(MetaDataType))) { ret.Add(elem.ToString(), string.IsNullOrWhiteSpace(fileUrl) ? _mbApiInterface.NowPlaying_GetFileTag(elem) : _mbApiInterface.Library_GetFileTag(fileUrl, elem)); } foreach (FilePropertyType elem in Enum.GetValues(typeof(FilePropertyType))) { ret.Add(elem.ToString(), string.IsNullOrWhiteSpace(fileUrl) ? _mbApiInterface.NowPlaying_GetFileProperty(elem) : _mbApiInterface.Library_GetFileProperty(fileUrl, elem)); } ret.Add("Extension", Path.GetExtension(string.IsNullOrWhiteSpace(fileUrl) ? _mbApiInterface.NowPlaying_GetFileUrl() : fileUrl).TrimStart('.').ToUpper()); ret.Add("PlayState", _mbApiInterface.Player_GetPlayState().ToString()); ret.Add("Volume", Convert.ToInt32(_mbApiInterface.Player_GetVolume() * 100.0f).ToString()); return(ret); }