internal async Task <Data> RetrieveMetaData(Disc d) { var inc = MB.Include.Artists | MB.Include.Labels | MB.Include.Recordings | MB.Include.ReleaseGroups | MB.Include.UrlRelationships; MB.Query query = null; MB.CoverArt.CoverArt coverArt = null; try { var lengths = d.StandardizedCDTableOfContents(); if (lengths != null) { if (lengths2Name.TryGetValue(lengths, out string name)) { return(discs[name]); } int frameCount = lengths.Length; MB.Interfaces.Entities.IDisc disc = null; MB.Interfaces.IDiscIdLookupResult result = null; int[] queryTOCArray = null; int[] firstTrackLBAs = MetaDataProvider.CDCommonFirstTrackLBAs; string graceNoteDiscID = (d as DiscSonyBD)?.DiscIDData?.GraceNoteDiscID; if (graceNoteDiscID != null) { int spaceIndex = graceNoteDiscID.IndexOf(' '); if (spaceIndex > 0 && Int32.TryParse(graceNoteDiscID.Substring(0, spaceIndex), out int firstTrackLBA)) { firstTrackLBAs = new int[] { firstTrackLBA } } ; } foreach (int initial in firstTrackLBAs) { // int initial = 150; var cumulative = lengths.Aggregate(new List <int>(frameCount + 4) { 1, frameCount, 0, initial }, (c, nxt) => { c.Add(c.Last() + nxt); return(c); }); int total = cumulative.Last(); cumulative[2] = total; var queryTOC = cumulative.Take(frameCount + 3); var discTOC = MB.DiscId.TableOfContents.SimulateDisc(1, (byte)frameCount, queryTOC.Skip(2).ToArray()); queryTOCArray = queryTOC.ToArray(); query = new MB.Query("DiscChangerApp"); result = await query.LookupDiscIdAsync(discTOC.DiscId, queryTOCArray, inc, true, true); disc = result.Disc; if (disc != null) { break; } } coverArt = new MB.CoverArt.CoverArt("DiscChanger.NET", "0.1", "*****@*****.**"); IReadOnlyList <MB.Interfaces.Entities.IRelease> releases = disc != null ? disc.Releases : result.Releases; if (releases == null || releases.Count == 0) { return(null); } Data data = new Data(); data.ArtRelPath = musicBrainzArtRelPath; data.Lengths = lengths; data.DiscID = disc?.Id; data.QueryTOC = queryTOCArray; int?trackCount = (d as DiscSony)?.DiscData?.TrackCount(); var rm = releases.Select(r => { var m_discs = r.Media?.Where(m => m.Discs != null && m.Discs.Any()); var ml = m_discs?.Where(m => m.Discs.Any(md => disc != null ? md.Id == disc.Id : discMatch(md, lengths))); var mt = ml?.Where(m => m.Tracks != null && m.Tracks.Any()); var m = mt?.FirstOrDefault(m => m.TrackCount == trackCount); ulong min_diff = 0UL; if (m == null) { m = mt?.FirstOrDefault(); } if (m == null) { var m_diff = m_discs?.Select(m => Tuple.Create(m, Enumerable.Min(m.Discs.Select(md => discDiff(md, lengths))))).OrderByDescending(t => t.Item2); var t = m_diff?.FirstOrDefault(); min_diff = t?.Item2 ?? Int64.MaxValue; m = t?.Item1; } return(Tuple.Create(r, min_diff, m?.Tracks)); }).OrderBy(t => t.Item2); // var selectedReleases = rm.Where(t => t.Item2 < Int64.MaxValue).Select(t => t.Item1); var selectedReleases = rm.Where(t => t.Item2 < Int64.MaxValue).Where(t => t.Item2 == rm.FirstOrDefault()?.Item2).Select(t => t.Item1); data.ReleaseIDs = selectedReleases.Select(r => r.Id).ToArray(); data.Tracks = rm.FirstOrDefault()?.Item3?.Select(t => new Track(t.Id, t.Length, t.Position, t.Title)).ToArray(); data.Artist = rm.FirstOrDefault(t => t.Item1.ArtistCredit.Count > 0)?.Item1.ArtistCredit.First().Name.Trim(); data.Title = rm.FirstOrDefault(t => !String.IsNullOrEmpty(t.Item1.Title))?.Item1.Title.Trim(); var URLs = selectedReleases.SelectMany(r => r.Relationships.Select(rel => rel.Url?.Resource?.AbsoluteUri).Where(s => !String.IsNullOrEmpty(s))).Distinct().ToArray(); data.URLs = URLs.Length > 0 ? URLs : null; string fileNameArtist = MetaDataProvider.RemoveBlacklistedCharacters(data.Artist ?? "ArtistUnk", 40); string fileNameTitle = MetaDataProvider.RemoveBlacklistedCharacters(data.Title ?? "TitleUnk", 80); string fileNameBaseK = fileNameArtist + '_' + fileNameTitle; string fileNameBase = fileNameBaseK; int i = 1; while (discs.ContainsKey(fileNameBase)) { fileNameBase = fileNameBaseK + "_(" + i.ToString() + ')'; i++; } var releasesWithFront = selectedReleases.Where(rel => rel.CoverArtArchive.Front); var artRelease = releasesWithFront.FirstOrDefault(r => r.Quality.ToLower() == "normal" && r.Packaging != null && r.Packaging.ToLower().Contains("jewel")) ?? releasesWithFront.FirstOrDefault(); var id = artRelease?.Id; if (id != null) { //try //{ var ca = coverArt.FetchFront(id.Value); data.ArtReleaseID = id; var ext = MimeTypeMap.GetExtension(ca.ContentType); var fileNameArt = Path.ChangeExtension("CoverArtFront_" + fileNameBase, ext); data.ArtContentType = ca.ContentType; data.ArtFileName = fileNameArt; using (var f = System.IO.File.OpenWrite(Path.Combine(this.musicBrainzArtPath, fileNameArt))) { ca.Data.Seek(0, System.IO.SeekOrigin.Begin); ca.Data.CopyTo(f); } //} //catch (WebException e) //{ // System.Diagnostics.Debug.WriteLine($"FetchFront {id.Value} Exception {e}"); //} } var fileName = Path.ChangeExtension(fileNameBase, "json"); using (var f = File.Create(Path.Combine(musicBrainzPath, fileName))) { var w = new Utf8JsonWriter(f, new JsonWriterOptions { Indented = true }); JsonSerializer.Serialize(w, data); f.Close(); } discs[fileNameBase] = data; lengths2Name[lengths] = fileNameBase; return(data); } return(null); } finally { if (query != null) { query.Dispose(); } } }
public async Task <bool> RetrieveMetaData(MetaDataGD3 metaDataGD3, string path) { if (Matches == null || Matches.Length == 0 || metaData != null) { return(false); } GD3DVD.DVDMatch match = Matches[SelectedMatch ?? 0]; var dvdCode = match.DVDCode; var discID = match.DiscID; var t = Tuple.Create(dvdCode, discID); if (AssociateMetaData()) { return(false); } var task = metaDataGD3.SoapClientDVD.RetrieveDVDMetaByDiscIDAsync(metaDataGD3.authDVD, dvdCode, discID); if (await Task.WhenAny(task, Task.Delay(30000)) != task) { throw new Exception("GD3DVD RetrieveDVDMetaByDiscIDAsync timeout: " + dvdCode); } var retrieveDVDMetaResponse = await task; var dvdMeta = retrieveDVDMetaResponse?.RetrieveDVDMetaByDiscIDResult; if (dvdMeta == null) { return(false); } string title = MetaDataProvider.RemoveBlacklistedCharacters(GetTitlePlusDisc(dvdMeta) ?? "NoTitle", 80); string fileNameBase = $"Meta_{match.MediaType}_{title}_{dvdCode}_{discID}"; string frontCoverImageFileName = null; string backCoverImageFileName = null; var ai = dvdMeta.FrontCover; var bc = dvdMeta.BackCover; if (ai != null) { if (ai.Length > 0) { frontCoverImageFileName = await WriteImage(ai, path, $"MetaFrontCover_{title}_{dvdCode}"); } dvdMeta.FrontCover = null; } if (bc != null) { if (bc.Length > 0) { backCoverImageFileName = await WriteImage(bc, path, $"MetaBackCover_{title}_{dvdCode}"); } dvdMeta.BackCover = null; } var m = new MetaDataDVD { DVDCode = dvdCode, DiscID = discID, DVDMeta = dvdMeta, ImageFileName = frontCoverImageFileName ?? backCoverImageFileName }; using (var f = File.Create(Path.Combine(path, Path.ChangeExtension(fileNameBase, "json")))) { var w = new Utf8JsonWriter(f, new JsonWriterOptions { Indented = true }); JsonSerializer.Serialize(w, m); f.Close(); } metaDataGD3.dvdCodeDiscIDToMetaData[t] = m; metaData = m; return(true); }
internal async Task <Match> RetrieveMatch(Disc d) { if (d is DiscSony ds) { if (ds.IsCD()) { var lengths = d.StandardizedCDTableOfContents(); if (lengths != null) { if (lengths2NameCD.TryGetValue(lengths, out string name)) { return(nameToMatchCD[name]); } if (authCD == null) { return(null); } int frameCount = lengths.Length; string graceNoteDiscID = (ds as DiscSonyBD)?.DiscIDData?.GraceNoteDiscID; string cdID; if (String.IsNullOrEmpty(graceNoteDiscID)) { graceNoteDiscID = null; int initial = 150; var cumulative = lengths.Aggregate(new List <int>(frameCount + 1) { initial }, (c, nxt) => { c.Add(c.Last() + nxt); return(c); }); cdID = String.Join(' ', cumulative); } else { cdID = graceNoteDiscID; } var task = SoapClientCD.MatchCDIDAsync(authCD, cdID); if (await Task.WhenAny(task, Task.Delay(30000)) != task) { throw new Exception("GD3 MatchCDIDAsync timeout: " + cdID); } var matchCDIDResponse = await task; var matchesCD = matchCDIDResponse?.MatchCDIDResult; GD3.AlbumCode[] matchesCDNonNull; if (matchesCD != null && (matchesCDNonNull = matchesCD.Where(m => m != null).ToArray()) != null && matchesCDNonNull.Length > 0) { var matchCD = new MatchCD(this) { SelectedMatch = 0, GraceNoteDiscID = graceNoteDiscID, Lengths = lengths, Matches = matchesCDNonNull }; var firstMatch = matchesCDNonNull.First(); string fileNameArtist = MetaDataProvider.RemoveBlacklistedCharacters(firstMatch.Artist ?? "ArtistUnk", 40); string fileNameAlbum = MetaDataProvider.RemoveBlacklistedCharacters(firstMatch.Album ?? "TitleUnk", 80); string fileName = MakeUniqueFileName(nameToMatchCD, $"Match_CD_{fileNameArtist}_{fileNameAlbum}_{firstMatch.MatchType}"); using (var f = File.Create(Path.Combine(GD3CDPath, Path.ChangeExtension(fileName, "json")))) { var w = new Utf8JsonWriter(f, new JsonWriterOptions { Indented = true }); JsonSerializer.Serialize(w, matchCD); f.Close(); } nameToMatchCD[fileName] = matchCD; lengths2NameCD[lengths] = fileName; matchCD.AssociateMetaData(); return(matchCD); } } } else if (ds.IsDVD() || ds.IsBD()) { MatchDVDBase match = null; GD3DVD.DVDMatch[] matches = null; IDictionary nameToMatch = null; string path = null;; if (ds.IsDVD()) { string gtoc = (ds as DiscSonyBD)?.DiscIDData?.GraceNoteDiscID; if (gtoc == null) { gtoc = TableOfContents2GTOC(ds.TableOfContents); } if (String.IsNullOrEmpty(gtoc)) { return(null); } if (graceNoteID2NameDVD.TryGetValue(gtoc, out string name)) { return(nameToMatchDVD[name]); } if (authDVD == null) { return(null); } var task = SoapClientDVD.MatchDVDID_vToc2Async(authDVD, gtoc); if (await Task.WhenAny(task, Task.Delay(30000)) != task) { throw new Exception("GD3 MatchDVDID_vToc2Async timeout: " + gtoc); } var matchDVDID_vToc2Response = await task; matches = matchDVDID_vToc2Response?.MatchDVDID_vToc2Result?.DVDMatches; path = GD3DVDPath; match = new MatchDVD(this) { SelectedMatch = 0, GraceNoteDiscID = gtoc }; nameToMatch = nameToMatchDVD; } else if (ds.IsBD() && d is DiscSonyBD bdd) { var AACSDiscID = bdd.DiscIDData?.AACSDiscID; if (AACSDiscID == null || AACSDiscID.Length == 0) { return(null); } if (AACSDiscID2NameBD.TryGetValue(AACSDiscID, out string name)) { return(nameToMatchBD[name]); } if (authDVD == null) { return(null); } var task = SoapClientDVD.Match_AACSAsync(authDVD, bdd.DiscIDData.AACSDiscID); if (await Task.WhenAny(task, Task.Delay(30000)) != task) { throw new Exception("GD3 Match_AACSAsync timeout"); } var match_AACSResponse = await task; matches = match_AACSResponse?.Match_AACSResult?.DVDMatches; path = GD3BDPath; match = new MatchBD(this) { SelectedMatch = 0, AACSDiscID = AACSDiscID }; nameToMatch = nameToMatchBD; } GD3DVD.DVDMatch[] matchesNonNull; if (matches != null && (matchesNonNull = matches.Where(m => m != null).ToArray()).Length > 0) { string[] frontCoverImages = new string[matchesNonNull.Length]; int i = 0; foreach (var m in matchesNonNull) { string mediaType2 = MetaDataProvider.RemoveBlacklistedCharacters(m.MediaType ?? "NoMediaType", 11); string title2 = MetaDataProvider.RemoveBlacklistedCharacters(m.DVDTitle ?? "NoTitle", 80); var frontCoverImage = m.FrontCoverImage; if (frontCoverImage != null && frontCoverImage.Length > 0) { var frontCoverImageFileName = await WriteImage(frontCoverImage, path, $"MatchFrontCover_{mediaType2}_{title2}_{m.DVDCode}_{m.DiscID}"); frontCoverImages[i] = frontCoverImageFileName; match.FrontCoverImages = frontCoverImages; m.FrontCoverImage = null;//erase base64-encoded thumbnail to save space } var extraImages = m.ExtraImages; if (extraImages != null) { foreach (var ei in extraImages) { try { var task2 = SoapClientDVD.RetrieveExtraMovieImageAsync(authDVD, ei.MovieImageID, false); if (await Task.WhenAny(task2, Task.Delay(30000)) != task2) { throw new Exception("GD3 RetrieveExtraMovieImageAsync timeout: " + ei.MovieImageID); } var retrieveExtraMovieImageResponse = await task2; byte[] b = retrieveExtraMovieImageResponse?.RetrieveExtraMovieImageResult; if (b != null && b.Length > 0) { var movieImageFileName = await WriteImage(b, path, $"MovieImage_{ei.MovieImageID}"); } } catch (Exception e) { System.Diagnostics.Debug.WriteLine($"Error retrieving Movie Image {ei.MovieImageID}: {e.Message}"); } } } i++; } match.Matches = matchesNonNull; var firstMatch = matchesNonNull.First(); string mediaType = MetaDataProvider.RemoveBlacklistedCharacters(firstMatch.MediaType ?? "NoMediaType", 11); string title = MetaDataProvider.RemoveBlacklistedCharacters(firstMatch.DVDTitle ?? "NoTitle", 80); string fileName = MakeUniqueFileName(nameToMatch, $"Match_{mediaType}_{title}_{firstMatch.MatchType}"); using (var f = File.Create(Path.Combine(path, Path.ChangeExtension(fileName, "json")))) { var w = new Utf8JsonWriter(f, new JsonWriterOptions { Indented = true }); JsonSerializer.Serialize(w, (object)match); f.Close(); } if (match is MatchDVD matchDVD) { nameToMatchDVD[fileName] = matchDVD; graceNoteID2NameDVD[matchDVD.GraceNoteDiscID] = fileName; } if (match is MatchBD matchBD) { nameToMatchBD[fileName] = matchBD; AACSDiscID2NameBD[matchBD.AACSDiscID] = fileName; } match.AssociateMetaData(); return(match); } } } return(null); }
public override async Task <bool> RetrieveMetaData() { if (Matches == null || Matches.Length == 0 || metaData != null) { return(false); } GD3.AlbumCode match = Matches[SelectedMatch ?? 0]; var albumCode1 = match.AlbumCode1; if (AssociateMetaData() || metaDataGD3.authCD == null) { return(false); } var task = metaDataGD3.SoapClientCD.RetrieveAlbumAsync(metaDataGD3.authCD, albumCode1, 0); if (await Task.WhenAny(task, Task.Delay(30000)) != task) { throw new Exception("GD3 RetrieveAlbumAsync timeout: " + albumCode1); } var retrieveAlbumResponse = await task; var albumMeta = retrieveAlbumResponse?.RetrieveAlbumResult; if (albumMeta == null) { return(false); } var albumCode = albumMeta.AlbumID; if (albumCode == 0) { albumCode = albumMeta.AlbumCode; } if (albumCode == 0) { albumCode = Math.Abs(albumCode1); } string fileNameArtist = MetaDataProvider.RemoveBlacklistedCharacters(albumMeta.Artist ?? "ArtistUnk", 40); string fileNameAlbum = MetaDataProvider.RemoveBlacklistedCharacters(albumMeta.Album ?? "AlbumUnk", 80); string fileNameBase = $"Meta_CD_{fileNameArtist}_{fileNameAlbum}_{albumCode}"; string albumImageFileName = null; var ai = albumMeta.AlbumImage; if (ai != null) { if (ai.Length > 0) { albumImageFileName = await WriteImage(ai, metaDataGD3.GD3CDPath, fileNameBase); } albumMeta.AlbumImage = null; } var m = new MetaDataCD { AlbumCode = albumCode, AlbumMeta = albumMeta, ImageFileName = albumImageFileName }; using (var f = File.Create(Path.Combine(metaDataGD3.GD3CDPath, Path.ChangeExtension(fileNameBase, "json")))) { var w = new Utf8JsonWriter(f, new JsonWriterOptions { Indented = true }); JsonSerializer.Serialize(w, m); f.Close(); } metaDataGD3.cdCodeToMetaData[albumCode] = m; metaData = m; return(true); }