public static bool TryMatchImdbId(string folderOrFileName, out string imdbId) { string extensionLower = StringUtils.TrimToEmpty(Path.GetExtension(folderOrFileName)).ToLower(); if (!MatroskaConsts.MATROSKA_VIDEO_EXTENSIONS.Contains(extensionLower)) { imdbId = null; return false; } MatroskaInfoReader mkvReader = new MatroskaInfoReader(folderOrFileName); // Add keys to be extracted to tags dictionary, matching results will returned as value Dictionary<string, IList<string>> tagsToExtract = MatroskaConsts.DefaultTags; mkvReader.ReadTags(tagsToExtract); if (tagsToExtract[MatroskaConsts.TAG_MOVIE_IMDB_ID] != null) { foreach (string candidate in tagsToExtract[MatroskaConsts.TAG_MOVIE_IMDB_ID]) { if (ImdbIdMatcher.TryMatchImdbId(candidate, out imdbId)) return true; } } imdbId = null; return false; }
public static bool TryMatchTmdbId(ILocalFsResourceAccessor folderOrFileLfsra, out int tmdbId) { // Calling EnsureLocalFileSystemAccess not necessary; only string operation string extensionLower = StringUtils.TrimToEmpty(Path.GetExtension(folderOrFileLfsra.LocalFileSystemPath)).ToLower(); if (!MatroskaConsts.MATROSKA_VIDEO_EXTENSIONS.Contains(extensionLower)) { tmdbId = 0; return false; } MatroskaInfoReader mkvReader = new MatroskaInfoReader(folderOrFileLfsra); // Add keys to be extracted to tags dictionary, matching results will returned as value Dictionary<string, IList<string>> tagsToExtract = MatroskaConsts.DefaultTags; mkvReader.ReadTags(tagsToExtract); if (tagsToExtract[MatroskaConsts.TAG_MOVIE_TMDB_ID] != null) { foreach (string candidate in tagsToExtract[MatroskaConsts.TAG_MOVIE_TMDB_ID]) { if (int.TryParse(candidate, out tmdbId)) return true; } } tmdbId = 0; return false; }
/// <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="seriesInfo">Returns the parsed SeriesInfo</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 bool MatchSeries(ILocalFsResourceAccessor folderOrFileLfsra, out SeriesInfo seriesInfo, ref IDictionary<Guid, MediaItemAspect> extractedAspectData) { // Calling EnsureLocalFileSystemAccess not necessary; only string operation string extensionLower = StringUtils.TrimToEmpty(Path.GetExtension(folderOrFileLfsra.LocalFileSystemPath)).ToLower(); if (!MatroskaConsts.MATROSKA_VIDEO_EXTENSIONS.Contains(extensionLower)) { seriesInfo = null; return false; } MatroskaInfoReader mkvReader = new MatroskaInfoReader(folderOrFileLfsra); // Add keys to be extracted to tags dictionary, matching results will returned as value Dictionary<string, IList<string>> tagsToExtract = MatroskaConsts.DefaultTags; mkvReader.ReadTags(tagsToExtract); string title = string.Empty; IList<string> tags = tagsToExtract[MatroskaConsts.TAG_SIMPLE_TITLE]; if (tags != null) title = tags.FirstOrDefault(); if (!string.IsNullOrEmpty(title)) MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_TITLE, title); string yearCandidate = null; tags = tagsToExtract[MatroskaConsts.TAG_EPISODE_YEAR] ?? tagsToExtract[MatroskaConsts.TAG_SEASON_YEAR]; if (tags != null) yearCandidate = (tags.FirstOrDefault() ?? string.Empty).Substring(0, 4); int year; if (int.TryParse(yearCandidate, out year)) MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_RECORDINGTIME, new DateTime(year, 1, 1)); tags = tagsToExtract[MatroskaConsts.TAG_EPISODE_SUMMARY]; string plot = tags != null ? tags.FirstOrDefault() : string.Empty; if (!string.IsNullOrEmpty(plot)) MediaItemAspect.SetAttribute(extractedAspectData, VideoAspect.ATTR_STORYPLOT, plot); // Series and episode handling. Prefer information from tags. seriesInfo = GetSeriesFromTags(tagsToExtract); return true; }
protected bool ExtractSeriesData(string localFsResourcePath, IDictionary<Guid, MediaItemAspect> extractedAspectData) { SeriesInfo seriesInfo = null; string extensionUpper = StringUtils.TrimToEmpty(Path.GetExtension(localFsResourcePath)).ToUpper(); // Try to get extended information out of matroska files) if (extensionUpper == ".MKV" || extensionUpper == ".MK3D") { MatroskaInfoReader mkvReader = new MatroskaInfoReader(localFsResourcePath); // Add keys to be extracted to tags dictionary, matching results will returned as value Dictionary<string, IList<string>> tagsToExtract = MatroskaConsts.DefaultTags; mkvReader.ReadTags(tagsToExtract); string title = string.Empty; IList<string> tags = tagsToExtract[MatroskaConsts.TAG_SIMPLE_TITLE]; if (tags != null) title = tags.FirstOrDefault(); if (!string.IsNullOrEmpty(title)) MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_TITLE, title); string yearCandidate = null; tags = tagsToExtract[MatroskaConsts.TAG_EPISODE_YEAR] ?? tagsToExtract[MatroskaConsts.TAG_SEASON_YEAR]; if (tags != null) yearCandidate = (tags.FirstOrDefault() ?? string.Empty).Substring(0, 4); int year; if (int.TryParse(yearCandidate, out year)) MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_RECORDINGTIME, new DateTime(year, 1, 1)); tags = tagsToExtract[MatroskaConsts.TAG_EPISODE_SUMMARY]; string plot = tags != null ? tags.FirstOrDefault() : string.Empty; if (!string.IsNullOrEmpty(plot)) MediaItemAspect.SetAttribute(extractedAspectData, VideoAspect.ATTR_STORYPLOT, plot); // Series and episode handling. Prefer information from tags. seriesInfo = GetSeriesFromTags(tagsToExtract); } // If now information from mkv were found, try name matching if (seriesInfo == null || !seriesInfo.IsCompleteMatch) { // Try to match series from folder and file namings SeriesMatcher seriesMatcher = new SeriesMatcher(); seriesMatcher.MatchSeries(localFsResourcePath, out seriesInfo); } // Lookup online information (incl. fanart) if (seriesInfo != null && seriesInfo.IsCompleteMatch) { SeriesTvDbMatcher.Instance.FindAndUpdateSeries(seriesInfo); seriesInfo.SetMetadata(extractedAspectData); } return (seriesInfo != null && seriesInfo.IsCompleteMatch); }
public bool TryGetFanArt(string mediaType, string fanArtType, string name, int maxWidth, int maxHeight, bool singleRandom, out IList<FanArtImage> result) { result = null; Guid mediaItemId; if (!Guid.TryParse(name, out mediaItemId)) return false; IMediaLibrary mediaLibrary = ServiceRegistration.Get<IMediaLibrary>(false); if (mediaLibrary == null) return false; IFilter filter = new MediaItemIdFilter(mediaItemId); IList<MediaItem> items = mediaLibrary.Search(new MediaItemQuery(NECESSARY_MIAS, filter), false); if (items == null || items.Count == 0) return false; MediaItem mediaItem = items.First(); string fileSystemPath = string.Empty; IList<string> patterns = new List<string>(); switch (fanArtType) { case FanArtTypes.Banner: patterns.Add("banner."); break; case FanArtTypes.ClearArt: patterns.Add("clearart."); break; case FanArtTypes.Poster: case FanArtTypes.Thumbnail: patterns.Add("cover."); patterns.Add("poster."); patterns.Add("folder."); break; case FanArtTypes.FanArt: patterns.Add("backdrop."); patterns.Add("fanart."); break; default: return false; } // File based access try { var resourceLocator = mediaItem.GetResourceLocator(); using (var accessor = resourceLocator.CreateAccessor()) { ILocalFsResourceAccessor fsra = accessor as ILocalFsResourceAccessor; if (fsra != null) { var ext = Path.GetExtension(fsra.LocalFileSystemPath); if (!SUPPORTED_EXTENSIONS.Contains(ext)) return false; MatroskaInfoReader mkvReader = new MatroskaInfoReader(fsra); byte[] binaryData = null; if (patterns.Any(pattern => mkvReader.GetAttachmentByName(pattern, out binaryData))) { result = new List<FanArtImage> { new FanArtImage(name, binaryData) }; return true; } } } } catch (Exception ex) { ServiceRegistration.Get<ILogger>().Warn("MkvAttachmentsProvider: Exception while reading mkv attachment of type '{0}' from '{1}'", ex, fanArtType, fileSystemPath); } return false; }
protected void ExtractMatroskaTags(ILocalFsResourceAccessor lfsra, IDictionary<Guid, MediaItemAspect> extractedAspectData, bool forceQuickMode) { // Calling EnsureLocalFileSystemAccess not necessary; only string operation string extensionLower = StringUtils.TrimToEmpty(Path.GetExtension(lfsra.LocalFileSystemPath)).ToLower(); if (!MatroskaConsts.MATROSKA_VIDEO_EXTENSIONS.Contains(extensionLower)) return; // Try to get extended information out of matroska files) MatroskaInfoReader mkvReader = new MatroskaInfoReader(lfsra); // Add keys to be extracted to tags dictionary, matching results will returned as value Dictionary<string, IList<string>> tagsToExtract = MatroskaConsts.DefaultTags; mkvReader.ReadTags(tagsToExtract); // Read title string title = string.Empty; IList<string> tags = tagsToExtract[MatroskaConsts.TAG_SIMPLE_TITLE]; if (tags != null) title = tags.FirstOrDefault(); if (!string.IsNullOrEmpty(title)) MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_TITLE, title); // Read release date int year; string yearCandidate = null; tags = tagsToExtract[MatroskaConsts.TAG_EPISODE_YEAR] ?? tagsToExtract[MatroskaConsts.TAG_SEASON_YEAR]; if (tags != null) yearCandidate = (tags.FirstOrDefault() ?? string.Empty).Substring(0, 4); if (int.TryParse(yearCandidate, out year)) MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_RECORDINGTIME, new DateTime(year, 1, 1)); // Read plot tags = tagsToExtract[MatroskaConsts.TAG_EPISODE_SUMMARY]; string plot = tags != null ? tags.FirstOrDefault() : string.Empty; if (!string.IsNullOrEmpty(plot)) MediaItemAspect.SetAttribute(extractedAspectData, VideoAspect.ATTR_STORYPLOT, plot); // Read genre tags = tagsToExtract[MatroskaConsts.TAG_SERIES_GENRE]; if (tags != null) MediaItemAspect.SetCollectionAttribute(extractedAspectData, VideoAspect.ATTR_GENRES, tags); // Read actors IEnumerable<string> actors; // Combine series actors and episode actors if both are available var tagSeriesActors = tagsToExtract[MatroskaConsts.TAG_SERIES_ACTORS]; var tagActors = tagsToExtract[MatroskaConsts.TAG_ACTORS]; if (tagSeriesActors != null && tagActors != null) actors = tagSeriesActors.Union(tagActors); else actors = tagSeriesActors ?? tagActors; if (actors != null) MediaItemAspect.SetCollectionAttribute(extractedAspectData, VideoAspect.ATTR_ACTORS, actors); tags = tagsToExtract[MatroskaConsts.TAG_DIRECTORS]; if (tags != null) MediaItemAspect.SetCollectionAttribute(extractedAspectData, VideoAspect.ATTR_DIRECTORS, tags); tags = tagsToExtract[MatroskaConsts.TAG_WRITTEN_BY]; if (tags != null) MediaItemAspect.SetCollectionAttribute(extractedAspectData, VideoAspect.ATTR_WRITERS, tags); }
protected void ExtractMatroskaTags(string localFsResourcePath, IDictionary<Guid, MediaItemAspect> extractedAspectData, bool forceQuickMode) { string extensionUpper = StringUtils.TrimToEmpty(Path.GetExtension(localFsResourcePath)).ToUpper(); // Try to get extended information out of matroska files) if (extensionUpper == ".MKV" || extensionUpper == ".MK3D") { MatroskaInfoReader mkvReader = new MatroskaInfoReader(localFsResourcePath); // Add keys to be extracted to tags dictionary, matching results will returned as value Dictionary<string, IList<string>> tagsToExtract = MatroskaConsts.DefaultTags; mkvReader.ReadTags(tagsToExtract); string title = string.Empty; IList<string> tags = tagsToExtract[MatroskaConsts.TAG_SIMPLE_TITLE]; if (tags != null) title = tags.FirstOrDefault(); int year; if (!string.IsNullOrEmpty(title)) MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_TITLE, title); string yearCandidate = null; tags = tagsToExtract[MatroskaConsts.TAG_EPISODE_YEAR] ?? tagsToExtract[MatroskaConsts.TAG_SEASON_YEAR]; if (tags != null) yearCandidate = (tags.FirstOrDefault() ?? string.Empty).Substring(0, 4); if (int.TryParse(yearCandidate, out year)) MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_RECORDINGTIME, new DateTime(year, 1, 1)); tags = tagsToExtract[MatroskaConsts.TAG_SERIES_GENRE]; if (tags != null) MediaItemAspect.SetCollectionAttribute(extractedAspectData, VideoAspect.ATTR_GENRES, tags); IEnumerable<string> actors; // Combine series actors and episode actors if both are available var tagSeriesActors = tagsToExtract[MatroskaConsts.TAG_SERIES_ACTORS]; var tagActors = tagsToExtract[MatroskaConsts.TAG_ACTORS]; if (tagSeriesActors != null && tagActors != null) actors = tagSeriesActors.Union(tagActors); else actors = tagSeriesActors ?? tagActors; if (actors != null) MediaItemAspect.SetCollectionAttribute(extractedAspectData, VideoAspect.ATTR_ACTORS, actors); } // Movie handling //if (!string.IsNullOrEmpty(title) && !forceQuickMode) //{ // // TODO: online information can overwrite information read out of mkv tags, how to handle this? // MovieInfo movieInfo = new MovieInfo // { // MovieName = title, // Year = year // }; // if (MovieTheMovieDbMatcher.Instance.FindAndUpdateMovie(movieInfo)) // movieInfo.SetMetadata(extractedAspectData); //} }