(3)视频预览方法
public void VideoPreview()
{
try
{
int hr = 0;
hr = this.m_graphBuilder.AddFilter(theVideoDevice, "Video Capture");
DsError.ThrowExceptionForHR(hr);
// 通过theVideoDevice(IBaseFilter)视频接口对象的Preview Pin预览
hr = this.m_captureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, theVideoDevice, null, null);
DsError.ThrowExceptionForHR(hr);
//插入SampleGrabber
m_pinStill = DsFindPin.ByCategory(theVideoDevice, PinCategory.Still, 0);
if (m_pinStill == null)
{
m_pinStill = DsFindPin.ByCategory(theVideoDevice, PinCategory.Capture, 0);
}
// 获取theVideoDevice的IAMVideoControl对象,对于具有Still Pin的对象可以获到,采集设备不具备Still Pin,那么该对象将为Null
m_VidControl = theVideoDevice as IAMVideoControl;
// 设置采集视频参数
if (this.videoHeight + this.videoWidth + this.videoStride > 0)
{
SetConfigParms(m_pinStill, this.videoWidth, this.videoHeight, 24);
}
//开始拍照功能所需的接口对象
// 获得SampleGrabber对象接口
sampGrabber = new SampleGrabber() as ISampleGrabber;
// 配置sample grabber
baseGrabFlt = sampGrabber as IBaseFilter;
ConfigureSampleGrabber(sampGrabber);
// 将sample grabber添加到图形过滤器中
hr = m_graphBuilder.AddFilter(baseGrabFlt, "Ds.NET Grabber");
DsError.ThrowExceptionForHR(hr);
//通过渲染将采集设备的相关输出Pin与sample grabber对象的输入Pin连接起来
//如果采集设备提供Still Pin,则通过Still Pin连接,否则直接使用Capture Pin连接
if (m_VidControl!=null)
{
hr = this.m_captureGraphBuilder.RenderStream(PinCategory.Still, MediaType.Video, theVideoDevice, null, baseGrabFlt);
DsError.ThrowExceptionForHR(hr);
}
else
{
hr = this.m_captureGraphBuilder.RenderStream(PinCategory.Capture, MediaType.Video, theVideoDevice, null, baseGrabFlt);
DsError.ThrowExceptionForHR(hr);
}
//设置抓取图片相关参数
SaveSizeInfo(sampGrabber);
//拍照功能所需的接口对象添加结束
// 开始将视频窗口绑定到主窗体上
hr = this.m_videoWindow.put_Owner(this.hwnVideoWindowOwner);
DsError.ThrowExceptionForHR(hr);
hr = this.m_videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren);
DsError.ThrowExceptionForHR(hr);
if (this.m_videoWindow != null)
{
this.m_videoWindow.SetWindowPosition(0, 0, this.videoWidth, this.videoHeight);
}
hr = this.m_videoWindow.put_Visible(OABool.True);
DsError.ThrowExceptionForHR(hr);
// 开始预览采集设备采集到的视频
hr = this.m_mediaControl.Run();
DsError.ThrowExceptionForHR(hr);
m_IsPreview = true;
}
catch
{
m_IsPreview = false;
throw new Exception("VideoPreview函数出现异常,视频预览失败!");
}
}
(4)抓图方法
public Bitmap SnapeBitmap()
{
if (this.m_IsPreview)
{
if (this.m_ipBuffer != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(this.m_ipBuffer);
this.m_ipBuffer = IntPtr.Zero;
}
this.m_PictureReady.Reset();
//分配空间存储抓取的图片
this.m_ipBuffer = Marshal.AllocCoTaskMem(Math.Abs(this.videoStride) * this.videoHeight);
try
{
this.m_WantOne = true;
if (this.m_VidControl != null)
{
//启动图片抓拍
DsError.ThrowExceptionForHR(this.m_VidControl.SetMode(this.m_pinStill, VideoControlFlags.Trigger));
}
if (!this.m_PictureReady.WaitOne(0xbb8, false))
{
throw new Exception("获取图片超时");
}
}
catch
{
Marshal.FreeCoTaskMem(this.m_ipBuffer);
this.m_ipBuffer = IntPtr.Zero;
//throw;
}
if (this.m_ipBuffer != IntPtr.Zero)
{
Bitmap bitmap = new Bitmap(this.videoWidth, this.videoHeight, this.videoStride, PixelFormat.Format24bppRgb, this.m_ipBuffer);//图片转存到Bitmap对象
bitmap.RotateFlip(RotateFlipType.Rotate180FlipX);//图片翻转
return bitmap;
}
}
return null;
}
(5)视频录像方法
public bool RecordVideo(string mSaveFileName)
{
if (this.m_IsRecord)
{
throw new Exception("正在录制视频,请停止后重新录制!");
}
try
{
IBaseFilter ppbf;
IFileSinkFilter ppSink;
if (!this.m_IsPreview)
{
this.VideoPreview();
}
this.m_mediaControl.Stop();
this.m_IsRecord = true;
if (this.m_VidControl == null)
{
//去除Filter baseGrabFlt
DsError.ThrowExceptionForHR(this.m_graphBuilder.RemoveFilter(this.baseGrabFlt));
}
//添加音频设备的Filter
DsError.ThrowExceptionForHR(this.m_graphBuilder.AddFilter(this.theAudioDevice, "Audio Input Device"));
//添加视频压缩Filter
DsError.ThrowExceptionForHR(this.m_graphBuilder.AddFilter(this.theVideoCompressor, "Video compressor filter"));
//添加音频压缩Filter
DsError.ThrowExceptionForHR(this.m_graphBuilder.AddFilter(this.theAudioCompressor, "Audio compressor filter"));
//设置视频录像输出文件参数
DsError.ThrowExceptionForHR(this.m_captureGraphBuilder.SetOutputFileName(MediaSubType.Avi, mSaveFileName, out ppbf, out ppSink));
//Render视频设备和压缩Filter
DsError.ThrowExceptionForHR(this.m_captureGraphBuilder.RenderStream(PinCategory.Capture, MediaType.Video, this.theVideoDevice, this.theVideoCompressor, ppbf));
//Render音频设备和压缩Filter
DsError.ThrowExceptionForHR(this.m_captureGraphBuilder.RenderStream(PinCategory.Capture, MediaType.Audio, this.theAudioDevice, this.theAudioCompressor, ppbf));
this.m_mediaControl.Run();
}
catch (Exception exception)
{
this.StopRecordVideo();
this.m_IsRecord = false;
throw new Exception(exception.Message + "\nRecordVideo函数出现异常,视频录制失败!");
}
return true;
}
|