Example #1
0
        public static async Task <VideoInfo> ConvertToAsync(this VideoInfo video, VideoConvertInfo newfile)
        {
            var ffmpeg = new FFMpeg(Logger);

            return(await ffmpeg.ConvertToAsync(video, newfile));
        }
Example #2
0
        public async Task <VideoInfo> ConvertToAsync(VideoInfo video, VideoConvertInfo newfile)
        {
            _logger.LogDebug("Converting Video");
            DateTime STime = DateTime.Now;

            FileInfo FinalVideoFile = null;

            try
            {
                // Dim FInf = newfile.File
                //newfile.Duration = video.Duration;
                var FNWE  = video.File.FileNameWithoutExtension();
                var FNWE2 = "";


                var TempDirectory = new System.IO.DirectoryInfo(video.File.Directory.FullName + @"\.Temp");
                if (!TempDirectory.Exists)
                {
                    TempDirectory.Create();
                }
                _logger.LogDebug("Setting up file links");
                if (newfile.File == null)
                {
                    newfile.File = new System.IO.FileInfo(video.File.Directory.FullName + @"\" + FNWE + "." + newfile.VideoEncoding.ToString());
                    FNWE2        = FNWE;
                }
                else
                {
                    FNWE2 = newfile.File.FileNameWithoutExtension();
                }

                System.IO.FileInfo TempVideoFile = new System.IO.FileInfo(TempDirectory.FullName + @"\" + FNWE + newfile.File.Extension);
                // Dim TempImageFile As New System.IO.FileInfo(TempDirectory.FullName & "\" & FNWE & ".jpg")
                System.IO.FileInfo TempVideoLogFile = new System.IO.FileInfo(TempDirectory.FullName + @"\" + FNWE2 + "_" + newfile.VideoEncoding.ToString() + ".log");
                // Dim TempImageLogFile As New System.IO.FileInfo(TempDirectory.FullName & "\" & FNWE & "-Img.log")


                FinalVideoFile = newfile.File;
                // Dim FinalImageFile As New System.IO.FileInfo(newfile.File.Directory.FullName & "\" & FNWE2 & ".jpg")


                if (TempVideoFile.Exists)
                {
                    TempVideoFile.Delete();
                }
                // If TempImageFile.Exists Then
                // TempImageFile.Delete()
                // End If
                if (TempVideoLogFile.Exists)
                {
                    TempVideoLogFile.Delete();
                }
                // If TempImageLogFile.Exists Then
                // TempImageLogFile.Delete()
                // End If

                if (newfile.Width == 0 && newfile.Height == 0)
                {
                    newfile.Width  = video.Width;
                    newfile.Height = video.Height;
                }

                string AdditionalString = "";

                _logger.LogDebug("Currently    : " + video.Width + "x" + video.Height);
                _logger.LogDebug("Currently Adj: " + video.WidthAdjusted + "x" + video.HeightAdjusted);
                _logger.LogDebug("Going to    : " + newfile.Width + "x" + newfile.Height);
                _logger.LogDebug("Going to Adj: " + newfile.WidthAdjusted + "x" + newfile.HeightAdjusted);
                var TopPad    = 0;
                var BottomPad = 0;
                var LeftPad   = 0;
                var RightPad  = 0;
                if (!newfile.Stretch)
                {
                    if (video.WidthAdjusted > 0 && video.HeightAdjusted > 0)
                    {
                        if ((newfile.WidthAdjusted / (double)video.WidthAdjusted) > (newfile.HeightAdjusted / (double)video.HeightAdjusted))
                        {
                            // Y limited
                            TopPad    = 0;
                            BottomPad = 0;
                            var AF  = newfile.WidthAdjusted - video.WidthAdjusted * (newfile.HeightAdjusted / (double)video.HeightAdjusted);
                            var AF2 = System.Convert.ToInt32(AF / (double)2);
                            if (AF2 % 2 > 0)
                            {
                                AF2 += 1;
                            }
                            LeftPad  = AF2;
                            RightPad = AF2;
                        }
                        else
                        {
                            // X Limited
                            LeftPad  = 0;
                            RightPad = 0;
                            var AF  = newfile.HeightAdjusted - video.HeightAdjusted * (newfile.WidthAdjusted / (double)video.WidthAdjusted);
                            var AF2 = System.Convert.ToInt32(AF / (double)2);
                            if (AF2 % 2 > 0)
                            {
                                AF2 += 1;
                            }
                            TopPad    = AF2;
                            BottomPad = AF2;
                        }
                        if (TopPad > 0 || BottomPad > 0 || LeftPad > 0 || RightPad > 0)
                        {
                            if (newfile.VideoEncoding == VideoEncodingEnum.h264_iPod || newfile.VideoEncoding == VideoEncodingEnum.h264)
                            {
                                AdditionalString = " -padtop " + TopPad + " -padbottom " + BottomPad + " -padleft " + LeftPad + " -padright " + RightPad + " -padcolor 000000";
                            }
                            else
                            {
                                AdditionalString = " -vf pad=" + RightPad + ":" + BottomPad + ":" + LeftPad + ":" + TopPad + ":000000";
                            }
                        }
                    }
                }

                _logger.LogDebug("Converting Video");
                string LogData = "";
                if (newfile.VideoEncoding == VideoEncodingEnum.flv)
                {
                    List <TestRun> TestList = new List <TestRun>();
                    TestList.Add(new TestRun()
                    {
                        Quality = (int)newfile.QMax, Passes = newfile.NumberPasses, BitRate = newfile.BitRate, MaxQuality = (int)newfile.QMax + 5
                    });
                    if (newfile.QMax > 0)
                    {
                        var QT = (int)newfile.QMax;
                        for (int a = 200; a <= 1000; a += 200)
                        {
                            TestList.Add(new TestRun()
                            {
                                Quality = QT, Passes = newfile.NumberPasses, BitRate = newfile.BitRate + a, MaxQuality = QT + 5
                            });
                        }
                        for (int a = 0; a <= 1000; a += 200)
                        {
                            TestList.Add(new TestRun()
                            {
                                Quality = QT + 5, Passes = newfile.NumberPasses, BitRate = newfile.BitRate + a, MaxQuality = QT + 8
                            });
                            TestList.Add(new TestRun()
                            {
                                Quality = QT + 10, Passes = newfile.NumberPasses, BitRate = newfile.BitRate + a, MaxQuality = QT + 11
                            });
                        }

                        TestList = (from TR in TestList
                                    orderby(Math.Pow(TR.MaxQuality, 2) + Math.Pow(TR.BitRate / 100.0, 2) * 0.65)
                                    select TR).ToList();

                        TestList.Add(new TestRun()
                        {
                            Quality = 0, Passes = PassEnum.Two, BitRate = newfile.BitRate + 1000, MaxQuality = 40
                        });
                        TestList.Add(new TestRun()
                        {
                            Quality = 0, Passes = PassEnum.One, BitRate = newfile.BitRate + 1000, MaxQuality = 40
                        });
                    }


                    TempVideoFile.Refresh();
                    int Cnt = 0;
                    _logger.LogDebug("TestList.Count=" + TestList.Count);
                    while (((!TempVideoFile.Exists || TempVideoFile.Length < 1000) && (Cnt < TestList.Count)))
                    {
                        _logger.LogDebug("Cnt=" + Cnt + " Q=" + TestList[Cnt].Quality + " Passes=" + TestList[Cnt].Passes.ToString());
                        newfile.QMax         = TestList[Cnt].Quality;
                        newfile.NumberPasses = TestList[Cnt].Passes;
                        newfile.BitRate      = TestList[Cnt].BitRate;

                        _logger.LogDebug("MaxQuality looking for=" + TestList[Cnt].MaxQuality);
                        MaxQualityFound = 0;

                        string Arguments = "-i \"" + video.File.FullName + "\" -r " + newfile.FrameRate + " -f flv " + (newfile.Deinterlace ? "-deinterlace " : "") + "-ac " + System.Convert.ToInt32(newfile.Channels) + " -ar " + newfile.AudioFrequency + " -ab " + newfile.AudioBitRate + "k" + (newfile.AudioEncoding != AudioEncodingEnum.None ? " -acodec " + newfile.AudioEncoding.AudioFormat() : "") + " -b " + newfile.BitRate + "k -s " + (newfile.WidthAdjusted - LeftPad - RightPad) + "x" + (newfile.HeightAdjusted - TopPad - BottomPad) + " -aspect 16:9 ";
                        if (TestList[Cnt].Quality > 0)
                        {
                            Arguments = Arguments + "-qmin " + newfile.QMin + " -qmax " + newfile.QMax + " -qcomp 0.7 -g 299.7 -qdiff 4 ";
                        }
                        Arguments = Arguments + (AdditionalString + (video.IsAudio ? " -vn" : ""));
                        if (newfile.NumberPasses == PassEnum.Two)
                        {
                            MaxQualityFound = 0;
                            StartConversion?.Invoke(PassEnum.Two, 1);
                            LogData = await RunFFMpegAsync("-pass 1 " + Arguments + " -y \"" + TempVideoFile.FullName + "\"");

                            EndConversion?.Invoke();
                            MaxQualityFound = 0;
                            StartConversion?.Invoke(PassEnum.Two, 2);
                            LogData = await RunFFMpegAsync("-pass 2 " + Arguments + " -y \"" + TempVideoFile.FullName + "\"");

                            EndConversion?.Invoke();

                            if (EncodingState == EncodingStateEnum.Not_Encoding)
                            {
                            }
                        }
                        else
                        {
                            MaxQualityFound = 0;
                            StartConversion?.Invoke(PassEnum.One, 1);
                            LogData = await RunFFMpegAsync(Arguments + " -y \"" + TempVideoFile.FullName + "\"");

                            //newfile.EncodingState = video.EncodingState;
                            EndConversion?.Invoke();

                            if (EncodingState == EncodingStateEnum.Not_Encoding)
                            {
                                throw new Exception("Nothing was encoded.\n\r" + LogData);
                            }
                        }
                        Cnt += 1;
                        TempVideoFile.Refresh();
                        _logger.LogDebug("MaxQualityFound=" + MaxQualityFound);
                        _logger.LogDebug("TempVideoFile.Exists=" + TempVideoFile.Exists);
                        if (MaxQualityFound > (TestList[Cnt - 1].MaxQuality) && TempVideoFile.Exists && TempVideoFile.Length > 1000 && Cnt < TestList.Count)
                        {
                            _logger.LogDebug("Video Created but not good enough quality");

                            TempVideoFile.Delete();
                            TempVideoFile.Refresh();
                        }


                        TempVideoLogFile.Refresh();
                        if (TempVideoLogFile.Exists)
                        {
                            TempVideoLogFile.Delete();
                        }
                        var SW2 = new System.IO.StreamWriter(TempVideoLogFile.OpenWrite());
                        SW2.Write(LogData);
                        SW2.Close();
                        TempVideoLogFile.Refresh();

                        _logger.LogDebug("");
                    }
                    _logger.LogDebug("TempVideoFile.Exists=" + TempVideoFile.Exists);
                }
                else if (newfile.VideoEncoding == VideoEncodingEnum.h264)
                {
                    MaxQualityFound = 0;
                    StartConversion?.Invoke(PassEnum.One, 1);
                    var task = RunFFMpegOldAsync("-i \"" + video.File.FullName + "\" -r " + newfile.FrameRate + " -vcodec libx264 -threads 0 " + (newfile.Deinterlace ? "-deinterlace " : "") + "-ac " + System.Convert.ToInt32(newfile.Channels) + " -ar " + newfile.AudioFrequency + " -ab " + newfile.AudioBitRate + "k" + (newfile.AudioEncoding != AudioEncodingEnum.None ? " -acodec " + newfile.AudioEncoding.AudioFormat() : "") + " -s " + (newfile.WidthAdjusted - LeftPad - RightPad) + "x" + (newfile.HeightAdjusted - TopPad - BottomPad) + " -aspect 16:9 " + AdditionalString + (video.IsAudio ? " -vn" : "") + " -level 41 -crf 20 -bufsize 20000k -maxrate 25000k -g 250 -coder 1 -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -flags2 +dct8x8+bpyramid -me_method umh -subq 7 -me_range 16 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -rc_eq 'blurCplx^(1-qComp)' -bf 16 -b_strategy 1 -bidir_refine 1 -refs 6 -deblockalpha 0 -deblockbeta 0 -y \"" + TempVideoFile.FullName + "\"");

                    _logger.LogDebug("ConvertTo - Awaiting Finishing of Convert");
                    LogData = await task;
                    _logger.LogDebug("ConvertTo - Convert Finished");
                    //newfile.EncodingState = video.EncodingState;
                    EndConversion?.Invoke();

                    if (EncodingState == EncodingStateEnum.Not_Encoding)
                    {
                        throw new Exception("Nothing was encoded.\n\r" + LogData);
                    }
                }
                else if (newfile.VideoEncoding == VideoEncodingEnum.h264_iPod)
                {
                    newfile.MaxQualityFound = 0;
                    StartConversion?.Invoke(PassEnum.One, 1);
                    LogData = await RunFFMpegOldAsync("-i \"" + video.File.FullName + "\" -r " + newfile.FrameRate + " -vcodec libx264 -threads 0 " + (newfile.Deinterlace ? "-deinterlace " : "") + "-ac " + System.Convert.ToInt32(newfile.Channels) + " -ar " + newfile.AudioFrequency + " -ab " + newfile.AudioBitRate + "k" + (newfile.AudioEncoding != AudioEncodingEnum.None ? " -acodec " + newfile.AudioEncoding.AudioFormat() : "") + " -s " + (newfile.WidthAdjusted - LeftPad - RightPad) + "x" + (newfile.HeightAdjusted - TopPad - BottomPad) + " -aspect " + (newfile.WidthAdjusted) + ":" + (newfile.HeightAdjusted) + " " + AdditionalString + (video.IsAudio ? " -vn" : "") + " -vpre \"" + Core.FFMpegLocation + @"ffpresets\libx264-ipod640.ffpreset"" -b " + newfile.BitRate + "k -bt " + newfile.BitRate + "k -f ipod -y \"" + TempVideoFile.FullName + "\"");

                    //newfile.EncodingState = video.EncodingState;
                    EndConversion?.Invoke();

                    if (EncodingState == EncodingStateEnum.Not_Encoding)
                    {
                        throw new Exception("Nothing was encoded.\n\r" + LogData);
                    }
                }
                else if (newfile.VideoEncoding == VideoEncodingEnum.OGG_Theora)
                {
                    // -f ogg -vcodec libtheora -b 800k -g 300 -acodec libvorbis -ab 128k

                    string Arguments = "-i \"" + video.File.FullName + "\" -threads 0 -g 300 " + "-qmin " + newfile.QMin + " -qmax " + newfile.QMax + (newfile.Deinterlace ? " -deinterlace " : "") + " -ac " + System.Convert.ToInt32(newfile.Channels) + " -vcodec libtheora -acodec libvorbis -ab 128k -b 800k -s " + (newfile.WidthAdjusted - LeftPad - RightPad) + "x" + (newfile.HeightAdjusted - TopPad - BottomPad) + " -aspect 16:9 ";

                    MaxQualityFound = 0;
                    StartConversion?.Invoke(PassEnum.Two, 1);
                    LogData = await RunFFMpegAsync("-pass 1 " + Arguments + " -y \"" + TempVideoFile.FullName + "\"");

                    //newfile.EncodingState = EncodingState;
                    EndConversion?.Invoke();
                    MaxQualityFound = 0;
                    StartConversion?.Invoke(PassEnum.Two, 2);
                    LogData = await RunFFMpegAsync("-pass 2 " + Arguments + " -y \"" + TempVideoFile.FullName + "\"");

                    //newfile.EncodingState = EncodingState;
                    EndConversion?.Invoke();
                    if (EncodingState == EncodingStateEnum.Not_Encoding)
                    {
                        throw new Exception("Nothing was encoded.\n\r" + LogData);
                    }
                }
                else if (newfile.VideoEncoding == VideoEncodingEnum.WebM)
                {
                    string Arguments = "-i \"" + video.File.FullName + "\" -threads 0 -keyint_min 0 -g 250 -skip_threshold 0 " + "-qmin " + newfile.QMin + " -qmax " + newfile.QMax + (newfile.Deinterlace ? " -deinterlace " : "") + " -ac " + System.Convert.ToInt32(newfile.Channels) + " -vcodec libvpx -acodec libvorbis -b 614400 -s " + (newfile.WidthAdjusted - LeftPad - RightPad) + "x" + (newfile.HeightAdjusted - TopPad - BottomPad) + " -aspect 16:9 ";

                    MaxQualityFound = 0;
                    StartConversion?.Invoke(PassEnum.Two, 1);
                    LogData = await RunFFMpegAsync("-pass 1 " + Arguments + " -y \"" + TempVideoFile.FullName + "\"");

                    //newfile.EncodingState = EncodingState;
                    EndConversion?.Invoke();
                    MaxQualityFound = 0;
                    StartConversion?.Invoke(PassEnum.Two, 2);
                    LogData = await RunFFMpegAsync("-pass 2 " + Arguments + " -y \"" + TempVideoFile.FullName + "\"");

                    //EncodingState = EncodingState;
                    EndConversion?.Invoke();

                    if (EncodingState == EncodingStateEnum.Not_Encoding)
                    {
                        throw new Exception("Nothing was encoded.\n\r" + LogData);
                    }
                }
                newfile.MaxQualityFound = MaxQualityFound;

                _logger.LogDebug("Video Converted");
                TempVideoFile.Refresh();

                if (TempVideoLogFile.Exists)
                {
                    TempVideoLogFile.Delete();
                }
                var SW = new System.IO.StreamWriter(TempVideoLogFile.OpenWrite());
                SW.Write(LogData);
                SW.Close();
                TempVideoLogFile.Refresh();

                if (newfile.VideoEncoding == VideoEncodingEnum.flv)
                {
                    _logger.LogDebug("Setting Meta Data");
                    LogData = await RunFLVToolAsync("-Uk \"" + TempVideoFile.FullName + "\"");
                }



                if (!FinalVideoFile.Directory.Exists)
                {
                    FinalVideoFile.Directory.Create();
                }



                _logger.LogDebug("Handling Temp Video File");
                bool AllOK = true;
                if (TempVideoFile.Exists && TempVideoFile.Length > 1000)
                {
                    FinalVideoFile.Refresh();
                    if (FinalVideoFile.Exists)
                    {
                        FinalVideoFile.Delete();
                        FinalVideoFile.Refresh();
                    }
                    if (!FinalVideoFile.Exists)
                    {
                        TempVideoFile.MoveTo(FinalVideoFile.FullName);
                    }
                    else
                    {
                        _logger.LogDebug("FINAL VIDEO FILE still exists");
                    }
                }
                else
                {
                    AllOK = false;
                }


                _logger.LogDebug("Cleaning up directory");
                if (AllOK)
                {
                    var HisDir = new System.IO.DirectoryInfo(video.File.Directory.FullName + @"\.Temp\" + DateTime.Now.Year + DateTime.Now.Month.ToString("00") + DateTime.Now.Day.ToString("00"));
                    if (!HisDir.Exists)
                    {
                        HisDir.Create();
                    }
                    System.IO.FileInfo FF;
                    FF = new System.IO.FileInfo(HisDir.FullName + @"\" + TempVideoLogFile.Name);
                    if (FF.Exists)
                    {
                        FF.Delete();
                    }
                    TempVideoLogFile.MoveTo(FF.FullName);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, ex.ToString());
                throw;
            }

            _logger.LogDebug("Time to convert:" + (DateTime.Now.Subtract(STime).TotalMilliseconds / 1000));
            Debug.WriteLine(DateTime.Now.Subtract(STime).TotalMilliseconds / 1000);


            return(new VideoInfo(FinalVideoFile));
        }