/// <summary>
        /// Gets a <see cref="FanArtPathCollection"/> containing all matching season fanart paths in the specified <see cref="ResourcePath"/>.
        /// </summary>
        /// <param name="seasonDirectory"><see cref="IFileSystemResourceAccessor"/> that points to the season directory.</param>
        /// <param name="seasonNumber">Season number.</param>
        /// <returns><see cref="FanArtPathCollection"/> containing all matching paths.</returns>
        protected FanArtPathCollection GetSeasonFolderFanArt(IFileSystemResourceAccessor seasonDirectory, int?seasonNumber, bool isSeriesFolder)
        {
            FanArtPathCollection paths = new FanArtPathCollection();

            if (seasonDirectory == null)
            {
                return(paths);
            }

            List <ResourcePath> potentialFanArtFiles = LocalFanartHelper.GetPotentialFanArtFiles(seasonDirectory);

            if (!isSeriesFolder)
            {
                ExtractAllFanArtImages(potentialFanArtFiles, paths);

                if (!seasonNumber.HasValue || !seasonDirectory.ResourceExists("../"))
                {
                    return(paths);
                }

                //Try and populate any missing fanart from the series directory
                using (IFileSystemResourceAccessor seriesDirectory = seasonDirectory.GetResource("../"))
                    potentialFanArtFiles = LocalFanartHelper.GetPotentialFanArtFiles(seriesDirectory);
            }
            GetAdditionalSeasonFolderFanArt(paths, potentialFanArtFiles, seasonNumber);

            return(paths);
        }
Beispiel #2
0
        /// <summary>
        /// Gets a <see cref="FanArtPathCollection"/> containing all matching fanart paths in the specified <see cref="ResourcePath"/>.
        /// </summary>
        /// <param name="albumDirectory"><see cref="IFileSystemResourceAccessor"/> that points to the album directory.</param>
        /// <returns><see cref="FanArtPathCollection"/> containing all matching paths.</returns>
        protected FanArtPathCollection GetAlbumFolderFanArt(IFileSystemResourceAccessor albumDirectory)
        {
            FanArtPathCollection paths = new FanArtPathCollection();

            if (albumDirectory == null)
            {
                return(paths);
            }

            //Get all fanart in the current directory
            List <ResourcePath> potentialFanArtFiles = LocalFanartHelper.GetPotentialFanArtFiles(albumDirectory);

            ExtractAllFanArtImages(potentialFanArtFiles, paths);

            //Add extra backdrops in ExtraFanArt directory
            if (albumDirectory.ResourceExists("ExtraFanArt/"))
            {
                using (IFileSystemResourceAccessor extraFanArtDirectory = albumDirectory.GetResource("ExtraFanArt/"))
                    paths.AddRange(FanArtTypes.FanArt, LocalFanartHelper.GetPotentialFanArtFiles(extraFanArtDirectory));
            }

            List <ResourcePath> covers;

            //Albums store posters as covers so switch the fanart type
            if (paths.Paths.TryGetValue(FanArtTypes.Poster, out covers))
            {
                paths.Paths.Remove(FanArtTypes.Poster);
                paths.AddRange(FanArtTypes.Cover, covers);
            }

            return(paths);
        }
