예제 #1
0
        public static Stream ExtractImage(MediaSource source, int startPosition, int? maxWidth, int? maxHeight)
        {
            if (!source.IsLocalFile)
            {
                Log.Warn("ExtractImage: Source type={0} id={1} is not supported yet", source.MediaType, source.Id);
                WCFUtil.SetResponseCode(System.Net.HttpStatusCode.NotImplemented);
                return null;
            }

            // calculate size
            string ffmpegResize = "";
            if (maxWidth != null && maxHeight != null)
            {
                try
                {
                    decimal resolution = MediaInfoWrapper.GetMediaInfo(source).VideoStreams.First().DisplayAspectRatio;
                    ffmpegResize = "-s " + Resolution.Calculate(resolution, new Resolution(maxWidth.Value, maxHeight.Value)).ToString();
                }
                catch (Exception ex)
                {
                    Log.Error("Error while getting resolution of video stream", ex);
                }
            }

            // get temporary filename
            string tempDir = Path.Combine(Path.GetTempPath(), "MPExtended", "imagecache");
            if (!Directory.Exists(tempDir))
            {
                Directory.CreateDirectory(tempDir);
            }
            string filename = String.Format("ex_{0}_{1}_{2}_{3}.jpg", source.GetUniqueIdentifier(), startPosition,
                maxWidth == null ? "null" : maxWidth.ToString(), maxHeight == null ? "null" : maxHeight.ToString());
            string tempFile = Path.Combine(tempDir, filename);

            // maybe it exists
            if (File.Exists(tempFile))
            {
                return StreamImage(new ImageSource(tempFile));
            }

            // execute it
            ProcessStartInfo info = new ProcessStartInfo();
            info.Arguments = String.Format("-ss {0} -vframes 1 -i \"{1}\" {2} -f image2 {3}", startPosition, source.GetPath(), ffmpegResize, tempFile);
            info.FileName = Configuration.Streaming.FFMpegPath;
            info.CreateNoWindow = true;
            info.UseShellExecute = false;
            Process proc = new Process();
            proc.StartInfo = info;
            proc.Start();
            proc.WaitForExit();

            // log when failed
            if (!File.Exists(tempFile))
            {
                Log.Warn("Failed to extract image to temporary file {0}", tempFile);
                WCFUtil.SetResponseCode(System.Net.HttpStatusCode.InternalServerError);
                return null;
            }
            return StreamImage(new ImageSource(tempFile));
        }
예제 #2
0
        public static Stream ExtractImage(MediaSource source, long position, int? maxWidth, int? maxHeight, string borders, string format)
        {
            if (!source.Exists)
            {
                Log.Warn("ExtractImage: Source {0} (resolved to path {1}) doesn't exists", source.GetDebugName(), source.GetPath());
                WCFUtil.SetResponseCode(System.Net.HttpStatusCode.NotFound);
                return Stream.Null;
            }

            if (!source.SupportsDirectAccess)
            {
                Log.Warn("ExtractImage: Extracting images from remote sources isn't supported yet", source.MediaType, source.Id);
                WCFUtil.SetResponseCode(System.Net.HttpStatusCode.NotImplemented);
                return Stream.Null;
            }

            // get temporary filename
            string filename = String.Format("extract_{0}_{1}.jpg", source.GetUniqueIdentifier(), position);
            string tempFile = cache.GetPath(filename);

            // maybe it exists in cache, return that then
            if (cache.Contains(filename))
            {
                return StreamPostprocessedImage(new ImageMediaSource(tempFile), maxWidth, maxHeight, borders, format);
            }

            // execute it
            ProcessStartInfo info = new ProcessStartInfo();
            using (var impersonator = source.GetImpersonator())
            {
                info.Arguments = String.Format("-ss {0} -i \"{1}\" -vframes 1 -f image2 {2}", position, source.GetPath(), tempFile);
                info.FileName = Configuration.StreamingProfiles.FFMpegPath;
                info.CreateNoWindow = true;
                info.UseShellExecute = false;
                Process proc = new Process();
                proc.StartInfo = info;
                proc.Start();
                proc.WaitForExit();
            }

            // log when failed
            if (!File.Exists(tempFile))
            {
                Log.Warn("Failed to extract image to temporary file {0} with command {1}", tempFile, info.Arguments);
                WCFUtil.SetResponseCode(System.Net.HttpStatusCode.InternalServerError);
                return Stream.Null;
            }

            return StreamPostprocessedImage(new ImageMediaSource(tempFile), maxWidth, maxHeight, borders, format);
        }
