共计 2633 个字符,预计需要花费 7 分钟才能阅读完成。
WPF RTSP 预览和录制 主要使用 OpenCvSharp4 库进行的流的传输和录制。
OpenCvSharp4 库:https://github.com/shimat/opencvsharp
NuGet 安装以下库:
创建的项目是 WPF 示例
首先创建 RtspHelpers 类,初始化 VideoCapture(),这个是 OpenCV 库中的一个类,用于捕捉视频。我们这边使用了 VideoCapture(rtsp) 当然也可以使用 VideoCapture.Open(rtsp)方法。
使用_Capture.Read(image)读取下一帧。使用 Action 回调 Mat 数据,这里是 Mat 数据(Mat 类表示一个 n 维的稠密数值型的单通道或多通道数组。它可以用于存储实数或复数值的向量和矩阵、灰度或彩色图像等)使用 WpfExtensions 进行转化。
OpenCvSharp.WpfExtensions.BitmapSourceConverter.ToBitmapSource(Mat)
接着使用VideoWriter
将图像序列写入视频文件中完成录制。
_videoWriter = new VideoWriter(path, FourCC.H264, _Capture.Fps, new OpenCvSharp.Size(_Capture.FrameWidth, _Capture.FrameHeight));
完整代码:
public class RtspHelpers
{
private readonly VideoCapture _Capture;
#region 预览
private bool _previewRunState = false;
#endregion
#region 录制
private VideoWriter? _videoWriter = null;
private bool _isRunRecord = false;
#endregion
/// <summary>
/// 初始化 VideoCapture
/// </summary>
/// <param name="rtsp">rtsp 地址 </param>
public RtspHelpers(string rtsp)
{_Capture = new VideoCapture(rtsp);
}
/// <summary>
/// 预览视频流
/// </summary>
/// <param name="action"> 预览回调 </param>
public async Task Preview(Action<Mat>? action = null)
{
_previewRunState = true;
await Task.Run(() =>
{using (Mat image = new Mat())
{while (_previewRunState)
{if (!_Capture.Read(image) || image.Empty())
{
_previewRunState = false;
break;
}
if (action != null)
{action.Invoke(image);
}
if (_videoWriter != null && _isRunRecord)
{_videoWriter.Write(image);
}
Cv2.WaitKey(30);
}
}
});
}
/// <summary>
/// 停止预览
/// </summary>
public bool StopPreview()
{if (!_previewRunState)
{return false;}
_previewRunState = false;
return true;
}
/// <summary>
/// 开始录制
/// </summary>
/// <param name="path"></param>
public bool StartRecord(string path)
{if (_Capture == null || _Capture.IsDisposed)
{return false;}
_videoWriter = new VideoWriter(path, FourCC.H264, _Capture.Fps, new OpenCvSharp.Size(_Capture.FrameWidth, _Capture.FrameHeight));
_isRunRecord = true;
return true;
}
/// <summary>
/// 停止录制
/// </summary>
public void StopRecord()
{
_isRunRecord = false;
if (_videoWriter != null && !_videoWriter.IsDisposed)
{_videoWriter.Dispose();
_videoWriter = null;
}
}
}
public partial class MainWindow : System.Windows.Window
{
private RtspHelpers rtspHelpers = null;
public MainWindow()
{InitializeComponent();
rtspHelpers = new RtspHelpers(RtspPath.Text);
Initialize();}
public async void Initialize()
{
await rtspHelpers.Preview(a =>
{this.Dispatcher.Invoke(new Action(() =>
{FrameImage.Source = OpenCvSharp.WpfExtensions.BitmapSourceConverter.ToBitmapSource(a);
}));
});
}
private void StartRecord_Click(object sender, RoutedEventArgs e)
{MessageBox.Show("开始录制视频,路径保存在程序目录下");
rtspHelpers.StartRecord(string.Format("{0}.mp4", DateTime.Now.ToString("yyyyMMddHHmm")));
}
private void StopRecord_Click(object sender, RoutedEventArgs e)
{MessageBox.Show("已停止");
rtspHelpers.StopRecord();}
}
正文完