Beispiel #3
0
        public bool TryExtractMetadata(IResourceAccessor mediaItemAccessor, IDictionary <Guid, MediaItemAspect> extractedAspectData, bool forceQuickMode)
        {
            try
            {
                if (!(mediaItemAccessor is IFileSystemResourceAccessor))
                {
                    return(false);
                }

                using (LocalFsResourceAccessorHelper rah = new LocalFsResourceAccessorHelper(mediaItemAccessor))
                {
                    ILocalFsResourceAccessor lfsra = rah.LocalFsResourceAccessor;
                    if (!lfsra.IsFile && lfsra.ResourceExists("BDMV"))
                    {
                        IFileSystemResourceAccessor fsraBDMV = lfsra.GetResource("BDMV");
                        if (fsraBDMV != null && fsraBDMV.ResourceExists("index.bdmv"))
                        {
                            // This line is important to keep in, if no VideoAspect is created here, the MediaItems is not detected as Video!
                            MediaItemAspect.GetOrCreateAspect(extractedAspectData, VideoAspect.Metadata);
                            MediaItemAspect mediaAspect = MediaItemAspect.GetOrCreateAspect(extractedAspectData, MediaAspect.Metadata);

                            mediaAspect.SetAttribute(MediaAspect.ATTR_MIME_TYPE, "video/bluray"); // BluRay disc

                            string    bdmvDirectory = lfsra.LocalFileSystemPath;
                            BDInfoExt bdinfo        = new BDInfoExt(bdmvDirectory);
                            string    title         = bdinfo.GetTitle();
                            mediaAspect.SetAttribute(MediaAspect.ATTR_TITLE, title ?? mediaItemAccessor.ResourceName);

                            // Check for BD disc thumbs
                            FileInfo thumbnail = bdinfo.GetBiggestThumb();
                            if (thumbnail != null)
                            {
                                try
                                {
                                    using (FileStream fileStream = new FileStream(thumbnail.FullName, FileMode.Open, FileAccess.Read))
                                        using (MemoryStream resized = (MemoryStream)ImageUtilities.ResizeImage(fileStream, ImageFormat.Jpeg, MAX_COVER_WIDTH, MAX_COVER_HEIGHT))
                                        {
                                            MediaItemAspect.SetAttribute(extractedAspectData, ThumbnailLargeAspect.ATTR_THUMBNAIL, resized.ToArray());
                                        }
                                }
                                // Decoding of invalid image data can fail, but main MediaItem is correct.
                                catch { }
                            }
                            return(true);
                        }
                    }
                }
                return(false);
            }
            catch
            {
                // Only log at the info level here - And simply return false. This makes the importer know that we
                // couldn't perform our task here
                if (mediaItemAccessor != null)
                {
                    ServiceRegistration.Get <ILogger>().Info("BluRayMetadataExtractor: Exception reading source '{0}'", mediaItemAccessor.ResourcePathName);
                }
                return(false);
            }
        }
        public bool TryExtractMetadata(IResourceAccessor mediaItemAccessor, IDictionary <Guid, MediaItemAspect> extractedAspectData, bool forceQuickMode)
        {
            try
            {
                IResourceAccessor ra = mediaItemAccessor.Clone();
                try
                {
                    using (ILocalFsResourceAccessor fsra = StreamedResourceToLocalFsAccessBridge.GetLocalFsResourceAccessor(ra))
                        if (fsra != null && fsra.IsDirectory && fsra.ResourceExists("BDMV"))
                        {
                            IFileSystemResourceAccessor fsraBDMV = fsra.GetResource("BDMV");
                            if (fsraBDMV != null && fsraBDMV.ResourceExists("index.bdmv"))
                            {
                                // This line is important to keep in, if no VideoAspect is created here, the MediaItems is not detected as Video!
                                MediaItemAspect.GetOrCreateAspect(extractedAspectData, VideoAspect.Metadata);
                                MediaItemAspect mediaAspect = MediaItemAspect.GetOrCreateAspect(extractedAspectData, MediaAspect.Metadata);

                                mediaAspect.SetAttribute(MediaAspect.ATTR_MIME_TYPE, "video/bluray"); // BluRay disc

                                string    bdmvDirectory = fsra.LocalFileSystemPath;
                                BDInfoExt bdinfo        = new BDInfoExt(bdmvDirectory);
                                string    title         = bdinfo.GetTitle();
                                mediaAspect.SetAttribute(MediaAspect.ATTR_TITLE, title ?? mediaItemAccessor.ResourceName);

                                // Check for BD disc thumbs
                                FileInfo thumbnail = bdinfo.GetBiggestThumb();
                                if (thumbnail != null)
                                {
                                    byte[] binary = new byte[thumbnail.Length];
                                    using (FileStream fileStream = new FileStream(thumbnail.FullName, FileMode.Open, FileAccess.Read))
                                        using (BinaryReader binaryReader = new BinaryReader(fileStream))
                                            binaryReader.Read(binary, 0, binary.Length);

                                    MediaItemAspect.SetAttribute(extractedAspectData, ThumbnailLargeAspect.ATTR_THUMBNAIL, binary);
                                }
                                return(true);
                            }
                        }
                }
                catch
                {
                    ra.Dispose();
                    throw;
                }
                return(false);
            }
            catch
            {
                // Only log at the info level here - And simply return false. This makes the importer know that we
                // couldn't perform our task here
                if (mediaItemAccessor != null)
                {
                    ServiceRegistration.Get <ILogger>().Info("BluRayMetadataExtractor: Exception reading source '{0}'", mediaItemAccessor.ResourcePathName);
                }
                return(false);
            }
        }
        private IEnumerable <ResourcePath> GetCollectionFanart(string fanArtType, IFileSystemResourceAccessor directoryFsra)
        {
            var fanArtPaths = new List <ResourcePath>();

            if (directoryFsra != null)
            {
                var potentialFanArtFiles = LocalFanartHelper.GetPotentialFanArtFiles(directoryFsra);

                if (fanArtType == FanArtTypes.Poster || fanArtType == FanArtTypes.Thumbnail)
                {
                    fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByName(potentialFanArtFiles, LocalFanartHelper.THUMB_FILENAMES.Select(f => "movieset-" + f)));
                    fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByName(potentialFanArtFiles, LocalFanartHelper.POSTER_FILENAMES.Select(f => "movieset-" + f)));
                    fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByName(potentialFanArtFiles, LocalFanartHelper.THUMB_FILENAMES));
                    fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByName(potentialFanArtFiles, LocalFanartHelper.POSTER_FILENAMES));
                }

                if (fanArtType == FanArtTypes.Banner)
                {
                    fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByName(potentialFanArtFiles, LocalFanartHelper.BANNER_FILENAMES.Select(f => "movieset-" + f)));
                    fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByName(potentialFanArtFiles, LocalFanartHelper.BANNER_FILENAMES));
                }

                if (fanArtType == FanArtTypes.Logo)
                {
                    fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByName(potentialFanArtFiles, LocalFanartHelper.LOGO_FILENAMES.Select(f => "movieset-" + f)));
                    fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByName(potentialFanArtFiles, LocalFanartHelper.LOGO_FILENAMES));
                }

                if (fanArtType == FanArtTypes.ClearArt)
                {
                    fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByName(potentialFanArtFiles, LocalFanartHelper.CLEARART_FILENAMES.Select(f => "movieset-" + f)));
                    fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByName(potentialFanArtFiles, LocalFanartHelper.CLEARART_FILENAMES));
                }

                if (fanArtType == FanArtTypes.FanArt)
                {
                    fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByPrefix(potentialFanArtFiles, LocalFanartHelper.BACKDROP_FILENAMES.Select(f => "movieset-" + f)));
                    fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByPrefix(potentialFanArtFiles, LocalFanartHelper.BACKDROP_FILENAMES));

                    if (directoryFsra.ResourceExists("ExtraFanArt/"))
                    {
                        using (var extraFanArtDirectoryFsra = directoryFsra.GetResource("ExtraFanArt/"))
                            fanArtPaths.AddRange(LocalFanartHelper.GetPotentialFanArtFiles(extraFanArtDirectoryFsra));
                    }
                }
            }
            return(fanArtPaths);
        }
        /// <summary>
        /// Gets a <see cref="FanArtPathCollection"/> containing all matching series fanart paths in the specified <see cref="ResourcePath"/>.
        /// </summary>
        /// <param name="seriesDirectory"><see cref="IFileSystemResourceAccessor"/> that points to the series directory.</param>
        /// <returns><see cref="FanArtPathCollection"/> containing all matching paths.</returns>
        protected FanArtPathCollection GetSeriesFolderFanArt(IFileSystemResourceAccessor seriesDirectory)
        {
            FanArtPathCollection paths = new FanArtPathCollection();

            if (seriesDirectory != null)
            {
                List <ResourcePath> potentialFanArtFiles = LocalFanartHelper.GetPotentialFanArtFiles(seriesDirectory);
                ExtractAllFanArtImages(potentialFanArtFiles, paths);

                if (seriesDirectory.ResourceExists("ExtraFanArt/"))
                {
                    using (IFileSystemResourceAccessor extraFanArtDirectory = seriesDirectory.GetResource("ExtraFanArt/"))
                        paths.AddRange(FanArtTypes.FanArt, LocalFanartHelper.GetPotentialFanArtFiles(extraFanArtDirectory));
                }
            }

            return(paths);
        }