예제 #3
0
        public static Stream ExtractImage(MediaSource source, long position, int?maxWidth, int?maxHeight, string borders, string format)
        {
            if (!source.Exists)
            {
                Log.Warn("ExtractImage: Source {0} (resolved to path {1}) doesn't exists", source.GetDebugName(), source.GetPath());
                WCFUtil.SetResponseCode(System.Net.HttpStatusCode.NotFound);
                return(Stream.Null);
            }

            if (!source.SupportsDirectAccess)
            {
                Log.Warn("ExtractImage: Extracting images from remote sources isn't supported yet", source.MediaType, source.Id);
                WCFUtil.SetResponseCode(System.Net.HttpStatusCode.NotImplemented);
                return(Stream.Null);
            }

            // get temporary filename
            string filename = String.Format("extract_{0}_{1}.jpg", source.GetUniqueIdentifier(), position);
            string tempFile = cache.GetPath(filename);

            // maybe it exists in cache, return that then
            if (cache.Contains(filename))
            {
                // if source is newer, cached image needs to be recreated
                if (source.GetFileInfo().LastModifiedTime > cache.GetLastModifiedTime(tempFile))
                {
                    cache.Invalidate(filename);
                }
                else
                {
                    return(StreamPostprocessedImage(new ImageMediaSource(tempFile), maxWidth, maxHeight, borders, format));
                }
            }

            // We need to impersonate to access the network drive and check if the thumbnail already exists. However, because
            // impersonation is lost when starting a process, we can't start ffmpeg from in here. We need to check whether the
            // file is accessible from outside the impersonation context again, and start the ffmpeg process as a different user
            // if that is the case.
            string fullPath;

            using (var context = source.CreateNetworkContext())
            {
                fullPath = context.RewritePath(source.GetPath());

                // stream a pre-existing thumbnail, if possible
                if (source.MediaType == WebMediaType.Recording && Path.GetExtension(fullPath).ToLower() == ".ts")
                {
                    var thumbnailFileInfo = new FileInfo(Path.ChangeExtension(fullPath, ".jpg"));
                    if (thumbnailFileInfo.Exists && thumbnailFileInfo.Length > 0)
                    {
                        return(StreamPostprocessedImage(new ImageMediaSource(thumbnailFileInfo.FullName), maxWidth, maxHeight, borders, format));
                    }
                }
            }

            // finally, extract the image with ffmpeg if everything else has failed
            bool extractResult = ExecuteFFMpegExtraction(source, fullPath, position, tempFile);

            if (!extractResult)
            {
                WCFUtil.SetResponseCode(System.Net.HttpStatusCode.InternalServerError);
                return(Stream.Null);
            }

            return(StreamPostprocessedImage(new ImageMediaSource(tempFile), maxWidth, maxHeight, borders, format));
        }
예제 #4
0
        public static Stream ExtractImage(MediaSource source, long startPosition, int?maxWidth, int?maxHeight)
        {
            if (!source.Exists)
            {
                Log.Warn("ExtractImage: Source {0} (resolved to path {1}) doesn't exists", source.GetDebugName(), source.GetPath());
                WCFUtil.SetResponseCode(System.Net.HttpStatusCode.NotFound);
                return(Stream.Null);
            }

            if (!source.SupportsDirectAccess)
            {
                Log.Warn("ExtractImage: Extracting images from remote sources isn't supported yet", source.MediaType, source.Id);
                WCFUtil.SetResponseCode(System.Net.HttpStatusCode.NotImplemented);
                return(Stream.Null);
            }

            // calculate size
            string ffmpegResize = "";

            if (maxWidth != null || maxHeight != null)
            {
                try
                {
                    decimal resolution = MediaInfoWrapper.GetMediaInfo(source).VideoStreams.First().DisplayAspectRatio;
                    ffmpegResize = "-s " + Resolution.Calculate(resolution, maxWidth, maxHeight).ToString();
                }
                catch (Exception ex)
                {
                    Log.Error("Error while getting resolution of video stream, not resizing", ex);
                }
            }

            // get temporary filename
            string filename = String.Format("extract_{0}_{1}_{2}_{3}.jpg", source.GetUniqueIdentifier(), startPosition,
                                            maxWidth == null ? "null" : maxWidth.ToString(), maxHeight == null ? "null" : maxHeight.ToString());
            string tempFile = cache.GetPath(filename);

            // maybe it exists in cache, return that then
            if (cache.Contains(filename))
            {
                return(StreamImage(new ImageMediaSource(tempFile)));
            }

            // execute it
            ProcessStartInfo info = new ProcessStartInfo();

            using (var impersonator = source.GetImpersonator())
            {
                info.Arguments       = String.Format("-ss {0} -i \"{1}\" {2} -vframes 1 -f image2 {3}", startPosition, source.GetPath(), ffmpegResize, tempFile);
                info.FileName        = Configuration.Streaming.FFMpegPath;
                info.CreateNoWindow  = true;
                info.UseShellExecute = false;
                Process proc = new Process();
                proc.StartInfo = info;
                proc.Start();
                proc.WaitForExit();
            }

            // log when failed
            if (!File.Exists(tempFile))
            {
                Log.Warn("Failed to extract image to temporary file {0} with command {1}", tempFile, info.Arguments);
                WCFUtil.SetResponseCode(System.Net.HttpStatusCode.InternalServerError);
                return(Stream.Null);
            }

            return(StreamImage(new ImageMediaSource(tempFile)));
        }
