예제 #1
0
        public Stream GetFrameStream(Config c, string virtualPath, System.Collections.Specialized.NameValueCollection queryString)
        {
            var job = new FFmpegJob(queryString);


            bool bufferToTemp = !File.Exists(HostingEnvironment.MapPath(virtualPath));

            job.SourcePath = !bufferToTemp?HostingEnvironment.MapPath(virtualPath) : Path.GetTempFileName();

            try
            {
                if (bufferToTemp)
                {
                    using (Stream input = c.Pipeline.GetFile(virtualPath, new System.Collections.Specialized.NameValueCollection()).Open())
                        using (Stream output = File.Create(job.SourcePath))
                        {
                            input.CopyToStream(output);
                        }
                }
                this.Execute(job);

                return(job.Result);
            }
            finally
            {
                if (bufferToTemp)
                {
                    File.Delete(job.SourcePath);
                }
            }
        }
예제 #2
0
        private XElement GetVideoInfo(FFmpegJob job)
        {
            //*ffprobe.exe -loglevel error -show_format -show_streams inputFile.extension -print_format json*/
            string result = RunExecutable(GetFFprobePath(), " -loglevel error -show_format -print_format xml -i \"" + job.SourcePath + "\"", job.Timeout / 2);

            return(XElement.Parse(result));
        }
예제 #3
0
        private bool InnerExecute(FFmpegJob job)
        {
            if (job.Seconds == null)
            {
                var xml      = GetVideoInfo(job);
                var duration = (double)xml.Descendants("format").FirstOrDefault().Attributes("duration").FirstOrDefault();
                job.Seconds = duration * job.Percent / 100;
            }

            bool failedTest = false;
            var  tries      = 0;

            do
            {
                if (tries > 4)
                {
                    throw new Exception("Failed to locate a non-blank frame");
                }

                var    path = Path.GetTempFileName();
                byte[] result;
                try{
                    string message = RunExecutable(GetFFmpegPath(), " -ss " + job.Seconds.ToString() + " -y -i \"" + job.SourcePath + "\" -an -vframes 1 -r 1 -f image2 -pix_fmt rgb24  \"" + path + "\"", job.Timeout);

                    if (message.Contains("Output file is empty, nothing was encoded"))
                    {
                        throw new Exception("You are outside the bounds of the video");
                    }
                    result     = File.ReadAllBytes(path);
                    job.Result = new MemoryStream(result);
                }finally{
                    File.Delete(path);
                }
                failedTest = (job.SkipBlankFrames == true && IsBlank(result, 10));
                if (failedTest)
                {
                    job.Seconds += job.IncrementWhenBlank ?? 5;
                }
                tries++;
            } while (failedTest);

            return(true);
        }
예제 #4
0
        public bool Execute(FFmpegJob job)
        {
            //If we have too many threads waiting to run CAIR, just kill the request.
            if (MaxConcurrentWaitingThreads > 0 &&
                _concurrentWaitingThreads > MaxConcurrentWaitingThreads)
            {
                throw new Exception("FFmpeg failed - too many threads waiting. Try again later.");
            }

            //If there are any threads waiting in line, or if the permitted number of CAIR.exe instances has been reached, get in line
            if (_concurrentWaitingThreads > 0 || (MaxConcurrentExecutions > 0 &&
                                                  _concurrentExecutions > MaxConcurrentExecutions))
            {
                try
                {
                    Interlocked.Increment(ref _concurrentWaitingThreads);
                    //Wait for a free slot
                    while (MaxConcurrentExecutions > 0 &&
                           _concurrentExecutions > MaxConcurrentExecutions)
                    {
                        turnstile.WaitOne(1000);
                    }
                }
                finally
                {
                    Interlocked.Decrement(ref _concurrentWaitingThreads);
                }
            }
            //Ok, there should be a free slot now.
            try
            {
                //Register, we have our own process slot now.
                Interlocked.Increment(ref _concurrentExecutions);

                return(InnerExecute(job));
            }
            finally
            {
                Interlocked.Decrement(ref _concurrentExecutions);
                turnstile.Set();
            }
        }
