Exemplo n.º 1
0
 public void AddFrame(string path, GIFQuality quality = GIFQuality.Default)
 {
     using (Image img = ImageHelpers.LoadImage(path))
     {
         AddFrame(img, quality);
     }
 }
Exemplo n.º 2
0
        public static void SaveGIF(this Image img, Stream stream, GIFQuality quality)
        {
            if (quality == GIFQuality.Default)
            {
                img.Save(stream, ImageFormat.Gif);
            }
            else
            {
                Quantizer quantizer;
                switch (quality)
                {
                case GIFQuality.Grayscale:
                    quantizer = new GrayscaleQuantizer();
                    break;

                case GIFQuality.Bit4:
                    quantizer = new OctreeQuantizer(15, 4);
                    break;

                default:
                case GIFQuality.Bit8:
                    quantizer = new OctreeQuantizer(255, 4);
                    break;
                }

                using (Bitmap quantized = quantizer.Quantize(img))
                {
                    quantized.Save(stream, ImageFormat.Gif);
                }
            }
        }
        public static void SaveGIF(this Image img, Stream stream, GIFQuality quality)
        {
            if (quality == GIFQuality.Default)
            {
                img.Save(stream, ImageFormat.Gif);
            }
            else
            {
                Quantizer quantizer;
                switch (quality)
                {
                    case GIFQuality.Grayscale:
                        quantizer = new GrayscaleQuantizer();
                        break;
                    case GIFQuality.Bit4:
                        quantizer = new OctreeQuantizer(15, 4);
                        break;
                    case GIFQuality.Bit8:
                    default:
                        quantizer = new OctreeQuantizer(255, 4);
                        break;
                }

                using (Bitmap quantized = quantizer.Quantize(img))
                {
                    quantized.Save(stream, ImageFormat.Gif);
                }
            }
        }
Exemplo n.º 4
0
 public void AddFrame(string path, GIFQuality quality = GIFQuality.Default)
 {
     using (Image img = Helpers.GetImageFromFile(path))
     {
         AddFrame(img, quality);
     }
 }
Exemplo n.º 5
0
        public void LoadGifPicture(Image img, GIFQuality quality)
        {
            List<byte> dataList;

            using (MemoryStream ms = new MemoryStream())
            {
                img.SaveGIF(ms, quality);
                dataList = new List<byte>(ms.ToArray());
            }

            if (!AnalyzeGifSignature(dataList))
            {
                throw new Exception("File is not a gif!");
            }

            AnalyzeScreenDescriptor(dataList);

            GIFBlockType blockType = GetTypeOfNextBlock(dataList);

            while (blockType != GIFBlockType.Trailer)
            {
                switch (blockType)
                {
                    case GIFBlockType.ImageDescriptor:
                        AnalyzeImageDescriptor(dataList);
                        break;
                    case GIFBlockType.Extension:
                        ThrowAwayExtensionBlock(dataList);
                        break;
                }

                blockType = GetTypeOfNextBlock(dataList);
            }
        }
Exemplo n.º 6
0
        public void AddFrame(Image img, GIFQuality quality = GIFQuality.Default)
        {
            GifClass gif = new GifClass();
            gif.LoadGifPicture(img, quality);

            if (frameNum == 0)
            {
                binaryWriter.Write(gif.m_ScreenDescriptor.ToArray());
            }

            binaryWriter.Write(graphicControlExtensionBlock);
            binaryWriter.Write(gif.m_ImageDescriptor.ToArray());
            binaryWriter.Write(gif.m_ColorTable.ToArray());
            binaryWriter.Write(gif.m_ImageData.ToArray());

            frameNum++;
        }
Exemplo n.º 7
0
        public void AddFrame(Image img, GIFQuality quality = GIFQuality.Default)
        {
            GifClass gif = new GifClass();

            gif.LoadGifPicture(img, quality);

            if (frameNum == 0)
            {
                binaryWriter.Write(gif.m_ScreenDescriptor.ToArray());
            }

            binaryWriter.Write(graphicControlExtensionBlock);
            binaryWriter.Write(gif.m_ImageDescriptor.ToArray());
            binaryWriter.Write(gif.m_ColorTable.ToArray());
            binaryWriter.Write(gif.m_ImageData.ToArray());

            frameNum++;
        }
Exemplo n.º 8
0
        public void AddFrame(Image img, GIFQuality quality = GIFQuality.Default)
        {
            GifClass gif = new GifClass();
            gif.LoadGifPicture(img, quality);

            if (stream == null)
            {
                stream = new FileStream(FilePath, FileMode.Create, FileAccess.Write, FileShare.Read);
                stream.Write(CreateHeaderBlock());
                stream.Write(gif.ScreenDescriptor.ToArray());
                stream.Write(CreateApplicationExtensionBlock(Repeat));
            }

            stream.Write(CreateGraphicsControlExtensionBlock(Delay));
            stream.Write(gif.ImageDescriptor.ToArray());
            stream.Write(gif.ColorTable.ToArray());
            stream.Write(gif.ImageData.ToArray());

            FrameCount++;
        }
Exemplo n.º 9
0
        public void AddFrame(Image img, GIFQuality quality = GIFQuality.Default)
        {
            GifClass gif = new GifClass();
            gif.LoadGifPicture(img, quality);

            if (stream == null)
            {
                stream = new FileStream(FilePath, FileMode.Create, FileAccess.Write, FileShare.Read);
                stream.Write(CreateHeaderBlock());
                stream.Write(gif.ScreenDescriptor.ToArray());
                stream.Write(CreateApplicationExtensionBlock(Repeat));
            }

            stream.Write(CreateGraphicsControlExtensionBlock(Delay));
            stream.Write(gif.ImageDescriptor.ToArray());
            stream.Write(gif.ColorTable.ToArray());
            stream.Write(gif.ImageData.ToArray());

            FrameCount++;
        }
Exemplo n.º 10
0
        /// <summary>
        ///     Add a new frame to the GIF
        /// </summary>
        /// <param name="image">The image to add to the GIF stack</param>
        /// <param name="delay">The delay in milliseconds this GIF will be delayed (-1: Indicating class property delay)</param>
        /// <param name="quality">The GIFs quality</param>
        public void AddFrame(Image image, int delay = -1, GIFQuality quality = GIFQuality.Default)
        {
            var gif = new GifClass();

            gif.LoadGifImage(image, quality);

            if (!_createdHeader)
            {
                AppendToStream(CreateHeaderBlock());
                AppendToStream(gif.ScreenDescriptor.ToArray());
                AppendToStream(CreateApplicationExtensionBlock(Repeat));
                _createdHeader = true;
            }

            AppendToStream(CreateGraphicsControlExtensionBlock(delay > -1 ? delay : Delay));
            AppendToStream(gif.ImageDescriptor.ToArray());
            AppendToStream(gif.ColorTable.ToArray());
            AppendToStream(gif.ImageData.ToArray());

            FrameCount++;
        }
Exemplo n.º 11
0
        /// <summary>
        ///     Add a new frame to the GIF async
        /// </summary>
        /// <param name="image">The image to add to the GIF stack</param>
        /// <param name="delay">The delay in milliseconds this GIF will be delayed (-1: Indicating class property delay)</param>
        /// <param name="quality">The GIFs quality</param>
        public async Task AddFrameAsync(Image image, int delay = -1, GIFQuality quality = GIFQuality.Default, CancellationToken cancellationToken = default(CancellationToken))
        {
            var gif = new GifClass();

            gif.LoadGifImage(image, quality);

            if (!_createdHeader)
            {
                await AppendToStreamAsync(CreateHeaderBlock(), cancellationToken);
                await AppendToStreamAsync(gif.ScreenDescriptor.ToArray(), cancellationToken);
                await AppendToStreamAsync(CreateApplicationExtensionBlock(Repeat), cancellationToken);

                _createdHeader = true;
            }

            await AppendToStreamAsync(CreateGraphicsControlExtensionBlock(delay > -1 ? delay : Delay), cancellationToken);
            await AppendToStreamAsync(gif.ImageDescriptor.ToArray(), cancellationToken);
            await AppendToStreamAsync(gif.ColorTable.ToArray(), cancellationToken);
            await AppendToStreamAsync(gif.ImageData.ToArray(), cancellationToken);

            FrameCount++;
        }