Beispiel #7
0
        public bool IsDirectorySingleResource(IResourceAccessor mediaItemAccessor)
        {
            IFileSystemResourceAccessor fsra = mediaItemAccessor as IFileSystemResourceAccessor;

            if (fsra == null)
            {
                return(false);
            }

            if (!fsra.IsFile && fsra.ResourceExists("BDMV"))
            {
                using (IFileSystemResourceAccessor fsraBDMV = fsra.GetResource("BDMV"))
                {
                    if (fsraBDMV != null && fsraBDMV.ResourceExists("index.bdmv"))
                    {
                        // Video Blu-ray
                        return(true);
                    }
                }
            }
            return(false);
        }
Beispiel #8
0
        /// <summary>
        /// Gets a <see cref="FanArtPathCollection"/> containing all matching fanart paths in the specified <see cref="ResourcePath"/>.
        /// </summary>
        /// <param name="artistDirectory"><see cref="IFileSystemResourceAccessor"/> that points to the artist directory.</param>
        /// <returns><see cref="FanArtPathCollection"/> containing all matching paths.</returns>
        protected FanArtPathCollection GetArtistFolderFanArt(IFileSystemResourceAccessor artistDirectory)
        {
            FanArtPathCollection paths = new FanArtPathCollection();

            if (artistDirectory == null)
            {
                return(paths);
            }

            //Get all fanart in the current directory
            List <ResourcePath> potentialFanArtFiles = LocalFanartHelper.GetPotentialFanArtFiles(artistDirectory);

            ExtractAllFanArtImages(potentialFanArtFiles, paths);

            //Add extra backdrops in ExtraFanArt directory
            if (artistDirectory.ResourceExists("ExtraFanArt/"))
            {
                using (IFileSystemResourceAccessor extraFanArtDirectory = artistDirectory.GetResource("ExtraFanArt/"))
                    paths.AddRange(FanArtTypes.FanArt, LocalFanartHelper.GetPotentialFanArtFiles(extraFanArtDirectory));
            }

            return(paths);
        }
        /// <summary>
        /// Gets a <see cref="FanArtPathCollection"/> containing all matching fanart paths in the specified <see cref="ResourcePath"/>.
        /// </summary>
        /// <param name="videoDirectory"><see cref="IFileSystemResourceAccessor"/> that points to the episode directory.</param>
        /// <param name="filename">The file name of the media item to extract images for.</param>
        /// <returns><see cref="FanArtPathCollection"/> containing all matching paths.</returns>
        protected FanArtPathCollection GetFolderFanArt(IFileSystemResourceAccessor videoDirectory, string filename, IDictionary <Guid, IList <MediaItemAspect> > aspects)
        {
            FanArtPathCollection paths = new FanArtPathCollection();

            if (videoDirectory == null)
            {
                return(paths);
            }

            //Get all fanart in the current directory
            List <ResourcePath> potentialFanArtFiles = LocalFanartHelper.GetPotentialFanArtFiles(videoDirectory);

            ExtractAllFanArtImages(potentialFanArtFiles, paths, filename);

            //Add extra backdrops in ExtraFanArt directory
            if (videoDirectory.ResourceExists("ExtraFanArt/"))
            {
                using (IFileSystemResourceAccessor extraFanArtDirectory = videoDirectory.GetResource("ExtraFanArt/"))
                    paths.AddRange(FanArtTypes.FanArt, LocalFanartHelper.GetPotentialFanArtFiles(extraFanArtDirectory));
            }

            return(paths);
        }
