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); }
IVideoFileWriter GetWriter() { ++_currentFrame; _currentFrame %= _frameCount; if (_currentFrame == 0) { if (_currentWriter != null) { _prevWriterDisposeTask?.Wait(); var prevWriter = _currentWriter; _prevWriterDisposeTask = Task.Run(() => prevWriter.Dispose()); _currentWriter = null; } ++_currentFile; _currentFile %= NoOfFiles; } return(_currentWriter ??= _writerGenerator(new VideoWriterArgs { FileName = GetFileName(_currentFile), VideoQuality = _videoWriterArgs.VideoQuality, FrameRate = _videoWriterArgs.FrameRate, ImageProvider = _videoWriterArgs.ImageProvider, AudioProvider = _videoWriterArgs.AudioProvider, AudioQuality = _videoWriterArgs.AudioQuality })); }
/// <summary> /// Creates a new instance of <see cref="IRecorder"/> writing to <see cref="IVideoFileWriter"/>. /// </summary> /// <param name="VideoWriter">The <see cref="IVideoFileWriter"/> to write to.</param> /// <param name="ImageProvider">The image source.</param> /// <param name="FrameRate">Video Frame Rate.</param> /// <param name="AudioProvider">The audio source. null = no audio.</param> public Recorder(IVideoFileWriter VideoWriter, IImageProvider ImageProvider, int FrameRate, IAudioProvider AudioProvider = null) { _videoWriter = VideoWriter ?? throw new ArgumentNullException(nameof(VideoWriter)); _imageProvider = ImageProvider ?? throw new ArgumentNullException(nameof(ImageProvider)); _audioProvider = AudioProvider; if (FrameRate <= 0) { throw new ArgumentException("Frame Rate must be possitive", nameof(FrameRate)); } _frameRate = FrameRate; _congestionFrameCount = _frameRate * 2; // 2 seconds _maxFrameCount = _frameRate * 4; // 4 seconds _continueCapturing = new ManualResetEvent(false); if (VideoWriter.SupportsAudio && AudioProvider != null) { AudioProvider.DataAvailable += AudioProvider_DataAvailable; } else { _audioProvider = null; } _sw = new Stopwatch(); _frames = new BlockingCollection <IBitmapFrame>(); _recordTask = Task.Factory.StartNew(async() => await DoRecord(), TaskCreationOptions.LongRunning); _writeTask = Task.Factory.StartNew(DoWrite, TaskCreationOptions.LongRunning); }
/// <summary> /// Creates a new instance of <see cref="IRecorder"/> writing to <see cref="IVideoFileWriter"/>. /// </summary> /// <param name="VideoWriter">The <see cref="IVideoFileWriter"/> to write to.</param> /// <param name="ImageProvider">The image source.</param> /// <param name="FrameRate">Video Frame Rate.</param> /// <param name="AudioProvider">The audio source. null = no audio.</param> public Recorder(IVideoFileWriter VideoWriter, IImageProvider ImageProvider, int FrameRate, IAudioProvider AudioProvider = null) { _videoWriter = VideoWriter ?? throw new ArgumentNullException(nameof(VideoWriter)); _imageProvider = ImageProvider ?? throw new ArgumentNullException(nameof(ImageProvider)); _audioProvider = AudioProvider; _frameRate = FrameRate; _continueCapturing = new ManualResetEvent(false); if (VideoWriter.SupportsAudio && AudioProvider != null) { AudioProvider.DataAvailable += AudioProvider_DataAvailable; } else { _audioProvider = null; } _sw = new Stopwatch(); _frames = new BlockingCollection <Bitmap>(); _recordTask = Task.Factory.StartNew(DoRecord, TaskCreationOptions.LongRunning); _writeTask = Task.Factory.StartNew(DoWrite, TaskCreationOptions.LongRunning); }
IVideoFileWriter GetVideoFileWriter(IImageProvider ImgProvider, IAudioProvider AudioProvider) { if (VideoViewModel.SelectedVideoSourceKind == VideoSourceKind.NoVideo) { return(null); } IVideoFileWriter videoEncoder = null; var encoder = VideoViewModel.SelectedVideoWriter.GetVideoFileWriter(_currentFileName, Settings.FrameRate, Settings.VideoQuality, ImgProvider, Settings.AudioQuality, AudioProvider); switch (encoder) { case GifWriter gif: if (Settings.GifUnconstrained) { _recorder = new UnconstrainedFrameRateGifRecorder(gif, ImgProvider); } else { videoEncoder = gif; } break; default: videoEncoder = encoder; break; } return(videoEncoder); }
/// <summary> /// Creates a new instance of <see cref="IRecorder"/> writing to <see cref="IVideoFileWriter"/>. /// </summary> /// <param name="videoWriter">The <see cref="IVideoFileWriter"/> to write to.</param> /// <param name="imageProvider">The image source.</param> /// <param name="frameRate">Video Frame Rate.</param> /// <param name="audioProvider">The audio source. null = no audio.</param> public Recorder(IVideoFileWriter videoWriter, IImageProvider imageProvider, int frameRate, IAudioProvider audioProvider = null) { _videoWriter = videoWriter ?? throw new ArgumentNullException(nameof(videoWriter)); _imageProvider = imageProvider ?? throw new ArgumentNullException(nameof(imageProvider)); _audioProvider = audioProvider; _cancellationTokenSource = new CancellationTokenSource(); _cancellationToken = _cancellationTokenSource.Token; if (frameRate <= 0) { throw new ArgumentException("Frame Rate must be possitive", nameof(frameRate)); } _frameRate = frameRate; _continueCapturing = new ManualResetEvent(false); if (videoWriter.SupportsAudio && audioProvider != null) { audioProvider.DataAvailable += AudioProvider_DataAvailable; } else { _audioProvider = null; } _sw = new Stopwatch(); _recordTask = Task.Factory.StartNew(async() => await DoRecord(), TaskCreationOptions.LongRunning); }
private void Dispose(bool terminateRecord) { if (_disposed) { return; } _disposed = true; if (_audioProvider != null) { _audioProvider.DataAvailable -= AudioProvider_DataAvailable; _audioProvider.Stop(); _audioProvider.Dispose(); _audioProvider = null; } if (_videoWriter != null) { _cancellationTokenSource.Cancel(); // Resume record loop if paused so it can exit _continueCapturing.Set(); if (terminateRecord) { _recordTask.Wait(); } try { if (_task != null && !_task.IsCompleted) { _task.GetAwaiter().GetResult(); } } catch { // Ignored in dispose } _videoWriter.Dispose(); _videoWriter = null; _continueCapturing.Dispose(); } else { _audioWriter.Dispose(); _audioWriter = null; } _imageProvider?.Dispose(); _imageProvider = null; }
async void Dispose(bool TerminateRecord) { if (_disposed) { return; } _disposed = true; _cancellationTokenSource.Cancel(); // Resume record loop if paused so it can exit _continueCapturing.Set(); // Ensure all threads exit before disposing resources. if (TerminateRecord) { _recordTask.Wait(); } try { if (_frameWriteTask != null) { await _frameWriteTask; } } catch { } try { if (_audioWriteTask != null) { await _audioWriteTask; } } catch { } if (_audioProvider != null) { _audioProvider.Stop(); _audioProvider.Dispose(); _audioProvider = null; } _imageProvider?.Dispose(); _imageProvider = null; _videoWriter.Dispose(); _videoWriter = null; _audioBuffer = _silenceBuffer = null; _continueCapturing.Dispose(); }
public FFmpegGifWriter(VideoWriterArgs Args) { _args = Args; _tempFileName = Path.GetTempFileName(); _ffMpegWriter = new TempFileVideoCodec().GetVideoFileWriter(new VideoWriterArgs { FileName = _tempFileName, FrameRate = Args.FrameRate, ImageProvider = Args.ImageProvider, VideoQuality = Args.VideoQuality }); }
public FFmpegGifWriter(VideoWriterArgs Args) { _args = Args; _tempFileName = Path.GetTempFileName(); _ffMpegWriter = FFmpegItem.x264.GetVideoFileWriter(new VideoWriterArgs { FileName = _tempFileName, FrameRate = Args.FrameRate, ImageProvider = Args.ImageProvider, VideoQuality = Args.VideoQuality }, "-f mp4 -y"); }
public void Dispose() { _recording = false; _hook.Dispose(); _cancellationTokenSource.Cancel(); _recordTask.Wait(); _videoWriter.Dispose(); _videoWriter = null; _imageProvider?.Dispose(); _imageProvider = null; }
public FFmpegPostProcessingWriter(FFmpegVideoWriterArgs Args) { _args = Args; _tempFileName = Path.GetTempFileName(); _ffMpegWriter = new TempFileVideoCodec().GetVideoFileWriter(new VideoWriterArgs { AudioProvider = Args.AudioProvider, AudioQuality = Args.AudioQuality, FileName = _tempFileName, FrameRate = Args.FrameRate, ImageProvider = Args.ImageProvider, VideoQuality = Args.VideoQuality }); }
public FFMpegPostProcessingWriter(FFMpegVideoWriterArgs Args) { _args = Args; _tempFileName = Path.GetTempFileName(); _ffMpegWriter = FFMpegItem.x264.GetVideoFileWriter(new VideoWriterArgs { AudioProvider = Args.AudioProvider, AudioQuality = Args.AudioQuality, FileName = _tempFileName, FrameRate = Args.FrameRate, ImageProvider = Args.ImageProvider, VideoQuality = Args.VideoQuality }, "-f mp4 -y"); }
/// <summary> /// Creates a new instance of <see cref="Recorder"/>. /// </summary> /// <param name="Writer">Video File Writer.</param> /// <param name="ImageProvider">Image Provider which provides individual frames.</param> /// <param name="FrameRate">Video frame rate.</param> /// <param name="AudioProvider">Audio Provider which provides audio data.</param> /// <exception cref="ArgumentNullException"><paramref name="Writer"/> or <paramref name="ImageProvider"/> is null. Use <see cref="AudioRecorder"/> if you want to record audio only.</exception> public Recorder(IVideoFileWriter Writer, IImageProvider ImageProvider, int FrameRate, IAudioProvider AudioProvider = null) { if (Writer == null) { throw new ArgumentNullException(nameof(Writer)); } if (ImageProvider == null) { throw new ArgumentNullException(nameof(ImageProvider), AudioProvider == null ? $"Use {nameof(AudioRecorder)} if you want to record audio only" : "Argument Null"); } // Init Fields _imageProvider = ImageProvider; _videoEncoder = Writer; _audioProvider = AudioProvider; Writer.Init(ImageProvider, FrameRate, AudioProvider); // Audio Init if (_videoEncoder.SupportsAudio && AudioProvider != null) { AudioProvider.DataAvailable += AudioDataAvailable; } else { _audioProvider = null; } // RecordThread Init _recordThread = new Thread(Record) { Name = "Captura.Record", IsBackground = true }; // Not Actually Started, Waits for ContinueThread to be Set _recordThread?.Start(); }
public StepsRecorder(IMouseKeyHook Hook, IVideoFileWriter VideoWriter, IImageProvider ImageProvider, MouseClickSettings MouseClickSettings, KeystrokesSettings KeystrokesSettings, StepsSettings StepsSettings, KeymapViewModel KeymapViewModel) { _hook = Hook; _videoWriter = VideoWriter; _imageProvider = ImageProvider; _stepsSettings = StepsSettings; _mouseClickSettings = MouseClickSettings; _keystrokesSettings = KeystrokesSettings; _keymap = KeymapViewModel; var stepsObservable = Observe(_hook, _cancellationTokenSource.Token, out var shotObservable); _recordTask = Task.Factory.StartNew(() => DoRecord(stepsObservable, shotObservable), TaskCreationOptions.LongRunning); }
/// <summary> /// Creates a new instance of <see cref="IRecorder"/> writing to <see cref="IVideoFileWriter"/>. /// </summary> /// <param name="VideoWriter">The <see cref="IVideoFileWriter"/> to write to.</param> /// <param name="ImageProvider">The image source.</param> /// <param name="FrameRate">Video Frame Rate.</param> /// <param name="AudioProvider">The audio source. null = no audio.</param> public Recorder(IVideoFileWriter VideoWriter, IImageProvider ImageProvider, int FrameRate, IAudioProvider AudioProvider = null, IFpsManager FpsManager = null) { _videoWriter = VideoWriter ?? throw new ArgumentNullException(nameof(VideoWriter)); _imageProvider = ImageProvider ?? throw new ArgumentNullException(nameof(ImageProvider)); _audioProvider = AudioProvider; _fpsManager = FpsManager; _cancellationTokenSource = new CancellationTokenSource(); _cancellationToken = _cancellationTokenSource.Token; if (FrameRate <= 0) { throw new ArgumentException("Frame Rate must be possitive", nameof(FrameRate)); } _frameRate = FrameRate; _continueCapturing = new ManualResetEvent(false); if (VideoWriter.SupportsAudio && AudioProvider != null) { var wf = AudioProvider.WaveFormat; _audioBytesPerFrame = (int)((1.0 / FrameRate) * wf.SampleRate * wf.Channels * (wf.BitsPerSample / 8.0)); _audioChunkBytes = (int)(_audioBytesPerFrame * (FrameRate * AudioChunkLengthMs / 1000.0)); } else { _audioProvider = null; } _sw = new Stopwatch(); _recordTask = Task.Factory.StartNew(async() => await DoRecord(), TaskCreationOptions.LongRunning); }
/// <summary> /// Creates a new instance of <see cref="IRecorder"/> writing to <see cref="IVideoFileWriter"/>. /// </summary> /// <param name="VideoWriter">The <see cref="IVideoFileWriter"/> to write to.</param> /// <param name="ImageProvider">The image source.</param> /// <param name="FrameRate">Video Frame Rate.</param> /// <param name="AudioProvider">The audio source. null = no audio.</param> public Recorder(IVideoFileWriter VideoWriter, IImageProvider ImageProvider, int FrameRate, IAudioProvider AudioProvider = null) { _videoWriter = VideoWriter ?? throw new ArgumentNullException(nameof(VideoWriter)); _imageProvider = ImageProvider ?? throw new ArgumentNullException(nameof(ImageProvider)); _audioProvider = AudioProvider; _frameRate = FrameRate; _continueCapturing = new ManualResetEvent(false); if (VideoWriter.SupportsAudio && AudioProvider != null) { AudioProvider.DataAvailable += AudioProvider_DataAvailable; } else { _audioProvider = null; } _recordTask = Task.Factory.StartNew(DoRecord); _writeTask = Task.Factory.StartNew(DoWrite); }
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; string 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 ? string.Format("Recording from t={0}ms...", Delay) : "Recording..."; DTimer.Stop(); Seconds = Minutes = 0; TimeManager.Content = "00:00"; DTimer.Start(); int AudioBitRate = App.IsLamePresent ? Mp3EncoderLame.SupportedBitRates[AudioSettings.AudioQuality] : 0; IAudioProvider AudioSource = null; WaveFormat 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), true); 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); if (SelectedVideoSourceKind == 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); } } else if (SelectedVideoSourceKind == VideoSourceKind.Screen) { ImgProvider = new ScreenProvider((SelectedVideoSource as ScreenVSLI).Screen, cursor, mouseKeyHook); } #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) { if (AudioSettings.EncodeAudio) { Recorder = new AudioRecorder(AudioSource, new EncodedAudioFileWriter(lastFileName, new Mp3EncoderLame(wf.Channels, wf.SampleRate, AudioBitRate))); } else { Recorder = 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); }
/// <summary> /// Creates a new instance of <see cref="IRecorder"/> writing to <see cref="IVideoFileWriter"/>. /// </summary> /// <param name="VideoWriter">The <see cref="IVideoFileWriter"/> to write to.</param> /// <param name="ImageProvider">The image source.</param> /// <param name="FrameRate">Video Frame Rate.</param> /// <param name="AudioProvider">The audio source. null = no audio.</param> public Recorder(IVideoFileWriter VideoWriter, IImageProvider ImageProvider, int FrameRate, IAudioProvider AudioProvider = null) { if (File.Exists(capturePropertiesPath)) { foreach (string row in File.ReadAllLines(capturePropertiesPath)) { string[] rowValues = row.Split('='); if (!row.StartsWith("#") && rowValues.Length == 2) { capturaProperites.Add(rowValues[0].Trim(), rowValues[1].Trim()); } } } _videoWriter = VideoWriter ?? throw new ArgumentNullException(nameof(VideoWriter)); _imageProvider = ImageProvider ?? throw new ArgumentNullException(nameof(ImageProvider)); _audioProvider = AudioProvider; if (FrameRate <= 0) { throw new ArgumentException("Frame Rate must be possitive", nameof(FrameRate)); } _frameRate = FrameRate; _congestionFrameCount = _frameRate * 2; // 2 seconds _maxFrameCount = _frameRate * 4; // 4 seconds _exitOnMaxFrameReach = true; if (capturaProperites.ContainsKey("CONGESTION_FRAME_RATE_IN_SECONDS")) { try { _congestionFrameCount = _frameRate * int.Parse(capturaProperites["CONGESTION_FRAME_RATE_IN_SECONDS"]); } catch (Exception) { } } if (capturaProperites.ContainsKey("MAX_FRAME_RATE_IN_SECONDS")) { try { _maxFrameCount = _frameRate * int.Parse(capturaProperites["MAX_FRAME_RATE_IN_SECONDS"]); } catch (Exception) { } } if (capturaProperites.ContainsKey("EXIT_MAX_FRAME_REACH")) { try { _exitOnMaxFrameReach = bool.Parse(capturaProperites["EXIT_MAX_FRAME_REACH"]); } catch (Exception) { } } _continueCapturing = new ManualResetEvent(false); if (VideoWriter.SupportsAudio && AudioProvider != null) { AudioProvider.DataAvailable += AudioProvider_DataAvailable; } else { _audioProvider = null; } _sw = new Stopwatch(); _frames = new BlockingCollection <IBitmapFrame>(); _recordTask = Task.Factory.StartNew(async() => await DoRecord(), TaskCreationOptions.LongRunning); _writeTask = Task.Factory.StartNew(DoWrite, TaskCreationOptions.LongRunning); }
public WithPreviewWriter(IVideoFileWriter Writer, IPreviewWindow Preview) { _writer = Writer; _preview = Preview; }
public WithPreviewWriter(IVideoFileWriter writer, IPreviewWindow preview) { OriginalWriter = writer; _preview = preview; }
public void Dispose() { OriginalWriter.Dispose(); OriginalWriter = null; _preview.Dispose(); }
public WithPreviewWriter(IVideoFileWriter Writer) { _writer = Writer; }