Beispiel #1
0
        public Recorder(string fileName, 
            FourCC codec, int quality, 
            int audioSourceIndex, SupportedWaveFormat audioWaveFormat, bool encodeAudio, int audioBitRate)
        {
            System.Windows.Media.Matrix toDevice;
            using (var source = new HwndSource(new HwndSourceParameters()))
            {
                toDevice = source.CompositionTarget.TransformToDevice;
            }

            screenWidth = (int)Math.Round(SystemParameters.PrimaryScreenWidth * toDevice.M11);
            screenHeight = (int)Math.Round(SystemParameters.PrimaryScreenHeight * toDevice.M22);

            // Create AVI writer and specify FPS
            writer = new AviWriter(fileName)
            {
                FramesPerSecond = 10,
                EmitIndex1 = true,
            };

            // Create video stream
            videoStream = CreateVideoStream(codec, quality);
            // Set only name. Other properties were when creating stream,
            // either explicitly by arguments or implicitly by the encoder used
            videoStream.Name = "Screencast";

            if (audioSourceIndex >= 0)
            {
                var waveFormat = ToWaveFormat(audioWaveFormat);

                audioStream = CreateAudioStream(waveFormat, encodeAudio, audioBitRate);
                // Set only name. Other properties were when creating stream,
                // either explicitly by arguments or implicitly by the encoder used
                audioStream.Name = "Voice";

                audioSource = new WaveInEvent
                {
                    DeviceNumber = audioSourceIndex,
                    WaveFormat = waveFormat,
                    // Buffer size to store duration of 1 frame
                    BufferMilliseconds = (int)Math.Ceiling(1000 / writer.FramesPerSecond),
                    NumberOfBuffers = 3,
                };
                audioSource.DataAvailable += audioSource_DataAvailable;
            }

            screenThread = new Thread(RecordScreen)
            {
                Name = typeof(Recorder).Name + ".RecordScreen",
                IsBackground = true
            };

            if (audioSource != null)
            {
                videoFrameWritten.Set();
                audioBlockWritten.Reset();
                audioSource.StartRecording();
            }
            screenThread.Start();
        }
        private void StartRecordingThread(string videoFileName, ISeleniumTest scenario, int fps)
        {
            fileName = videoFileName;

            using (writer = new AviWriter(videoFileName)
            {
                FramesPerSecond = fps,
                EmitIndex1 = true
            })
            {
                stream = writer.AddVideoStream();
                this.ConfigureStream(stream);

                while (!scenario.IsFinished || forceStop)
                {
                    GetScreenshot(buffer);

                    //Thread safety issues
                    lock (locker)
                    {
                        stream.WriteFrame(true, buffer, 0, buffer.Length);
                    }

                }
            }

        }
        private ImageProvider m_imageProvider = new ImageProvider(); /* Create one image provider. */

        #endregion Fields

        #region Constructors

        /* Set up the controls and events to be used and update the device list. */
        public MainForm()
        {
            InitializeComponent();

            /* Register for the events of the image provider needed for proper operation. */
            m_imageProvider.GrabErrorEvent += new ImageProvider.GrabErrorEventHandler(OnGrabErrorEventCallback);
            m_imageProvider.DeviceRemovedEvent += new ImageProvider.DeviceRemovedEventHandler(OnDeviceRemovedEventCallback);
            m_imageProvider.DeviceOpenedEvent += new ImageProvider.DeviceOpenedEventHandler(OnDeviceOpenedEventCallback);
            m_imageProvider.DeviceClosedEvent += new ImageProvider.DeviceClosedEventHandler(OnDeviceClosedEventCallback);
            m_imageProvider.GrabbingStartedEvent += new ImageProvider.GrabbingStartedEventHandler(OnGrabbingStartedEventCallback);
            m_imageProvider.ImageReadyEvent += new ImageProvider.ImageReadyEventHandler(OnImageReadyEventCallback);
            m_imageProvider.GrabbingStoppedEvent += new ImageProvider.GrabbingStoppedEventHandler(OnGrabbingStoppedEventCallback);

            /* Provide the controls in the lower left area with the image provider object. */
            sliderGain.MyImageProvider = m_imageProvider;
            sliderExposureTime.MyImageProvider = m_imageProvider;
            sliderHeight.MyImageProvider = m_imageProvider;
            sliderWidth.MyImageProvider = m_imageProvider;
            comboBoxPixelFormat.MyImageProvider = m_imageProvider;

            /* Update the list of available devices in the upper left area. */
            UpdateDeviceList();

            /* Enable the tool strip buttons according to the state of the image provider. */
            EnableButtons(m_imageProvider.IsOpen, false);
             //   hDev = Pylon.CreateDeviceByIndex(0);
            aw = new AviWriter();
        }
        static void Main(string[] args)
        {
            var endOfRec = DateTime.Now.Add(TimeSpan.FromSeconds(30));
            using (var writer = new AviWriter("test.avi")
            {
                FramesPerSecond = 15,
                EmitIndex1 = true
            })
            {
                var stream = writer.AddVideoStream();

                stream.Width = Screen.PrimaryScreen.WorkingArea.Width;
                stream.Height = Screen.PrimaryScreen.WorkingArea.Height;
                stream.Codec = KnownFourCCs.Codecs.Uncompressed;
                stream.BitsPerPixel = BitsPerPixel.Bpp32;

                var googleChrome = new TestCase();

                Task.Factory.StartNew(() =>
                {
                    googleChrome.Scenario("http://www.google.com", "что посмотреть сегодня?");
                });

                var buffer = new byte[Screen.PrimaryScreen.WorkingArea.Width * Screen.PrimaryScreen.WorkingArea.Height * 4];
                while (!TestCase.isFinished)
                {
                    GetScreenshot(buffer);
                    stream.WriteFrame(true, buffer, 0, buffer.Length);
                }
            }

            Console.WriteLine("Execution Done");
        }
Beispiel #5
0
        public static void CreateVideo(List<Frame> frames, string outputFile)
        {
            var writer = new AviWriter(outputFile)
            {
                FramesPerSecond = 30,
                // Emitting AVI v1 index in addition to OpenDML index (AVI v2)
                // improves compatibility with some software, including
                // standard Windows programs like Media Player and File Explorer
                EmitIndex1 = true
            };

            // returns IAviVideoStream
            var stream = writer.AddVideoStream();

            // set standard VGA resolution
            stream.Width = 640;
            stream.Height = 480;

            // class SharpAvi.KnownFourCCs.Codecs contains FOURCCs for several well-known codecs
            // Uncompressed is the default value, just set it for clarity
            stream.Codec = KnownFourCCs.Codecs.Uncompressed;

            // Uncompressed format requires to also specify bits per pixel
            stream.BitsPerPixel = BitsPerPixel.Bpp32;

            var frameData = new byte[stream.Width * stream.Height * 4];

            foreach (var item in frames)
            {

                // Say, you have a System.Drawing.Bitmap
                Bitmap bitmap = (Bitmap)item.Image;

                // and buffer of appropriate size for storing its bits
                var buffer = new byte[stream.Width * stream.Height * 4];

                var pixelFormat = PixelFormat.Format32bppRgb;

                // Now copy bits from bitmap to buffer
                var bits = bitmap.LockBits(new Rectangle(0, 0, stream.Width, stream.Height), ImageLockMode.ReadOnly, pixelFormat);

                //Marshal.Copy(bits.Scan0, buffer, 0, buffer.Length);

                Marshal.Copy(bits.Scan0, buffer, 0, buffer.Length);

                bitmap.UnlockBits(bits);

                // and flush buffer to encoding stream
                stream.WriteFrame(true, buffer, 0, buffer.Length);

            }

            writer.Close();
        }
        public VideoRecorder()
        {
            forceStop = false;
            writer = null;
            stream = null;

            if (streamingTask != null)
            {
                streamingTask.Dispose();
                streamingTask = null;
            }
        }
Beispiel #7
0
        private static void Main(string[] args)
        {
            var firstFrame = CaptureScreen(null);

            var aviWriter = new AviWriter();
            var bitmap = aviWriter.Open("test.avi", 10, firstFrame.Width, firstFrame.Height);
            for (var i = 0; i < 25*5; i++)
            {
                CaptureScreen(bitmap);
                aviWriter.AddFrame();
            }

            aviWriter.Close();
        }
Beispiel #8
0
        /// <summary>
        /// Records this instance.
        /// </summary>
        /// <exception cref="RedCell.Research.ResearchException">
        /// Filename must be set before recording.
        /// or
        /// A recording has already started.
        /// </exception>
        /// <exception cref="System.InvalidOperationException">Filename must be set before recording.</exception>
        public void StartRecord()
        {
            // Automatic filename
            if (string.IsNullOrWhiteSpace(Filename))
                Filename = "Video_" + DateTime.Now.ToString("yyyyMMddHHmmss");

            if(_writer != null)
                throw new ResearchException("A recording has already started.");

            // Get video details from camera.
            if (StreamSetting == null)
                StreamSetting = Camera.StreamSetting;

            var encoder = new Mpeg4VideoEncoderVcm(StreamSetting.Width, StreamSetting.Height, StreamSetting.Framerate, 0, 50, KnownFourCCs.Codecs.X264);
            _writer = new AviWriter(Filename);
            _video = _writer.AddEncodingVideoStream(encoder, true, StreamSetting.Width, StreamSetting.Height);
            

            Camera.FrameAvailable += Camera_FrameAvailable;
        }
Beispiel #9
0
        /// <summary>
        /// 画面キャプチャ(音声録音)の停止
        /// </summary>
        private void StopCapture()
        {
            foreach (var pair in m_WebSocketClients)
            {
                var data = new MessageData { type = MessageData.Type.StopCapture };
                var json = JsonConvert.SerializeObject(data);

                pair.Value.Send(json);
            }

            m_Capture.StopAsync();

            if (checkBox_sendAudio.Checked || checkBox_recordAudio.Checked)
            {
                m_Recorder.StopRecording();
            }

            if (m_AviWriter != null)
            {
                Debug.Log("" + m_AviVideoStream.FramesWritten);
                m_AviWriter.Close();
                m_AviWriter = null;
                m_AviVideoStream = null;
                m_AviAudioStream = null;
            }
        }
Beispiel #10
0
        private bool StartRecording()
        {
            int captureWidth = (int)(m_Capture.CaptureBounds.Width * m_Capture.Scale),
                captureHeight = (int)(m_Capture.CaptureBounds.Height * m_Capture.Scale),
                codecSelectedIndex = comboBox_videoCodec.SelectedIndex,
                codecQuality = Convert.ToInt32(textBox_recordQuality.Text);

            try
            {
                m_AviWriter = new AviWriter(m_AviFilePath)
                {
                    FramesPerSecond = m_Capture.FramesPerSecond,
                    EmitIndex1 = true,
                };

                if (codecSelectedIndex == 0)
                {
                    m_AviVideoStream = m_AviWriter.AddVideoStream(captureWidth, captureHeight);
                }
                else if (codecSelectedIndex == 1)
                {
                    m_AviVideoStream = m_AviWriter.AddMotionJpegVideoStream(captureWidth, captureHeight, codecQuality);
                }
                else
                {
                    var codecs = Mpeg4VideoEncoderVcm.GetAvailableCodecs();
                    var encoder = new Mpeg4VideoEncoderVcm(captureWidth, captureHeight, m_Capture.FramesPerSecond, 0, codecQuality, codecs[codecSelectedIndex - 2].Codec);
                    m_AviVideoStream = m_AviWriter.AddEncodingVideoStream(encoder);
                }


                if (checkBox_recordAudio.Checked)
                {
                    m_AviAudioStream = m_AviWriter.AddAudioStream(m_Recorder.WaveFormat.Channels, m_Recorder.WaveFormat.SampleRate, m_Recorder.WaveFormat.BitsPerSample);
                }
            }
            catch
            {
                Debug.Log("Failed to Start Recording.");
                return false;
            }

            return true;
        }
Beispiel #11
0
 public void CaptureStarted(int width, int height, int pitch, TextureFormat format, bool flipVertical)
 {
     aviWriter = new AviWriter(File.Create("capture.avi", pitch * height), width, height, 60, !flipVertical);
 }
Beispiel #12
0
 public IAviAudioStream CreateAudioStream(AviWriter writer)
 {
     // Create encoding or simple stream based on settings
     if (IsLoopback) return writer.AddAudioStream(WaveFormat.Channels, WaveFormat.SampleRate, WaveFormat.BitsPerSample, AudioFormats.Float);
     else if (EncodeAudio)
     {
         // LAME DLL path is set in App.OnStartup()
         return writer.AddMp3AudioStream(WaveFormat.Channels, WaveFormat.SampleRate, AudioBitRate);
     }
     else return writer.AddAudioStream(WaveFormat.Channels, WaveFormat.SampleRate, WaveFormat.BitsPerSample);
 }
Beispiel #13
0
        public Recorder(RecorderParams Params)
        {
            this.Params = Params;

            if (Params.CaptureVideo)
            {
                // Create AVI writer and specify FPS
                writer = Params.CreateAviWriter();

                // Create video stream
                videoStream = Params.CreateVideoStream(writer);
                // Set only name. Other properties were when creating stream,
                // either explicitly by arguments or implicitly by the encoder used
                videoStream.Name = "Captura";
            }

            try
            {
                int AudioSourceId = int.Parse(Params.AudioSourceId);

                if (AudioSourceId != -1)
                {
                    if (Params.CaptureVideo)
                    {
                        audioStream = Params.CreateAudioStream(writer);
                        audioStream.Name = "Voice";
                    }

                    audioSource = new WaveInEvent
                    {
                        DeviceNumber = AudioSourceId,
                        WaveFormat = Params.WaveFormat,
                        // Buffer size to store duration of 1 frame
                        BufferMilliseconds = (int)Math.Ceiling(1000 / writer.FramesPerSecond),
                        NumberOfBuffers = 3,
                    };
                }
            }
            catch
            {
                var dev = Params.LoopbackDevice;

                SilencePlayer = new WasapiOut(dev, AudioClientShareMode.Shared, false, 100);

                SilencePlayer.Init(new SilenceProvider(Params.WaveFormat));

                SilencePlayer.Play();

                if (Params.CaptureVideo)
                {
                    audioStream = Params.CreateAudioStream(writer);
                    audioStream.Name = "Loopback";
                }

                audioSource = new WasapiLoopbackCapture(dev) { ShareMode = AudioClientShareMode.Shared };
            }

            if (Params.CaptureVideo)
            {
                screenThread = new Thread(RecordScreen)
                {
                    Name = typeof(Recorder).Name + ".RecordScreen",
                    IsBackground = true
                };
            }
            else WaveWriter = Params.CreateWaveWriter();

            if (Params.CaptureVideo) screenThread.Start();

            if (audioSource != null)
            {
                audioSource.DataAvailable += AudioDataAvailable;

                if (Params.CaptureVideo)
                {
                    videoFrameWritten.Set();
                    audioBlockWritten.Reset();
                }

                audioSource.StartRecording();
            }
        }
Beispiel #14
0
        private async void Encode(List <FrameInfo> listFrames, int id, Parameters param, CancellationTokenSource tokenSource)
        {
            var processing = this.DispatcherStringResource("Encoder.Processing");

            try
            {
                switch (param.Type)
                {
                case Export.Gif:

                    #region Gif

                    #region Cut/Paint Unchanged Pixels

                    if (param.EncoderType == GifEncoderType.Legacy || param.EncoderType == GifEncoderType.ScreenToGif)
                    {
                        if (param.DetectUnchangedPixels)
                        {
                            Update(id, 0, FindResource("Encoder.Analyzing").ToString());

                            if (param.DummyColor.HasValue)
                            {
                                listFrames = ImageMethods.PaintTransparentAndCut(listFrames, param.DummyColor.Value, id, tokenSource);
                            }
                            else
                            {
                                listFrames = ImageMethods.CutUnchanged(listFrames, id, tokenSource);
                            }
                        }
                        else
                        {
                            var size = listFrames[0].Path.ScaledSize();
                            listFrames.ForEach(x => x.Rect = new Int32Rect(0, 0, (int)size.Width, (int)size.Height));
                        }
                    }

                    #endregion

                    switch (param.EncoderType)
                    {
                    case GifEncoderType.ScreenToGif:

                        #region Improved encoding

                        using (var stream = new MemoryStream())
                        {
                            using (var encoder = new GifFile(stream, param.RepeatCount))
                            {
                                encoder.UseGlobalColorTable = param.UseGlobalColorTable;
                                encoder.TransparentColor    = param.DummyColor;
                                encoder.MaximumNumberColor  = param.MaximumNumberColors;

                                for (var i = 0; i < listFrames.Count; i++)
                                {
                                    if (!listFrames[i].HasArea && param.DetectUnchangedPixels)
                                    {
                                        continue;
                                    }

                                    if (listFrames[i].Delay == 0)
                                    {
                                        listFrames[i].Delay = 10;
                                    }

                                    encoder.AddFrame(listFrames[i].Path, listFrames[i].Rect, listFrames[i].Delay);

                                    Update(id, i, string.Format(processing, i));

                                    #region Cancellation

                                    if (tokenSource.Token.IsCancellationRequested)
                                    {
                                        SetStatus(Status.Canceled, id);
                                        break;
                                    }

                                    #endregion
                                }
                            }

                            try
                            {
                                using (var fileStream = new FileStream(param.Filename, FileMode.Create, FileAccess.Write, FileShare.None, 4096))
                                    stream.WriteTo(fileStream);
                            }
                            catch (Exception ex)
                            {
                                SetStatus(Status.Error, id);
                                LogWriter.Log(ex, "Improved Encoding");
                            }
                        }

                        #endregion

                        break;

                    case GifEncoderType.Legacy:

                        #region Legacy Encoding

                        using (var encoder = new AnimatedGifEncoder())
                        {
                            if (param.DummyColor.HasValue)
                            {
                                encoder.SetTransparent(param.DummyColor.Value);
                                encoder.SetDispose(1);         //Undraw Method, "Leave".
                            }

                            encoder.Start(param.Filename);
                            encoder.SetQuality(param.Quality);
                            encoder.SetRepeat(param.RepeatCount);

                            var numImage = 0;
                            foreach (var frame in listFrames)
                            {
                                #region Cancellation

                                if (tokenSource.Token.IsCancellationRequested)
                                {
                                    SetStatus(Status.Canceled, id);
                                    break;
                                }

                                #endregion

                                if (!frame.HasArea && param.DetectUnchangedPixels)
                                {
                                    continue;
                                }

                                var bitmapAux = new Bitmap(frame.Path);

                                encoder.SetDelay(frame.Delay);
                                encoder.AddFrame(bitmapAux, frame.Rect.X, frame.Rect.Y);

                                bitmapAux.Dispose();

                                Update(id, numImage, string.Format(processing, numImage));
                                numImage++;
                            }
                        }

                        #endregion

                        break;

                    case GifEncoderType.PaintNet:

                        #region paint.NET encoding

                        using (var stream = new MemoryStream())
                        {
                            using (var encoder = new GifEncoder(stream, null, null, param.RepeatCount))
                            {
                                for (var i = 0; i < listFrames.Count; i++)
                                {
                                    var bitmapAux = new Bitmap(listFrames[i].Path);
                                    encoder.AddFrame(bitmapAux, 0, 0, TimeSpan.FromMilliseconds(listFrames[i].Delay));
                                    bitmapAux.Dispose();

                                    Update(id, i, string.Format(processing, i));

                                    #region Cancellation

                                    if (tokenSource.Token.IsCancellationRequested)
                                    {
                                        SetStatus(Status.Canceled, id);

                                        break;
                                    }

                                    #endregion
                                }
                            }

                            stream.Position = 0;

                            try
                            {
                                using (var fileStream = new FileStream(param.Filename, FileMode.Create, FileAccess.Write, FileShare.None, Constants.BufferSize, false))
                                    stream.WriteTo(fileStream);
                            }
                            catch (Exception ex)
                            {
                                SetStatus(Status.Error, id);
                                LogWriter.Log(ex, "Encoding with paint.Net.");
                            }
                        }

                        #endregion

                        break;

                    case GifEncoderType.FFmpeg:

                        #region FFmpeg encoding

                        SetStatus(Status.Processing, id, null, true);

                        if (!Util.Other.IsFfmpegPresent())
                        {
                            throw new ApplicationException("FFmpeg not present.");
                        }

                        if (File.Exists(param.Filename))
                        {
                            File.Delete(param.Filename);
                        }

                        #region Generate concat

                        var concat = new StringBuilder();
                        foreach (var frame in listFrames)
                        {
                            concat.AppendLine("file '" + frame.Path + "'");
                            concat.AppendLine("duration " + (frame.Delay / 1000d).ToString(CultureInfo.InvariantCulture));
                        }

                        var concatPath = Path.GetDirectoryName(listFrames[0].Path) ?? Path.GetTempPath();
                        var concatFile = Path.Combine(concatPath, "concat.txt");

                        if (!Directory.Exists(concatPath))
                        {
                            Directory.CreateDirectory(concatPath);
                        }

                        if (File.Exists(concatFile))
                        {
                            File.Delete(concatFile);
                        }

                        File.WriteAllText(concatFile, concat.ToString());

                        #endregion

                        param.Command = string.Format(param.Command, concatFile, param.ExtraParameters.Replace("{H}", param.Height.ToString()).Replace("{W}", param.Width.ToString()), param.Filename);

                        var process = new ProcessStartInfo(UserSettings.All.FfmpegLocation)
                        {
                            Arguments             = param.Command,
                            CreateNoWindow        = true,
                            ErrorDialog           = false,
                            UseShellExecute       = false,
                            RedirectStandardError = true
                        };

                        var pro = Process.Start(process);

                        var str = pro.StandardError.ReadToEnd();

                        var fileInfo = new FileInfo(param.Filename);

                        if (!fileInfo.Exists || fileInfo.Length == 0)
                        {
                            throw new Exception("Error while encoding the gif with FFmpeg.")
                                  {
                                      HelpLink = $"Command:\n\r{param.Command}\n\rResult:\n\r{str}"
                                  }
                        }
                        ;

                        #endregion

                        break;

                    case GifEncoderType.Gifski:

                        #region Gifski encoding

                        SetStatus(Status.Processing, id, null, true);

                        if (!Util.Other.IsGifskiPresent())
                        {
                            throw new ApplicationException("Gifski not present.");
                        }

                        if (File.Exists(param.Filename))
                        {
                            File.Delete(param.Filename);
                        }

                        var gifski = new GifskiInterop();
                        var handle = gifski.Start(UserSettings.All.GifskiQuality, UserSettings.All.Looped);

                        ThreadPool.QueueUserWorkItem(delegate
                        {
                            Thread.Sleep(500);
                            SetStatus(Status.Processing, id, null, false);

                            for (var i = 0; i < listFrames.Count; i++)
                            {
                                Update(id, i, string.Format(processing, i));
                                gifski.AddFrame(handle, (uint)i, listFrames[i].Path, listFrames[i].Delay);
                            }

                            gifski.EndAdding(handle);
                        }, null);

                        gifski.End(handle, param.Filename);

                        var fileInfo2 = new FileInfo(param.Filename);

                        if (!fileInfo2.Exists || fileInfo2.Length == 0)
                        {
                            throw new Exception("Error while encoding the gif with Gifski.", new Win32Exception())
                                  {
                                      HelpLink = $"Result:\n\r{Marshal.GetLastWin32Error()}"
                                  }
                        }
                        ;

                        #endregion

                        break;

                    default:
                        throw new Exception("Undefined Gif encoder type");
                    }

                    #endregion

                    break;

                case Export.Apng:

                    #region Apng

                    #region Cut/Paint Unchanged Pixels

                    if (param.DetectUnchangedPixels)
                    {
                        Update(id, 0, FindResource("Encoder.Analyzing").ToString());

                        if (param.DummyColor.HasValue)
                        {
                            listFrames = ImageMethods.PaintTransparentAndCut(listFrames, param.DummyColor.Value, id, tokenSource);
                        }
                        else
                        {
                            listFrames = ImageMethods.CutUnchanged(listFrames, id, tokenSource);
                        }
                    }
                    else
                    {
                        var size = listFrames[0].Path.ScaledSize();
                        listFrames.ForEach(x => x.Rect = new Int32Rect(0, 0, (int)size.Width, (int)size.Height));
                    }

                    #endregion

                    #region Encoding

                    using (var stream = new MemoryStream())
                    {
                        var frameCount = listFrames.Count(x => x.HasArea);

                        using (var encoder = new Apng(stream, frameCount, param.RepeatCount))
                        {
                            for (var i = 0; i < listFrames.Count; i++)
                            {
                                if (!listFrames[i].HasArea && param.DetectUnchangedPixels)
                                {
                                    continue;
                                }

                                if (listFrames[i].Delay == 0)
                                {
                                    listFrames[i].Delay = 10;
                                }

                                encoder.AddFrame(listFrames[i].Path, listFrames[i].Rect, listFrames[i].Delay);

                                Update(id, i, string.Format(processing, i));

                                #region Cancellation

                                if (tokenSource.Token.IsCancellationRequested)
                                {
                                    SetStatus(Status.Canceled, id);
                                    break;
                                }

                                #endregion
                            }
                        }

                        try
                        {
                            using (var fileStream = new FileStream(param.Filename, FileMode.Create, FileAccess.Write, FileShare.None, 4096))
                                stream.WriteTo(fileStream);
                        }
                        catch (Exception ex)
                        {
                            SetStatus(Status.Error, id);
                            LogWriter.Log(ex, "Apng Encoding");
                        }
                    }

                    #endregion

                    #endregion

                    break;

                case Export.Photoshop:

                    #region Psd

                    using (var stream = new MemoryStream())
                    {
                        using (var encoder = new Psd(stream, param.RepeatCount, param.Height, param.Width, param.Compress, param.SaveTimeline))
                        {
                            for (var i = 0; i < listFrames.Count; i++)
                            {
                                if (listFrames[i].Delay == 0)
                                {
                                    listFrames[i].Delay = 10;
                                }

                                encoder.AddFrame(i, listFrames[i].Path, listFrames[i].Delay);

                                Update(id, i, string.Format(processing, i));

                                #region Cancellation

                                if (tokenSource.Token.IsCancellationRequested)
                                {
                                    SetStatus(Status.Canceled, id);
                                    break;
                                }

                                #endregion
                            }
                        }

                        using (var fileStream = new FileStream(param.Filename, FileMode.Create, FileAccess.Write, FileShare.None, 4096))
                            stream.WriteTo(fileStream);
                    }

                    #endregion

                    break;

                case Export.Video:

                    #region Video

                    switch (param.VideoEncoder)
                    {
                    case VideoEncoderType.AviStandalone:

                        #region Avi Standalone

                        var image = listFrames[0].Path.SourceFrom();

                        if (File.Exists(param.Filename))
                        {
                            File.Delete(param.Filename);
                        }

                        //1000 / listFrames[0].Delay
                        using (var aviWriter = new AviWriter(param.Filename, param.Framerate, image.PixelWidth, image.PixelHeight, param.VideoQuality))
                        {
                            var numImage = 0;
                            foreach (var frame in listFrames)
                            {
                                using (var outStream = new MemoryStream())
                                {
                                    var bitImage = frame.Path.SourceFrom();

                                    var enc = new BmpBitmapEncoder();
                                    enc.Frames.Add(BitmapFrame.Create(bitImage));
                                    enc.Save(outStream);

                                    outStream.Flush();

                                    using (var bitmap = new Bitmap(outStream))
                                        aviWriter.AddFrame(bitmap, param.FlipVideo);
                                }

                                Update(id, numImage, string.Format(processing, numImage));
                                numImage++;

                                #region Cancellation

                                if (tokenSource.Token.IsCancellationRequested)
                                {
                                    SetStatus(Status.Canceled, id);
                                    break;
                                }

                                #endregion
                            }
                        }

                        #endregion

                        break;

                    case VideoEncoderType.Ffmpg:

                        #region Video using FFmpeg

                        SetStatus(Status.Processing, id, null, true);

                        if (!Util.Other.IsFfmpegPresent())
                        {
                            throw new ApplicationException("FFmpeg not present.");
                        }

                        if (File.Exists(param.Filename))
                        {
                            File.Delete(param.Filename);
                        }

                        #region Generate concat

                        var concat = new StringBuilder();
                        foreach (var frame in listFrames)
                        {
                            concat.AppendLine("file '" + frame.Path + "'");
                            concat.AppendLine("duration " + (frame.Delay / 1000d).ToString(CultureInfo.InvariantCulture));
                        }

                        var concatPath = Path.GetDirectoryName(listFrames[0].Path) ?? Path.GetTempPath();
                        var concatFile = Path.Combine(concatPath, "concat.txt");

                        if (!Directory.Exists(concatPath))
                        {
                            Directory.CreateDirectory(concatPath);
                        }

                        if (File.Exists(concatFile))
                        {
                            File.Delete(concatFile);
                        }

                        File.WriteAllText(concatFile, concat.ToString());

                        #endregion

                        param.Command = string.Format(param.Command, concatFile, param.ExtraParameters.Replace("{H}", param.Height.ToString()).Replace("{W}", param.Width.ToString()), param.Filename);

                        var process = new ProcessStartInfo(UserSettings.All.FfmpegLocation)
                        {
                            Arguments             = param.Command,
                            CreateNoWindow        = true,
                            ErrorDialog           = false,
                            UseShellExecute       = false,
                            RedirectStandardError = true
                        };

                        var pro = Process.Start(process);

                        var str = pro.StandardError.ReadToEnd();

                        var fileInfo = new FileInfo(param.Filename);

                        if (!fileInfo.Exists || fileInfo.Length == 0)
                        {
                            throw new Exception("Error while encoding with FFmpeg.")
                                  {
                                      HelpLink = str
                                  }
                        }
                        ;

                        #endregion

                        break;

                    default:
                        throw new Exception("Undefined video encoder");
                    }

                    #endregion

                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(param));
                }

                //If it was canceled, try deleting the file.
                if (tokenSource.Token.IsCancellationRequested)
                {
                    if (File.Exists(param.Filename))
                    {
                        File.Delete(param.Filename);
                    }

                    SetStatus(Status.Canceled, id);
                    return;
                }

                #region Upload

                if (param.Upload && File.Exists(param.Filename))
                {
                    InternalUpdate(id, "Encoder.Uploading", true, true);

                    try
                    {
                        var cloud = CloudFactory.CreateCloud(param.UploadDestination);

                        var uploadedFile = await cloud.UploadFileAsync(param.Filename, CancellationToken.None);

                        InternalSetUpload(id, true, uploadedFile.Link, uploadedFile.DeleteLink);
                    }
                    catch (Exception e)
                    {
                        LogWriter.Log(e, "It was not possible to upload.");
                        InternalSetUpload(id, false, null, null, e);
                    }
                }

                #endregion

                #region Copy to clipboard

                if (param.CopyToClipboard && File.Exists(param.Filename))
                {
                    Dispatcher.Invoke(() =>
                    {
                        try
                        {
                            var data = new DataObject();

                            switch (param.CopyType)
                            {
                            case CopyType.File:
                                if (param.Type != Export.Video)
                                {
                                    data.SetImage(param.Filename.SourceFrom());
                                }

                                data.SetText(param.Filename, TextDataFormat.Text);
                                data.SetFileDropList(new StringCollection {
                                    param.Filename
                                });
                                break;

                            case CopyType.FolderPath:
                                data.SetText(Path.GetDirectoryName(param.Filename) ?? param.Filename, TextDataFormat.Text);
                                break;

                            case CopyType.Link:
                                var link = InternalGetUpload(id);

                                data.SetText(string.IsNullOrEmpty(link) ? param.Filename : link, TextDataFormat.Text);
                                break;

                            default:
                                data.SetText(param.Filename, TextDataFormat.Text);
                                break;
                            }

                            //It tries to set the data to the clipboard 10 times before failing it to do so.
                            //This issue may happen if the clipboard is opened by any clipboard manager.
                            for (var i = 0; i < 10; i++)
                            {
                                try
                                {
                                    Clipboard.SetDataObject(data, true);
                                    break;
                                }
                                catch (COMException ex)
                                {
                                    if ((uint)ex.ErrorCode != 0x800401D0) //CLIPBRD_E_CANT_OPEN
                                    {
                                        throw;
                                    }
                                }

                                Thread.Sleep(100);
                            }

                            InternalSetCopy(id, true);
                        }
                        catch (Exception e)
                        {
                            LogWriter.Log(e, "It was not possible to copy the file.");
                            InternalSetCopy(id, false, e);
                        }
                    });
                }

                #endregion

                #region Execute commands

#if !UWP
                if (param.ExecuteCommands && !string.IsNullOrWhiteSpace(param.PostCommands))
                {
                    InternalUpdate(id, "Encoder.Executing", true, true);

                    var command = param.PostCommands.Replace("{p}", "\"" + param.Filename + "\"").Replace("{f}", "\"" + Path.GetDirectoryName(param.Filename) + "\"");
                    var output  = "";

                    try
                    {
                        foreach (var com in command.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries))
                        {
                            var procStartInfo = new ProcessStartInfo("cmd", "/c " + com)
                            {
                                RedirectStandardOutput = true,
                                RedirectStandardError  = true,
                                UseShellExecute        = false,
                                CreateNoWindow         = true
                            };

                            using (var process = new Process())
                            {
                                process.StartInfo = procStartInfo;
                                process.Start();

                                var message = process.StandardOutput.ReadToEnd();
                                var error   = process.StandardError.ReadToEnd();

                                if (!string.IsNullOrWhiteSpace(message))
                                {
                                    output += message + Environment.NewLine;
                                }

                                if (!string.IsNullOrWhiteSpace(message))
                                {
                                    output += message + Environment.NewLine;
                                }

                                if (!string.IsNullOrWhiteSpace(error))
                                {
                                    throw new Exception(error);
                                }

                                process.WaitForExit(1000);
                            }
                        }

                        InternalSetCommand(id, true, command, output);
                    }
                    catch (Exception e)
                    {
                        LogWriter.Log(e, "It was not possible to run the post encoding command.");
                        InternalSetCommand(id, false, command, output, e);
                    }
                }