예제 #5
0
        public bool Execute(FFmpegJob job)
        {
            //If we have too many threads waiting to run CAIR, just kill the request.
            if (MaxConcurrentWaitingThreads > 0 &&
                _concurrentWaitingThreads > MaxConcurrentWaitingThreads)
                throw new Exception("FFmpeg failed - too many threads waiting. Try again later.");

            //If there are any threads waiting in line, or if the permitted number of CAIR.exe instances has been reached, get in line
            if (_concurrentWaitingThreads > 0 || (MaxConcurrentExecutions > 0 &&
                    _concurrentExecutions > MaxConcurrentExecutions))
            {
                try
                {
                    Interlocked.Increment(ref _concurrentWaitingThreads);
                    //Wait for a free slot
                    while (MaxConcurrentExecutions > 0 &&
                        _concurrentExecutions > MaxConcurrentExecutions)
                    {
                        turnstile.WaitOne(1000);
                    }
                }
                finally
                {
                    Interlocked.Decrement(ref _concurrentWaitingThreads);
                }
            }
            //Ok, there should be a free slot now.
            try
            {
                //Register, we have our own process slot now.
                Interlocked.Increment(ref _concurrentExecutions);

                return InnerExecute(job);

            }
            finally
            {
                Interlocked.Decrement(ref _concurrentExecutions);
                turnstile.Set();
            }
        }
예제 #6
0
        private bool InnerExecute(FFmpegJob job)
        {
            if (job.Seconds == null){
                var xml = GetVideoInfo(job);
                var duration = (double)xml.Descendants("format").FirstOrDefault().Attributes("duration").FirstOrDefault();
                job.Seconds = duration * job.Percent / 100;
            }

            bool failedTest = false;
            var tries = 0;
            do
            {
                if (tries > 4) throw new Exception("Failed to locate a non-blank frame");

                var path = Path.GetTempFileName();
                byte[] result;
                try{
                    string message = RunExecutable(GetFFmpegPath(), " -ss " + job.Seconds.ToString() + " -y -i \"" + job.SourcePath + "\" -an -vframes 1 -r 1 -f image2 -pix_fmt rgb24  \"" + path + "\"", job.Timeout);

                    if (message.Contains("Output file is empty, nothing was encoded"))
                    {
                        throw new Exception("You are outside the bounds of the video");
                    }
                    result = File.ReadAllBytes(path);
                    job.Result = new MemoryStream(result);
                }finally{
                    File.Delete(path);
                }
                failedTest = (job.SkipBlankFrames == true && IsBlank(result,10));
                if (failedTest) job.Seconds += job.IncrementWhenBlank ?? 5;
                tries++;

            } while (failedTest);

            return true;
        }
예제 #7
0
 private XElement GetVideoInfo(FFmpegJob job)
 {
     //*ffprobe.exe -loglevel error -show_format -show_streams inputFile.extension -print_format json*/
     string result = RunExecutable(GetFFprobePath(), " -loglevel error -show_format -print_format xml -i \"" + job.SourcePath + "\"", job.Timeout /2);
     return XElement.Parse(result);
 }
예제 #8
0
        public Stream GetFrameStream(Config c,string virtualPath, System.Collections.Specialized.NameValueCollection queryString)
        {
            var job = new FFmpegJob(queryString);

            bool bufferToTemp = !File.Exists(HostingEnvironment.MapPath(virtualPath));

            job.SourcePath = !bufferToTemp ? HostingEnvironment.MapPath(virtualPath) : Path.GetTempFileName();
            try
            {
                if (bufferToTemp)
                {
                    using (Stream input = c.Pipeline.GetFile(virtualPath, new System.Collections.Specialized.NameValueCollection()).Open())
                    using (Stream output = File.Create(job.SourcePath))
                    {
                        StreamExtensions.CopyToStream(input, output);
                    }
                }
                this.Execute(job);

                return job.Result;
            }
            finally
            {
                if (bufferToTemp) File.Delete(job.SourcePath);
            }
        }