Exemplo n.º 12
0
        public static MemoryStream SaveImageAsStream(Image img, EImageFormat imageFormat, PNGBitDepth pngBitDepth = PNGBitDepth.Automatic,
                                                     int jpegQuality = 90, GIFQuality gifQuality = GIFQuality.Default)
        {
            MemoryStream stream = new MemoryStream();

            switch (imageFormat)
            {
            case EImageFormat.PNG:
                SaveImageAsPNGStream(img, stream, pngBitDepth);

                if (Option.Settings.PNGStripColorSpaceInformation)
                {
                    using (stream)
                    {
                        return(PNGStripColorSpaceInformation(stream));
                    }
                }
                break;

            case EImageFormat.JPEG:
                SaveImageAsJPEGStream(img, stream, jpegQuality);
                break;

            case EImageFormat.GIF:
                img.SaveGIF(stream, gifQuality);
                break;

            case EImageFormat.BMP:
                img.Save(stream, ImageFormat.Bmp);
                break;

            case EImageFormat.TIFF:
                img.Save(stream, ImageFormat.Tiff);
                break;
            }

            return(stream);
        }
Exemplo n.º 13
0
        public void SaveAsGIF(string path, GIFQuality quality)
        {
            if (imgCache != null && imgCache is HardDiskCache && !IsRecording)
            {
                HardDiskCache hdCache = imgCache as HardDiskCache;

                using (AnimatedGifCreator gifEncoder = new AnimatedGifCreator(path, delay))
                {
                    int i     = 0;
                    int count = hdCache.Count;

                    foreach (Image img in hdCache.GetImageEnumerator())
                    {
                        i++;
                        OnEncodingProgressChanged((int)((float)i / count * 100));

                        using (img)
                        {
                            gifEncoder.AddFrame(img, quality);
                        }
                    }
                }
            }
        }
