(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;
}
|