public bool IsResource(IFileSystemResourceAccessor baseResourceAccessor, string path)
        {
            string entryPath = ZipResourceAccessor.ToEntryPath(path);

            lock (_syncObj)
            {
                string key = baseResourceAccessor.CanonicalLocalResourcePath.Serialize();
                try
                {
                    ZipResourceProxy proxy;
                    if (_zipUsages.TryGetValue(key, out proxy))
                    {
                        return(path.Equals("/") || ZipResourceAccessor.IsResource(proxy.ZipFile, entryPath));
                    }
                }
                catch (Exception)
                {
                    return(false);
                }
            }

            using (Stream resourceStream = baseResourceAccessor.OpenRead()) // Not sure if the ZipFile will close the stream so we dispose it here
                try
                {
                    using (ZipFile zFile = new ZipFile(resourceStream))
                        return(path.Equals("/") || ZipResourceAccessor.IsResource(zFile, entryPath));
                }
                catch (Exception)
                {
                    return(false);
                }
        }
예제 #2
0
        /// <summary>
        /// Sets the data of the new image to be played.
        /// </summary>
        /// <param name="locator">Resource locator of the image item.</param>
        /// <param name="mediaItemTitle">Title of the image item.</param>
        /// <param name="rotation">Rotation of the image.</param>
        /// <param name="flipX">Flipping in horizontal direction.</param>
        /// <param name="flipY">Flipping in vertical direction.</param>
        public void SetMediaItemData(IResourceLocator locator, string mediaItemTitle, RightAngledRotation rotation, bool flipX, bool flipY)
        {
            if (locator == null)
            {
                lock (_syncObj)
                {
                    DisposeTexture();
                    _currentLocator = null;
                    return;
                }
            }

            Texture          texture;
            ImageInformation imageInformation;

            using (IResourceAccessor ra = locator.CreateAccessor())
            {
                IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor;
                if (fsra == null)
                {
                    return;
                }
                using (Stream stream = fsra.OpenRead())
                    using (Stream tmpImageStream = ImageUtilities.ResizeImage(stream, ImageFormat.MemoryBmp, MAX_TEXTURE_DIMENSION, MAX_TEXTURE_DIMENSION))
                        texture = Texture.FromStream(SkinContext.Device, tmpImageStream, (int)tmpImageStream.Length, 0, 0, 1, Usage.None,
                                                     Format.A8R8G8B8, Pool.Default, Filter.None, Filter.None, 0, out imageInformation);
            }
            lock (_syncObj)
            {
                ReloadSettings();
                _state = PlayerState.Active;

                DisposeTexture();
                _currentLocator = locator;
                _mediaItemTitle = mediaItemTitle;
                _texture        = texture;
                _rotation       = rotation;
                _flipX          = flipX;
                _flipY          = flipY;
                SurfaceDescription desc = _texture.GetLevelDescription(0);
                _textureMaxUV = new SizeF(imageInformation.Width / (float)desc.Width, imageInformation.Height / (float)desc.Height);

                // Reset animation
                _animator.Initialize();

                if (_slideShowTimer != null)
                {
                    _slideShowTimer.Change(_slideShowImageDuration, TS_INFINITE);
                }
                else
                {
                    CheckTimer();
                }
                _playbackStartTime = DateTime.Now;
                if (_pauseTime.HasValue)
                {
                    _pauseTime = _playbackStartTime;
                }
            }
        }
 /// <summary>
 /// Constructs a <see cref="ResourceAccessorTextureImageSource"/> for the given data.
 /// </summary>
 /// <param name="resourceAccessor">The resource accessor to load the texture data from.</param>
 /// <param name="rotation">Desired rotation for the given image.</param>
 public ResourceAccessorTextureImageSource(IFileSystemResourceAccessor resourceAccessor, RightAngledRotation rotation)
 {
   _key = resourceAccessor.CanonicalLocalResourcePath.Serialize();
   _resourceAccessor = resourceAccessor;
   _stream = _resourceAccessor.OpenRead();
   _rotation = rotation;
 }
예제 #4
0
        protected MediaInfoWrapper ReadMediaInfo(IFileSystemResourceAccessor mediaItemAccessor)
        {
            MediaInfoWrapper result = new MediaInfoWrapper();

            ILocalFsResourceAccessor localFsResourceAccessor = mediaItemAccessor as ILocalFsResourceAccessor;

            if (ReferenceEquals(localFsResourceAccessor, null))
            {
                Stream stream = null;
                try
                {
                    stream = mediaItemAccessor.OpenRead();
                    if (stream != null)
                    {
                        result.Open(stream);
                    }
                }
                finally
                {
                    if (stream != null)
                    {
                        stream.Close();
                    }
                }
            }
            else
            {
                using (localFsResourceAccessor.EnsureLocalFileSystemAccess())
                    result.Open(localFsResourceAccessor.LocalFileSystemPath);
            }
            return(result);
        }