Exemplo n.º 14
0
        public void StartRecording(ScreenRecordOutput outputType, TaskSettings taskSettings, ScreenRecordStartMethod startMethod = ScreenRecordStartMethod.Region)
        {
            string debugText;

            if (outputType == ScreenRecordOutput.FFmpeg)
            {
                debugText = string.Format("Starting FFmpeg recording. Video encoder: \"{0}\", Audio encoder: \"{1}\", FPS: {2}",
                                          taskSettings.CaptureSettings.FFmpegOptions.VideoCodec.GetDescription(), taskSettings.CaptureSettings.FFmpegOptions.AudioCodec.GetDescription(),
                                          taskSettings.CaptureSettings.ScreenRecordFPS);
            }
            else
            {
                debugText = string.Format("Starting Animated GIF recording. GIF encoding: \"{0}\", FPS: {1}",
                                          taskSettings.CaptureSettings.GIFEncoding.GetDescription(), taskSettings.CaptureSettings.GIFFPS);
            }

            DebugHelper.WriteLine(debugText);

            if (taskSettings.CaptureSettings.RunScreencastCLI)
            {
                if (!Program.Settings.VideoEncoders.IsValidIndex(taskSettings.CaptureSettings.VideoEncoderSelected))
                {
                    MessageBox.Show(Resources.ScreenRecordForm_StartRecording_There_is_no_valid_CLI_video_encoder_selected_,
                                    "ShareXYZ", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                if (!Program.Settings.VideoEncoders[taskSettings.CaptureSettings.VideoEncoderSelected].IsValid())
                {
                    MessageBox.Show(Resources.ScreenRecordForm_StartRecording_CLI_video_encoder_file_does_not_exist__ +
                                    Program.Settings.VideoEncoders[taskSettings.CaptureSettings.VideoEncoderSelected].Path,
                                    "ShareXYZ", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
            }

            if (outputType == ScreenRecordOutput.GIF && taskSettings.CaptureSettings.GIFEncoding == ScreenRecordGIFEncoding.FFmpeg)
            {
                outputType = ScreenRecordOutput.FFmpeg;
                taskSettings.CaptureSettings.FFmpegOptions.VideoCodec        = FFmpegVideoCodec.gif;
                taskSettings.CaptureSettings.FFmpegOptions.UseCustomCommands = false;
            }

            if (outputType == ScreenRecordOutput.FFmpeg)
            {
                if (!TaskHelpers.CheckFFmpeg(taskSettings))
                {
                    return;
                }

                if (!taskSettings.CaptureSettings.FFmpegOptions.IsSourceSelected)
                {
                    MessageBox.Show(Resources.ScreenRecordForm_StartRecording_FFmpeg_video_and_audio_source_both_can_t_be__None__,
                                    "ShareXYZ - " + Resources.ScreenRecordForm_StartRecording_FFmpeg_error, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
            }

            Rectangle captureRectangle = Rectangle.Empty;

            switch (startMethod)
            {
            case ScreenRecordStartMethod.Region:
                TaskHelpers.SelectRegion(out captureRectangle, taskSettings);
                break;

            case ScreenRecordStartMethod.ActiveWindow:
                if (taskSettings.CaptureSettings.CaptureClientArea)
                {
                    captureRectangle = CaptureHelpers.GetActiveWindowClientRectangle();
                }
                else
                {
                    captureRectangle = CaptureHelpers.GetActiveWindowRectangle();
                }
                break;

            case ScreenRecordStartMethod.LastRegion:
                captureRectangle = Program.Settings.ScreenRecordRegion;
                break;
            }

            captureRectangle = CaptureHelpers.EvenRectangleSize(captureRectangle);

            if (IsRecording || !captureRectangle.IsValid() || screenRecorder != null)
            {
                return;
            }

            Program.Settings.ScreenRecordRegion = captureRectangle;

            IsRecording = true;

            Screenshot.CaptureCursor = taskSettings.CaptureSettings.ScreenRecordShowCursor;

            string trayText = "ShareXYZ - " + Resources.ScreenRecordForm_StartRecording_Waiting___;

            TrayIcon.Text    = trayText.Truncate(63);
            TrayIcon.Icon    = Resources.control_record_yellow.ToIcon();
            cmsMain.Enabled  = false;
            TrayIcon.Visible = true;

            string path = "";

            float duration = taskSettings.CaptureSettings.ScreenRecordFixedDuration ? taskSettings.CaptureSettings.ScreenRecordDuration : 0;

            regionForm = ScreenRegionForm.Show(captureRectangle, StopRecording, startMethod == ScreenRecordStartMethod.Region, duration);
            regionForm.RecordResetEvent = new ManualResetEvent(false);

            TaskEx.Run(() =>
            {
                try
                {
                    if (outputType == ScreenRecordOutput.FFmpeg)
                    {
                        path = Path.Combine(taskSettings.CaptureFolder, TaskHelpers.GetFilename(taskSettings, taskSettings.CaptureSettings.FFmpegOptions.Extension));
                    }
                    else
                    {
                        path = Program.ScreenRecorderCacheFilePath;
                    }

                    ScreencastOptions options = new ScreencastOptions()
                    {
                        FFmpeg          = taskSettings.CaptureSettings.FFmpegOptions,
                        ScreenRecordFPS = taskSettings.CaptureSettings.ScreenRecordFPS,
                        GIFFPS          = taskSettings.CaptureSettings.GIFFPS,
                        Duration        = duration,
                        OutputPath      = path,
                        CaptureArea     = captureRectangle,
                        DrawCursor      = taskSettings.CaptureSettings.ScreenRecordShowCursor
                    };

                    screenRecorder = new ScreenRecorder(outputType, options, captureRectangle);

                    if (regionForm != null && regionForm.RecordResetEvent != null)
                    {
                        trayText      = "ShareXYZ - " + Resources.ScreenRecordForm_StartRecording_Click_tray_icon_to_start_recording_;
                        TrayIcon.Text = trayText.Truncate(63);

                        this.InvokeSafe(() =>
                        {
                            tsmiStart.Text  = Resources.AutoCaptureForm_Execute_Start;
                            cmsMain.Enabled = true;
                        });

                        if (taskSettings.CaptureSettings.ScreenRecordAutoStart)
                        {
                            int delay = (int)(taskSettings.CaptureSettings.ScreenRecordStartDelay * 1000);

                            if (delay > 0)
                            {
                                regionForm.InvokeSafe(() => regionForm.StartCountdown(delay));

                                regionForm.RecordResetEvent.WaitOne(delay);
                            }
                        }
                        else
                        {
                            regionForm.RecordResetEvent.WaitOne();
                        }

                        if (regionForm.AbortRequested)
                        {
                            abortRequested = true;
                        }
                    }

                    if (!abortRequested)
                    {
                        trayText      = "ShareXYZ - " + Resources.ScreenRecordForm_StartRecording_Click_tray_icon_to_stop_recording_;
                        TrayIcon.Text = trayText.Truncate(63);
                        TrayIcon.Icon = Resources.control_record.ToIcon();

                        this.InvokeSafe(() =>
                        {
                            tsmiStart.Text = Resources.AutoCaptureForm_Execute_Stop;
                        });

                        if (regionForm != null)
                        {
                            regionForm.InvokeSafe(() => regionForm.StartRecordingTimer(duration > 0, duration));
                        }

                        screenRecorder.StartRecording();

                        if (regionForm != null && regionForm.AbortRequested)
                        {
                            abortRequested = true;
                        }
                    }
                }
                catch (Exception e)
                {
                    DebugHelper.WriteException(e);
                }
                finally
                {
                    if (regionForm != null)
                    {
                        if (regionForm.RecordResetEvent != null)
                        {
                            regionForm.RecordResetEvent.Dispose();
                        }

                        regionForm.InvokeSafe(() => regionForm.Close());
                        regionForm = null;
                    }
                }

                try
                {
                    if (!abortRequested && screenRecorder != null)
                    {
                        TrayIcon.Text = "ShareXYZ - " + Resources.ScreenRecordForm_StartRecording_Encoding___;
                        TrayIcon.Icon = Resources.camcorder_pencil.ToIcon();

                        this.InvokeSafe(() =>
                        {
                            cmsMain.Enabled = false;
                        });

                        if (outputType == ScreenRecordOutput.GIF)
                        {
                            path = Path.Combine(taskSettings.CaptureFolder, TaskHelpers.GetFilename(taskSettings, "gif"));
                            screenRecorder.EncodingProgressChanged += progress => TrayIcon.Text = string.Format("ShareXYZ - {0} ({1}%)", Resources.ScreenRecordForm_StartRecording_Encoding___, progress);
                            GIFQuality gifQuality = taskSettings.CaptureSettings.GIFEncoding == ScreenRecordGIFEncoding.OctreeQuantizer ? GIFQuality.Bit8 : GIFQuality.Default;
                            screenRecorder.SaveAsGIF(path, gifQuality);
                        }
                        else if (outputType == ScreenRecordOutput.FFmpeg && taskSettings.CaptureSettings.FFmpegOptions.VideoCodec == FFmpegVideoCodec.gif)
                        {
                            path = Path.Combine(taskSettings.CaptureFolder, TaskHelpers.GetFilename(taskSettings, "gif"));
                            screenRecorder.FFmpegEncodeAsGIF(path);
                        }

                        if (taskSettings.CaptureSettings.RunScreencastCLI)
                        {
                            VideoEncoder encoder  = Program.Settings.VideoEncoders[taskSettings.CaptureSettings.VideoEncoderSelected];
                            string sourceFilePath = path;
                            path = Path.Combine(taskSettings.CaptureFolder, TaskHelpers.GetFilename(taskSettings, encoder.OutputExtension));
                            screenRecorder.EncodeUsingCommandLine(encoder, sourceFilePath, path);
                        }
                    }
                }
                finally
                {
                    if (screenRecorder != null)
                    {
                        if ((outputType == ScreenRecordOutput.GIF || taskSettings.CaptureSettings.RunScreencastCLI ||
                             (outputType == ScreenRecordOutput.FFmpeg && taskSettings.CaptureSettings.FFmpegOptions.VideoCodec == FFmpegVideoCodec.gif)) &&
                            !string.IsNullOrEmpty(screenRecorder.CachePath) && File.Exists(screenRecorder.CachePath))
                        {
                            File.Delete(screenRecorder.CachePath);
                        }

                        screenRecorder.Dispose();
                        screenRecorder = null;

                        if (abortRequested && !string.IsNullOrEmpty(path) && File.Exists(path))
                        {
                            File.Delete(path);
                        }
                    }
                }
            },
                       () =>
            {
                if (TrayIcon.Visible)
                {
                    TrayIcon.Visible = false;
                }

                if (!abortRequested && !string.IsNullOrEmpty(path) && File.Exists(path) && TaskHelpers.ShowAfterCaptureForm(taskSettings))
                {
                    WorkerTask task = WorkerTask.CreateFileJobTask(path, taskSettings);
                    TaskManager.Start(task);
                }

                abortRequested = false;
                IsRecording    = false;
            });
        }
Exemplo n.º 15
0
        public static MemoryStream SaveImage(Image img, EImageFormat imageFormat, int jpegQuality = 90, GIFQuality gifQuality = GIFQuality.Default)
        {
            MemoryStream stream = new MemoryStream();

            switch (imageFormat)
            {
            case EImageFormat.PNG:
                img.Save(stream, ImageFormat.Png);
                break;

            case EImageFormat.JPEG:
                img.SaveJPG(stream, jpegQuality);
                break;

            case EImageFormat.GIF:
                img.SaveGIF(stream, gifQuality);
                break;

            case EImageFormat.BMP:
                img.Save(stream, ImageFormat.Bmp);
                break;

            case EImageFormat.TIFF:
                img.Save(stream, ImageFormat.Tiff);
                break;
            }

            return(stream);
        }
Exemplo n.º 16
0
        public void SaveAsGIF(string path, GIFQuality quality)
        {
            if (!IsRecording)
            {
                using (GifCreator gifEncoder = new GifCreator(delay))
                {
                    int i = 0;
                    int count = hdCache.Count;

                    foreach (Image img in hdCache.GetImageEnumerator())
                    {
                        i++;
                        OnEncodingProgressChanged((int)((float)i / count * 100));

                        using (img)
                        {
                            gifEncoder.AddFrame(img, quality);
                        }
                    }

                    gifEncoder.Finish();
                    gifEncoder.Save(path);
                }
            }
        }
Exemplo n.º 17
0
        public void SaveAsGIF(string path, GIFQuality quality)
        {
            if (imgCache != null && imgCache is HardDiskCache && !IsRecording)
            {
                Helpers.CreateDirectoryFromFilePath(path);

                HardDiskCache hdCache = imgCache as HardDiskCache;

                using (AnimatedGifCreator gifEncoder = new AnimatedGifCreator(path, delay))
                {
                    int i = 0;
                    int count = hdCache.Count;

                    foreach (Image img in hdCache.GetImageEnumerator())
                    {
                        i++;
                        OnEncodingProgressChanged((int)((float)i / count * 100));

                        using (img)
                        {
                            gifEncoder.AddFrame(img, quality);
                        }
                    }
                }
            }
        }
Exemplo n.º 18
0
        public static MemoryStream SaveImageAsStream(Image img, EImageFormat imageFormat, int jpegQuality = 90, GIFQuality gifQuality = GIFQuality.Default)
        {
            MemoryStream stream = new MemoryStream();

            switch (imageFormat)
            {
            case EImageFormat.PNG:
                img.Save(stream, ImageFormat.Png);
                break;

            case EImageFormat.JPEG:
                try
                {
                    img = (Image)img.Clone();
                    img = ImageHelpers.FillBackground(img, Color.White);
                    img.SaveJPG(stream, jpegQuality);
                }
                finally
                {
                    if (img != null)
                    {
                        img.Dispose();
                    }
                }
                break;

            case EImageFormat.GIF:
                img.SaveGIF(stream, gifQuality);
                break;

            case EImageFormat.BMP:
                img.Save(stream, ImageFormat.Bmp);
                break;

            case EImageFormat.TIFF:
                img.Save(stream, ImageFormat.Tiff);
                break;
            }

            return(stream);
        }
Exemplo n.º 19
0
        private static void StartRecording(ScreenRecordOutput outputType, TaskSettings taskSettings, ScreenRecordStartMethod startMethod = ScreenRecordStartMethod.Region)
        {
            string debugText;

            if (outputType == ScreenRecordOutput.FFmpeg)
            {
                debugText = string.Format("Starting FFmpeg recording. Video encoder: \"{0}\", Audio encoder: \"{1}\", FPS: {2}",
                                          taskSettings.CaptureSettings.FFmpegOptions.VideoCodec.GetDescription(), taskSettings.CaptureSettings.FFmpegOptions.AudioCodec.GetDescription(),
                                          taskSettings.CaptureSettings.ScreenRecordFPS);
            }
            else
            {
                debugText = string.Format("Starting Animated GIF recording. GIF encoding: \"{0}\", FPS: {1}",
                                          taskSettings.CaptureSettings.GIFEncoding.GetDescription(), taskSettings.CaptureSettings.GIFFPS);
            }

            DebugHelper.WriteLine(debugText);

            if (taskSettings.CaptureSettings.RunScreencastCLI)
            {
                if (!Program.Settings.VideoEncoders.IsValidIndex(taskSettings.CaptureSettings.VideoEncoderSelected))
                {
                    MessageBox.Show(Resources.ScreenRecordForm_StartRecording_There_is_no_valid_CLI_video_encoder_selected_,
                                    "ShareX", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                if (!Program.Settings.VideoEncoders[taskSettings.CaptureSettings.VideoEncoderSelected].IsValid())
                {
                    MessageBox.Show(Resources.ScreenRecordForm_StartRecording_CLI_video_encoder_file_does_not_exist__ +
                                    Program.Settings.VideoEncoders[taskSettings.CaptureSettings.VideoEncoderSelected].Path,
                                    "ShareX", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
            }

            if (outputType == ScreenRecordOutput.GIF && taskSettings.CaptureSettings.GIFEncoding == ScreenRecordGIFEncoding.FFmpeg)
            {
                outputType = ScreenRecordOutput.FFmpeg;
                taskSettings.CaptureSettings.FFmpegOptions.VideoCodec        = FFmpegVideoCodec.gif;
                taskSettings.CaptureSettings.FFmpegOptions.UseCustomCommands = false;
            }

            if (outputType == ScreenRecordOutput.FFmpeg)
            {
                if (!TaskHelpers.CheckFFmpeg(taskSettings))
                {
                    return;
                }

                if (!taskSettings.CaptureSettings.FFmpegOptions.IsSourceSelected)
                {
                    MessageBox.Show(Resources.ScreenRecordForm_StartRecording_FFmpeg_video_and_audio_source_both_can_t_be__None__,
                                    "ShareX - " + Resources.ScreenRecordForm_StartRecording_FFmpeg_error, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
            }

            Rectangle captureRectangle = Rectangle.Empty;

            switch (startMethod)
            {
            case ScreenRecordStartMethod.Region:
                RegionCaptureTasks.GetRectangleRegion(out captureRectangle, taskSettings.CaptureSettings.SurfaceOptions);
                break;

            case ScreenRecordStartMethod.ActiveWindow:
                if (taskSettings.CaptureSettings.CaptureClientArea)
                {
                    captureRectangle = CaptureHelpers.GetActiveWindowClientRectangle();
                }
                else
                {
                    captureRectangle = CaptureHelpers.GetActiveWindowRectangle();
                }
                break;

            case ScreenRecordStartMethod.CustomRegion:
                captureRectangle = taskSettings.CaptureSettings.CaptureCustomRegion;
                break;

            case ScreenRecordStartMethod.LastRegion:
                captureRectangle = Program.Settings.ScreenRecordRegion;
                break;
            }

            captureRectangle = CaptureHelpers.EvenRectangleSize(captureRectangle);

            if (IsRecording || !captureRectangle.IsValid() || screenRecorder != null)
            {
                return;
            }

            Program.Settings.ScreenRecordRegion = captureRectangle;

            IsRecording = true;

            string path           = "";
            bool   abortRequested = false;

            float duration = taskSettings.CaptureSettings.ScreenRecordFixedDuration ? taskSettings.CaptureSettings.ScreenRecordDuration : 0;

            recordForm = new ScreenRecordForm(captureRectangle, startMethod == ScreenRecordStartMethod.Region, duration);
            recordForm.StopRequested += StopRecording;
            recordForm.Show();

            TaskEx.Run(() =>
            {
                try
                {
                    if (outputType == ScreenRecordOutput.FFmpeg)
                    {
                        string filename = TaskHelpers.GetFilename(taskSettings, taskSettings.CaptureSettings.FFmpegOptions.Extension);
                        path            = TaskHelpers.CheckFilePath(taskSettings.CaptureFolder, filename, taskSettings);
                    }
                    else
                    {
                        path = Program.ScreenRecorderCacheFilePath;
                    }

                    if (string.IsNullOrEmpty(path))
                    {
                        abortRequested = true;
                    }

                    if (!abortRequested)
                    {
                        recordForm.ChangeState(ScreenRecordState.BeforeStart);

                        if (taskSettings.CaptureSettings.ScreenRecordAutoStart)
                        {
                            int delay = (int)(taskSettings.CaptureSettings.ScreenRecordStartDelay * 1000);

                            if (delay > 0)
                            {
                                recordForm.InvokeSafe(() => recordForm.StartCountdown(delay));

                                recordForm.RecordResetEvent.WaitOne(delay);
                            }
                        }
                        else
                        {
                            recordForm.RecordResetEvent.WaitOne();
                        }

                        if (recordForm.AbortRequested)
                        {
                            abortRequested = true;
                        }

                        if (!abortRequested)
                        {
                            ScreencastOptions options = new ScreencastOptions()
                            {
                                FFmpeg          = taskSettings.CaptureSettings.FFmpegOptions,
                                ScreenRecordFPS = taskSettings.CaptureSettings.ScreenRecordFPS,
                                GIFFPS          = taskSettings.CaptureSettings.GIFFPS,
                                Duration        = duration,
                                OutputPath      = path,
                                CaptureArea     = captureRectangle,
                                DrawCursor      = taskSettings.CaptureSettings.ScreenRecordShowCursor
                            };

                            Screenshot screenshot    = TaskHelpers.GetScreenshot(taskSettings);
                            screenshot.CaptureCursor = taskSettings.CaptureSettings.ScreenRecordShowCursor;

                            screenRecorder = new ScreenRecorder(outputType, options, screenshot, captureRectangle);
                            screenRecorder.RecordingStarted += () => recordForm.ChangeState(ScreenRecordState.AfterRecordingStart);
                            recordForm.ChangeState(ScreenRecordState.AfterStart);
                            screenRecorder.StartRecording();

                            if (recordForm.AbortRequested)
                            {
                                abortRequested = true;
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    DebugHelper.WriteException(e);
                }

                try
                {
                    if (!abortRequested && screenRecorder != null)
                    {
                        recordForm.ChangeState(ScreenRecordState.AfterStop);

                        if (outputType == ScreenRecordOutput.GIF)
                        {
                            path = Path.Combine(taskSettings.CaptureFolder, TaskHelpers.GetFilename(taskSettings, "gif"));
                            screenRecorder.EncodingProgressChanged += progress => recordForm.ChangeStateProgress(progress);
                            GIFQuality gifQuality = taskSettings.CaptureSettings.GIFEncoding == ScreenRecordGIFEncoding.OctreeQuantizer ? GIFQuality.Bit8 : GIFQuality.Default;
                            screenRecorder.SaveAsGIF(path, gifQuality);
                        }
                        else if (outputType == ScreenRecordOutput.FFmpeg && taskSettings.CaptureSettings.FFmpegOptions.VideoCodec == FFmpegVideoCodec.gif)
                        {
                            path = Path.Combine(taskSettings.CaptureFolder, TaskHelpers.GetFilename(taskSettings, "gif"));
                            screenRecorder.FFmpegEncodeAsGIF(path);
                        }

                        if (taskSettings.CaptureSettings.RunScreencastCLI)
                        {
                            VideoEncoder encoder  = Program.Settings.VideoEncoders[taskSettings.CaptureSettings.VideoEncoderSelected];
                            string sourceFilePath = path;
                            path = Path.Combine(taskSettings.CaptureFolder, TaskHelpers.GetFilename(taskSettings, encoder.OutputExtension));
                            screenRecorder.EncodeUsingCommandLine(encoder, sourceFilePath, path);
                        }
                    }
                }
                finally
                {
                    if (recordForm != null)
                    {
                        recordForm.InvokeSafe(() =>
                        {
                            recordForm.Close();
                            recordForm.Dispose();
                            recordForm = null;
                        });
                    }

                    if (screenRecorder != null)
                    {
                        if ((outputType == ScreenRecordOutput.GIF || taskSettings.CaptureSettings.RunScreencastCLI ||
                             (outputType == ScreenRecordOutput.FFmpeg && taskSettings.CaptureSettings.FFmpegOptions.VideoCodec == FFmpegVideoCodec.gif)) &&
                            !string.IsNullOrEmpty(screenRecorder.CachePath) && File.Exists(screenRecorder.CachePath))
                        {
                            File.Delete(screenRecorder.CachePath);
                        }

                        screenRecorder.Dispose();
                        screenRecorder = null;

                        if (abortRequested && !string.IsNullOrEmpty(path) && File.Exists(path))
                        {
                            File.Delete(path);
                        }
                    }
                }
            },
                       () =>
            {
                string customFileName;

                if (!abortRequested && !string.IsNullOrEmpty(path) && File.Exists(path) && TaskHelpers.ShowAfterCaptureForm(taskSettings, out customFileName, null, path))
                {
                    if (!string.IsNullOrEmpty(customFileName))
                    {
                        string currentFilename = Path.GetFileNameWithoutExtension(path);
                        string ext             = Path.GetExtension(path);

                        if (!currentFilename.Equals(customFileName, StringComparison.InvariantCultureIgnoreCase))
                        {
                            path = Helpers.RenameFile(path, customFileName + ext);
                        }
                    }

                    WorkerTask task = WorkerTask.CreateFileJobTask(path, taskSettings, customFileName);
                    TaskManager.Start(task);
                }

                abortRequested = false;
                IsRecording    = false;
            });
        }