Skip to content

Instantly share code, notes, and snippets.

@krisives
Created March 25, 2014 07:12
Show Gist options
  • Save krisives/9756550 to your computer and use it in GitHub Desktop.
Save krisives/9756550 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.IO;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace Remote
{
public partial class Form1 : Form
{
BoundsForm boundsForm = new BoundsForm();
Bitmap captureBuffer = null;
Graphics captureGraphics;
Graphics controlGraphics;
int screenX = 0, screenY = 0;
Size screenSize = new Size();
bool recording = false;
BufferedGraphicsContext bufferContext;
BufferedGraphics bg;
Graphics g;
Process encoderProcess;
Rectangle bounds = new Rectangle();
byte[] dataBuffer = null;
StreamWriter sw;
Stream stream;
BufferedStream bf;
public Form1()
{
bufferContext = BufferedGraphicsManager.Current;
InitializeComponent();
}
private void createEncoderProcess()
{
String ffmpegPath = "X:\\GRemote\\ffmpeg.exe";
String args = String.Format(
"-f rawvideo -pixel_format bgr24 -video_size {0}x{1} -framerate 30 -i - X:\\GRemote\\xxxx.avi",
captureBuffer.Width,
captureBuffer.Height
);
// Process p = Process.Start(ffmpegPath, args);
encoderProcess = new Process();
encoderProcess.StartInfo.FileName = ffmpegPath;
encoderProcess.StartInfo.Arguments = args;
encoderProcess.StartInfo.UseShellExecute = false;
encoderProcess.StartInfo.RedirectStandardInput = true;
encoderProcess.StartInfo.RedirectStandardError = true;
//p.StartInfo.RedirectStandardOutput = true;
encoderProcess.Start();
sw = encoderProcess.StandardInput;
stream = sw.BaseStream;
bf = new BufferedStream(stream);
}
/*
private ImageCodecInfo GetEncoder(ImageFormat format)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
foreach (ImageCodecInfo codec in codecs)
{
if (codec.FormatID == format.Guid)
{
return codec;
}
}
return null;
}
*/
private void button1_Click(object sender, EventArgs e)
{
boundsForm.Show();
}
private void snapshotTimer_Tick(object sender, EventArgs e)
{
if (!recording)
{
return;
}
captureGraphics.CopyFromScreen(screenX, screenY, 0, 0, screenSize);
// Stream stream = new MemoryStream();
// captureBuffer.Save(stream, ImageFormat.Jpeg);
// captureBuffer.Save(stream, jgpEncoder, p);
// bytesLabel.Text = stream.Position.ToString();
//captureBuffer.Save(stream, ImageFormat.Bmp);
// captureBuffer.Save(stream, jgpEncoder, p);
BitmapData data = captureBuffer.LockBits(bounds, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
Marshal.Copy(data.Scan0, dataBuffer, 0, dataBuffer.Length);
// MemoryStream ms = new MemoryStream(b);
//stream.Write(data.Scan0.);
captureBuffer.UnlockBits(data);
data = null;
//stream.Write(dataBuffer, 0, dataBuffer.Length);
bf.Write(dataBuffer, 0, dataBuffer.Length);
//stream.WriteByte(0);
// encoderProcess.StandardError.BaseStream.ReadTimeout = 1;
// String s = encoderProcess.StandardError.ReadLine();
//if (s != null && s.Length > 0)
// {
// Console.WriteLine(s);
//}
g.DrawImage(captureBuffer, 0, 0);//, 0, 0, captureBuffer.Width, captureBuffer.Height);
bg.Render();
}
public void updateBounds()
{
int w;
int h;
screenSize.Width = w = boundsForm.Width;
screenSize.Height = h = boundsForm.Height;
screenX = boundsForm.Left;
screenY = boundsForm.Top;
if (captureBuffer != null && (captureBuffer.Width != w || captureBuffer.Height != h))
{
captureBuffer.Dispose();
captureBuffer = null;
}
captureBuffer = new Bitmap(w, h, PixelFormat.Format24bppRgb);
captureGraphics = Graphics.FromImage(captureBuffer);
controlGraphics = previewPanel.CreateGraphics();
bg = bufferContext.Allocate(controlGraphics, new Rectangle(0, 0, w, h));
g = bg.Graphics;
bounds.Width = screenSize.Width;
bounds.Height = screenSize.Height;
dataBuffer = new byte[bounds.Width * bounds.Height * 3];
}
private void recordButton_Click(object sender, EventArgs e)
{
ToggleRecording();
}
public void ToggleRecording()
{
if (recording)
{
StopRecording();
}
else
{
StartRecording();
}
}
public void StartRecording()
{
if (recording)
{
return;
}
recording = true;
updateBounds();
createEncoderProcess();
recordButton.Text = "Stop";
statusLabel.Text = "Recording...";
snapshotTimer.Start();
}
public void StopRecording()
{
if (!recording)
{
return;
}
recording = false;
recordButton.Text = "Start";
statusLabel.Text = "Not Recording";
snapshotTimer.Stop();
encoderProcess.Close();
}
private void previewPanel_Paint(object sender, PaintEventArgs e)
{
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment