Skip to content

Instantly share code, notes, and snippets.

@glebov21
Last active February 15, 2024 13:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save glebov21/25f0c1552a103e939e5f413c4e8b56fd to your computer and use it in GitHub Desktop.
Save glebov21/25f0c1552a103e939e5f413c4e8b56fd to your computer and use it in GitHub Desktop.
Audio and video recording from screen (output audio. Not microphone input)
//1) Add projects: Captura.Base, Captura.Bass, Captura.SharpAvi, Screna from this repository:
https://github.com/MathewSachin v8.0.0
//2) Copy bass.dll & bassmix.dll from x64 folder:
//http://www.un4seen.com/files/bassmix24.zip
//http://www.un4seen.com/files/bass24.zip
recordTask = new Task((cancelationToken) =>
{
var fps = 30;
var sharpAVICodec = new SharpAviItem(AviCodec.MotionJpeg, "Motion JPEG encoder using WPF's JPG encoder");
using (var imageProvider = new ImageProvider(height, width, dpiKoeff, rect.Left, rect.Top))
using (var audioSource = new BassAudioSource(new Captura.AudioSettings()
{
Enabled = true,
PlaybackRecordingRealTime = false,
Quality = 100,
}))
using (var audioProvider = audioSource.GetMixedAudioProvider())
using (var videoWriter = sharpAVICodec.GetVideoFileWriter(new Captura.Models.VideoWriterArgs()
{
FileName = _capturedVideoPath,
AudioProvider = audioProvider,
AudioQuality = 70,
FrameRate = fps,
ImageProvider = imageProvider,
VideoQuality = 70
}))
using (var recorder = new Recorder(videoWriter, imageProvider, fps, audioProvider))
{
//error:
//foreach(var rs in audioSource.AvailableRecordingSources)
// rs.Active = true;
foreach (var ls in audioSource.AvailableLoopbackSources)
ls.Active = true;
recorder.Start();
while (!recordTaskCancel.IsCancellationRequested)
Task.Yield();
recorder.Stop();
}
}
}, recordTaskCancel.Token);
recordTask.Start();
internal class ImageProvider : IImageProvider
{
public ImageProvider(int height, int width, double dpiKoeff, int left, int top)
{
Height = height;
Width = width;
DPIKoeff = dpiKoeff;
Left = left;
Top = top;
}
public int Height { get; }
public int Width { get; }
public int Left { get; }
public int Top { get; }
public double DPIKoeff { get; }
public IBitmapFrame Capture()
{
return new OneTimeFrame(GetScreenshot(Left, Top, Width, Height));
}
public void Dispose()
{
}
private Bitmap GetScreenshot(int left, int top, int screenWidth, int screenHeight)
{
var bitmap = new Bitmap(screenWidth, screenHeight);
using (var graphics = Graphics.FromImage(bitmap))
{
graphics.CopyFromScreen(left, top, 0, 0, new System.Drawing.Size(screenWidth, screenHeight));
var mousePos = WinProcess.GetMousePosition();
var mouseDpiAdditionalOffset = -(200.0 - (200.0 * DPIKoeff));
graphics.FillEllipse(
new SolidBrush(Color.Red),
(float)(mousePos.X - (left / DPIKoeff) + mouseDpiAdditionalOffset),
(float)(mousePos.Y - (top / DPIKoeff) + mouseDpiAdditionalOffset),
10,
10);
graphics.Flush();
}
return bitmap;
}
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetCursorPos(ref Win32Point pt);
[StructLayout(LayoutKind.Sequential)]
internal struct Win32Point
{
public Int32 X;
public Int32 Y;
};
public static Point GetMousePosition()
{
var w32Mouse = new Win32Point();
GetCursorPos(ref w32Mouse);
return new Point(w32Mouse.X, w32Mouse.Y);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment