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); } }
protected static void AddToCache(ResourcePath path, IResourceAccessor ra) { lock (_cachedResourceAccessors.SyncObj) { if (!_cachedResourceAccessors.Contains(path)) { _cachedResourceAccessors.Add(path, ra.Clone()); } } }
protected static bool TryGetCloneFromCache(ResourcePath path, out IResourceAccessor ra) { lock (_cachedResourceAccessors.SyncObj) if (_cachedResourceAccessors.TryGetValue(path, out ra)) { _cachedResourceAccessors.Touch(path); ra = ra.Clone(); return(true); } return(false); }
protected static void AddToCache(ResourcePath path, IResourceAccessor ra) { if (ra is IUncachableResource) { return; // not cacheable } lock (_cachedResourceAccessors.SyncObj) { if (!_cachedResourceAccessors.Contains(path)) { _cachedResourceAccessors.Add(path, ra.Clone()); } } }
/// <summary> /// Creates a new <see cref="LocalFsResourceAccessor"/> instance. The given <paramref name="mediaItemAccessor"/> will be either directly used or /// given over to the <see cref="StreamedResourceToLocalFsAccessBridge"/>. The caller must call <see cref="Dispose"/> on the created <see cref="LocalFsResourceAccessorHelper"/> /// instance but must not dispose the given <paramref name="mediaItemAccessor"/>. /// </summary> /// <param name="mediaItemAccessor">IResourceAccessor.</param> public LocalFsResourceAccessorHelper(IResourceAccessor mediaItemAccessor) { _localFsra = mediaItemAccessor as ILocalFsResourceAccessor; _disposeLfsra = null; if (_localFsra != null) return; IFileSystemResourceAccessor localFsra = (IFileSystemResourceAccessor) mediaItemAccessor.Clone(); try { _localFsra = StreamedResourceToLocalFsAccessBridge.GetLocalFsResourceAccessor(localFsra); _disposeLfsra = _localFsra; } catch (Exception) { localFsra.Dispose(); throw; } }
public bool TryExtractMetadata(IResourceAccessor mediaItemAccessor, IDictionary <Guid, MediaItemAspect> extractedAspectData, bool forceQuickMode) { try { if (forceQuickMode) { return(false); } using (IResourceAccessor ra = mediaItemAccessor.Clone()) using (ILocalFsResourceAccessor lfsra = StreamedResourceToLocalFsAccessBridge.GetLocalFsResourceAccessor(ra)) return(ExtractMovieData(lfsra, extractedAspectData)); } 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("MoviesMetadataExtractor: Exception reading resource '{0}' (Text: '{1}')", mediaItemAccessor.CanonicalLocalResourcePath, e.Message); } return(false); }
/// <summary> /// Creates a new <see cref="LocalFsResourceAccessor"/> instance. The given <paramref name="mediaItemAccessor"/> will be either directly used or /// given over to the <see cref="StreamedResourceToLocalFsAccessBridge"/>. The caller must call <see cref="Dispose"/> on the created <see cref="LocalFsResourceAccessorHelper"/> /// instance but must not dispose the given <paramref name="mediaItemAccessor"/>. /// </summary> /// <param name="mediaItemAccessor">IResourceAccessor.</param> public LocalFsResourceAccessorHelper(IResourceAccessor mediaItemAccessor) { _localFsra = mediaItemAccessor as ILocalFsResourceAccessor; _disposeLfsra = null; if (_localFsra != null) { return; } IFileSystemResourceAccessor localFsra = (IFileSystemResourceAccessor)mediaItemAccessor.Clone(); try { _localFsra = StreamedResourceToLocalFsAccessBridge.GetLocalFsResourceAccessor(localFsra); _disposeLfsra = _localFsra; } catch (Exception) { localFsra.Dispose(); throw; } }
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")) { // BluRay MediaItemAspect mediaAspect; if (!extractedAspectData.TryGetValue(MediaAspect.ASPECT_ID, out mediaAspect)) extractedAspectData[MediaAspect.ASPECT_ID] = mediaAspect = new MediaItemAspect(MediaAspect.Metadata); MediaItemAspect videoAspect; if (!extractedAspectData.TryGetValue(VideoAspect.ASPECT_ID, out videoAspect)) extractedAspectData[VideoAspect.ASPECT_ID] = new MediaItemAspect(VideoAspect.Metadata); mediaAspect.SetAttribute(MediaAspect.ATTR_MIME_TYPE, "video/bluray"); // BluRay disc string bdmvDirectory = fsra.LocalFileSystemPath; BDInfoExt bdinfo = new BDInfoExt(bdmvDirectory); mediaAspect.SetAttribute(MediaAspect.ATTR_TITLE, bdinfo.GetTitle() ?? mediaItemAccessor.ResourceName); 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; } }
public bool TryExtractMetadata(IResourceAccessor mediaItemAccessor, IDictionary<Guid, MediaItemAspect> extractedAspectData, bool forceQuickMode) { try { if (forceQuickMode) return false; if (!(mediaItemAccessor is IFileSystemResourceAccessor)) return false; using (IFileSystemResourceAccessor fsra = (IFileSystemResourceAccessor) mediaItemAccessor.Clone()) using (ILocalFsResourceAccessor lfsra = StreamedResourceToLocalFsAccessBridge.GetLocalFsResourceAccessor(fsra)) { string localFsPath = lfsra.LocalFileSystemPath; return ExtractSeriesData(localFsPath, extractedAspectData); } } 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("SeriesMetadataExtractor: Exception reading resource '{0}' (Text: '{1}')", mediaItemAccessor.CanonicalLocalResourcePath, e.Message); } 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); }
/// <summary> /// Returns all child directories of the given directory. /// </summary> /// <remarks> /// This will return all native child directories of the given directory together with all virtual child /// directories. The native child directories are taken directly from the given <paramref name="directoryAccessor"/>, /// the virtual child directories are obtained by taking the root directories of each chained resource provider applied /// to the child files of the given directory. /// If, for example, the given <paramref name="directoryAccessor"/> contains a child directory "A" and a child /// archive file "B" which can work as input for an installed archive provider, providing the root directory "C" /// of that archive, this method will return the resource accessors for directories "A" and "C". /// </remarks> /// <param name="directoryAccessor">Directory resource accessor to get all child directories for.</param> /// <param name="showSystemResources">If set to <c>true</c>, system resources like the virtual drives and directories of the /// <see cref="IResourceMountingService"/> will also be returned, else removed from the result value.</param> /// <returns>Collection of directory accessors for all native and virtual child directories or <c>null</c>, /// if the given <paramref name="directoryAccessor"/> is not a <see cref="IFileSystemResourceAccessor"/> and /// if there is no chained resource provider to unfold the given directory.</returns> public static ICollection<IFileSystemResourceAccessor> GetChildDirectories(IResourceAccessor directoryAccessor, bool showSystemResources) { IResourceMountingService resourceMountingService = ServiceRegistration.Get<IResourceMountingService>(); IResourceAccessor chainedResourceAccesor; // Needed in multiple source locations, that's why we declare it here if (directoryAccessor is IFileSystemResourceAccessor) { IFileSystemResourceAccessor dirFsra = (IFileSystemResourceAccessor) directoryAccessor; ICollection<IFileSystemResourceAccessor> childDirectories = dirFsra.GetChildDirectories(); ICollection<IFileSystemResourceAccessor> result = new List<IFileSystemResourceAccessor>(); if (childDirectories != null) // Directories are maybe filtered and then just added foreach (IFileSystemResourceAccessor childDirectoryAccessor in childDirectories) { if (!showSystemResources && resourceMountingService.IsVirtualResource(childDirectoryAccessor.CanonicalLocalResourcePath)) { childDirectoryAccessor.Dispose(); continue; } result.Add(childDirectoryAccessor); } ICollection<IFileSystemResourceAccessor> files = dirFsra.GetFiles(); if (files != null) // For files, we try to chain up chained resource providers foreach (IFileSystemResourceAccessor fileAccessor in files) { if (!showSystemResources && resourceMountingService.IsVirtualResource(fileAccessor.CanonicalLocalResourcePath)) { fileAccessor.Dispose(); continue; } if (TryUnfold(fileAccessor, out chainedResourceAccesor)) { IFileSystemResourceAccessor chainedFsra = chainedResourceAccesor as IFileSystemResourceAccessor; if (chainedFsra != null) result.Add(chainedFsra); else chainedResourceAccesor.Dispose(); } else fileAccessor.Dispose(); } return result; } // Try to unfold simple resource IResourceAccessor dra = directoryAccessor.Clone(); try { if (TryUnfold(dra, out chainedResourceAccesor)) { IFileSystemResourceAccessor chainedFsra = chainedResourceAccesor as IFileSystemResourceAccessor; if (chainedFsra != null) return new List<IFileSystemResourceAccessor>(new IFileSystemResourceAccessor[] {chainedFsra}); chainedResourceAccesor.Dispose(); } else dra.Dispose(); } catch { dra.Dispose(); throw; } return null; }
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; } }
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; }
public bool TryExtractMetadata(IResourceAccessor mediaItemAccessor, IDictionary<Guid, MediaItemAspect> extractedAspectData, bool forceQuickMode) { string fileName = mediaItemAccessor.ResourceName; if (!HasImageExtension(fileName)) return false; MediaItemAspect mediaAspect = MediaItemAspect.GetOrCreateAspect(extractedAspectData, MediaAspect.Metadata); MediaItemAspect imageAspect = MediaItemAspect.GetOrCreateAspect(extractedAspectData, ImageAspect.Metadata); MediaItemAspect thumbnailSmallAspect = MediaItemAspect.GetOrCreateAspect(extractedAspectData, ThumbnailSmallAspect.Metadata); MediaItemAspect thumbnailLargeAspect = MediaItemAspect.GetOrCreateAspect(extractedAspectData, ThumbnailLargeAspect.Metadata); try { // Open a stream for media item to detect mimeType. using (Stream mediaStream = mediaItemAccessor.OpenRead()) { string mimeType = MimeTypeDetector.GetMimeType(mediaStream); if (mimeType != null) mediaAspect.SetAttribute(MediaAspect.ATTR_MIME_TYPE, mimeType); } // Extract EXIF information from media item. using (ExifMetaInfo.ExifMetaInfo exif = new ExifMetaInfo.ExifMetaInfo(mediaItemAccessor)) { mediaAspect.SetAttribute(MediaAspect.ATTR_TITLE, ProviderPathHelper.GetFileNameWithoutExtension(fileName)); mediaAspect.SetAttribute(MediaAspect.ATTR_RECORDINGTIME, exif.OriginalDate != DateTime.MinValue ? exif.OriginalDate : mediaItemAccessor.LastChanged); mediaAspect.SetAttribute(MediaAspect.ATTR_COMMENT, StringUtils.TrimToNull(exif.ImageDescription)); imageAspect.SetAttribute(ImageAspect.ATTR_WIDTH, (int) exif.PixXDim); imageAspect.SetAttribute(ImageAspect.ATTR_HEIGHT, (int) exif.PixYDim); imageAspect.SetAttribute(ImageAspect.ATTR_MAKE, StringUtils.TrimToNull(exif.EquipMake)); imageAspect.SetAttribute(ImageAspect.ATTR_MODEL, StringUtils.TrimToNull(exif.EquipModel)); imageAspect.SetAttribute(ImageAspect.ATTR_EXPOSURE_BIAS, ((double) exif.ExposureBias).ToString()); imageAspect.SetAttribute(ImageAspect.ATTR_EXPOSURE_TIME, exif.ExposureTime.ToString()); imageAspect.SetAttribute(ImageAspect.ATTR_FLASH_MODE, StringUtils.TrimToNull(exif.FlashMode)); imageAspect.SetAttribute(ImageAspect.ATTR_FNUMBER, string.Format("F {0}", (double) exif.FNumber)); imageAspect.SetAttribute(ImageAspect.ATTR_ISO_SPEED, StringUtils.TrimToNull(exif.ISOSpeed)); imageAspect.SetAttribute(ImageAspect.ATTR_ORIENTATION, (Int32) exif.Orientation); imageAspect.SetAttribute(ImageAspect.ATTR_METERING_MODE, exif.MeteringMode.ToString()); IResourceAccessor ra = mediaItemAccessor.Clone(); ILocalFsResourceAccessor lfsra; try { lfsra = StreamedResourceToLocalFsAccessBridge.GetLocalFsResourceAccessor(ra); } catch { ra.Dispose(); throw; } using (lfsra) { string localFsResourcePath = lfsra.LocalFileSystemPath; if (localFsResourcePath != null) { // In quick mode only allow thumbs taken from cache. bool cachedOnly = forceQuickMode; // Thumbnail extraction IThumbnailGenerator generator = ServiceRegistration.Get<IThumbnailGenerator>(); byte[] thumbData; ImageType imageType; if (generator.GetThumbnail(localFsResourcePath, 96, 96, cachedOnly, out thumbData, out imageType)) thumbnailSmallAspect.SetAttribute(ThumbnailSmallAspect.ATTR_THUMBNAIL, thumbData); if (generator.GetThumbnail(localFsResourcePath, 256, 256, cachedOnly, out thumbData, out imageType)) thumbnailLargeAspect.SetAttribute(ThumbnailLargeAspect.ATTR_THUMBNAIL, thumbData); } } } return true; } catch (Exception e) { // Only log at the info level here - And simply return false. This makes the importer know that we // couldn't perform our task here. ServiceRegistration.Get<ILogger>().Info("ImageMetadataExtractor: Exception reading resource '{0}' (Text: '{1}')", mediaItemAccessor.CanonicalLocalResourcePath, e.Message); } return false; }
/// <summary> /// Returns all child directories of the given directory. /// </summary> /// <remarks> /// This will return all native child directories of the given directory together with all virtual child /// directories. The native child directories are taken directly from the given <paramref name="directoryAccessor"/>, /// the virtual child directories are obtained by taking the root directories of each chained resource provider applied /// to the child files of the given directory. /// If, for example, the given <paramref name="directoryAccessor"/> contains a child directory "A" and a child /// archive file "B" which can work as input for an installed archive provider, providing the root directory "C" /// of that archive, this method will return the resource accessors for directories "A" and "C". /// </remarks> /// <param name="directoryAccessor">Directory resource accessor to get all child directories for.</param> /// <param name="showSystemResources">If set to <c>true</c>, system resources like the virtual drives and directories of the /// <see cref="IResourceMountingService"/> will also be returned, else removed from the result value.</param> /// <returns>Collection of directory accessors for all native and virtual child directories or <c>null</c>, /// if the given <paramref name="directoryAccessor"/> is not a <see cref="IFileSystemResourceAccessor"/> and /// if there is no chained resource provider to unfold the given directory.</returns> public static ICollection <IFileSystemResourceAccessor> GetChildDirectories(IResourceAccessor directoryAccessor, bool showSystemResources) { IResourceMountingService resourceMountingService = ServiceRegistration.Get <IResourceMountingService>(); IResourceAccessor chainedResourceAccesor; // Needed in multiple source locations, that's why we declare it here if (directoryAccessor is IFileSystemResourceAccessor) { IFileSystemResourceAccessor dirFsra = (IFileSystemResourceAccessor)directoryAccessor; ICollection <IFileSystemResourceAccessor> childDirectories = dirFsra.GetChildDirectories(); ICollection <IFileSystemResourceAccessor> result = new List <IFileSystemResourceAccessor>(); if (childDirectories != null) { // Directories are maybe filtered and then just added foreach (IFileSystemResourceAccessor childDirectoryAccessor in childDirectories) { if (!showSystemResources && resourceMountingService.IsVirtualResource(childDirectoryAccessor.CanonicalLocalResourcePath)) { childDirectoryAccessor.Dispose(); continue; } result.Add(childDirectoryAccessor); } } ICollection <IFileSystemResourceAccessor> files = dirFsra.GetFiles(); if (files != null) { // For files, we try to chain up chained resource providers foreach (IFileSystemResourceAccessor fileAccessor in files) { if (!showSystemResources && resourceMountingService.IsVirtualResource(fileAccessor.CanonicalLocalResourcePath)) { fileAccessor.Dispose(); continue; } if (TryUnfold(fileAccessor, out chainedResourceAccesor)) { IFileSystemResourceAccessor chainedFsra = chainedResourceAccesor as IFileSystemResourceAccessor; if (chainedFsra != null) { result.Add(chainedFsra); } else { chainedResourceAccesor.Dispose(); } } else { fileAccessor.Dispose(); } } } return(result); } // Try to unfold simple resource IResourceAccessor dra = directoryAccessor.Clone(); try { if (TryUnfold(dra, out chainedResourceAccesor)) { IFileSystemResourceAccessor chainedFsra = chainedResourceAccesor as IFileSystemResourceAccessor; if (chainedFsra != null) { return(new List <IFileSystemResourceAccessor>(new IFileSystemResourceAccessor[] { chainedFsra })); } chainedResourceAccesor.Dispose(); } else { dra.Dispose(); } } catch { dra.Dispose(); throw; } return(null); }
public bool TryExtractMetadata(IResourceAccessor mediaItemAccessor, IDictionary <Guid, MediaItemAspect> extractedAspectData, bool forceQuickMode) { string fileName = mediaItemAccessor.ResourceName; if (!HasImageExtension(fileName)) { return(false); } MediaItemAspect mediaAspect = MediaItemAspect.GetOrCreateAspect(extractedAspectData, MediaAspect.Metadata); MediaItemAspect imageAspect = MediaItemAspect.GetOrCreateAspect(extractedAspectData, ImageAspect.Metadata); MediaItemAspect thumbnailSmallAspect = MediaItemAspect.GetOrCreateAspect(extractedAspectData, ThumbnailSmallAspect.Metadata); MediaItemAspect thumbnailLargeAspect = MediaItemAspect.GetOrCreateAspect(extractedAspectData, ThumbnailLargeAspect.Metadata); try { // Open a stream for media item to detect mimeType. using (Stream mediaStream = mediaItemAccessor.OpenRead()) { string mimeType = MimeTypeDetector.GetMimeType(mediaStream); if (mimeType != null) { mediaAspect.SetAttribute(MediaAspect.ATTR_MIME_TYPE, mimeType); } } // Extract EXIF information from media item. using (ExifMetaInfo.ExifMetaInfo exif = new ExifMetaInfo.ExifMetaInfo(mediaItemAccessor)) { mediaAspect.SetAttribute(MediaAspect.ATTR_TITLE, ProviderPathHelper.GetFileNameWithoutExtension(fileName)); mediaAspect.SetAttribute(MediaAspect.ATTR_RECORDINGTIME, exif.OriginalDate != DateTime.MinValue ? exif.OriginalDate : mediaItemAccessor.LastChanged); mediaAspect.SetAttribute(MediaAspect.ATTR_COMMENT, StringUtils.TrimToNull(exif.ImageDescription)); imageAspect.SetAttribute(ImageAspect.ATTR_WIDTH, (int)exif.PixXDim); imageAspect.SetAttribute(ImageAspect.ATTR_HEIGHT, (int)exif.PixYDim); imageAspect.SetAttribute(ImageAspect.ATTR_MAKE, StringUtils.TrimToNull(exif.EquipMake)); imageAspect.SetAttribute(ImageAspect.ATTR_MODEL, StringUtils.TrimToNull(exif.EquipModel)); imageAspect.SetAttribute(ImageAspect.ATTR_EXPOSURE_BIAS, ((double)exif.ExposureBias).ToString()); imageAspect.SetAttribute(ImageAspect.ATTR_EXPOSURE_TIME, exif.ExposureTime.ToString()); imageAspect.SetAttribute(ImageAspect.ATTR_FLASH_MODE, StringUtils.TrimToNull(exif.FlashMode)); imageAspect.SetAttribute(ImageAspect.ATTR_FNUMBER, string.Format("F {0}", (double)exif.FNumber)); imageAspect.SetAttribute(ImageAspect.ATTR_ISO_SPEED, StringUtils.TrimToNull(exif.ISOSpeed)); imageAspect.SetAttribute(ImageAspect.ATTR_ORIENTATION, (Int32)exif.Orientation); imageAspect.SetAttribute(ImageAspect.ATTR_METERING_MODE, exif.MeteringMode.ToString()); IResourceAccessor ra = mediaItemAccessor.Clone(); ILocalFsResourceAccessor lfsra; try { lfsra = StreamedResourceToLocalFsAccessBridge.GetLocalFsResourceAccessor(ra); } catch { ra.Dispose(); throw; } using (lfsra) { string localFsResourcePath = lfsra.LocalFileSystemPath; if (localFsResourcePath != null) { // In quick mode only allow thumbs taken from cache. bool cachedOnly = forceQuickMode; // Thumbnail extraction IThumbnailGenerator generator = ServiceRegistration.Get <IThumbnailGenerator>(); byte[] thumbData; ImageType imageType; if (generator.GetThumbnail(localFsResourcePath, 96, 96, cachedOnly, out thumbData, out imageType)) { thumbnailSmallAspect.SetAttribute(ThumbnailSmallAspect.ATTR_THUMBNAIL, thumbData); } if (generator.GetThumbnail(localFsResourcePath, 256, 256, cachedOnly, out thumbData, out imageType)) { thumbnailLargeAspect.SetAttribute(ThumbnailLargeAspect.ATTR_THUMBNAIL, thumbData); } } } } return(true); } catch (Exception e) { // Only log at the info level here - And simply return false. This makes the importer know that we // couldn't perform our task here. ServiceRegistration.Get <ILogger>().Info("ImageMetadataExtractor: Exception reading resource '{0}' (Text: '{1}')", mediaItemAccessor.CanonicalLocalResourcePath, e.Message); } return(false); }