public static async Task <string> TryMatchTmdbIdAsync(ILocalFsResourceAccessor folderOrFileLfsra) { // Calling EnsureLocalFileSystemAccess not necessary; only string operation string extensionLower = StringUtils.TrimToEmpty(Path.GetExtension(folderOrFileLfsra.LocalFileSystemPath)).ToLower(); if (!MatroskaConsts.MATROSKA_VIDEO_EXTENSIONS.Contains(extensionLower)) { return(null); } MatroskaBinaryReader mkvReader = new MatroskaBinaryReader(folderOrFileLfsra); // Add keys to be extracted to tags dictionary, matching results will returned as value Dictionary <string, IList <string> > tagsToExtract = MatroskaConsts.DefaultVideoTags; await mkvReader.ReadTagsAsync(tagsToExtract).ConfigureAwait(false); if (tagsToExtract[MatroskaConsts.TAG_MOVIE_TMDB_ID] != null) { foreach (string candidate in tagsToExtract[MatroskaConsts.TAG_MOVIE_TMDB_ID]) { if (int.TryParse(candidate, out int tmdbIdInt)) { return(tmdbIdInt.ToString()); } } } return(null); }
public void TestMatroskaBinaryTagInfo() { // Arrange MatroskaBinaryReader matroskaInfoReader = GetMatroskaBinaryFileReader(); var tags = MatroskaConsts.DefaultVideoTags; // Act matroskaInfoReader.ReadTagsAsync(tags).Wait(); // Assert Assert.AreEqual("Test Title", tags[MatroskaConsts.TAG_SIMPLE_TITLE].First()); Assert.AreEqual("Doctor Who", tags[MatroskaConsts.TAG_SERIES_TITLE].First()); Assert.AreEqual("76107", tags[MatroskaConsts.TAG_SERIES_TVDB_ID].First()); Assert.IsTrue(tags[MatroskaConsts.TAG_EPISODE_SUMMARY].First().Length > 0); Assert.AreEqual("1963-11-23", tags[MatroskaConsts.TAG_EPISODE_YEAR].First()); Assert.AreEqual("Doctor Who", tags[MatroskaConsts.TAG_EPISODE_TITLE].First()); Assert.AreEqual("1", tags[MatroskaConsts.TAG_EPISODE_NUMBER].First()); Assert.AreEqual("tt0056751", tags[MatroskaConsts.TAG_MOVIE_IMDB_ID].First()); }
public static async Task <bool> ExtractFromTagsAsync(ILocalFsResourceAccessor folderOrFileLfsra, MovieInfo movieInfo) { // Calling EnsureLocalFileSystemAccess not necessary; only string operation string extensionLower = StringUtils.TrimToEmpty(Path.GetExtension(folderOrFileLfsra.LocalFileSystemPath)).ToLower(); if (!MatroskaConsts.MATROSKA_VIDEO_EXTENSIONS.Contains(extensionLower)) { return(false); } // Try to get extended information out of matroska files) MatroskaBinaryReader mkvReader = new MatroskaBinaryReader(folderOrFileLfsra); // Add keys to be extracted to tags dictionary, matching results will returned as value Dictionary <string, IList <string> > tagsToExtract = MatroskaConsts.DefaultVideoTags; await mkvReader.ReadTagsAsync(tagsToExtract).ConfigureAwait(false); // Read plot IList <string> tags = tagsToExtract[MatroskaConsts.TAG_EPISODE_SUMMARY]; string plot = tags != null?tags.FirstOrDefault() : string.Empty; if (!string.IsNullOrEmpty(plot)) { movieInfo.HasChanged |= MetadataUpdater.SetOrUpdateString(ref movieInfo.Summary, plot, true); } // Read genre tags = tagsToExtract[MatroskaConsts.TAG_SERIES_GENRE]; if (tags != null) { List <GenreInfo> genreList = tags.Where(s => !string.IsNullOrEmpty(s?.Trim())).Select(s => new GenreInfo { Name = s.Trim() }).ToList(); movieInfo.HasChanged |= MetadataUpdater.SetOrUpdateList(movieInfo.Genres, genreList, movieInfo.Genres.Count == 0); } // Read actors tags = tagsToExtract[MatroskaConsts.TAG_ACTORS]; if (tags != null) { movieInfo.HasChanged |= MetadataUpdater.SetOrUpdateList(movieInfo.Actors, tags.Select(t => new PersonInfo() { Name = t, Occupation = PersonAspect.OCCUPATION_ACTOR, MediaName = movieInfo.MovieName.Text }).ToList(), false); } tags = tagsToExtract[MatroskaConsts.TAG_DIRECTORS]; if (tags != null) { movieInfo.HasChanged |= MetadataUpdater.SetOrUpdateList(movieInfo.Directors, tags.Select(t => new PersonInfo() { Name = t, Occupation = PersonAspect.OCCUPATION_DIRECTOR, MediaName = movieInfo.MovieName.Text }).ToList(), false); } tags = tagsToExtract[MatroskaConsts.TAG_WRITTEN_BY]; if (tags != null) { movieInfo.HasChanged |= MetadataUpdater.SetOrUpdateList(movieInfo.Writers, tags.Select(t => new PersonInfo() { Name = t, Occupation = PersonAspect.OCCUPATION_WRITER, MediaName = movieInfo.MovieName.Text }).ToList(), false); } if (tagsToExtract[MatroskaConsts.TAG_MOVIE_IMDB_ID] != null) { string imdbId; foreach (string candidate in tagsToExtract[MatroskaConsts.TAG_MOVIE_IMDB_ID]) { if (ImdbIdMatcher.TryMatchImdbId(candidate, out imdbId)) { movieInfo.HasChanged |= MetadataUpdater.SetOrUpdateId(ref movieInfo.ImdbId, imdbId); break; } } } if (tagsToExtract[MatroskaConsts.TAG_MOVIE_TMDB_ID] != null) { int tmp; foreach (string candidate in tagsToExtract[MatroskaConsts.TAG_MOVIE_TMDB_ID]) { if (int.TryParse(candidate, out tmp) == true) { movieInfo.HasChanged |= MetadataUpdater.SetOrUpdateId(ref movieInfo.MovieDbId, tmp); break; } } } return(true); }
/// <summary> /// Tries to match series by reading matroska tags from <paramref name="folderOrFileLfsra"/>. /// </summary> /// <param name="folderOrFileLfsra"><see cref="ILocalFsResourceAccessor"/> to file or folder</param> /// <param name="episodeInfo">Returns the parsed EpisodeInfo</param> /// <param name="extractedAspectData">Dictionary containing a mapping of media item aspect ids to /// already present media item aspects, this metadata extractor should edit. If a media item aspect is not present /// in this dictionary but found by this metadata extractor, it will add it to the dictionary.</param> /// <returns><c>true</c> if successful.</returns> public async Task <bool> MatchSeriesAsync(ILocalFsResourceAccessor folderOrFileLfsra, EpisodeInfo episodeInfo) { // Calling EnsureLocalFileSystemAccess not necessary; only string operation string extensionLower = StringUtils.TrimToEmpty(Path.GetExtension(folderOrFileLfsra.LocalFileSystemPath)).ToLower(); if (!MatroskaConsts.MATROSKA_VIDEO_EXTENSIONS.Contains(extensionLower)) { return(false); } MatroskaBinaryReader mkvReader = new MatroskaBinaryReader(folderOrFileLfsra); // Add keys to be extracted to tags dictionary, matching results will returned as value Dictionary <string, IList <string> > tagsToExtract = MatroskaConsts.DefaultVideoTags; await mkvReader.ReadTagsAsync(tagsToExtract).ConfigureAwait(false); IList <string> tags = tagsToExtract[MatroskaConsts.TAG_EPISODE_SUMMARY]; string plot = tags != null?tags.FirstOrDefault() : string.Empty; if (!string.IsNullOrEmpty(plot)) { episodeInfo.HasChanged |= MetadataUpdater.SetOrUpdateString(ref episodeInfo.Summary, plot, true); } // Series and episode handling. Prefer information from tags. if (tagsToExtract[MatroskaConsts.TAG_EPISODE_TITLE] != null) { string title = tagsToExtract[MatroskaConsts.TAG_EPISODE_TITLE].FirstOrDefault(); if (!string.IsNullOrEmpty(title)) { title = CultureInfo.InvariantCulture.TextInfo.ToTitleCase(title); episodeInfo.HasChanged |= MetadataUpdater.SetOrUpdateString(ref episodeInfo.EpisodeName, title, true); } } if (tagsToExtract[MatroskaConsts.TAG_SERIES_TITLE] != null) { string title = tagsToExtract[MatroskaConsts.TAG_SERIES_TITLE].FirstOrDefault(); if (!string.IsNullOrEmpty(title)) { title = CultureInfo.InvariantCulture.TextInfo.ToTitleCase(title); episodeInfo.HasChanged |= MetadataUpdater.SetOrUpdateString(ref episodeInfo.SeriesName, title, true); } } if (tagsToExtract[MatroskaConsts.TAG_SERIES_IMDB_ID] != null) { string imdbId; foreach (string candidate in tagsToExtract[MatroskaConsts.TAG_SERIES_IMDB_ID]) { if (ImdbIdMatcher.TryMatchImdbId(candidate, out imdbId)) { episodeInfo.HasChanged |= MetadataUpdater.SetOrUpdateId(ref episodeInfo.SeriesImdbId, imdbId); break; } } } if (tagsToExtract[MatroskaConsts.TAG_SERIES_ACTORS] != null) { episodeInfo.HasChanged |= MetadataUpdater.SetOrUpdateList(episodeInfo.Actors, tagsToExtract[MatroskaConsts.TAG_SERIES_ACTORS].Select(t => new PersonInfo() { Name = t, Occupation = PersonAspect.OCCUPATION_ACTOR, MediaName = episodeInfo.EpisodeName.Text, ParentMediaName = episodeInfo.SeriesName.Text }).ToList(), false); } // On Series, the counting tag is "TVDB" if (tagsToExtract[MatroskaConsts.TAG_SERIES_TVDB_ID] != null) { int tmp; foreach (string candidate in tagsToExtract[MatroskaConsts.TAG_SERIES_TVDB_ID]) { if (int.TryParse(candidate, out tmp) == true) { episodeInfo.HasChanged |= MetadataUpdater.SetOrUpdateId(ref episodeInfo.SeriesTvdbId, tmp); break; } } } int tmpInt; if (tagsToExtract[MatroskaConsts.TAG_SEASON_NUMBER] != null && int.TryParse(tagsToExtract[MatroskaConsts.TAG_SEASON_NUMBER].FirstOrDefault(), out tmpInt)) { episodeInfo.HasChanged |= MetadataUpdater.SetOrUpdateValue(ref episodeInfo.SeasonNumber, tmpInt); } if (tagsToExtract[MatroskaConsts.TAG_EPISODE_NUMBER] != null) { int episodeNum; foreach (string s in tagsToExtract[MatroskaConsts.TAG_EPISODE_NUMBER]) { if (int.TryParse(s, out episodeNum)) { if (!episodeInfo.EpisodeNumbers.Contains(episodeNum)) { episodeInfo.EpisodeNumbers.Add(episodeNum); } } } } return(true); }