예제 #5
0
        public static Stream ExtractImage(MediaSource source, int startPosition, int? maxWidth, int? maxHeight)
        {
            if (!source.Exists)
            {
                Log.Warn("ExtractImage: Source {0} (resolved to path {1}) doesn't exists", source.GetDebugName(), source.GetPath());
                WCFUtil.SetResponseCode(System.Net.HttpStatusCode.NotFound);
                return Stream.Null;
            }

            if (!source.SupportsDirectAccess)
            {
                Log.Warn("ExtractImage: Extracting images from remote sources isn't supported yet", source.MediaType, source.Id);
                WCFUtil.SetResponseCode(System.Net.HttpStatusCode.NotImplemented);
                return Stream.Null;
            }

            // calculate size
            string ffmpegResize = "";
            if (maxWidth != null || maxHeight != null)
            {
                try
                {
                    decimal resolution = MediaInfoWrapper.GetMediaInfo(source).VideoStreams.First().DisplayAspectRatio;
                    ffmpegResize = "-s " + Resolution.Calculate(resolution, maxWidth, maxHeight).ToString();
                }
                catch (Exception ex)
                {
                    Log.Error("Error while getting resolution of video stream, not resizing", ex);
                }
            }

            // get temporary filename
            string tempDir = Path.Combine(Installation.GetCacheDirectory(), "imagecache");
            if (!Directory.Exists(tempDir))
            {
                Directory.CreateDirectory(tempDir);
            }
            string filename = String.Format("extract_{0}_{1}_{2}_{3}.jpg", source.GetUniqueIdentifier(), startPosition,
                maxWidth == null ? "null" : maxWidth.ToString(), maxHeight == null ? "null" : maxHeight.ToString());
            string tempFile = Path.Combine(tempDir, filename);

            // maybe it exists in cache, return that then
            if (File.Exists(tempFile))
            {
                return StreamImage(new ImageMediaSource(tempFile));
            }

            // execute it
            ProcessStartInfo info = new ProcessStartInfo();
            using (var impersonator = source.GetImpersonator())
            {
                info.Arguments = String.Format("-ss {0} -i \"{1}\" {2} -vframes 1 -f image2 {3}", startPosition, source.GetPath(), ffmpegResize, tempFile);
                info.FileName = Configuration.Streaming.FFMpegPath;
                info.CreateNoWindow = true;
                info.UseShellExecute = false;
                Process proc = new Process();
                proc.StartInfo = info;
                proc.Start();
                proc.WaitForExit();
            }

            // log when failed
            if (!File.Exists(tempFile))
            {
                Log.Warn("Failed to extract image to temporary file {0} with command {1}", tempFile, info.Arguments);
                WCFUtil.SetResponseCode(System.Net.HttpStatusCode.InternalServerError);
                return Stream.Null;
            }

            return StreamImage(new ImageMediaSource(tempFile));
        }
예제 #6
0
파일: Images.cs 프로젝트: jpykie/MPExtended
        public static Stream ExtractImage(MediaSource source, long position, int? maxWidth, int? maxHeight, string borders, string format)
        {
            if (!source.Exists)
            {
                Log.Warn("ExtractImage: Source {0} (resolved to path {1}) doesn't exists", source.GetDebugName(), source.GetPath());
                WCFUtil.SetResponseCode(System.Net.HttpStatusCode.NotFound);
                return Stream.Null;
            }

            if (!source.SupportsDirectAccess)
            {
                Log.Warn("ExtractImage: Extracting images from remote sources isn't supported yet", source.MediaType, source.Id);
                WCFUtil.SetResponseCode(System.Net.HttpStatusCode.NotImplemented);
                return Stream.Null;
            }

            // get temporary filename
            string filename = String.Format("extract_{0}_{1}.jpg", source.GetUniqueIdentifier(), position);
            string tempFile = cache.GetPath(filename);

            // maybe it exists in cache, return that then
            if (cache.Contains(filename))
            {
                // if source is newer, cached image needs to be recreated
                if (source.GetFileInfo().LastModifiedTime > cache.GetLastModifiedTime(tempFile))
                {
                    cache.Invalidate(filename);
                }
                else
                {
                    return StreamPostprocessedImage(new ImageMediaSource(tempFile), maxWidth, maxHeight, borders, format);
                }
            }

            // We need to impersonate to access the network drive and check if the thumbnail already exists. However, because
            // impersonation is lost when starting a process, we can't start ffmpeg from in here. We need to check whether the
            // file is accessible from outside the impersonation context again, and start the ffmpeg process as a different user
            // if that is the case.
            string fullPath;
            using (var context = source.CreateNetworkContext())
            {
                fullPath = context.RewritePath(source.GetPath());

                // stream a pre-existing thumbnail, if possible
                if (source.MediaType == WebMediaType.Recording && Path.GetExtension(fullPath).ToLower() == ".ts")
                {
                    var thumbnailFileInfo = new FileInfo(Path.ChangeExtension(fullPath, ".jpg"));
                    if (thumbnailFileInfo.Exists && thumbnailFileInfo.Length > 0)
                        return StreamPostprocessedImage(new ImageMediaSource(thumbnailFileInfo.FullName), maxWidth, maxHeight, borders, format);
                }
            }

            // finally, extract the image with ffmpeg if everything else has failed
            bool extractResult = ExecuteFFMpegExtraction(source, fullPath, position, tempFile);
            if (!extractResult)
            {
                WCFUtil.SetResponseCode(System.Net.HttpStatusCode.InternalServerError);
                return Stream.Null;
            }

            return StreamPostprocessedImage(new ImageMediaSource(tempFile), maxWidth, maxHeight, borders, format);
        }
예제 #7
0
 public WebMediaInfo GetForSource(MediaSource src)
 {
     return cache[src.GetUniqueIdentifier()];
 }
예제 #8
0
 public void Save(MediaSource src, WebMediaInfo info)
 {
     lock (cache)
     {
         cache[src.GetUniqueIdentifier()] = info;
     }
     isDirty = true;
 }
예제 #9
0
 public bool HasForSource(MediaSource src)
 {
     return cache.ContainsKey(src.GetUniqueIdentifier());
 }
예제 #10
0
        public void Save(MediaSource src, CachedInfoWrapper info)
        {
            lock (cache)
                cache[src.GetUniqueIdentifier()] = info;

            isDirty = true;
        }
예제 #11
0
 public CachedInfoWrapper GetForSource(MediaSource src)
 {
     return cache[src.GetUniqueIdentifier()];
 }
예제 #12
0
        public static Stream GetResizedImage(MediaSource source, WebArtworkType artworktype, int maxWidth, int maxHeight)
        {
            // load file
            ImageSource src = ConvertToImageSource(source, artworktype);
            if (src == null)
            {
                WCFUtil.SetResponseCode(System.Net.HttpStatusCode.NotFound);
                return null;
            }

            // create cache path
            string tmpDir = Path.Combine(Path.GetTempPath(), "MPExtended", "imagecache");
            if (!Directory.Exists(tmpDir))
                Directory.CreateDirectory(tmpDir);
            string cachedPath = Path.Combine(tmpDir, String.Format("rs_{0}_{1}_{2}_{3}.jpg", source.GetUniqueIdentifier(), artworktype, maxWidth, maxHeight));

            // check for existence on disk
            if (!File.Exists(cachedPath))
            {
                Image orig = Image.FromStream(src.GetDataStream());
                if (!ResizeImage(orig, cachedPath, maxWidth, maxHeight))
                {
                    return null;
                }
            }

            return StreamImage(new ImageSource(cachedPath));
        }