[英]How to record video playing on a pictureBox?
我正在访问 Microsoft Azure Kinect 深度相机的视频片段,并使用 C# WinForm 应用程序在图片框上显示视频。 我正在寻找一种方法来录制这个视频。 有没有办法在应用程序运行时录制在我的整个图片框上播放的视频?
我正在使用 .NET 框架 4.7.2
我写了这个 class 来环绕 ffmpeg (遵循 ffmpeg 文档中的“如何记录屏幕”帮助)并使一些位更容易:
using System;
using System.Diagnostics;
using System.Drawing;
using System.Text;
namespace CJCam
{
public class FfmpegRecorder : Recorder
{
public string OutputPath { get; set; }
private Process _ffmpeg = null;
private readonly StringBuilder _ffLog = new StringBuilder();
//like STDERR: frame=113987 fps= 10 q=-1.0 Lsize= 204000kB time=03:09:58.50 bitrate= 146.6kbits/s
private string _streamStats = "";
~FfmpegRecorder()
{
Dispose();
}
public override void Dispose()
{
}
public FfmpegRecorder(string outputPath, Rectangle recordingRect)
{
ScreenCaptureRecorderRegistry.SetRecordRegion(recordingRect);
OutputPath = outputPath;
}
public override void StartRecording()
{
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = Properties.Settings.Default.CommandLineFfmpegPath,
Arguments = string.Format(
Properties.Settings.Default.CommandLineFfmpegArgs,
OutputPath
),
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true
};
_ffmpeg = System.Diagnostics.Process.Start(psi);
_ffmpeg.OutputDataReceived += Ffmpeg_OutputDataReceived;
_ffmpeg.ErrorDataReceived += Ffmpeg_ErrorDataReceived;
_ffmpeg.BeginOutputReadLine();
_ffmpeg.BeginErrorReadLine();
_ffmpeg.PriorityClass = ProcessPriorityClass.High;
}
void Ffmpeg_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null && IsInteresting(e.Data))
{
_ffLog.Append("STDOUT: ").AppendLine(e.Data);
}
}
void Ffmpeg_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null && IsInteresting(e.Data))
{
_ffLog.Append("STDERR: ").AppendLine(e.Data);
}
}
bool IsInteresting(string data)
{
if (data.StartsWith("frame="))
{
_streamStats = data;
return false;
}
return true;
}
public override void PauseRecording()
{
throw new NotImplementedException("Cannot pause FFmpeg at this time");
}
public override void StopRecording()
{
if (_ffmpeg == null)
return;
if (_ffmpeg.HasExited)
return;
_ffmpeg.StandardInput.WriteLine("q");
_ffmpeg.WaitForExit(5000);
}
public override string GetLogFile()
{
return _ffLog.AppendLine().Append("CURRENT FRAME:").AppendLine(_streamStats).ToString();
}
}
}
它从这个 class 得到一些帮助:
class ScreenCaptureRecorderRegistry
{
public static void SetRecordRegion(Rectangle region)
{
RegistryKey key = Registry.CurrentUser.OpenSubKey("Software\\screen-capture-recorder");
// If the return value is null, the key doesn't exist
if (key == null)
key = Registry.CurrentUser.CreateSubKey("Software\\screen-capture-recorder");
key = Registry.CurrentUser.OpenSubKey("Software\\screen-capture-recorder", true);
key.SetValue("start_x", region.X, RegistryValueKind.DWord);
key.SetValue("start_y", region.Y, RegistryValueKind.DWord);
key.SetValue("capture_width", region.Width, RegistryValueKind.DWord);
key.SetValue("capture_height", region.Height, RegistryValueKind.DWord);
}
}
然后,您只需将 ffmpeg 二进制文件放在某个位置,并将路径放入设置( CommandLineFfmpegPath
)和一些合适的参数(设置名称CommandLineFfmpegArgs
)以记录您想要记录的内容
我的参数是-rtbufsize 2048M -thread_queue_size 512 -f dshow -i video="screen-capture-recorder" -thread_queue_size 512 -f dshow -i audio="Line 1 (Virtual Audio Cable)" -x264opts keyint=50 -map 0:v -map 1:a -pix_fmt yuv420p -y "{0}"
- 如果您安装它,您将只有一条虚拟音频电缆,但您可以让 ffmpeg 列出您系统上的声音设备并放置其中一个相反,如果您不想要声音,甚至可以省略它。
设置编辑器截图:
然后你制作一个带有矩形记录的 FfmpegRecorder 实例——这将是你的图片框的坐标, 转换为屏幕坐标(注意 DPI/如果你的 Windows 没有以 100%“缩放”运行,你必须调整你的值")
如果你想让你的生活更轻松/获得我提到的“单行记录”,只要确保你的图片框一直在同一个地方(最大化表格),使用 regedit 设置一次 reg 设置,然后启动关闭进程。开始使用一些参数启动Process.Start
。 这个答案中的其他大部分内容是因为我想捕获FF的日志,或者与之交互,或者一直将记录区域调整到不同的地方
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.