예제 #5
0
        /// <summary>
        /// Gets a stream for the resource which is described by this file handle if the stream is already open or opens a new stream for it.
        /// </summary>
        /// <returns>
        /// This method returns the same stream for the same thread; it returns a new stream for a new thread.
        /// </returns>
        public Stream GetOrOpenStream()
        {
            Thread currentThread = Thread.CurrentThread;
            Stream stream;

            lock (_syncObj)
                if (_threadStreams.TryGetValue(currentThread, out stream))
                {
                    return(stream);
                }

            IFileSystemResourceAccessor resourceAccessor = _resource.ResourceAccessor;

            try
            {
                if (resourceAccessor != null)
                {
                    resourceAccessor.PrepareStreamAccess();
                    lock (_syncObj)
                        return(_threadStreams[currentThread] = resourceAccessor.OpenRead());
                }
            }
            catch (Exception e)
            {
                ServiceRegistration.Get <ILogger>().Warn("Dokan FileHandle: Error creating stream for resource '{0}'", e, resourceAccessor);
            }
            return(null);
        }
 /// <summary>
 /// Constructs a <see cref="ResourceAccessorTextureImageSource"/> for the given data.
 /// </summary>
 /// <param name="resourceAccessor">The resource accessor to load the texture data from.</param>
 /// <param name="rotation">Desired rotation for the given image.</param>
 public ResourceAccessorTextureImageSource(IFileSystemResourceAccessor resourceAccessor, RightAngledRotation rotation)
 {
     _key = resourceAccessor.CanonicalLocalResourcePath.Serialize();
     _resourceAccessor = resourceAccessor;
     _stream           = _resourceAccessor.OpenRead();
     _rotation         = rotation;
 }
예제 #7
0
        /// <summary>
        /// Method that processes the Uri.
        /// </summary>
        /// <param name="request">Information sent by the browser about the request.</param>
        /// <param name="response">Information that is being sent back to the client.</param>
        /// <param name="session">Session object used during the client connection.</param>
        /// <returns><c>true</c> if this module is able to handle the request, else <c>false</c>.</returns>
        /// <exception cref="InternalServerException">If an exception occured in the server.</exception>
        /// <exception cref="ForbiddenException">If the file path is forbidden.</exception>
        public override bool Process(IHttpRequest request, IHttpResponse response, IHttpSession session)
        {
            ResourcePath resourcePath;
            Uri          uri = request.Uri;

            if (!uri.AbsolutePath.StartsWith(ResourceHttpAccessUrlUtils.RESOURCE_ACCESS_PATH))
            {
                return(false);
            }
            if (!ResourceHttpAccessUrlUtils.ParseResourceURI(uri, out resourcePath))
            {
                throw new BadRequestException(string.Format("Illegal request syntax. Correct syntax is '{0}'", ResourceHttpAccessUrlUtils.SYNTAX));
            }
            if (!IsAllowedToAccess(resourcePath))
            {
                ServiceRegistration.Get <ILogger>().Warn("ResourceAccessModule: Client tries to access forbidden resource '{0}'", resourcePath);
                throw new ForbiddenException(string.Format("Access of resource '{0}' not allowed", resourcePath));
            }

            try
            {
                IFileSystemResourceAccessor fsra = GetResourceAccessor(resourcePath);
                using (Stream resourceStream = fsra.OpenRead())
                {
                    response.ContentType = GuessMimeType(resourceStream, resourcePath.FileName);

                    if (!string.IsNullOrEmpty(request.Headers["If-Modified-Since"]))
                    {
                        DateTime lastRequest = DateTime.Parse(request.Headers["If-Modified-Since"]);
                        if (lastRequest.CompareTo(fsra.LastChanged) <= 0)
                        {
                            response.Status = HttpStatusCode.NotModified;
                        }
                    }

                    response.AddHeader("Last-Modified", fsra.LastChanged.ToUniversalTime().ToString("r"));

                    string        byteRangesSpecifier = request.Headers["Range"];
                    IList <Range> ranges      = ParseRanges(byteRangesSpecifier, resourceStream.Length);
                    bool          onlyHeaders = request.Method == "Headers" || response.Status == HttpStatusCode.NotModified;
                    if (ranges != null && ranges.Count == 1)
                    {
                        // We only support one range
                        SendRange(response, resourceStream, ranges[0], onlyHeaders);
                    }
                    else
                    {
                        SendWholeFile(response, resourceStream, onlyHeaders);
                    }
                }
            }
            catch (FileNotFoundException ex)
            {
                throw new InternalServerException(string.Format("Failed to proccess resource '{0}'", resourcePath), ex);
            }

            return(true);
        }
예제 #8
0
        public static async Task <bool> ProcessAsync(IOwinContext context, WebMediaType type, string id)
        {
            if (id == null)
            {
                throw new BadRequestException("GetImage: id is null");
            }

            ISet <Guid> necessaryMIATypes = new HashSet <Guid>();

            necessaryMIATypes.Add(MediaAspect.ASPECT_ID);
            necessaryMIATypes.Add(ProviderResourceAspect.ASPECT_ID);
            necessaryMIATypes.Add(ImporterAspect.ASPECT_ID);
            necessaryMIATypes.Add(ImageAspect.ASPECT_ID);
            MediaItem item = MediaLibraryAccess.GetMediaItemById(context, id, necessaryMIATypes, null);

            var resourcePathStr = item.PrimaryResources[item.ActiveResourceLocatorIndex].GetAttributeValue(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH);
            var resourcePath    = ResourcePath.Deserialize(resourcePathStr.ToString());

            var ra = GetResourceAccessor(resourcePath);
            IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor;

            if (fsra == null)
            {
                throw new InternalServerException("GetImage: failed to create IFileSystemResourceAccessor");
            }

            using (var resourceStream = fsra.OpenRead())
            {
                // HTTP/1.1 RFC2616 section 14.25 'If-Modified-Since'
                if (!string.IsNullOrEmpty(context.Request.Headers["If-Modified-Since"]))
                {
                    DateTime lastRequest = DateTime.Parse(context.Request.Headers["If-Modified-Since"]);
                    if (lastRequest.CompareTo(fsra.LastChanged) <= 0)
                    {
                        context.Response.StatusCode = (int)HttpStatusCode.NotModified;
                    }
                }

                // HTTP/1.1 RFC2616 section 14.29 'Last-Modified'
                context.Response.Headers["Last-Modified"] = fsra.LastChanged.ToUniversalTime().ToString("r");

                string        byteRangesSpecifier = context.Request.Headers["Range"];
                IList <Range> ranges      = ParseByteRanges(byteRangesSpecifier, resourceStream.Length);
                bool          onlyHeaders = context.Request.Method == "HEAD" || context.Response.StatusCode == (int)HttpStatusCode.NotModified;
                if (ranges != null && ranges.Count > 0)
                {
                    // We only support last range
                    await SendRangeAsync(context, resourceStream, ranges[ranges.Count - 1], onlyHeaders);
                }
                else
                {
                    await SendWholeFileAsync(context, resourceStream, onlyHeaders);
                }
            }
            return(true);
        }
예제 #9
0
 public ZipResourceProxy(string key, IFileSystemResourceAccessor zipFileAccessor)
 {
     _key = key;
     _zipFileResourceAccessor = zipFileAccessor;
     _zipFileStream           = _zipFileResourceAccessor.OpenRead(); // Not sure if the ZipFile closes the stream appropriately, so we keep a reference to it
     try
     {
         _zipFile = new ZipFile(_zipFileStream);
     }
     catch
     {
         _zipFileStream.Dispose();
         throw;
     }
 }
예제 #10
0
 public ZipResourceProxy(string key, IFileSystemResourceAccessor zipFileAccessor)
 {
   _key = key;
   _zipFileResourceAccessor = zipFileAccessor;
   _zipFileStream = _zipFileResourceAccessor.OpenRead(); // Not sure if the ZipFile closes the stream appropriately, so we keep a reference to it
   try
   {
     _zipFile = new ZipFile(_zipFileStream);
   }
   catch
   {
     _zipFileStream.Dispose();
     throw;
   }
 }
예제 #11
0
    public IsoResourceProxy(string key, IFileSystemResourceAccessor isoFileResourceAccessor)
    {
      _key = key;
      _isoFileResourceAccessor = isoFileResourceAccessor;

      _underlayingStream = _isoFileResourceAccessor.OpenRead();
      try
      {
        _diskFileSystem = GetFileSystem(_underlayingStream);
      }
      catch
      {
        _underlayingStream.Dispose();
        throw;
      }
    }
예제 #12
0
        public IsoResourceProxy(string key, IFileSystemResourceAccessor isoFileResourceAccessor)
        {
            _key = key;
            _isoFileResourceAccessor = isoFileResourceAccessor;

            _underlayingStream = Stream.Synchronized(_isoFileResourceAccessor.OpenRead());
            try
            {
                _diskFileSystem = GetFileSystem(_underlayingStream);
            }
            catch
            {
                _underlayingStream.Dispose();
                throw;
            }
        }
예제 #13
0
        public bool IsResource(IFileSystemResourceAccessor baseResourceAccessor, string path)
        {
            string resourceName = baseResourceAccessor.ResourceName;

            if (string.IsNullOrEmpty(resourceName) || !baseResourceAccessor.IsFile)
            {
                return(false);
            }

            // Test if we have already an ISO proxy for that ISO file...
            lock (_syncObj)
            {
                string key = baseResourceAccessor.CanonicalLocalResourcePath.Serialize();
                try
                {
                    IsoResourceProxy proxy;
                    if (_isoUsages.TryGetValue(key, out proxy))
                    {
                        lock (proxy.SyncObj)
                            return(IsoResourceAccessor.IsResource(proxy.DiskFileSystem, path));
                    }
                }
                catch (Exception)
                {
                    return(false);
                }
            }

            // ... if not, test the resource in a new disk file system instance
            using (Stream underlayingStream = baseResourceAccessor.OpenRead())
            {
                try
                {
                    IFileSystem diskFileSystem = IsoResourceProxy.GetFileSystem(underlayingStream);
                    using (diskFileSystem as IDisposable)
                        return(IsoResourceAccessor.IsResource(diskFileSystem, path));
                }
                catch
                {
                    return(false);
                }
            }
        }
        protected MediaInfoWrapper ReadMediaInfo(IFileSystemResourceAccessor mediaItemAccessor)
        {
            MediaInfoWrapper result = new MediaInfoWrapper();
            Stream           stream = null;

            try
            {
                stream = mediaItemAccessor.OpenRead();
                if (stream != null)
                {
                    result.Open(stream);
                }
            }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                }
            }
            return(result);
        }