#endif

                #endregion

                if (!tokenSource.Token.IsCancellationRequested)
                {
                    SetStatus(Status.Completed, id, param.Filename);
                }
            }
            catch (Exception ex)
            {
                LogWriter.Log(ex, "Encode");

                SetStatus(Status.Error, id, null, false, ex);
            }
            finally
            {
                #region Delete Encoder Folder

                try
                {
                    var encoderFolder = Path.GetDirectoryName(listFrames[0].Path);

                    if (!string.IsNullOrEmpty(encoderFolder))
                    {
                        if (Directory.Exists(encoderFolder))
                        {
                            Directory.Delete(encoderFolder, true);
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogWriter.Log(ex, "Cleaning the Encode folder");
                }

                #endregion

                GC.Collect();
            }
        }
        public Recorder(string filePath,
                        int quality, int x, int y, int width, int height, bool captureCursor,
                        int inputSourceIndex, bool separateAudio)
        {
            this.x             = x;
            this.y             = y;
            this.width         = width;
            this.height        = height;
            this.captureCursor = captureCursor;

            writer = new AviWriter(filePath)
            {
                FramesPerSecond = 15,
                EmitIndex1      = true,
            };

            if (quality == 0)
            {
                videoStream      = writer.AddUncompressedVideoStream(width, height);
                videoStream.Name = "Quick Screen Recorder - Motion JPEG video stream";
            }
            else
            {
                videoStream      = writer.AddMotionJpegVideoStream(width, height, quality);
                videoStream.Name = "Quick Screen Recorder - Motion JPEG video stream";
            }

            if (inputSourceIndex >= 0)
            {
                var waveFormat = new WaveFormat(44100, 16, 1);

                audioStream = writer.AddAudioStream(
                    channelCount: waveFormat.Channels,
                    samplesPerSecond: waveFormat.SampleRate,
                    bitsPerSample: waveFormat.BitsPerSample
                    );
                audioStream.Name = "Quick Screen Recorder - Input audio stream";

                audioSource = new WaveInEvent()
                {
                    DeviceNumber       = inputSourceIndex,
                    WaveFormat         = waveFormat,
                    BufferMilliseconds = (int)Math.Ceiling(1000 / writer.FramesPerSecond),
                    NumberOfBuffers    = 3,
                };
                audioSource.DataAvailable += audioSource_DataAvailable;

                if (separateAudio)
                {
                    waveFile = new WaveFileWriter(filePath + " (Input audio).wav", audioSource.WaveFormat);
                }
            }
            else if (inputSourceIndex == -1)
            {
                audioSource = new WasapiLoopbackCapture();

                audioStream = writer.AddAudioStream(
                    channelCount: 1,
                    samplesPerSecond: audioSource.WaveFormat.SampleRate,
                    bitsPerSample: audioSource.WaveFormat.BitsPerSample
                    );
                audioStream.Name = "Quick Screen Recorder - System sounds audio stream";

                audioSource.DataAvailable += audioSource_DataAvailable;

                if (separateAudio)
                {
                    waveFile = new WaveFileWriter(filePath + " (System sounds).wav", audioSource.WaveFormat);
                }
            }

            screenThread = new Thread(RecordScreen)
            {
                Name         = typeof(Recorder).Name + ".RecordScreen",
                IsBackground = true
            };

            if (audioSource != null)
            {
                videoFrameWritten.Set();
                audioBlockWritten.Reset();
                audioSource.StartRecording();
            }

            screenThread.Start();
        }
Beispiel #16
0
        public Recorder(string fileName,
                        FourCC codec, int quality,
                        int audioSourceIndex, SupportedWaveFormat audioWaveFormat, bool encodeAudio, int audioBitRate)
        {
            System.Windows.Media.Matrix toDevice;
            using (var source = new HwndSource(new HwndSourceParameters()))
            {
                toDevice = source.CompositionTarget.TransformToDevice;
            }

            screenWidth  = (int)Math.Round(SystemParameters.PrimaryScreenWidth * toDevice.M11);
            screenHeight = (int)Math.Round(SystemParameters.PrimaryScreenHeight * toDevice.M22);

            try
            {
                // Create AVI writer and specify FPS
                writer = new AviWriter(fileName)
                {
                    FramesPerSecond = 10,
                    EmitIndex1      = true,
                };
            }
            catch (Exception)
            {
                try
                {
                    writer.Close();
                }
                catch (Exception)
                {
                }
                throw;
            }
            // Create video stream
            videoStream = CreateVideoStream(codec, quality);
            // Set only name. Other properties were when creating stream,
            // either explicitly by arguments or implicitly by the encoder used
            videoStream.Name = "Screencast";

            if (audioSourceIndex >= 0)
            {
                var waveFormat = ToWaveFormat(audioWaveFormat);

                audioStream = CreateAudioStream(waveFormat, encodeAudio, audioBitRate);
                // Set only name. Other properties were when creating stream,
                // either explicitly by arguments or implicitly by the encoder used
                audioStream.Name = "Voice";

                audioSource = new WaveInEvent
                {
                    DeviceNumber = audioSourceIndex,
                    WaveFormat   = waveFormat,
                    // Buffer size to store duration of 1 frame
                    BufferMilliseconds = (int)Math.Ceiling(1000 / writer.FramesPerSecond),
                    NumberOfBuffers    = 3,
                };
                audioSource.DataAvailable += audioSource_DataAvailable;
            }

            screenThread = new Thread(RecordScreen)
            {
                Name         = typeof(Recorder).Name + ".RecordScreen",
                IsBackground = true
            };

            if (audioSource != null)
            {
                videoFrameWritten.Set();
                audioBlockWritten.Reset();
                audioSource.StartRecording();
            }
            screenThread.Start();
        }
Beispiel #17
0
        private void Encode(List <FrameInfo> listFrames, int id, Parameters param, CancellationTokenSource tokenSource)
        {
            var processing = FindResource("Encoder.Processing").ToString();

            try
            {
                switch (param.Type)
                {
                case Export.Gif:

                    #region Gif

                    var gifParam = (GifParameters)param;

                    #region Cut/Paint Unchanged Pixels

                    if (gifParam.DetectUnchangedPixels && (gifParam.EncoderType == GifEncoderType.Legacy || gifParam.EncoderType == GifEncoderType.ScreenToGif))
                    {
                        Update(id, 0, FindResource("Encoder.Analyzing").ToString());

                        if (gifParam.DummyColor.HasValue)
                        {
                            var color = Color.FromArgb(gifParam.DummyColor.Value.R, gifParam.DummyColor.Value.G, gifParam.DummyColor.Value.B);

                            listFrames = ImageMethods.PaintTransparentAndCut(listFrames, color, id, tokenSource);
                        }
                        else
                        {
                            listFrames = ImageMethods.CutUnchanged(listFrames, id, tokenSource);
                        }
                    }

                    #endregion

                    switch (gifParam.EncoderType)
                    {
                    case GifEncoderType.ScreenToGif:

                        #region Improved encoding

                        using (var stream = new MemoryStream())
                        {
                            using (var encoder = new GifFile(stream, gifParam.RepeatCount))
                            {
                                encoder.UseGlobalColorTable = gifParam.UseGlobalColorTable;
                                encoder.TransparentColor    = gifParam.DummyColor;
                                encoder.MaximumNumberColor  = gifParam.MaximumNumberColors;

                                for (var i = 0; i < listFrames.Count; i++)
                                {
                                    if (!listFrames[i].HasArea && gifParam.DetectUnchangedPixels)
                                    {
                                        continue;
                                    }

                                    if (listFrames[i].Delay == 0)
                                    {
                                        listFrames[i].Delay = 10;
                                    }

                                    encoder.AddFrame(listFrames[i].Path, listFrames[i].Rect, listFrames[i].Delay);

                                    Update(id, i, string.Format(processing, i));

                                    #region Cancellation

                                    if (tokenSource.Token.IsCancellationRequested)
                                    {
                                        SetStatus(Status.Canceled, id);
                                        break;
                                    }

                                    #endregion
                                }
                            }

                            try
                            {
                                using (var fileStream = new FileStream(gifParam.Filename, FileMode.Create, FileAccess.Write, FileShare.None, 4096))
                                {
                                    stream.WriteTo(fileStream);
                                }

                                if (gifParam.SaveToClipboard)
                                {
                                    CopyToClipboard(gifParam.Filename);
                                }
                            }
                            catch (Exception ex)
                            {
                                SetStatus(Status.Error, id);
                                LogWriter.Log(ex, "Improved Encoding");
                            }
                        }

                        #endregion

                        break;

                    case GifEncoderType.Legacy:

                        #region Legacy Encoding

                        using (var encoder = new AnimatedGifEncoder())
                        {
                            if (gifParam.DummyColor.HasValue)
                            {
                                var color = Color.FromArgb(gifParam.DummyColor.Value.R,
                                                           gifParam.DummyColor.Value.G, gifParam.DummyColor.Value.B);

                                encoder.SetTransparent(color);
                                encoder.SetDispose(1);         //Undraw Method, "Leave".
                            }

                            encoder.Start(gifParam.Filename);
                            encoder.SetQuality(gifParam.Quality);
                            encoder.SetRepeat(gifParam.RepeatCount);

                            var numImage = 0;
                            foreach (var frame in listFrames)
                            {
                                #region Cancellation

                                if (tokenSource.Token.IsCancellationRequested)
                                {
                                    SetStatus(Status.Canceled, id);
                                    break;
                                }

                                #endregion

                                if (!frame.HasArea && gifParam.DetectUnchangedPixels)
                                {
                                    continue;
                                }

                                var bitmapAux = new Bitmap(frame.Path);

                                encoder.SetDelay(frame.Delay);
                                encoder.AddFrame(bitmapAux, frame.Rect.X, frame.Rect.Y);

                                bitmapAux.Dispose();

                                Update(id, numImage, string.Format(processing, numImage));
                                numImage++;
                            }
                        }

                        if (gifParam.SaveToClipboard)
                        {
                            CopyToClipboard(gifParam.Filename);
                        }

                        #endregion

                        break;

                    case GifEncoderType.PaintNet:

                        #region paint.NET encoding

                        using (var stream = new MemoryStream())
                        {
                            using (var encoder = new GifEncoder(stream, null, null, gifParam.RepeatCount))
                            {
                                for (var i = 0; i < listFrames.Count; i++)
                                {
                                    var bitmapAux = new Bitmap(listFrames[i].Path);
                                    encoder.AddFrame(bitmapAux, 0, 0, TimeSpan.FromMilliseconds(listFrames[i].Delay));
                                    bitmapAux.Dispose();

                                    Update(id, i, string.Format(processing, i));

                                    #region Cancellation

                                    if (tokenSource.Token.IsCancellationRequested)
                                    {
                                        SetStatus(Status.Canceled, id);

                                        break;
                                    }

                                    #endregion
                                }
                            }

                            stream.Position = 0;

                            try
                            {
                                using (var fileStream = new FileStream(gifParam.Filename, FileMode.Create, FileAccess.Write, FileShare.None, Constants.BufferSize, false))
                                {
                                    stream.WriteTo(fileStream);
                                }

                                if (gifParam.SaveToClipboard)
                                {
                                    CopyToClipboard(gifParam.Filename);
                                }
                            }
                            catch (Exception ex)
                            {
                                SetStatus(Status.Error, id);
                                LogWriter.Log(ex, "Encoding with paint.Net.");
                            }
                        }

                        #endregion

                        break;

                    default:
                        throw new Exception("Undefined Gif encoder type");
                    }

                    #endregion

                    break;

                case Export.Video:

                    #region Video

                    var videoParam = (VideoParameters)param;

                    switch (videoParam.VideoEncoder)
                    {
                    case VideoEncoderType.AviStandalone:

                        #region Avi Standalone

                        var image = listFrames[0].Path.SourceFrom();

                        if (File.Exists(videoParam.Filename))
                        {
                            File.Delete(videoParam.Filename);
                        }

                        using (var aviWriter = new AviWriter(videoParam.Filename, 1000 / listFrames[0].Delay, image.PixelWidth, image.PixelHeight, videoParam.Quality))
                        {
                            var numImage = 0;
                            foreach (var frame in listFrames)
                            {
                                using (var outStream = new MemoryStream())
                                {
                                    var bitImage = frame.Path.SourceFrom();

                                    var enc = new BmpBitmapEncoder();
                                    enc.Frames.Add(BitmapFrame.Create(bitImage));
                                    enc.Save(outStream);

                                    outStream.Flush();

                                    using (var bitmap = new Bitmap(outStream))
                                        aviWriter.AddFrame(bitmap, videoParam.FlipVideo);
                                }

                                //aviWriter.AddFrame(new BitmapImage(new Uri(frame.Path)));

                                Update(id, numImage, string.Format(processing, numImage));
                                numImage++;

                                #region Cancellation

                                if (tokenSource.Token.IsCancellationRequested)
                                {
                                    SetStatus(Status.Canceled, id);
                                    break;
                                }

                                #endregion
                            }
                        }

                        #endregion

                        break;

                    case VideoEncoderType.Ffmpg:

                        #region Video using FFmpeg

                        SetStatus(Status.Encoding, id, null, true);

                        if (!Util.Other.IsFfmpegPresent())
                        {
                            throw new ApplicationException("FFmpeg not present.");
                        }

                        videoParam.Command = string.Format(videoParam.Command,
                                                           Path.Combine(Path.GetDirectoryName(listFrames[0].Path), "%d.png"),
                                                           videoParam.ExtraParameters, videoParam.Framerate,
                                                           param.Filename);

                        var process = new ProcessStartInfo(UserSettings.All.FfmpegLocation)
                        {
                            Arguments             = videoParam.Command,
                            CreateNoWindow        = true,
                            ErrorDialog           = false,
                            UseShellExecute       = false,
                            RedirectStandardError = true
                        };

                        var pro = Process.Start(process);

                        var str = pro.StandardError.ReadToEnd();

                        var fileInfo = new FileInfo(param.Filename);

                        if (!fileInfo.Exists || fileInfo.Length == 0)
                        {
                            throw new Exception("Error while encoding with FFmpeg.", new Exception(str));
                        }

                        #endregion

                        break;

                    default:
                        throw new Exception("Undefined video encoder");
                    }

                    #endregion

                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(param));
                }

                if (!tokenSource.Token.IsCancellationRequested)
                {
                    SetStatus(Status.Completed, id, param.Filename);
                }
            }
            catch (Exception ex)
            {
                LogWriter.Log(ex, "Encode");

                SetStatus(Status.Error, id, null, false, ex);
            }
            finally
            {
                #region Delete Encoder Folder

                try
                {
                    var encoderFolder = Path.GetDirectoryName(listFrames[0].Path);

                    if (!string.IsNullOrEmpty(encoderFolder))
                    {
                        if (Directory.Exists(encoderFolder))
                        {
                            Directory.Delete(encoderFolder, true);
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogWriter.Log(ex, "Cleaning the Encode folder");
                }

                #endregion

                GC.Collect();
            }
        }
Beispiel #18
0
        private void recordHudToAVIToolStripMenuItem_Click(object sender, EventArgs e)
        {
            stopRecordToolStripMenuItem_Click(sender, e);

            MessageBox.Show("Output avi will be saved to the log folder");

            aviwriter = new AviWriter();
            Directory.CreateDirectory(Path.GetDirectoryName(Application.ExecutablePath) + Path.DirectorySeparatorChar + @"logs");
            aviwriter.avi_start(Path.GetDirectoryName(Application.ExecutablePath) + Path.DirectorySeparatorChar + @"logs" + Path.DirectorySeparatorChar + DateTime.Now.ToString("yyyy-MM-dd hh-mm-ss") + ".avi");

            recordHudToAVIToolStripMenuItem.Text = "Recording";
        }
Beispiel #19
0
 public void CaptureFinished()
 {
     aviWriter.Close();
     aviWriter = null;
 }
 public H264Writer(System.IO.Stream outputAvi, int width, int height, float fps)
 {
     aviWriter = new AviWriter(outputAvi, "H264", width, height, fps);
 }
Beispiel #21
0
        private void Encode(List <FrameInfo> listFrames, int id, string fileName, Export type, CancellationTokenSource tokenSource)
        {
            if (type == Export.Gif)
            {
                #region Gif

                if (Settings.Default.CustomEncoding)
                {
                    #region Custom Gif Encoding

                    using (var encoder = new AnimatedGifEncoder())
                    {
                        string cutFolder = null;

                        #region Cut/Paint Unchanged Pixels

                        if (Settings.Default.DetectUnchanged)
                        {
                            Update(id, 0, "Analizing Unchanged Pixels");

                            if (Settings.Default.PaintTransparent)
                            {
                                var color = Color.FromArgb(Settings.Default.TransparentColor.R,
                                                           Settings.Default.TransparentColor.G, Settings.Default.TransparentColor.B);

                                listFrames = ImageMethods.PaintTransparentAndCut(listFrames, color, id, tokenSource);

                                //TODO: Use System.Windows.Media.Color inside the AnimatedGifEncoder.
                                encoder.SetTransparent(color);
                                encoder.SetDispose(1); //Undraw Method, "Leave".
                            }
                            else
                            {
                                listFrames = ImageMethods.CutUnchanged(listFrames, id, tokenSource);
                            }
                        }

                        #endregion

                        encoder.Start(fileName);
                        encoder.SetQuality(Settings.Default.Quality);
                        encoder.SetRepeat(Settings.Default.Looped ? (Settings.Default.RepeatForever ? 0 : Settings.Default.RepeatCount) : -1); // 0 = Always, -1 once

                        int numImage = 0;
                        foreach (FrameInfo image in listFrames)
                        {
                            #region Cancellation

                            if (tokenSource.Token.IsCancellationRequested)
                            {
                                SetStatus(Status.Cancelled, id);

                                break;
                            }

                            #endregion

                            var bitmapAux = new Bitmap(image.ImageLocation);

                            encoder.SetDelay(image.Delay);
                            encoder.AddFrame(bitmapAux, image.PositionTopLeft.X, image.PositionTopLeft.Y);

                            bitmapAux.Dispose();

                            Update(id, numImage, "Processing " + numImage);
                            numImage++;
                        }

                        #region Specific Clear

                        try
                        {
                            if (!String.IsNullOrEmpty(cutFolder))
                            {
                                if (Directory.Exists(cutFolder))
                                {
                                    Directory.Delete(cutFolder, true);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            LogWriter.Log(ex, "Errow while Deleting and Cleaning Specific Variables");
                        }

                        #endregion
                    }

                    #endregion
                }
                else
                {
                    #region paint.NET encoding

                    //0 = Always, -1 = no repeat, n = repeat number (first shown + repeat number = total number of iterations)
                    var repeat = (Settings.Default.Looped ? (Settings.Default.RepeatForever ? 0 : Settings.Default.RepeatCount) : -1);

                    using (var stream = new MemoryStream())
                    {
                        using (var encoderNet = new GifEncoder(stream, null, null, repeat))
                        {
                            for (int i = 0; i < listFrames.Count; i++)
                            {
                                var bitmapAux = new Bitmap(listFrames[i].ImageLocation);
                                encoderNet.AddFrame(bitmapAux, 0, 0, TimeSpan.FromMilliseconds(listFrames[i].Delay));
                                bitmapAux.Dispose();

                                Update(id, i, "Processing " + i);

                                #region Cancellation

                                if (tokenSource.Token.IsCancellationRequested)
                                {
                                    SetStatus(Status.Cancelled, id);

                                    break;
                                }

                                #endregion
                            }
                        }

                        stream.Position = 0;

                        try
                        {
                            using (var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None,
                                                                   Constants.BufferSize, false))
                            {
                                stream.WriteTo(fileStream);
                            }
                        }
                        catch (Exception ex)
                        {
                            SetStatus(Status.Error, id);
                            LogWriter.Log(ex, "Error while writing to disk.");
                        }
                    }

                    #endregion
                }

                #endregion
            }
            else
            {
                #region Avi

                var image = listFrames[0].ImageLocation.SourceFrom();

                string mp4FileName = null;
                if (fileName.EndsWith(".mp4"))
                {
                    mp4FileName = fileName;
                    fileName    = Path.Combine(Path.GetTempPath(), "temp.avi");

                    if (File.Exists(fileName))
                    {
                        File.Delete(fileName);
                    }
                }

                using (var aviWriter = new AviWriter(fileName, 1000 / listFrames[0].Delay, (int)Math.Round(image.Width, MidpointRounding.AwayFromZero), (int)Math.Round(image.Height, MidpointRounding.AwayFromZero), 5000))
                {
                    int numImage = 0;
                    foreach (FrameInfo frame in listFrames)
                    {
                        using (MemoryStream outStream = new MemoryStream())
                        {
                            var bitImage = frame.ImageLocation.SourceFrom();

                            var enc = new BmpBitmapEncoder();
                            enc.Frames.Add(BitmapFrame.Create(bitImage));
                            enc.Save(outStream);

                            outStream.Flush();

                            using (var bitmap = new Bitmap(outStream))
                            {
                                aviWriter.AddFrame(bitmap);
                            }
                        }

                        //aviWriter.AddFrame(new BitmapImage(new Uri(frame.ImageLocation)));

                        Update(id, numImage, "Processing " + numImage);
                        numImage++;

                        #region Cancellation

                        if (tokenSource.Token.IsCancellationRequested)
                        {
                            SetStatus(Status.Cancelled, id);
                            break;
                        }

                        #endregion
                    }
                }

                if (!String.IsNullOrEmpty(mp4FileName))
                {
                    var startInfo = new ProcessStartInfo("ffmpeg", String.Format("-i \"{0}\" \"{1}\"", fileName, mp4FileName));
                    startInfo.UseShellExecute = false;
                    var process = Process.Start(startInfo);
                    process.WaitForExit(10000);
                    File.Delete(fileName);
                }

                #endregion
            }

            #region Delete Encoder Folder

            try
            {
                var encoderFolder = Path.GetDirectoryName(listFrames[0].ImageLocation);

                if (!String.IsNullOrEmpty(encoderFolder))
                {
                    if (Directory.Exists(encoderFolder))
                    {
                        Directory.Delete(encoderFolder, true);
                    }
                }
            }
            catch (Exception ex)
            {
                LogWriter.Log(ex, "Errow while deleting and cleaning the Encode folder");
            }

            #endregion

            GC.Collect();

            if (!tokenSource.Token.IsCancellationRequested)
            {
                SetStatus(Status.Completed, id, fileName);
            }
        }
Beispiel #22
0
        private static void CreateMapFromPoints(List <Position> points, Settings settings)
        {
            points = points.Select(LocationUtils.ToMercator).ToList();
            var boundingBox = LocationUtils.GetBoundingBox(points);

            var mapper = Tiler.RenderMap(boundingBox, settings.VideoConfig.Width, settings.VideoConfig.Height);

            points = mapper.GetPixels(points).ToList();
            points = points.SkipTooClose(8).ToList();
            points = points.SmoothLineChaikin(settings.SofteningSettings);

            mapper.Save(Path.Combine(settings.OutputDirectory, "empty-map.png"));

            var writer = new AviWriter(Path.Combine(settings.OutputDirectory, "map.avi"))
            {
                FramesPerSecond = settings.VideoConfig.Framerate,
                EmitIndex1      = true
            };

            IAviVideoStream stream = new NullVideoStream(settings.VideoConfig.Width, settings.VideoConfig.Height);

            if (settings.VideoConfig.ProduceVideo)
            {
                var encoder = new MotionJpegVideoEncoderWpf(settings.VideoConfig.Width, settings.VideoConfig.Height, 70);
                stream        = writer.AddEncodingVideoStream(encoder, true, settings.VideoConfig.Width, settings.VideoConfig.Height);
                stream.Width  = settings.VideoConfig.Width;
                stream.Height = settings.VideoConfig.Height;
            }

            double lengthSeconds       = settings.VideoConfig.VideoDuration.TotalSeconds;
            double totalDistanceMeters = 0;

            double yieldFrame = Math.Max(1, (points.Count / (lengthSeconds * settings.VideoConfig.Framerate)));

            double nextFrame   = 1;
            int    wroteFrames = 0;

            for (int i = 1; i < points.Count; i++)
            {
                var previousPoint = mapper.FromPixelsToMercator(points[i - 1]);
                var currentPoint  = mapper.FromPixelsToMercator(points[i]);
                totalDistanceMeters += previousPoint.DistanceMeters(currentPoint);

                if (mapper.IsStashed)
                {
                    mapper.StashPop();
                }

                mapper.DrawLine(points[i - 1], points[i]);
                if (settings.DisplayDistance || settings.DisplayDateTime)
                {
                    mapper.Stash();
                }
                if (settings.DisplayDistance)
                {
                    mapper.WriteText(string.Format("{0:0}km", totalDistanceMeters / 1000));
                }

                if (settings.DisplayDateTime)
                {
                    // mapper.WriteText(points[i].Time.ToString(), settings.VideoConfig.Height - 200);
                    Position positionWgs84 = currentPoint.GetWgs84();
                    var      ianaTz        = TimeZoneLookup.GetTimeZone(positionWgs84.Latitude, positionWgs84.Longitude).Result;
                    TimeSpan offset        = TimeZoneConverter.TZConvert.GetTimeZoneInfo(ianaTz).GetUtcOffset(points[i].Time);
                    mapper.WriteText(points[i].Time.ToUniversalTime().Add(offset).ToString("MM/dd hh tt"), settings.VideoConfig.Height - 100);
                }

                if (i >= nextFrame)
                {
                    byte[] frameData = mapper.GetBitmap();
                    stream.WriteFrame(true, frameData, 0, frameData.Length);
                    wroteFrames++;

                    nextFrame += yieldFrame;
                }
            }
            if (mapper.IsStashed)
            {
                mapper.StashPop();
            }
            byte[] lastFrameData = mapper.GetBitmap();
            stream.WriteFrame(true, lastFrameData, 0, lastFrameData.Length);
            writer.Close();
            // DrawBoundingBox(boundingBox, mapper);
            string path = Path.Combine(settings.OutputDirectory, "complete-map.png");

            mapper.Save(path);
            Console.WriteLine("Wrote frames: {0}, points.Count={1}, yieldFrame={2}, path={3}", wroteFrames, points.Count, yieldFrame, path);
        }
Beispiel #23
0
 public void CaptureStarted(int width, int height, int pitch, TextureFormat format, bool flipVertical)
 {
     aviWriter = new AviWriter(File.Create("capture.avi", pitch * height), width, height, 60, !flipVertical);
 }
Beispiel #24
0
        private void CaptureDone(System.Drawing.Bitmap e)
        {
            const float parse_fps = 10.0f;
            float video_fps = me.fpsVideo;
            long max_size = me.trocearTamMB*1048576;
           
            
            if (saving_picture)
            {
                saving_picture = false;

                string path = me.PicturePath;
                if (path != null && path != "")
                {
                    DateTime dt = DateTime.Now;

                    if (!Directory.Exists(path))
                        Directory.CreateDirectory(path);

                    string filename = path + "\\PIC_"
                        + dt.Year.ToString("00") + dt.Month.ToString("00") + dt.Day.ToString("00")
                        + "-" + dt.Hour.ToString("00") + dt.Minute.ToString("00") + dt.Second.ToString("00") + ".jpg";

                    try
                    {
                        e.Save(filename, ImageFormat.Jpeg);
                    }
                    catch (Exception) { }
                }

            }

            if (starting_video)
            {
                starting_video = false;
                
                string path = me.VideosPath;
                if (path != null && path != "")
                {
                    DateTime dt = DateTime.Now;

                    if (!Directory.Exists(path))
                        Directory.CreateDirectory(path);

                    string filename = path + "\\VID_"
                        + dt.Year.ToString("00") + dt.Month.ToString("00") + dt.Day.ToString("00")
                        + "-" + dt.Hour.ToString("00") + dt.Minute.ToString("00") + dt.Second.ToString("00")+".avi";

                    avi_writer = new AviWriter();
                    avi_writer.avi_start(filename);

                    saving_video = true;
                    button15.Image = UAVConsole.Properties.Resources.video_red;
                }

            }
            else if (stoping_video)
            {
                saving_video = false;
                stoping_video = false;
                avi_writer.avi_close();
                avi_writer = null;
                
            }
            else if (saving_video && DateTime.Now.Ticks > video_last_tick)
            {
                video_last_tick = DateTime.Now.Ticks + (long)(TimeSpan.TicksPerSecond / video_fps);
                if (me.trocearVideo && max_size > 0 && avi_writer.current_lenght > max_size)
                {
                    avi_writer.avi_close();
                    avi_writer = new AviWriter();
                    DateTime dt = DateTime.Now;

                    string filename = me.VideosPath + "\\VID_"
                       + dt.Year.ToString("00") + dt.Month.ToString("00") + dt.Day.ToString("00")
                       + "-" + dt.Hour.ToString("00") + dt.Minute.ToString("00") + dt.Second.ToString("00") + ".avi";
                    avi_writer.avi_start(filename);
                }
                    avi_writer.SaveFrame(e, me.calidadVideo);
              
            }

            if (modem is ModemVideo && DateTime.Now.Ticks > parse_last_tick)
            {
                parse_last_tick = DateTime.Now.Ticks + (long)(TimeSpan.TicksPerSecond / parse_fps);
                ((ModemVideo)modem).SetImage(e);
            }

            capture.GrapImg2();
        }
Beispiel #25
0
 public IAviVideoStream CreateVideoStream(AviWriter writer)
 {
     // Select encoder type based on FOURCC of codec
     if (Codec == KnownFourCCs.Codecs.Uncompressed) return writer.AddUncompressedVideoStream(Width, Height);
     else if (Codec == KnownFourCCs.Codecs.MotionJpeg) return writer.AddMotionJpegVideoStream(Width, Height, Quality);
     else
     {
         return writer.AddMpeg4VideoStream(Width, Height, (double)writer.FramesPerSecond,
             // It seems that all tested MPEG-4 VfW codecs ignore the quality affecting parameters passed through VfW API
             // They only respect the settings from their own configuration dialogs, and Mpeg4VideoEncoder currently has no support for this
             quality: Quality,
             codec: Codec,
             // Most of VfW codecs expect single-threaded use, so we wrap this encoder to special wrapper
             // Thus all calls to the encoder (including its instantiation) will be invoked on a single thread although encoding (and writing) is performed asynchronously
             forceSingleThreadedAccess: true);
     }
 }
Beispiel #26
0
        private void recordHudToAVIToolStripMenuItem_Click(object sender, EventArgs e)
        {
            stopRecordToolStripMenuItem_Click(sender, e);

            CustomMessageBox.Show("Output avi will be saved to the log folder");

            aviwriter = new AviWriter();
            Directory.CreateDirectory(MainV2.LogDir);
            aviwriter.avi_start(MainV2.LogDir + Path.DirectorySeparatorChar +
                                DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ".avi");

            recordHudToAVIToolStripMenuItem.Text = "Recording";
        }
Beispiel #27
0
        private void Encode(List <FrameInfo> listFrames, int id, Parameters param, CancellationTokenSource tokenSource)
        {
            var processing = this.DispatcherStringResource("Encoder.Processing");

            try
            {
                switch (param.Type)
                {
                case Export.Gif:

                    #region Gif

                    #region Cut/Paint Unchanged Pixels

                    if (param.EncoderType == GifEncoderType.Legacy || param.EncoderType == GifEncoderType.ScreenToGif)
                    {
                        if (param.DetectUnchangedPixels)
                        {
                            Update(id, 0, FindResource("Encoder.Analyzing").ToString());

                            if (param.DummyColor.HasValue)
                            {
                                var color = Color.FromArgb(param.DummyColor.Value.R, param.DummyColor.Value.G, param.DummyColor.Value.B);

                                listFrames = ImageMethods.PaintTransparentAndCut(listFrames, color, id, tokenSource);
                            }
                            else
                            {
                                listFrames = ImageMethods.CutUnchanged(listFrames, id, tokenSource);
                            }
                        }
                        else
                        {
                            var size = listFrames[0].Path.ScaledSize();
                            listFrames.ForEach(x => x.Rect = new Int32Rect(0, 0, (int)size.Width, (int)size.Height));
                        }
                    }

                    #endregion

                    switch (param.EncoderType)
                    {
                    case GifEncoderType.ScreenToGif:

                        #region Improved encoding

                        using (var stream = new MemoryStream())
                        {
                            using (var encoder = new GifFile(stream, param.RepeatCount))
                            {
                                encoder.UseGlobalColorTable = param.UseGlobalColorTable;
                                encoder.TransparentColor    = param.DummyColor;
                                encoder.MaximumNumberColor  = param.MaximumNumberColors;

                                for (var i = 0; i < listFrames.Count; i++)
                                {
                                    if (!listFrames[i].HasArea && param.DetectUnchangedPixels)
                                    {
                                        continue;
                                    }

                                    if (listFrames[i].Delay == 0)
                                    {
                                        listFrames[i].Delay = 10;
                                    }

                                    encoder.AddFrame(listFrames[i].Path, listFrames[i].Rect, listFrames[i].Delay);

                                    Update(id, i, string.Format(processing, i));

                                    #region Cancellation

                                    if (tokenSource.Token.IsCancellationRequested)
                                    {
                                        SetStatus(Status.Canceled, id);
                                        break;
                                    }

                                    #endregion
                                }
                            }

                            try
                            {
                                using (var fileStream = new FileStream(param.Filename, FileMode.Create, FileAccess.Write, FileShare.None, 4096))
                                    stream.WriteTo(fileStream);
                            }
                            catch (Exception ex)
                            {
                                SetStatus(Status.Error, id);
                                LogWriter.Log(ex, "Improved Encoding");
                            }
                        }

                        #endregion

                        break;

                    case GifEncoderType.Legacy:

                        #region Legacy Encoding

                        using (var encoder = new AnimatedGifEncoder())
                        {
                            if (param.DummyColor.HasValue)
                            {
                                var color = Color.FromArgb(param.DummyColor.Value.R,
                                                           param.DummyColor.Value.G, param.DummyColor.Value.B);

                                encoder.SetTransparent(color);
                                encoder.SetDispose(1);         //Undraw Method, "Leave".
                            }

                            encoder.Start(param.Filename);
                            encoder.SetQuality(param.Quality);
                            encoder.SetRepeat(param.RepeatCount);

                            var numImage = 0;
                            foreach (var frame in listFrames)
                            {
                                #region Cancellation

                                if (tokenSource.Token.IsCancellationRequested)
                                {
                                    SetStatus(Status.Canceled, id);
                                    break;
                                }

                                #endregion

                                if (!frame.HasArea && param.DetectUnchangedPixels)
                                {
                                    continue;
                                }

                                var bitmapAux = new Bitmap(frame.Path);

                                encoder.SetDelay(frame.Delay);
                                encoder.AddFrame(bitmapAux, frame.Rect.X, frame.Rect.Y);

                                bitmapAux.Dispose();

                                Update(id, numImage, string.Format(processing, numImage));
                                numImage++;
                            }
                        }

                        #endregion

                        break;

                    case GifEncoderType.PaintNet:

                        #region paint.NET encoding

                        using (var stream = new MemoryStream())
                        {
                            using (var encoder = new GifEncoder(stream, null, null, param.RepeatCount))
                            {
                                for (var i = 0; i < listFrames.Count; i++)
                                {
                                    var bitmapAux = new Bitmap(listFrames[i].Path);
                                    encoder.AddFrame(bitmapAux, 0, 0, TimeSpan.FromMilliseconds(listFrames[i].Delay));
                                    bitmapAux.Dispose();

                                    Update(id, i, string.Format(processing, i));

                                    #region Cancellation

                                    if (tokenSource.Token.IsCancellationRequested)
                                    {
                                        SetStatus(Status.Canceled, id);

                                        break;
                                    }

                                    #endregion
                                }
                            }

                            stream.Position = 0;

                            try
                            {
                                using (var fileStream = new FileStream(param.Filename, FileMode.Create, FileAccess.Write, FileShare.None, Constants.BufferSize, false))
                                    stream.WriteTo(fileStream);
                            }
                            catch (Exception ex)
                            {
                                SetStatus(Status.Error, id);
                                LogWriter.Log(ex, "Encoding with paint.Net.");
                            }
                        }

                        #endregion

                        break;

                    case GifEncoderType.FFmpeg:

                        #region FFmpeg encoding

                        SetStatus(Status.Processing, id, null, true);

                        if (!Util.Other.IsFfmpegPresent())
                        {
                            throw new ApplicationException("FFmpeg not present.");
                        }

                        if (File.Exists(param.Filename))
                        {
                            File.Delete(param.Filename);
                        }

                        #region Generate concat

                        var concat = new StringBuilder();
                        foreach (var frame in listFrames)
                        {
                            concat.AppendLine("file '" + frame.Path + "'");
                            concat.AppendLine("duration " + (frame.Delay / 1000d).ToString(CultureInfo.InvariantCulture));
                        }

                        var concatPath = Path.GetDirectoryName(listFrames[0].Path) ?? Path.GetTempPath();
                        var concatFile = Path.Combine(concatPath, "concat.txt");

                        if (!Directory.Exists(concatPath))
                        {
                            Directory.CreateDirectory(concatPath);
                        }

                        if (File.Exists(concatFile))
                        {
                            File.Delete(concatFile);
                        }

                        File.WriteAllText(concatFile, concat.ToString());

                        #endregion

                        param.Command = string.Format(param.Command, concatFile, param.ExtraParameters.Replace("{H}", param.Height.ToString()).Replace("{W}", param.Width.ToString()), param.Filename);

                        var process = new ProcessStartInfo(UserSettings.All.FfmpegLocation)
                        {
                            Arguments             = param.Command,
                            CreateNoWindow        = true,
                            ErrorDialog           = false,
                            UseShellExecute       = false,
                            RedirectStandardError = true
                        };

                        var pro = Process.Start(process);

                        var str = pro.StandardError.ReadToEnd();

                        var fileInfo = new FileInfo(param.Filename);

                        if (!fileInfo.Exists || fileInfo.Length == 0)
                        {
                            throw new Exception("Error while encoding the gif with FFmpeg.")
                                  {
                                      HelpLink = str
                                  }
                        }
                        ;

                        #endregion

                        break;

                    case GifEncoderType.Gifski:

                        #region Gifski encoding

                        SetStatus(Status.Processing, id, null, true);

                        if (!Util.Other.IsGifskiPresent())
                        {
                            throw new ApplicationException("Gifski not present.");
                        }

                        if (File.Exists(param.Filename))
                        {
                            File.Delete(param.Filename);
                        }

                        var outputPath = Path.GetDirectoryName(listFrames[0].Path);
                        var fps        = !param.ExtraParameters.Contains("--fps") ? "--fps " + (int)(1000d / listFrames.Average(x => x.Delay)) : "";

                        param.Command = $"{param.ExtraParameters} {fps} -o \"{param.Filename}\" \"{Path.Combine(outputPath, "*.png")}\"";

                        var process2 = new ProcessStartInfo(UserSettings.All.GifskiLocation)
                        {
                            Arguments             = param.Command,
                            CreateNoWindow        = true,
                            ErrorDialog           = false,
                            UseShellExecute       = false,
                            RedirectStandardError = true
                        };

                        var pro2 = Process.Start(process2);

                        var str2 = pro2.StandardError.ReadToEnd();

                        var fileInfo2 = new FileInfo(param.Filename);

                        if (!fileInfo2.Exists || fileInfo2.Length == 0)
                        {
                            throw new Exception("Error while encoding the gif with Gifski.")
                                  {
                                      HelpLink = str2
                                  }
                        }
                        ;

                        #endregion

                        break;

                    default:
                        throw new Exception("Undefined Gif encoder type");
                    }

                    #endregion

                    break;

                case Export.Apng:

                    #region Apng

                    #region Cut/Paint Unchanged Pixels

                    if (param.DetectUnchangedPixels)
                    {
                        Update(id, 0, FindResource("Encoder.Analyzing").ToString());

                        if (param.DummyColor.HasValue)
                        {
                            var color = Color.FromArgb(param.DummyColor.Value.A, param.DummyColor.Value.R, param.DummyColor.Value.G, param.DummyColor.Value.B);
                            listFrames = ImageMethods.PaintTransparentAndCut(listFrames, color, id, tokenSource);
                        }
                        else
                        {
                            listFrames = ImageMethods.CutUnchanged(listFrames, id, tokenSource);
                        }
                    }
                    else
                    {
                        var size = listFrames[0].Path.ScaledSize();
                        listFrames.ForEach(x => x.Rect = new Int32Rect(0, 0, (int)size.Width, (int)size.Height));
                    }

                    #endregion

                    #region Encoding

                    using (var stream = new MemoryStream())
                    {
                        var frameCount = listFrames.Count(x => x.HasArea);

                        using (var encoder = new Apng(stream, frameCount, param.RepeatCount))
                        {
                            for (var i = 0; i < listFrames.Count; i++)
                            {
                                if (!listFrames[i].HasArea && param.DetectUnchangedPixels)
                                {
                                    continue;
                                }

                                if (listFrames[i].Delay == 0)
                                {
                                    listFrames[i].Delay = 10;
                                }

                                encoder.AddFrame(listFrames[i].Path, listFrames[i].Rect, listFrames[i].Delay);

                                Update(id, i, string.Format(processing, i));

                                #region Cancellation

                                if (tokenSource.Token.IsCancellationRequested)
                                {
                                    SetStatus(Status.Canceled, id);
                                    break;
                                }

                                #endregion
                            }
                        }

                        try
                        {
                            using (var fileStream = new FileStream(param.Filename, FileMode.Create, FileAccess.Write, FileShare.None, 4096))
                                stream.WriteTo(fileStream);
                        }
                        catch (Exception ex)
                        {
                            SetStatus(Status.Error, id);
                            LogWriter.Log(ex, "Apng Encoding");
                        }
                    }

                    #endregion

                    #endregion

                    break;

                case Export.Video:

                    #region Video

                    switch (param.VideoEncoder)
                    {
                    case VideoEncoderType.AviStandalone:

                        #region Avi Standalone

                        var image = listFrames[0].Path.SourceFrom();

                        if (File.Exists(param.Filename))
                        {
                            File.Delete(param.Filename);
                        }

                        //1000 / listFrames[0].Delay
                        using (var aviWriter = new AviWriter(param.Filename, param.Framerate, image.PixelWidth, image.PixelHeight, param.VideoQuality))
                        {
                            var numImage = 0;
                            foreach (var frame in listFrames)
                            {
                                using (var outStream = new MemoryStream())
                                {
                                    var bitImage = frame.Path.SourceFrom();

                                    var enc = new BmpBitmapEncoder();
                                    enc.Frames.Add(BitmapFrame.Create(bitImage));
                                    enc.Save(outStream);

                                    outStream.Flush();

                                    using (var bitmap = new Bitmap(outStream))
                                        aviWriter.AddFrame(bitmap, param.FlipVideo);
                                }

                                Update(id, numImage, string.Format(processing, numImage));
                                numImage++;

                                #region Cancellation

                                if (tokenSource.Token.IsCancellationRequested)
                                {
                                    SetStatus(Status.Canceled, id);
                                    break;
                                }

                                #endregion
                            }
                        }

                        #endregion

                        break;

                    case VideoEncoderType.Ffmpg:

                        #region Video using FFmpeg

                        SetStatus(Status.Processing, id, null, true);

                        if (!Util.Other.IsFfmpegPresent())
                        {
                            throw new ApplicationException("FFmpeg not present.");
                        }

                        if (File.Exists(param.Filename))
                        {
                            File.Delete(param.Filename);
                        }

                        #region Generate concat

                        var concat = new StringBuilder();
                        foreach (var frame in listFrames)
                        {
                            concat.AppendLine("file '" + frame.Path + "'");
                            concat.AppendLine("duration " + (frame.Delay / 1000d).ToString(CultureInfo.InvariantCulture));
                        }

                        var concatPath = Path.GetDirectoryName(listFrames[0].Path) ?? Path.GetTempPath();
                        var concatFile = Path.Combine(concatPath, "concat.txt");

                        if (!Directory.Exists(concatPath))
                        {
                            Directory.CreateDirectory(concatPath);
                        }

                        if (File.Exists(concatFile))
                        {
                            File.Delete(concatFile);
                        }

                        File.WriteAllText(concatFile, concat.ToString());

                        #endregion

                        param.Command = string.Format(param.Command, concatFile, param.ExtraParameters.Replace("{H}", param.Height.ToString()).Replace("{W}", param.Width.ToString()), param.Filename);

                        var process = new ProcessStartInfo(UserSettings.All.FfmpegLocation)
                        {
                            Arguments             = param.Command,
                            CreateNoWindow        = true,
                            ErrorDialog           = false,
                            UseShellExecute       = false,
                            RedirectStandardError = true
                        };

                        var pro = Process.Start(process);

                        var str = pro.StandardError.ReadToEnd();

                        var fileInfo = new FileInfo(param.Filename);

                        if (!fileInfo.Exists || fileInfo.Length == 0)
                        {
                            throw new Exception("Error while encoding with FFmpeg.")
                                  {
                                      HelpLink = str
                                  }
                        }
                        ;

                        #endregion

                        break;

                    default:
                        throw new Exception("Undefined video encoder");
                    }

                    #endregion

                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(param));
                }

                //If it was canceled, try deleting the file.
                if (tokenSource.Token.IsCancellationRequested)
                {
                    if (File.Exists(param.Filename))
                    {
                        File.Delete(param.Filename);
                    }

                    SetStatus(Status.Canceled, id);
                    return;
                }

                #region Upload

                if (param.Upload && File.Exists(param.Filename))
                {
                    InternalUpdate(id, "Encoder.Uploading", true, true);

                    try
                    {
                        //TODO: Make it less hardcoded.
                        switch (param.UploadDestinationIndex)
                        {
                        case 0:     //Imgur.
                            using (var w = new WebClient())
                            {
                                w.Headers.Add("Authorization", "Client-ID " + Secret.ImgurId);
                                var values = new NameValueCollection {
                                    { "image", Convert.ToBase64String(File.ReadAllBytes(param.Filename)) }
                                };
                                var response = w.UploadValues("https://api.imgur.com/3/upload.xml", values);
                                var x        = XDocument.Load(new MemoryStream(response));

                                var node     = x.Descendants().FirstOrDefault(n => n.Name == "link");
                                var nodeHash = x.Descendants().FirstOrDefault(n => n.Name == "deletehash");

                                if (node == null)
                                {
                                    throw new Exception("No link was provided by Imgur", new Exception(x.Document?.ToString() ?? "The document was null. :/"));
                                }

                                InternalSetUpload(id, true, node.Value, "https://imgur.com/delete/" + nodeHash?.Value);
                            }
                            break;

                        case 1:     //Gfycat.
                            using (var client = new HttpClient())
                            {
                                using (var res = client.PostAsync(@"https://api.gfycat.com/v1/gfycats", null).Result)
                                {
                                    var result = res.Content.ReadAsStringAsync().Result;
                                    //{"isOk":true,"gfyname":"ThreeWordCode","secret":"15alphanumerics","uploadType":"filedrop.gfycat.com"}

                                    var ser = new JavaScriptSerializer();

                                    if (!(ser.DeserializeObject(result) is Dictionary <string, object> thing))
                                    {
                                        throw new Exception("It was not possible to get the gfycat name: " + res);
                                    }

                                    var name = thing["gfyname"] as string;

                                    using (var content = new MultipartFormDataContent())
                                    {
                                        content.Add(new StringContent(name), "key");
                                        content.Add(new ByteArrayContent(File.ReadAllBytes(param.Filename)), "file", name);

                                        using (var res2 = client.PostAsync("https://filedrop.gfycat.com", content).Result)
                                        {
                                            if (!res2.IsSuccessStatusCode)
                                            {
                                                throw new Exception("It was not possible to get the gfycat upload result: " + res2);
                                            }

                                            //{"task": "complete", "gfyname": "ThreeWordCode"}
                                            //{"progress": "0.03", "task": "encoding", "time": 10}

                                            //If the task is not yet completed, try waiting.

                                            var input2 = "";

                                            while (!input2.Contains("complete"))
                                            {
                                                using (var res3 = client.GetAsync("https://api.gfycat.com/v1/gfycats/fetch/status/" + name).Result)
                                                {
                                                    input2 = res3.Content.ReadAsStringAsync().Result;

                                                    if (!res3.IsSuccessStatusCode)
                                                    {
                                                        throw new Exception("It was not possible to get the gfycat upload status: " + res3);
                                                    }
                                                }

                                                if (!input2.Contains("complete"))
                                                {
                                                    Thread.Sleep(1000);
                                                }
                                            }

                                            if (res2.IsSuccessStatusCode)
                                            {
                                                InternalSetUpload(id, true, "https://gfycat.com/" + name);
                                            }
                                        }
                                    }
                                }
                            }
                            break;
                        }
                    }
                    catch (Exception e)
                    {
                        LogWriter.Log(e, "It was not possible to run the post encoding command.");
                        InternalSetUpload(id, false, null, null, e);
                    }
                }

                #endregion

                #region Copy to clipboard

                if (param.CopyToClipboard && File.Exists(param.Filename))
                {
                    Dispatcher.Invoke(() =>
                    {
                        try
                        {
                            var data = new DataObject();

                            switch (param.CopyType)
                            {
                            case CopyType.File:
                                if (param.Type != Export.Video)
                                {
                                    data.SetImage(param.Filename.SourceFrom());
                                }

                                data.SetText(param.Filename, TextDataFormat.Text);
                                data.SetFileDropList(new StringCollection {
                                    param.Filename
                                });
                                break;

                            case CopyType.FolderPath:
                                data.SetText(Path.GetDirectoryName(param.Filename) ?? param.Filename, TextDataFormat.Text);
                                break;

                            case CopyType.Link:
                                data.SetText(param.Filename, TextDataFormat.Text);     //TODO: Link.
                                break;

                            default:
                                data.SetText(param.Filename, TextDataFormat.Text);
                                break;
                            }

                            Clipboard.SetDataObject(data, true);
                            InternalSetCopy(id, true);
                        }
                        catch (Exception e)
                        {
                            LogWriter.Log(e, "It was not possible to copy the file.");
                            InternalSetCopy(id, false, e);
                        }
                    });
                }

                #endregion

                #region Execute commands

                if (param.ExecuteCommands && !string.IsNullOrWhiteSpace(param.PostCommands))
                {
                    InternalUpdate(id, "Encoder.Executing", true, true);

                    var command = param.PostCommands.Replace("{p}", "\"" + param.Filename + "\"").Replace("{f}", "\"" + Path.GetDirectoryName(param.Filename) + "\"");
                    var output  = "";

                    try
                    {
                        foreach (var com in command.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries))
                        {
                            var procStartInfo = new ProcessStartInfo("cmd", "/c " + com)
                            {
                                RedirectStandardOutput = true,
                                RedirectStandardError  = true,
                                UseShellExecute        = false,
                                CreateNoWindow         = true
                            };

                            using (var process = new Process())
                            {
                                process.StartInfo = procStartInfo;
                                process.Start();

                                var message = process.StandardOutput.ReadToEnd();
                                var error   = process.StandardError.ReadToEnd();

                                if (!string.IsNullOrWhiteSpace(message))
                                {
                                    output += message + Environment.NewLine;
                                }

                                if (!string.IsNullOrWhiteSpace(message))
                                {
                                    output += message + Environment.NewLine;
                                }

                                if (!string.IsNullOrWhiteSpace(error))
                                {
                                    throw new Exception(error);
                                }

                                process.WaitForExit(1000);
                            }
                        }

                        InternalSetCommand(id, true, command, output);
                    }
                    catch (Exception e)
                    {
                        LogWriter.Log(e, "It was not possible to run the post encoding command.");
                        InternalSetCommand(id, false, command, output, e);
                    }
                }

                #endregion

                if (!tokenSource.Token.IsCancellationRequested)
                {
                    SetStatus(Status.Completed, id, param.Filename);
                }
            }
            catch (Exception ex)
            {
                LogWriter.Log(ex, "Encode");

                SetStatus(Status.Error, id, null, false, ex);
            }
            finally
            {
                #region Delete Encoder Folder

                try
                {
                    var encoderFolder = Path.GetDirectoryName(listFrames[0].Path);

                    if (!string.IsNullOrEmpty(encoderFolder))
                    {
                        if (Directory.Exists(encoderFolder))
                        {
                            Directory.Delete(encoderFolder, true);
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogWriter.Log(ex, "Cleaning the Encode folder");
                }

                #endregion

                GC.Collect();
            }
        }
Beispiel #28
0
 public void CaptureFinished()
 {
     aviWriter.Close();
     aviWriter = null;
 }
Beispiel #29
0
        IVideoFileWriter GetVideoFileWriter(IImageProvider ImgProvider)
        {
            var selectedVideoSourceKind = VideoViewModel.SelectedVideoSourceKind;
            var encoder = VideoViewModel.SelectedCodec;

            IVideoFileWriter videoEncoder = null;
            encoder.Quality = VideoViewModel.Quality;

            if (encoder.Name == "Gif")
            {
                if (GifViewModel.Unconstrained)
                    _recorder = new UnconstrainedFrameRateGifRecorder(
                        new GifWriter(_currentFileName,
                            Repeat: GifViewModel.Repeat ? GifViewModel.RepeatCount : -1),
                        ImgProvider);

                else
                    videoEncoder = new GifWriter(_currentFileName, 1000/VideoViewModel.FrameRate,
                        GifViewModel.Repeat ? GifViewModel.RepeatCount : -1);
            }

            else if (selectedVideoSourceKind != VideoSourceKind.NoVideo)
                videoEncoder = new AviWriter(_currentFileName, encoder);
            return videoEncoder;
        }
Beispiel #30
0
        public static void Decode(string filename, Stream fs, bool swapped, long framePosition)
        {
            char progress = ' ';

            var aviWriter = new AviWriter(filename + ".avi")
            {
                EmitIndex1 = true, FramesPerSecond = 18
            };

            IAviVideoStream videoStream = aviWriter.AddVideoStream(144, 80, BitsPerPixel.Bpp24);

            videoStream.Codec = KnownFourCCs.Codecs.Uncompressed;
            IAviAudioStream audioStream = aviWriter.AddAudioStream(2, 17640, 8);

            fs.Position = framePosition;
            byte[] frameBuffer = new byte[19600];
            fs.Read(frameBuffer, 0, frameBuffer.Length);

            int audioStart = swapped ? 9 : 8;

            byte[] frameMarkerToUse = swapped ? SwappedFrameMarker : FrameMarker;

            if (!swapped)
            {
                frameBuffer = Swapping.SwapBuffer(frameBuffer);
            }

            var outFs = new MemoryStream();

            for (int i = 9; i <= frameBuffer.Length; i += 10)
            {
                switch ((i / 10) % 4)
                {
                case 0:
                    progress = '-';

                    break;

                case 1:
                    progress = '\\';

                    break;

                case 2:
                    progress = '|';

                    break;

                case 3:
                    progress = '/';

                    break;
                }

                Console.Write($"\r{Localization.ExtractingAudio}", progress);
                outFs.WriteByte(frameBuffer[i]);
            }

            byte[] videoFrame = DecodeFrame(frameBuffer);
            videoStream.WriteFrame(true, videoFrame, 0, videoFrame.Length);
            audioStream.WriteBlock(outFs.ToArray(), 0, (int)outFs.Length);

            int totalFrames = 1;

            framePosition += 19600;
            byte[] buffer = new byte[frameMarkerToUse.Length];

            while (framePosition + 19600 < fs.Length)
            {
                switch (totalFrames % 4)
                {
                case 0:
                    progress = '-';

                    break;

                case 1:
                    progress = '\\';

                    break;

                case 2:
                    progress = '|';

                    break;

                case 3:
                    progress = '/';

                    break;
                }

                Console.Write($"\r{Localization.LookingForMoreFrames}", progress);

                for (int ab = audioStart; ab < buffer.Length; ab += 10)
                {
                    buffer[ab] = 0;
                }

                if (!buffer.SequenceEqual(frameMarkerToUse))
                {
                    Console.Write("\r                                      \r");
                    Console.WriteLine(Localization.FrameAndNextAreNotAligned, totalFrames);
                    long expectedFramePosition = framePosition;

                    while (framePosition < fs.Length)
                    {
                        fs.Position = framePosition;
                        fs.Read(buffer, 0, buffer.Length);

                        for (int ab = audioStart; ab < buffer.Length; ab += 10)
                        {
                            buffer[ab] = 0;
                        }

                        if (buffer.SequenceEqual(frameMarkerToUse))
                        {
                            Console.Write("\r                                      \r");

                            fs.Position = framePosition;
                            frameBuffer = new byte[19600];
                            fs.Read(frameBuffer, 0, frameBuffer.Length);

                            if (!swapped)
                            {
                                frameBuffer = Swapping.SwapBuffer(frameBuffer);
                            }

                            outFs = new MemoryStream();

                            for (int i = 9; i <= frameBuffer.Length; i += 10)
                            {
                                switch ((i / 10) % 4)
                                {
                                case 0:
                                    progress = '-';

                                    break;

                                case 1:
                                    progress = '\\';

                                    break;

                                case 2:
                                    progress = '|';

                                    break;

                                case 3:
                                    progress = '/';

                                    break;
                                }

                                Console.Write($"\r{Localization.ExtractingAudio}", progress);
                                outFs.WriteByte(frameBuffer[i]);
                            }

                            videoFrame = DecodeFrame(frameBuffer);
                            videoStream.WriteFrame(true, videoFrame, 0, videoFrame.Length);
                            audioStream.WriteBlock(outFs.ToArray(), 0, (int)outFs.Length);

                            totalFrames++;
                            Console.Write("\r                                      \r");

                            Console.WriteLine(Localization.FrameFoundAtPosition, framePosition, totalFrames,
                                              framePosition - expectedFramePosition);

                            Console.
                            WriteLine(framePosition % 2352 == 0 ? Localization.FrameIsAtSectorBoundary : Localization.FrameIsNotAtSectorBoundary,
                                      totalFrames);

                            framePosition += 19600;

                            break;
                        }

                        framePosition++;
                    }

                    continue;
                }

                if (framePosition % 2352 == 0)
                {
                    Console.Write("\r                                      \r");
                    Console.WriteLine(Localization.FrameIsAtSectorBoundary, totalFrames);
                }

                Console.Write("\r                                      \r");
                fs.Position = framePosition;
                frameBuffer = new byte[19600];
                fs.Read(frameBuffer, 0, frameBuffer.Length);

                if (!swapped)
                {
                    frameBuffer = Swapping.SwapBuffer(frameBuffer);
                }

                outFs = new MemoryStream();

                for (int i = 9; i <= frameBuffer.Length; i += 10)
                {
                    switch ((i / 10) % 4)
                    {
                    case 0:
                        progress = '-';

                        break;

                    case 1:
                        progress = '\\';

                        break;

                    case 2:
                        progress = '|';

                        break;

                    case 3:
                        progress = '/';

                        break;
                    }

                    Console.Write($"\r{Localization.ExtractingAudio}", progress);
                    outFs.WriteByte(frameBuffer[i]);
                }

                videoFrame = DecodeFrame(frameBuffer);
                videoStream.WriteFrame(true, videoFrame, 0, videoFrame.Length);
                audioStream.WriteBlock(outFs.ToArray(), 0, (int)outFs.Length);

                totalFrames++;
                fs.Position = framePosition;
                fs.Read(buffer, 0, buffer.Length);
                framePosition += 19600;
            }

            Console.Write("\r                                      \r");
            Console.WriteLine(Localization.FramesFound, totalFrames);

            outFs.Close();
            aviWriter.Close();
        }
        private void RenderVideo()
        {
            try
            {
                if (!TrackResults)
                {
                    return;
                }


                Log.Debug($"Generated all images, now rendering movie.");

                //var files = Directory.EnumerateFiles(@"D:\Temp\Light\", "*.bmp");
                //files = files.OrderBy(s => s);

                //int fps = (int) (RenderingTasks.Count()/10f); // Movie should last 5 seconds
                int fps = 10;

                var writer = new AviWriter(@"D:\Temp\Light\test.avi")
                {
                    FramesPerSecond = fps,
                    // Emitting AVI v1 index in addition to OpenDML index (AVI v2)
                    // improves compatibility with some software, including
                    // standard Windows programs like Media Player and File Explorer
                    EmitIndex1 = true
                };

                var stream = writer.AddVideoStream();
                stream.Width  = GetWidth();
                stream.Height = GetHeight();
                stream.Codec  = KnownFourCCs.Codecs.Uncompressed;

                stream.BitsPerPixel = BitsPerPixel.Bpp32;

                Log.Debug($"Waiting for image rendering of {RenderingTasks.Count} images to complete");
                foreach (var renderingTask in RenderingTasks)
                {
                    renderingTask.RunSynchronously();
                    Bitmap image = renderingTask.Result;
                    //}

                    //foreach (var file in files)
                    //{
                    lock (_imageSync)
                    {
                        //Bitmap image = (Bitmap) Image.FromFile(file);
                        //image = new Bitmap(image, stream.Width, stream.Height);

                        byte[] imageData = (byte[])ToByteArray(image, ImageFormat.Bmp);

                        if (imageData == null)
                        {
                            Log.Warn($"No image data for file.");
                            continue;
                        }

                        if (imageData.Length != stream.Height * stream.Width * 4)
                        {
                            imageData = imageData.Skip(imageData.Length - (stream.Height * stream.Width * 4)).ToArray();
                        }

                        // fill frameData with image

                        // write data to a frame
                        stream.WriteFrame(true,            // is key frame? (many codecs use concept of key frames, for others - all frames are keys)
                                          imageData,       // array with frame data
                                          0,               // starting index in the array
                                          imageData.Length // length of the data
                                          );
                    }
                }

                writer.Close();
            }
            catch (Exception e)
            {
                Log.Error("Rendering movie", e);
            }
        }
Beispiel #32
0
        private void LoadSettings()
        {
            try
            {
                writer = new AviWriter("test.avi")
                    {
                        FramesPerSecond = 25,
                        // Emitting AVI v1 index in addition to OpenDML index (AVI v2)
                        // improves compatibility with some software, including
                        // standard Windows programs like Media Player and File Explorer
                        EmitIndex1 = true
                    };

                var encoder = new Mpeg4VideoEncoderVcm((int)numericWidth.Value, (int)numericHeight.Value, 25, 0, 100, KnownFourCCs.Codecs.Xvid);
            //                stream = writer.AddMotionJpegVideoStream(640, 480, quality: 100);
                //stream = writer.AddMpeg4VideoStream(640, 480, 30, quality: 70, codec: KnownFourCCs.Codecs.X264, forceSingleThreadedAccess: true);
                stream = writer.AddEncodingVideoStream(encoder, true, (int)numericWidth.Value, (int)numericHeight.Value);

                // set standard VGA resolution
                //            stream.Width = 640;
                //            stream.Height = 480;
                // class SharpAvi.KnownFourCCs.Codecs contains FOURCCs for several well-known codecs
                // Uncompressed is the default value, just set it for clarity

                //stream.Codec = KnownFourCCs.Codecs.MotionJpeg;
                // Uncompressed format requires to also specify bits per pixel
                //stream.BitsPerPixel = BitsPerPixel.Bpp32;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        private void stopRecordToolStripMenuItem_Click(object sender, EventArgs e)
        {
            recordHudToAVIToolStripMenuItem.Text = "Start Recording";

            if (aviwriter != null)
                aviwriter.avi_close();

            aviwriter = null;
        }
 public AviWriterCiCs()
 {
     avi = new AviWriter();
 }
Beispiel #35
0
        private void stopRecordToolStripMenuItem_Click(object sender, EventArgs e)
        {
            recordHudToAVIToolStripMenuItem.Text = "Start Recording";

            try
            {
                if (aviwriter != null)
                    aviwriter.avi_close();
            }
            catch (Exception ex)
            {
                CustomMessageBox.Show(Strings.ERROR + " " + ex, Strings.ERROR);
            }

            aviwriter = null;
        }
Beispiel #36
0
        void StartRecording()
        {
            var SelectedAudioSourceId   = AudioSettings.SelectedAudioSourceId;
            var SelectedVideoSourceKind = VideoSettings.SelectedVideoSourceKind;
            var SelectedVideoSource     = VideoSettings.SelectedVideoSource;
            var Encoder = VideoSettings.Encoder;

            _duration = OtherSettings.CaptureDuration;
            _delay    = OtherSettings.StartDelay;

            if (_duration != 0 && (_delay * 1000 > _duration))
            {
                Status.Content = "Delay cannot be greater than Duration";
                SystemSounds.Asterisk.Play();
                return;
            }

            if (OtherSettings.MinimizeOnStart)
            {
                WindowState = WindowState.Minimized;
            }

            VideoSettings.Instance.VideoSourceKindBox.IsEnabled = false;
            VideoSettings.Instance.VideoSourceBox.IsEnabled     = SelectedVideoSourceKind == VideoSourceKind.Window;

            // UI Buttons
            RecordButton.ToolTip  = "Stop";
            RecordButton.IconData = (RectangleGeometry)FindResource("StopIcon");

            ReadyToRecord = false;

            int temp;

            var Extension = SelectedVideoSourceKind == VideoSourceKind.NoVideo
                ? (AudioSettings.EncodeAudio && int.TryParse(SelectedAudioSourceId, out temp) ? ".mp3" : ".wav")
                : (Encoder.Name == "Gif" ? ".gif" : ".avi");

            lastFileName = Path.Combine(OutPath.Text, DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + Extension);

            Status.Content = _delay > 0 ? $"Recording from t={_delay}ms..." : "Recording...";

            DTimer.Stop();
            _seconds            = _minutes = 0;
            TimeManager.Content = "00:00";

            DTimer.Start();

            var AudioBitRate = App.IsLamePresent ? Mp3EncoderLame.SupportedBitRates[AudioSettings.AudioQuality] : 0;

            IAudioProvider AudioSource = null;
            var            wf          = new WaveFormat(44100, 16, AudioSettings.Stereo ? 2 : 1);

            if (SelectedAudioSourceId != "-1")
            {
                int i;
                if (int.TryParse(SelectedAudioSourceId, out i))
                {
                    AudioSource = new WaveIn(i, VideoSettings.FrameRate, wf);
                }
                else
                {
                    AudioSource = new WasapiLoopbackCapture(WasapiAudioDevice.Get(SelectedAudioSourceId));
                    wf          = AudioSource.WaveFormat;
                }
            }

            #region ImageProvider
            IImageProvider ImgProvider = null;

            Func <System.Windows.Media.Color, System.Drawing.Color> ConvertColor = C => System.Drawing.Color.FromArgb(C.A, C.R, C.G, C.B);

            var mouseKeyHook = new MouseKeyHook(OtherSettings.CaptureClicks,
                                                OtherSettings.CaptureKeystrokes);

            switch (SelectedVideoSourceKind)
            {
            case VideoSourceKind.Window:
                var Src = SelectedVideoSource as WindowVSLI;

                if (Src.Handle == RegionSelector.Instance.Handle &&
                    OtherSettings.StaticRegionCapture)
                {
                    ImgProvider = new StaticRegionProvider(RegionSelector.Instance,
                                                           cursor,
                                                           mouseKeyHook);
                    VideoSettings.Instance.VideoSourceBox.IsEnabled = false;
                }
                else
                {
                    ImgProvider = new WindowProvider(() => (VideoSettings.SelectedVideoSource as WindowVSLI).Handle,
                                                     ConvertColor(VideoSettings.BackgroundColor),
                                                     cursor,
                                                     mouseKeyHook);
                }
                break;

            case VideoSourceKind.Screen:
                ImgProvider = new ScreenProvider((SelectedVideoSource as ScreenVSLI).Screen,
                                                 cursor,
                                                 mouseKeyHook);
                break;
            }
            #endregion

            #region VideoEncoder
            IVideoFileWriter VideoEncoder = null;

            if (Encoder.Name == "Gif")
            {
                if (GifSettings.UnconstrainedGif)
                {
                    Recorder = new UnconstrainedFrameRateGifRecorder(
                        new GifWriter(lastFileName,
                                      Repeat: GifSettings.GifRepeat ? GifSettings.GifRepeatCount : -1),
                        ImgProvider);
                }

                else
                {
                    VideoEncoder = new GifWriter(lastFileName, 1000 / VideoSettings.FrameRate,
                                                 GifSettings.GifRepeat ? GifSettings.GifRepeatCount : -1);
                }
            }

            else if (SelectedVideoSourceKind != VideoSourceKind.NoVideo)
            {
                VideoEncoder = new AviWriter(lastFileName,
                                             ImgProvider,
                                             Encoder,
                                             VideoSettings.VideoQuality,
                                             VideoSettings.FrameRate,
                                             AudioSource,
                                             AudioBitRate == 0 ? null
                                                                : new Mp3EncoderLame(wf.Channels, wf.SampleRate, AudioBitRate));
            }
            #endregion

            if (Recorder == null)
            {
                if (SelectedVideoSourceKind == VideoSourceKind.NoVideo)
                {
                    Recorder = AudioSettings.EncodeAudio ? new AudioRecorder(AudioSource, new EncodedAudioFileWriter(lastFileName, new Mp3EncoderLame(wf.Channels, wf.SampleRate, AudioBitRate)))
                                                         : new AudioRecorder(AudioSource, new WaveFileWriter(lastFileName, wf));
                }

                else
                {
                    Recorder = new Recorder(VideoEncoder, ImgProvider, AudioSource);
                }
            }

            Recorder.RecordingStopped += E => Dispatcher.Invoke(() =>
            {
                OnStopped();

                if (E != null)
                {
                    Status.Content = "Error";
                    MessageBox.Show(E.ToString());
                }
            });

            Recorder.Start(_delay);

            Recent.Add(lastFileName,
                       VideoEncoder == null ? RecentItemType.Audio : RecentItemType.Video);
        }