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"); }
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; } }
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(); }
/// <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; }
/// <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; } }
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; }
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); }
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); }
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(); } }
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(); }
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(); }
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(); } }
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"; }
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); }
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); } }
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); }
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); }
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(); }
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); } }
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"; }
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(); } }
public void CaptureFinished() { aviWriter.Close(); aviWriter = null; }
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; }
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); } }
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(); }
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; }
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); }