Beispiel #10
0
        public bool TryExtractMetadata(IResourceAccessor mediaItemAccessor, IDictionary <Guid, IList <MediaItemAspect> > extractedAspectData, bool importOnly, bool forceQuickMode)
        {
            try
            {
                if (!(mediaItemAccessor is IFileSystemResourceAccessor))
                {
                    return(false);
                }

                if (extractedAspectData.ContainsKey(VideoAspect.ASPECT_ID))
                {
                    return(false);
                }

                using (LocalFsResourceAccessorHelper rah = new LocalFsResourceAccessorHelper(mediaItemAccessor))
                {
                    if (!rah.LocalFsResourceAccessor.IsFile && rah.LocalFsResourceAccessor.ResourceExists("BDMV"))
                    {
                        using (IFileSystemResourceAccessor fsraBDMV = rah.LocalFsResourceAccessor.GetResource("BDMV"))
                            if (fsraBDMV != null && fsraBDMV.ResourceExists("index.bdmv"))
                            {
                                MultipleMediaItemAspect providerResourceAspect = MediaItemAspect.CreateAspect(extractedAspectData, ProviderResourceAspect.Metadata);
                                // Calling EnsureLocalFileSystemAccess not necessary; only string operation
                                providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_RESOURCE_INDEX, 0);
                                providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_PRIMARY, true);
                                providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_MIME_TYPE, "video/bluray"); // BluRay disc
                                providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH, mediaItemAccessor.CanonicalLocalResourcePath.Serialize());

                                // This line is important to keep in, if no VideoAspect is created here, the MediaItems is not detected as Video!
                                SingleMediaItemAspect videoAspect = MediaItemAspect.GetOrCreateAspect(extractedAspectData, VideoAspect.Metadata);
                                videoAspect.SetAttribute(VideoAspect.ATTR_ISDVD, true);

                                MultipleMediaItemAspect videoStreamAspect = MediaItemAspect.CreateAspect(extractedAspectData, VideoStreamAspect.Metadata);
                                videoStreamAspect.SetAttribute(VideoStreamAspect.ATTR_RESOURCE_INDEX, 0);
                                videoStreamAspect.SetAttribute(VideoStreamAspect.ATTR_STREAM_INDEX, -1);

                                MediaItemAspect mediaAspect = MediaItemAspect.GetOrCreateAspect(extractedAspectData, MediaAspect.Metadata);
                                mediaAspect.SetAttribute(MediaAspect.ATTR_ISVIRTUAL, false);

                                using (rah.LocalFsResourceAccessor.EnsureLocalFileSystemAccess())
                                {
                                    BDInfoExt bdinfo = new BDInfoExt(rah.LocalFsResourceAccessor.LocalFileSystemPath);
                                    string    title  = bdinfo.GetTitle();
                                    mediaAspect.SetAttribute(MediaAspect.ATTR_TITLE, title ?? mediaItemAccessor.ResourceName);

                                    // Check for BD disc thumbs
                                    FileInfo thumbnail = bdinfo.GetBiggestThumb();
                                    if (thumbnail != null)
                                    {
                                        try
                                        {
                                            using (FileStream fileStream = new FileStream(thumbnail.FullName, FileMode.Open, FileAccess.Read))
                                                using (MemoryStream resized = (MemoryStream)ImageUtilities.ResizeImage(fileStream, ImageFormat.Jpeg, MAX_COVER_WIDTH, MAX_COVER_HEIGHT))
                                                {
                                                    MediaItemAspect.SetAttribute(extractedAspectData, ThumbnailLargeAspect.ATTR_THUMBNAIL, resized.ToArray());
                                                }
                                        }
                                        // Decoding of invalid image data can fail, but main MediaItem is correct.
                                        catch
                                        {
                                        }
                                    }
                                }
                                return(true);
                            }
                    }
                }
                return(false);
            }
            catch
            {
                // Only log at the info level here - And simply return false. This makes the importer know that we
                // couldn't perform our task here
                if (mediaItemAccessor != null)
                {
                    ServiceRegistration.Get <ILogger>().Info("BluRayMetadataExtractor: Exception reading source '{0}'", mediaItemAccessor.ResourcePathName);
                }
                return(false);
            }
        }
        public bool TryExtractMetadata(IResourceAccessor mediaItemAccessor, IDictionary <Guid, MediaItemAspect> extractedAspectData, bool forceQuickMode)
        {
            try
            {
                VideoResult result = null;
                IFileSystemResourceAccessor fsra = mediaItemAccessor as IFileSystemResourceAccessor;
                if (fsra != null && fsra.IsDirectory && fsra.ResourceExists("VIDEO_TS"))
                {
                    IFileSystemResourceAccessor fsraVideoTs = fsra.GetResource("VIDEO_TS");
                    if (fsraVideoTs != null && fsraVideoTs.ResourceExists("VIDEO_TS.IFO"))
                    {
                        // Video DVD
                        using (MediaInfoWrapper videoTsInfo = ReadMediaInfo(fsraVideoTs.GetResource("VIDEO_TS.IFO")))
                        {
                            if (!videoTsInfo.IsValid || videoTsInfo.GetVideoCount() == 0)
                            {
                                return(false); // Invalid video_ts.ifo file
                            }
                            result = VideoResult.CreateDVDInfo(fsra.ResourceName, videoTsInfo);
                        }
                        // Iterate over all video files; MediaInfo finds different audio/video metadata for each .ifo file
                        ICollection <IFileSystemResourceAccessor> files = fsraVideoTs.GetFiles();
                        if (files != null)
                        {
                            foreach (IFileSystemResourceAccessor file in files)
                            {
                                string lowerPath = (file.ResourcePathName ?? string.Empty).ToLowerInvariant();
                                if (!lowerPath.EndsWith(".ifo") || lowerPath.EndsWith("video_ts.ifo"))
                                {
                                    continue;
                                }
                                using (MediaInfoWrapper mediaInfo = ReadMediaInfo(file))
                                {
                                    // Before we start evaluating the file, check if it is a video at all
                                    if (mediaInfo.IsValid && mediaInfo.GetVideoCount() == 0)
                                    {
                                        continue;
                                    }
                                    result.AddMediaInfo(mediaInfo);
                                }
                            }
                        }
                    }
                }
                else if (mediaItemAccessor.IsFile)
                {
                    string filePath = mediaItemAccessor.ResourcePathName;
                    if (!HasVideoExtension(filePath))
                    {
                        return(false);
                    }
                    using (MediaInfoWrapper fileInfo = ReadMediaInfo(mediaItemAccessor))
                    {
                        // Before we start evaluating the file, check if it is a video at all
                        if (!fileInfo.IsValid || (fileInfo.GetVideoCount() == 0 && !IsWorkaroundRequired(filePath)))
                        {
                            return(false);
                        }

                        string mediaTitle = DosPathHelper.GetFileNameWithoutExtension(mediaItemAccessor.ResourceName);
                        result = VideoResult.CreateFileInfo(mediaTitle, fileInfo);
                    }
                    using (Stream stream = mediaItemAccessor.OpenRead())
                        result.MimeType = MimeTypeDetector.GetMimeType(stream);
                }
                if (result != null)
                {
                    result.UpdateMetadata(extractedAspectData);

                    ILocalFsResourceAccessor disposeLfsra = null;
                    try
                    {
                        ILocalFsResourceAccessor lfsra = mediaItemAccessor as ILocalFsResourceAccessor;
                        if (lfsra == null && !forceQuickMode)
                        { // In case forceQuickMode, we only want local browsing
                            IResourceAccessor ra = mediaItemAccessor.Clone();
                            try
                            {
                                lfsra        = StreamedResourceToLocalFsAccessBridge.GetLocalFsResourceAccessor(ra);
                                disposeLfsra = lfsra; // Remember to dispose the extra resource accessor instance
                            }
                            catch (Exception)
                            {
                                ra.Dispose();
                            }
                        }
                        if (lfsra != null)
                        {
                            string localFsPath = lfsra.LocalFileSystemPath;
                            ExtractMatroskaTags(localFsPath, extractedAspectData, forceQuickMode);
                            ExtractThumbnailData(localFsPath, extractedAspectData, forceQuickMode);
                        }
                    }
                    finally
                    {
                        if (disposeLfsra != null)
                        {
                            disposeLfsra.Dispose();
                        }
                    }
                    return(true);
                }
            }
            catch (Exception e)
            {
                // Only log at the info level here - And simply return false. This lets the caller know that we
                // couldn't perform our task here.
                ServiceRegistration.Get <ILogger>().Info("VideoMetadataExtractor: Exception reading resource '{0}' (Text: '{1}')", mediaItemAccessor.CanonicalLocalResourcePath, e.Message);
            }
            return(false);
        }
Beispiel #12
0
        public bool TryExtractMetadata(IResourceAccessor mediaItemAccessor, IDictionary <Guid, MediaItemAspect> extractedAspectData, bool forceQuickMode)
        {
            try
            {
                VideoResult result = null;
                IFileSystemResourceAccessor fsra = mediaItemAccessor as IFileSystemResourceAccessor;
                if (fsra == null)
                {
                    return(false);
                }
                if (!fsra.IsFile && fsra.ResourceExists("VIDEO_TS"))
                {
                    IFileSystemResourceAccessor fsraVideoTs = fsra.GetResource("VIDEO_TS");
                    if (fsraVideoTs != null && fsraVideoTs.ResourceExists("VIDEO_TS.IFO"))
                    {
                        // Video DVD
                        using (MediaInfoWrapper videoTsInfo = ReadMediaInfo(fsraVideoTs.GetResource("VIDEO_TS.IFO")))
                        {
                            if (!videoTsInfo.IsValid || videoTsInfo.GetVideoCount() == 0)
                            {
                                return(false); // Invalid video_ts.ifo file
                            }
                            result = VideoResult.CreateDVDInfo(fsra.ResourceName, videoTsInfo);
                        }
                        // Iterate over all video files; MediaInfo finds different audio/video metadata for each .ifo file
                        ICollection <IFileSystemResourceAccessor> files = fsraVideoTs.GetFiles();
                        if (files != null)
                        {
                            foreach (IFileSystemResourceAccessor file in files)
                            {
                                string lowerPath = (file.ResourcePathName ?? string.Empty).ToLowerInvariant();
                                if (!lowerPath.EndsWith(".ifo") || lowerPath.EndsWith("video_ts.ifo"))
                                {
                                    continue;
                                }
                                using (MediaInfoWrapper mediaInfo = ReadMediaInfo(file))
                                {
                                    // Before we start evaluating the file, check if it is a video at all
                                    if (mediaInfo.IsValid && mediaInfo.GetVideoCount() == 0)
                                    {
                                        continue;
                                    }
                                    result.AddMediaInfo(mediaInfo);
                                }
                            }
                        }
                    }
                }
                else if (fsra.IsFile)
                {
                    string filePath = fsra.ResourcePathName;
                    if (!HasVideoExtension(filePath))
                    {
                        return(false);
                    }
                    using (MediaInfoWrapper fileInfo = ReadMediaInfo(fsra))
                    {
                        // Before we start evaluating the file, check if it is a video at all
                        if (!fileInfo.IsValid || (fileInfo.GetVideoCount() == 0 && !IsWorkaroundRequired(filePath)))
                        {
                            return(false);
                        }

                        string mediaTitle = DosPathHelper.GetFileNameWithoutExtension(fsra.ResourceName);
                        result = VideoResult.CreateFileInfo(mediaTitle, fileInfo);
                    }
                    using (Stream stream = fsra.OpenRead())
                        result.MimeType = MimeTypeDetector.GetMimeType(stream, DEFAULT_MIMETYPE);
                }
                if (result != null)
                {
                    result.UpdateMetadata(extractedAspectData);

                    using (LocalFsResourceAccessorHelper rah = new LocalFsResourceAccessorHelper(mediaItemAccessor))
                    {
                        ILocalFsResourceAccessor lfsra = rah.LocalFsResourceAccessor;
                        if (lfsra != null)
                        {
                            MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_SIZE, lfsra.Size);
                            MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_RECORDINGTIME, lfsra.LastChanged);
                            ExtractMatroskaTags(lfsra, extractedAspectData, forceQuickMode);
                            ExtractMp4Tags(lfsra, extractedAspectData, forceQuickMode);
                            ExtractThumbnailData(lfsra, extractedAspectData, forceQuickMode);
                        }
                        return(true);
                    }
                }
            }
            catch (Exception e)
            {
                // Only log at the info level here - And simply return false. This lets the caller know that we
                // couldn't perform our task here.
                ServiceRegistration.Get <ILogger>().Info("VideoMetadataExtractor: Exception reading resource '{0}' (Text: '{1}')", mediaItemAccessor.CanonicalLocalResourcePath, e.Message);
            }
            return(false);
        }
        public async Task <MetadataContainer> ParseMediaItemAsync(MediaItem media, int?editionId = null, bool cache = true)
        {
            try
            {
                if (media.IsStub)
                {
                    return(null);
                }

                string            category = null;
                MetadataContainer info     = null;

                //Check for live items
                if (media.Aspects.ContainsKey(AudioAspect.ASPECT_ID))
                {
                    category = AUDIO_CATEGORY;
                    if (media.IsLiveRadioItem() && media is LiveTvMediaItem ltmi)
                    {
                        info = await ParseSlimTvItemAsync(ltmi).ConfigureAwait(false);

                        if (info != null)
                        {
                            info.Metadata[Editions.DEFAULT_EDITION].Live = true;
                            info.Metadata[Editions.DEFAULT_EDITION].Size = 0;
                        }
                        return(info);
                    }
                }
                else if (media.Aspects.ContainsKey(VideoAspect.ASPECT_ID))
                {
                    category = VIDEO_CATEGORY;
                    if (media.IsLiveTvItem() && media is LiveTvMediaItem ltmi)
                    {
                        info = await ParseSlimTvItemAsync(ltmi).ConfigureAwait(false);

                        if (info != null)
                        {
                            info.Metadata[Editions.DEFAULT_EDITION].Live = true;
                            info.Metadata[Editions.DEFAULT_EDITION].Size = 0;
                        }
                        return(info);
                    }
                }
                else if (media.Aspects.ContainsKey(ImageAspect.ASPECT_ID))
                {
                    category = IMAGE_CATEGORY;
                }

                info = await LoadAnalysisAsync(media, category, media.MediaItemId);

                if (info != null)
                {
                    return(info);
                }

                IList <MultipleMediaItemAspect> providerAspects;
                if (!MediaItemAspect.TryGetAspects(media.Aspects, ProviderResourceAspect.Metadata, out providerAspects))
                {
                    return(null);
                }

                IDictionary <int, ResourceLocator> resources = null;
                if (media.HasEditions)
                {
                    IEnumerable <int> praIdxs = null;
                    if (editionId.HasValue)
                    {
                        praIdxs = media.Editions.First(e => e.Key == editionId.Value).Value.PrimaryResourceIndexes;
                    }
                    else
                    {
                        praIdxs = media.Editions.SelectMany(e => e.Value.PrimaryResourceIndexes).Distinct();
                    }

                    resources = providerAspects.Where(pra => praIdxs.Contains(pra.GetAttributeValue <int>(ProviderResourceAspect.ATTR_RESOURCE_INDEX))).
                                ToDictionary(pra => pra.GetAttributeValue <int>(ProviderResourceAspect.ATTR_RESOURCE_INDEX), pra => new ResourceLocator(pra.GetAttributeValue <string>(ProviderResourceAspect.ATTR_SYSTEM_ID), ResourcePath.Deserialize(pra.GetAttributeValue <string>(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH))));
                }
                else
                {
                    resources = providerAspects.Where(pra => pra.GetAttributeValue <int>(ProviderResourceAspect.ATTR_TYPE) == ProviderResourceAspect.TYPE_PRIMARY).
                                ToDictionary(pra => pra.GetAttributeValue <int>(ProviderResourceAspect.ATTR_RESOURCE_INDEX), pra => new ResourceLocator(pra.GetAttributeValue <string>(ProviderResourceAspect.ATTR_SYSTEM_ID), ResourcePath.Deserialize(pra.GetAttributeValue <string>(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH))));
                }

                //Process media resources
                Dictionary <int, Dictionary <int, IResourceAccessor> > editions = new Dictionary <int, Dictionary <int, IResourceAccessor> >();
                foreach (var res in resources)
                {
                    int edition = Editions.DEFAULT_EDITION;
                    if (media.HasEditions)
                    {
                        edition = media.Editions.FirstOrDefault(e => e.Value.PrimaryResourceIndexes.Contains(res.Key)).Value.SetNo;
                    }

                    if (!editions.ContainsKey(edition))
                    {
                        editions.Add(edition, new Dictionary <int, IResourceAccessor>());
                    }
                    IResourceAccessor mia = res.Value.CreateAccessor();

                    if (mia is IFileSystemResourceAccessor fileRes && !fileRes.IsFile)
                    {
                        if (fileRes.ResourceExists("VIDEO_TS"))
                        {
                            using (IFileSystemResourceAccessor fsraVideoTs = fileRes.GetResource("VIDEO_TS"))
                            {
                                if (fsraVideoTs != null && fsraVideoTs.ResourceExists("VIDEO_TS.IFO"))
                                {
                                    //Find all titles and add each of them
                                    var titles = GetDvdTitleFiles(fsraVideoTs);
                                    foreach (var title in titles)
                                    {
                                        int fileNo = 0;
                                        foreach (var file in title.Value)
                                        {
                                            fileNo++;
                                            int titleKey = MetadataContainer.GetDvdResource(res.Key, title.Key, fileNo);
                                            editions[edition].Add(titleKey, file);
                                        }
                                    }
                                }
                            }
                        }
                        else if (fileRes.ResourceExists("BDMV"))
                        {
                            using (IFileSystemResourceAccessor fsraBDMV = fileRes.GetResource("BDMV"))
                            {
                                if (fsraBDMV != null && fsraBDMV.ResourceExists("index.bdmv") && fsraBDMV.ResourceExists("STREAM"))
                                {
                                    using (IFileSystemResourceAccessor fsraStream = fsraBDMV.GetResource("STREAM"))
                                    {
                                        var orderedFileList = fsraStream.GetFiles().Where(f => f.ResourceName.EndsWith(".m2ts", StringComparison.InvariantCultureIgnoreCase)).OrderByDescending(f => f.Size);
                                        //Use the largest file which is probably the main stream
                                        var mainStream = orderedFileList.First();
                                        editions[edition].Add(res.Key, mainStream);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        editions[edition].Add(res.Key, mia);
                    }
                    mia.Dispose();
                }