This commit is contained in:
xyy
2026-01-06 13:34:31 +08:00
parent c11aac8a67
commit ffa627e2bf
23 changed files with 135 additions and 19845 deletions

View File

@@ -60,10 +60,6 @@ namespace BasicDemo
// 视频录制相关(新增)
private VideoFileWriter[] videoWriters = new VideoFileWriter[MAX_CAMERAS];
private string[] videoFilePaths = new string[MAX_CAMERAS];
private bool[] isRecording = new bool[MAX_CAMERAS];
// 构造函数
@@ -76,14 +72,14 @@ namespace BasicDemo
OnReturnRequested += returnCallback;
}
// 设置视频保存路径
if (!string.IsNullOrEmpty(videoSavePath))
{
_videoSavePath = videoSavePath;
}
//// 设置视频保存路径
//if (!string.IsNullOrEmpty(videoSavePath))
//{
// _videoSavePath = videoSavePath;
//}
// 确保保存目录存在
Directory.CreateDirectory(_videoSavePath);
//// 确保保存目录存在
//Directory.CreateDirectory(_videoSavePath);
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
@@ -482,8 +478,7 @@ namespace BasicDemo
return;
}
// 2. 初始化视频录制(新增)
InitializeVideoRecording(cameraIndex);
// 2. 设置采集标志
@@ -510,8 +505,6 @@ namespace BasicDemo
return;
}
// 6. 开始录制视频(新增)
StartVideoRecording(cameraIndex);
UpdateCameraStatus(cameraIndex, "正在采集...", Color.Green);
}
@@ -524,81 +517,6 @@ namespace BasicDemo
/// <summary>
/// 初始化视频录制(新增)
/// </summary>
private void InitializeVideoRecording(int cameraIndex)
{
try
{
// 生成唯一的视频文件名
string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
string fileName = $"Camera{cameraIndex + 1}_{timestamp}.mp4";
videoFilePaths[cameraIndex] = Path.Combine(_videoSavePath, fileName);
// 创建 VideoFileWriter 实例
videoWriters[cameraIndex] = new VideoFileWriter();
// 从相机获取帧率(如果支持)
try
{
MyCamera.MVCC_FLOATVALUE frameRate = new MyCamera.MVCC_FLOATVALUE();
int ret = cameras[cameraIndex].MV_CC_GetFloatValue_NET("AcquisitionFrameRate", ref frameRate);
if (ret == MyCamera.MV_OK && frameRate.fCurValue > 0)
{
_frameRate = frameRate.fCurValue;
}
}
catch
{
// 如果获取失败,使用默认帧率
_frameRate = 30.0;
}
Console.WriteLine($"相机 {cameraIndex + 1} 准备录制到: {videoFilePaths[cameraIndex]}, 帧率: {_frameRate}FPS");
}
catch (Exception ex)
{
Console.WriteLine($"初始化视频录制失败: {ex.Message}");
videoWriters[cameraIndex] = null;
}
}
/// <summary>
/// 开始录制视频(新增)- 简化版本
/// </summary>
private void StartVideoRecording(int cameraIndex)
{
if (videoWriters[cameraIndex] == null || displayBitmaps[cameraIndex] == null)
return;
try
{
int width = displayBitmaps[cameraIndex].Width;
int height = displayBitmaps[cameraIndex].Height;
// 将帧率转换为整数(四舍五入)
int fps = (int)Math.Round(_frameRate);
// 确保帧率至少为1
if (fps < 1) fps = 30;
// 创建 Rational 帧率
Accord.Math.Rational frameRateRational = new Accord.Math.Rational(fps, 1);
// 打开视频文件
videoWriters[cameraIndex].Open(videoFilePaths[cameraIndex], width, height, frameRateRational, VideoCodec.H264);
isRecording[cameraIndex] = true;
UpdateCameraStatus(cameraIndex, $"录制中: {Path.GetFileName(videoFilePaths[cameraIndex])}", Color.Green);
}
catch (Exception ex)
{
Console.WriteLine($"开始录制视频失败: {ex.Message}");
isRecording[cameraIndex] = false;
}
}
/// <summary>
/// 检查相机是否有效
@@ -636,8 +554,6 @@ namespace BasicDemo
// 3. 停止相机采集
cameras[cameraIndex].MV_CC_StopGrabbing_NET();
// 4. 停止视频录制(新增)
StopVideoRecording(cameraIndex);
// 4. 清理资源
CleanupCameraResources(cameraIndex);
@@ -651,37 +567,7 @@ namespace BasicDemo
}
/// <summary>
/// 停止视频录制(新增)
/// </summary>
private void StopVideoRecording(int cameraIndex)
{
try
{
if (videoWriters[cameraIndex] != null && isRecording[cameraIndex])
{
videoWriters[cameraIndex].Close();
isRecording[cameraIndex] = false;
Console.WriteLine($"相机 {cameraIndex + 1} 视频已保存到: {videoFilePaths[cameraIndex]}");
// 可选:显示保存路径
UpdateCameraStatus(cameraIndex, $"视频已保存", Color.Blue);
}
}
catch (Exception ex)
{
Console.WriteLine($"停止视频录制异常: {ex.Message}");
}
finally
{
if (videoWriters[cameraIndex] != null)
{
videoWriters[cameraIndex].Dispose();
videoWriters[cameraIndex] = null;
}
}
}
private bool PrepareForGrabbing(int cameraIndex)
{
@@ -920,36 +806,7 @@ namespace BasicDemo
displayBitmaps[cameraIndex].UnlockBits(bitmapData);
}
// 录制视频(新增)
if (isRecording[cameraIndex] && videoWriters[cameraIndex] != null && videoWriters[cameraIndex].IsOpen)
{
// 简单的帧率控制
DateTime now = DateTime.Now;
if ((now - lastWriteTime).TotalMilliseconds >= (1000.0 / _frameRate) || framesWritten == 0)
{
try
{
// 锁定以避免线程冲突
Bitmap frameToWrite;
lock (locks[cameraIndex])
{
// 克隆Bitmap用于写入避免资源冲突
frameToWrite = (Bitmap)displayBitmaps[cameraIndex].Clone();
}
videoWriters[cameraIndex].WriteVideoFrame(frameToWrite);
frameToWrite.Dispose();
framesWritten++;
lastWriteTime = now;
}
catch (Exception ex)
{
Console.WriteLine($"写入视频帧失败: {ex.Message}");
}
}
}
// 使用SDK显示
displayInfo.hWnd = pictureBoxes[cameraIndex].Handle;
displayInfo.pData = frameOut.pBufAddr;
@@ -1004,27 +861,7 @@ namespace BasicDemo
displayBufSizes[cameraIndex] = 0;
// 清理视频录制资源(新增)
if (videoWriters[cameraIndex] != null)
{
try
{
if (isRecording[cameraIndex])
{
videoWriters[cameraIndex].Close();
isRecording[cameraIndex] = false;
}
videoWriters[cameraIndex].Dispose();
}
catch (Exception ex)
{
Console.WriteLine($"清理视频录制资源异常: {ex.Message}");
}
finally
{
videoWriters[cameraIndex] = null;
}
}
}
/// <summary>