예제 #15
0
        public static async Task ProcessAsync(IOwinContext context, WebMediaType type, string id, int maxWidth, int maxHeight, string borders = null)
        {
            if (id == null)
            {
                throw new BadRequestException("GetImageResized: id is null");
            }
            if (maxWidth == 0)
            {
                throw new BadRequestException("GetImageResized: maxWidth is null");
            }
            if (maxHeight == 0)
            {
                throw new BadRequestException("GetImageResized: maxHeight is null");
            }

            Guid idGuid;

            if (!Guid.TryParse(id, out idGuid))
            {
                throw new BadRequestException(String.Format("GetImageResized: Couldn't parse if '{0}' to Guid", id));
            }

            ISet <Guid> necessaryMIATypes = new HashSet <Guid>();

            necessaryMIATypes.Add(MediaAspect.ASPECT_ID);
            necessaryMIATypes.Add(ProviderResourceAspect.ASPECT_ID);
            necessaryMIATypes.Add(ImporterAspect.ASPECT_ID);
            necessaryMIATypes.Add(ImageAspect.ASPECT_ID);
            MediaItem item = MediaLibraryAccess.GetMediaItemById(context, idGuid, necessaryMIATypes, null);

            var resourcePathStr = item.PrimaryResources[item.ActiveResourceLocatorIndex].GetAttributeValue(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH);
            var resourcePath    = ResourcePath.Deserialize(resourcePathStr.ToString());

            var ra = GetResourceAccessor(resourcePath);
            IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor;

            if (fsra == null)
            {
                throw new InternalServerException("GetImage: failed to create IFileSystemResourceAccessor");
            }

            // Resize
            ImageCache.CacheIdentifier identifier = ImageCache.GetIdentifier(idGuid, false, maxWidth, maxHeight, borders, 0, FanArtTypes.Undefined, FanArtMediaTypes.Image);
            byte[] resizedImage;

            if (ImageCache.TryGetImageFromCache(context, identifier, out resizedImage))
            {
                Logger.Info("GetImageResized: Got image from cache");
            }
            else
            {
                using (var resourceStream = fsra.OpenRead())
                {
                    byte[] buffer = new byte[resourceStream.Length];
                    resourceStream.Read(buffer, 0, Convert.ToInt32(resourceStream.Length));
                    resizedImage = Plugins.MP2Extended.WSS.Images.ResizeImage(buffer, maxWidth, maxHeight, borders);
                }

                // Add to cache
                if (ImageCache.AddImageToCache(context, resizedImage, identifier))
                {
                    Logger.Info("GetImageResized: Added image to cache");
                }
            }

            using (var resourceStream = new MemoryStream(resizedImage))
            {
                // HTTP/1.1 RFC2616 section 14.25 'If-Modified-Since'
                if (!string.IsNullOrEmpty(context.Request.Headers["If-Modified-Since"]))
                {
                    DateTime lastRequest = DateTime.Parse(context.Request.Headers["If-Modified-Since"]);
                    if (lastRequest.CompareTo(fsra.LastChanged) <= 0)
                    {
                        context.Response.StatusCode = (int)HttpStatusCode.NotModified;
                    }
                }

                // HTTP/1.1 RFC2616 section 14.29 'Last-Modified'
                context.Response.Headers["Last-Modified"] = fsra.LastChanged.ToUniversalTime().ToString("r");

                string        byteRangesSpecifier = context.Request.Headers["Range"];
                IList <Range> ranges      = ParseByteRanges(byteRangesSpecifier, resourceStream.Length);
                bool          onlyHeaders = context.Request.Method == "HEAD" || context.Response.StatusCode == (int)HttpStatusCode.NotModified;
                if (ranges != null && ranges.Count > 0)
                {
                    // We only support last range
                    await SendRangeAsync(context, resourceStream, ranges[ranges.Count - 1], onlyHeaders);
                }
                else
                {
                    await SendWholeFileAsync(context, resourceStream, onlyHeaders);
                }
            }
        }
예제 #16
0
        /// <summary>
        /// Method that processes the Uri.
        /// </summary>
        public override async Task Invoke(IOwinContext context)
        {
            var          request  = context.Request;
            var          response = context.Response;
            ResourcePath resourcePath;
            Uri          uri = request.Uri;

            if (!uri.AbsolutePath.StartsWith(ResourceHttpAccessUrlUtils.RESOURCE_SERVER_BASE_PATH) || !uri.AbsolutePath.Contains(ResourceHttpAccessUrlUtils.RESOURCE_ACCESS_PATH))
            {
                await Next.Invoke(context);

                return;
            }
            if (!ResourceHttpAccessUrlUtils.ParseResourceURI(uri, out resourcePath))
            {
                response.StatusCode   = (int)HttpStatusCode.BadRequest;
                response.ReasonPhrase = string.Format("Illegal request syntax. Correct syntax is '{0}'", ResourceHttpAccessUrlUtils.SYNTAX);
                return;
            }
            if (!IsAllowedToAccess(resourcePath))
            {
                ServiceRegistration.Get <ILogger>().Warn("ResourceAccessModule: Client tries to access forbidden resource '{0}'", resourcePath);
                response.StatusCode   = (int)HttpStatusCode.Forbidden;
                response.ReasonPhrase = string.Format("Access of resource '{0}' not allowed", resourcePath);
                return;
            }

            try
            {
                IFileSystemResourceAccessor fsra = GetResourceAccessor(resourcePath);
                using (Stream resourceStream = fsra.OpenRead())
                {
                    response.ContentType = GuessMimeType(resourceStream, resourcePath.FileName);

                    if (!string.IsNullOrEmpty(request.Headers["If-Modified-Since"]))
                    {
                        DateTime lastRequest = DateTime.Parse(request.Headers["If-Modified-Since"], System.Globalization.CultureInfo.InvariantCulture);
                        if (lastRequest.CompareTo(fsra.LastChanged) <= 0)
                        {
                            response.StatusCode = (int)HttpStatusCode.NotModified;
                        }
                    }

                    response.Headers["Last-Modified"] = fsra.LastChanged.ToUniversalTime().ToString("r");

                    string        byteRangesSpecifier = request.Headers["Range"];
                    IList <Range> ranges      = ParseRanges(byteRangesSpecifier, resourceStream.Length);
                    bool          onlyHeaders = request.Method == "Headers" || response.StatusCode == (int)HttpStatusCode.NotModified;

                    CancellationTokenSource cts = new CancellationTokenSource();
                    if (ranges != null && ranges.Count == 1)
                    {
                        // We only support one range
                        await SendRange(response, resourceStream, ranges[0], onlyHeaders, cts.Token);
                    }
                    else
                    {
                        await SendWholeFile(response, resourceStream, onlyHeaders, cts.Token);
                    }
                }
            }
            catch (FileNotFoundException ex)
            {
                response.StatusCode   = (int)HttpStatusCode.InternalServerError;
                response.ReasonPhrase = string.Format("Failed to proccess resource '{0}': {1}", resourcePath, ex.Message);
            }
        }
예제 #17
0
        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
            {
                if (!(mediaItemAccessor is IFileSystemResourceAccessor))
                {
                    return(false);
                }
                IFileSystemResourceAccessor fsra = mediaItemAccessor as IFileSystemResourceAccessor;
                // Open a stream for media item to detect mimeType.
                using (Stream mediaStream = fsra.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(fsra))
                {
                    mediaAspect.SetAttribute(MediaAspect.ATTR_TITLE, ProviderPathHelper.GetFileNameWithoutExtension(fileName));
                    mediaAspect.SetAttribute(MediaAspect.ATTR_RECORDINGTIME, exif.OriginalDate != DateTime.MinValue ? exif.OriginalDate : fsra.LastChanged);
                    mediaAspect.SetAttribute(MediaAspect.ATTR_COMMENT, StringUtils.TrimToNull(exif.ImageDescription));

                    if (exif.PixXDim.HasValue)
                    {
                        imageAspect.SetAttribute(ImageAspect.ATTR_WIDTH, (int)exif.PixXDim);
                    }
                    if (exif.PixYDim.HasValue)
                    {
                        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));
                    if (exif.ExposureBias.HasValue)
                    {
                        imageAspect.SetAttribute(ImageAspect.ATTR_EXPOSURE_BIAS, ((double)exif.ExposureBias).ToString());
                    }
                    imageAspect.SetAttribute(ImageAspect.ATTR_EXPOSURE_TIME, exif.ExposureTime);
                    imageAspect.SetAttribute(ImageAspect.ATTR_FLASH_MODE, StringUtils.TrimToNull(exif.FlashMode));
                    if (exif.FNumber.HasValue)
                    {
                        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.OrientationType ?? 0));
                    imageAspect.SetAttribute(ImageAspect.ATTR_METERING_MODE, exif.MeteringMode.ToString());

                    if (exif.Latitude.HasValue && exif.Longitude.HasValue)
                    {
                        imageAspect.SetAttribute(ImageAspect.ATTR_LATITUDE, exif.Latitude);
                        imageAspect.SetAttribute(ImageAspect.ATTR_LONGITUDE, exif.Longitude);

                        LocationInfo locationInfo;
                        if (!forceQuickMode && GeoLocationMatcher.Instance.TryLookup(exif.Latitude.Value, exif.Longitude.Value, out locationInfo))
                        {
                            imageAspect.SetAttribute(ImageAspect.ATTR_CITY, locationInfo.City);
                            imageAspect.SetAttribute(ImageAspect.ATTR_STATE, locationInfo.State);
                            imageAspect.SetAttribute(ImageAspect.ATTR_COUNTRY, locationInfo.Country);
                        }
                    }

                    using (ILocalFsResourceAccessor lfsra = StreamedResourceToLocalFsAccessBridge.GetLocalFsResourceAccessor((IFileSystemResourceAccessor)fsra.Clone()))
                    {
                        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);
        }
예제 #18
0
        public static async Task <bool> ParseAsync(JObject message, SocketServer server, AsyncSocket sender)
        {
            string imagePath = GetMessageValue <string>(message, "ImagePath");
            string userTag   = GetMessageValue <string>(message, "UserTag");
            int    maxWidth  = GetMessageValue <int>(message, "MaximumWidth");
            int    maxHeight = GetMessageValue <int>(message, "MaximumHeight");
            string id        = GetMessageValue <string>(message, "ImageId");
            var    client    = sender.GetRemoteClient();

            ServiceRegistration.Get <ILogger>().Debug("WifiRemote: Get Image: UserTag: {0}, ImageId: {1}, ImagePath: {2}, MaximumWidth: {3}, MaximumHeight: {4}", userTag, id, imagePath, maxWidth, maxHeight);

            if (!string.IsNullOrEmpty(imagePath) && string.IsNullOrEmpty(id))
            {
                var item = await Helper.GetMediaItemByFileNameAsync(client.UserId, imagePath);

                id = item?.MediaItemId.ToString();
            }

            if (!Guid.TryParse(id, out Guid mediaItemGuid))
            {
                ServiceRegistration.Get <ILogger>().Error("WifiRemote: Get Image: Couldn't convert ImageId {0} to Guid", id);
                return(false);
            }

            MessageImage msg       = new MessageImage();
            var          mediaItem = await Helper.GetMediaItemByIdAsync(client.UserId, mediaItemGuid);

            Image            image   = null;
            IResourceLocator locator = mediaItem.GetResourceLocator();

            using (IResourceAccessor ra = locator.CreateAccessor())
            {
                IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor;
                if (fsra == null)
                {
                    ServiceRegistration.Get <ILogger>().Error("WifiRemote: Get Image: Couldn't read image {0}", id);
                    return(false);
                }
                using (Stream stream = fsra.OpenRead())
                {
                    image = Image.FromStream(stream);
                }
            }

            if ((maxWidth > 0 && image.Width > maxWidth) || (maxHeight > 0 && image.Height > maxHeight))
            {
                int height = image.Height;
                int width  = image.Width;
                if (maxHeight > 0 && height > maxHeight)
                {
                    float ratio = (float)height / (float)maxHeight;
                    width = Convert.ToInt32((float)width / ratio);
                }
                if (maxWidth > 0 && width > maxWidth)
                {
                    width = maxWidth;
                }
                var newImage = ImageHelper.ResizedImage(image, width);
                image.Dispose();
                image = newImage;
            }

            byte[] data = ImageHelper.ImageToByteArray(image, System.Drawing.Imaging.ImageFormat.Jpeg);
            image?.Dispose();
            msg.ImagePath = mediaItem.ToString();
            msg.UserTag   = userTag;
            msg.Image     = Convert.ToBase64String(data);
            SendMessageToClient.Send(msg, sender);

            return(true);
        }
예제 #19
0
    public bool IsResource(IFileSystemResourceAccessor baseResourceAccessor, string path)
    {
      string resourceName = baseResourceAccessor.ResourceName;
      if (string.IsNullOrEmpty(resourceName) || !baseResourceAccessor.IsFile)
        return false;

      // Test if we have already an ISO proxy for that ISO file...
      lock (_syncObj)
      {
        string key = baseResourceAccessor.CanonicalLocalResourcePath.Serialize();
        try
        {
          IsoResourceProxy proxy;
          if (_isoUsages.TryGetValue(key, out proxy))
            lock (proxy.SyncObj)
              return IsoResourceAccessor.IsResource(proxy.DiskFileSystem, path);
        }
        catch (Exception)
        {
          return false;
        }
      }

      // ... if not, test the resource in a new disk file system instance
      using (Stream underlayingStream = baseResourceAccessor.OpenRead())
      {
        try
        {
          IFileSystem diskFileSystem = IsoResourceProxy.GetFileSystem(underlayingStream);
          using (diskFileSystem as IDisposable)
            return IsoResourceAccessor.IsResource(diskFileSystem, path);
        }
        catch
        {
          return false;
        }
      }
    }
예제 #20
0
 private void ReadMetaInfo(IFileSystemResourceAccessor mediaItemAccessor)
 {
     using (Stream mediaStream = mediaItemAccessor.OpenRead())
         ReadMetaInfo(mediaStream);
 }
예제 #21
0
        public bool TryExtractMetadata(IResourceAccessor mediaItemAccessor, IDictionary <Guid, IList <MediaItemAspect> > extractedAspectData, bool importOnly, bool forceQuickMode)
        {
            string fileName = mediaItemAccessor.ResourceName;

            if (!HasImageExtension(fileName))
            {
                return(false);
            }

            bool refresh = false;

            if (extractedAspectData.ContainsKey(ImageAspect.ASPECT_ID))
            {
                refresh = true;
            }

            try
            {
                IFileSystemResourceAccessor fsra = mediaItemAccessor as IFileSystemResourceAccessor;
                if (!refresh)
                {
                    MultipleMediaItemAspect providerResourceAspect = MediaItemAspect.CreateAspect(extractedAspectData, ProviderResourceAspect.Metadata);
                    providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_RESOURCE_INDEX, 0);
                    providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_PRIMARY, true);

                    if (!(mediaItemAccessor is IFileSystemResourceAccessor))
                    {
                        return(false);
                    }

                    // Open a stream for media item to detect mimeType.
                    using (Stream mediaStream = fsra.OpenRead())
                    {
                        string mimeType = MimeTypeDetector.GetMimeType(mediaStream) ?? DEFAULT_MIMETYPE;
                        providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_MIME_TYPE, mimeType);
                        providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_SIZE, fsra.Size);
                    }
                }

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

                if (!refresh)
                {
                    // Extract EXIF information from media item.
                    using (ExifMetaInfo.ExifMetaInfo exif = new ExifMetaInfo.ExifMetaInfo(fsra))
                    {
                        mediaAspect.SetAttribute(MediaAspect.ATTR_TITLE, ProviderPathHelper.GetFileNameWithoutExtension(fileName));
                        mediaAspect.SetAttribute(MediaAspect.ATTR_RECORDINGTIME, exif.OriginalDate != DateTime.MinValue ? exif.OriginalDate : fsra.LastChanged);
                        mediaAspect.SetAttribute(MediaAspect.ATTR_COMMENT, StringUtils.TrimToNull(exif.ImageDescription));

                        if (exif.PixXDim.HasValue)
                        {
                            imageAspect.SetAttribute(ImageAspect.ATTR_WIDTH, (int)exif.PixXDim);
                        }
                        if (exif.PixYDim.HasValue)
                        {
                            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));
                        if (exif.ExposureBias.HasValue)
                        {
                            imageAspect.SetAttribute(ImageAspect.ATTR_EXPOSURE_BIAS, ((double)exif.ExposureBias).ToString());
                        }
                        imageAspect.SetAttribute(ImageAspect.ATTR_EXPOSURE_TIME, exif.ExposureTime);
                        imageAspect.SetAttribute(ImageAspect.ATTR_FLASH_MODE, StringUtils.TrimToNull(exif.FlashMode));
                        if (exif.FNumber.HasValue)
                        {
                            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.OrientationType ?? 0));
                        imageAspect.SetAttribute(ImageAspect.ATTR_METERING_MODE, exif.MeteringMode.ToString());

                        if (exif.Latitude.HasValue && exif.Longitude.HasValue)
                        {
                            imageAspect.SetAttribute(ImageAspect.ATTR_LATITUDE, exif.Latitude);
                            imageAspect.SetAttribute(ImageAspect.ATTR_LONGITUDE, exif.Longitude);
                        }
                    }

                    byte[] thumbData;
                    // We only want to create missing thumbnails here, so check for existing ones first
                    if (MediaItemAspect.TryGetAttribute(extractedAspectData, ThumbnailLargeAspect.ATTR_THUMBNAIL, out thumbData) && thumbData != null)
                    {
                        return(true);
                    }

                    using (LocalFsResourceAccessorHelper rah = new LocalFsResourceAccessorHelper(mediaItemAccessor))
                        using (rah.LocalFsResourceAccessor.EnsureLocalFileSystemAccess())
                        {
                            string localFsResourcePath = rah.LocalFsResourceAccessor.LocalFileSystemPath;
                            if (localFsResourcePath != null)
                            {
                                // Thumbnail extraction
                                IThumbnailGenerator generator = ServiceRegistration.Get <IThumbnailGenerator>();
                                ImageType           imageType;
                                if (generator.GetThumbnail(localFsResourcePath, true, out thumbData, out imageType))
                                {
                                    MediaItemAspect.SetAttribute(extractedAspectData, ThumbnailLargeAspect.ATTR_THUMBNAIL, thumbData);
                                }
                            }
                        }
                    return(true);
                }
                else
                {
                    bool   updated   = false;
                    double?latitude  = imageAspect.GetAttributeValue <double?>(ImageAspect.ATTR_LATITUDE);
                    double?longitude = imageAspect.GetAttributeValue <double?>(ImageAspect.ATTR_LONGITUDE);
                    if (IncludeGeoLocationDetails && !importOnly && latitude.HasValue && longitude.HasValue &&
                        string.IsNullOrEmpty(imageAspect.GetAttributeValue <string>(ImageAspect.ATTR_COUNTRY)))
                    {
                        CivicAddress locationInfo;
                        if (!forceQuickMode && GeoLocationService.Instance.TryLookup(new GeoCoordinate(latitude.Value, longitude.Value), out locationInfo))
                        {
                            imageAspect.SetAttribute(ImageAspect.ATTR_CITY, locationInfo.City);
                            imageAspect.SetAttribute(ImageAspect.ATTR_STATE, locationInfo.StateProvince);
                            imageAspect.SetAttribute(ImageAspect.ATTR_COUNTRY, locationInfo.CountryRegion);
                            updated = true;
                        }
                    }

                    byte[] thumbData;
                    // We only want to create missing thumbnails here, so check for existing ones first
                    if (MediaItemAspect.TryGetAttribute(extractedAspectData, ThumbnailLargeAspect.ATTR_THUMBNAIL, out thumbData) && thumbData != null)
                    {
                        return(updated);
                    }

                    using (LocalFsResourceAccessorHelper rah = new LocalFsResourceAccessorHelper(mediaItemAccessor))
                        using (rah.LocalFsResourceAccessor.EnsureLocalFileSystemAccess())
                        {
                            string localFsResourcePath = rah.LocalFsResourceAccessor.LocalFileSystemPath;
                            if (localFsResourcePath != null)
                            {
                                // In quick mode only allow thumbs taken from cache.
                                bool cachedOnly = forceQuickMode;
                                // Thumbnail extraction
                                IThumbnailGenerator generator = ServiceRegistration.Get <IThumbnailGenerator>();
                                ImageType           imageType;
                                if (generator.GetThumbnail(localFsResourcePath, cachedOnly, out thumbData, out imageType))
                                {
                                    MediaItemAspect.SetAttribute(extractedAspectData, ThumbnailLargeAspect.ATTR_THUMBNAIL, thumbData);
                                    updated = true;
                                }
                            }
                        }
                    return(updated);
                }
            }
            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);
        }
예제 #22
0
    public bool IsResource(IFileSystemResourceAccessor baseResourceAccessor, string path)
    {
      string entryPath = ZipResourceAccessor.ToEntryPath(path);

      lock (_syncObj)
      {
        string key = baseResourceAccessor.CanonicalLocalResourcePath.Serialize();
        try
        {
          ZipResourceProxy proxy;
          if (_zipUsages.TryGetValue(key, out proxy))
            return path.Equals("/") || ZipResourceAccessor.IsResource(proxy.ZipFile, entryPath);
        }
        catch (Exception)
        {
          return false;
        }
      }

      using (Stream resourceStream = baseResourceAccessor.OpenRead()) // Not sure if the ZipFile will close the stream so we dispose it here
        try
        {
          using (ZipFile zFile = new ZipFile(resourceStream))
            return path.Equals("/") || ZipResourceAccessor.IsResource(zFile, entryPath);
        }
        catch (Exception)
        {
          return false;
        }
    }
예제 #23
0
        /// <summary>
        /// Sets the data of the new image to be played.
        /// </summary>
        /// <param name="locator">Resource locator of the image item.</param>
        /// <param name="mediaItemTitle">Title of the image item.</param>
        /// <param name="rotation">Rotation of the image.</param>
        /// <param name="flipX">Flipping in horizontal direction.</param>
        /// <param name="flipY">Flipping in vertical direction.</param>
        public void SetMediaItemData(IResourceLocator locator, string mediaItemTitle, RightAngledRotation rotation, bool flipX, bool flipY)
        {
            if (locator == null)
            {
                lock (_syncObj)
                {
                    _currentLocator = null;
                    return;
                }
            }

            using (IResourceAccessor ra = locator.CreateAccessor())
            {
                IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor;
                if (fsra == null)
                {
                    return;
                }
                using (Stream stream = fsra.OpenRead())
                {
                    string key = fsra.CanonicalLocalResourcePath.Serialize();
                    _texture = ContentManager.Instance.GetTexture(stream, key, true);
                    if (_texture == null)
                    {
                        return;
                    }
                    if (!_texture.IsAllocated)
                    {
                        _texture.Allocate();
                    }
                    if (!_texture.IsAllocated)
                    {
                        return;
                    }
                }
            }
            lock (_syncObj)
            {
                ReloadSettings();
                _state = PlayerState.Active;

                _currentLocator = locator;
                _mediaItemTitle = mediaItemTitle;
                _rotation       = rotation;
                _flipX          = flipX;
                _flipY          = flipY;
                SurfaceDescription desc = _texture.Texture.GetLevelDescription(0);
                _textureMaxUV = new SizeF(_texture.Width / (float)desc.Width, _texture.Height / (float)desc.Height);

                // Reset animation
                _animator.Initialize();

                if (_slideShowTimer != null)
                {
                    _slideShowTimer.Change(_slideShowImageDuration, TS_INFINITE);
                }
                else
                {
                    CheckTimer();
                }
                _playbackStartTime = DateTime.Now;
                if (_pauseTime.HasValue)
                {
                    _pauseTime = _playbackStartTime;
                }
            }
        }
예제 #24
0
        public static async Task ProcessAsync(IOwinContext context, Guid itemId)
        {
            // Grab the media item given in the request.
            try
            {
                Logger.Debug("GetMediaItem: Attempting to load mediaitem {0}", itemId.ToString());

                // Attempt to grab the media item from the database.
                ISet <Guid> necessaryMIATypes = new HashSet <Guid>();
                necessaryMIATypes.Add(MediaAspect.ASPECT_ID);
                necessaryMIATypes.Add(ImporterAspect.ASPECT_ID);
                necessaryMIATypes.Add(ProviderResourceAspect.ASPECT_ID);
                var item = MediaLibraryAccess.GetMediaItemById(context, itemId, necessaryMIATypes, null);
                if (item == null)
                {
                    throw new NotFoundException(string.Format("Media item '{0}' not found.", itemId));
                }

                // Grab the mimetype from the media item and set the Content Type header.
                // TODO: Fix
                string mimeType = item?.PrimaryResources?.FirstOrDefault()?.GetAttributeValue <string>(ProviderResourceAspect.ATTR_MIME_TYPE) ?? "video/*";
                context.Response.ContentType = mimeType;

                // Grab the resource path for the media item.
                var resourcePathStr = item.PrimaryResources[item.ActiveResourceLocatorIndex].GetAttributeValue(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH);
                var resourcePath    = ResourcePath.Deserialize(resourcePathStr.ToString());

                var ra = GetResourceAccessor(resourcePath);
                IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor;
                if (fsra == null)
                {
                    throw new InternalServerException("GetMediaItem: failed to create IFileSystemResourceAccessor");
                }

                using (var resourceStream = fsra.OpenRead())
                {
                    // HTTP/1.1 RFC2616 section 14.25 'If-Modified-Since'
                    if (!string.IsNullOrEmpty(context.Response.Headers["If-Modified-Since"]))
                    {
                        DateTime lastRequest = DateTime.Parse(context.Response.Headers["If-Modified-Since"]);
                        if (lastRequest.CompareTo(fsra.LastChanged) <= 0)
                        {
                            context.Response.StatusCode = (int)HttpStatusCode.NotModified;
                        }
                    }

                    // HTTP/1.1 RFC2616 section 14.29 'Last-Modified'
                    context.Response.Headers["Last-Modified"] = fsra.LastChanged.ToUniversalTime().ToString("r");

                    string        byteRangesSpecifier = context.Request.Headers["Range"];
                    IList <Range> ranges      = ParseByteRanges(byteRangesSpecifier, resourceStream.Length);
                    bool          onlyHeaders = context.Request.Method == "HEAD" || context.Response.StatusCode == (int)HttpStatusCode.NotModified;
                    if (ranges != null)
                    {
                        // We only support last range
                        await SendRangeAsync(context, resourceStream, ranges[ranges.Count - 1], onlyHeaders);
                    }
                    else
                    {
                        await SendWholeFileAsync(context, resourceStream, onlyHeaders);
                    }
                }
            }
            catch (FileNotFoundException ex)
            {
                throw new InternalServerException(string.Format("Failed to proccess media item '{0}'", itemId), ex);
            }
        }
예제 #25
0
    protected MediaInfoWrapper ReadMediaInfo(IFileSystemResourceAccessor mediaItemAccessor)
    {
      MediaInfoWrapper result = new MediaInfoWrapper();

      ILocalFsResourceAccessor localFsResourceAccessor = mediaItemAccessor as ILocalFsResourceAccessor;
      if (ReferenceEquals(localFsResourceAccessor, null))
      {
        Stream stream = null;
        try
        {
          stream = mediaItemAccessor.OpenRead();
          if (stream != null)
            result.Open(stream);
        }
        finally
        {
          if (stream != null)
            stream.Close();
        }
      }
      else
      {
        using (localFsResourceAccessor.EnsureLocalFileSystemAccess())
          result.Open(localFsResourceAccessor.LocalFileSystemPath);
      }

      return result;
    }
예제 #26
0
 private void ReadMetaInfo(IFileSystemResourceAccessor mediaItemAccessor)
 {
   using (Stream mediaStream = mediaItemAccessor.OpenRead())
     ReadMetaInfo(mediaStream);
 }
        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);
                            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);
        }
 protected MediaInfoWrapper ReadMediaInfo(IFileSystemResourceAccessor mediaItemAccessor)
 {
   MediaInfoWrapper result = new MediaInfoWrapper();
   Stream stream = null;
   try
   {
     stream = mediaItemAccessor.OpenRead();
     if (stream != null)
       result.Open(stream);
   }
   finally
   {
     if (stream != null)
       stream.Close();
   }
   return result;
 }