1 using DirectShowLib; 2 using System; 3 using System.Collections; 4 using System.Windows.Forms; 5 6 namespace CaptureTest 7 { 8 public partial class Form1 : Form 9 { 10 private IBaseFilter theVideoDevice; 11 private IBaseFilter baseGrabFlt ; 12 private int videoHeight; 13 private int videoWidth; 14 private int videoStride; 15 private int WM_GRAPHNOTIFY; 16 private ICaptureGraphBuilder2 m_captureGraphBuilder; 17 private IAMVideoControl m_VidControl; 18 private IVideoWindow m_videoWindow; 19 private IMediaControl m_mediaControl; 20 private IGraphBuilder m_graphBuilder; 21 private IMediaEventEx m_mediaEventEx; 22 private IntPtr hwnVideoWindowOwner; 23 private IntPtr hwnPropertyPageOwner; 24 private bool m_IsPreview; 25 26 public Form1() 27 { 28 InitializeComponent(); 29 } 30 31 //1、获取视频采集设备IBaseFilter接口对象的方法 32 33 //获取所有视频设备名称 34 public ArrayList GetVideoInputDevice() 35 { return GetDeviceCollection(FilterCategory.VideoInputDevice); } 36 private ArrayList GetDeviceCollection(Guid DeviceType) 37 { 38 ArrayList returnString = new ArrayList(); 39 foreach (DsDevice ds in DsDevice.GetDevicesOfCat(DeviceType)) 40 { 41 returnString.Add(ds.Name); 42 } 43 return returnString; 44 } 45 46 //通过获取到的视频设备名称设置采集设备的IBaseFilter对象 47 public bool SetVideoInputDevice(string VideoInputDeviceName) 48 { //创建视频输入设备接口 49 theVideoDevice = CreateFilter(FilterCategory.VideoInputDevice, VideoInputDeviceName); 50 return true; 51 } 52 //通过过滤器类型和过滤器名称获取IBaseFilter接口 53 private IBaseFilter CreateFilter(Guid category, string friendlyname) 54 { 55 object source = null; 56 Guid iid = typeof(IBaseFilter).GUID; 57 foreach (DsDevice device in DsDevice.GetDevicesOfCat(category)) 58 { 59 if (device.Name.CompareTo(friendlyname) == 0) 60 { 61 device.Mon.BindToObject(null, null, ref iid, out source); 62 break; 63 } 64 } 65 66 return (IBaseFilter)source; 67 } 68 69 //2、初始化基本的接口对象 70 71 private void InitInterfaces() 72 { 73 int hr = 0; 74 75 // 获取IGraphBuilder接口对象 76 this.m_graphBuilder = (IGraphBuilder)new FilterGraph(); 77 //获取ICaptureGraphBuilder2接口对象 78 this.m_captureGraphBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); 79 //获取m_graphBuilder 接口对象的IMediaControl对象 80 this.m_mediaControl = (IMediaControl)this.m_graphBuilder; 81 //获取m_graphBuilder 接口对象的IVideoWindow对象 82 this.m_videoWindow = (IVideoWindow)this.m_graphBuilder; 83 //获取m_graphBuilder 接口对象的IMediaEventEx对象 84 this.m_mediaEventEx = (IMediaEventEx)this.m_graphBuilder; 85 //设置ICaptureGraphBuilder2的IGraphBuilder接口对象为当前对象 86 hr = this.m_captureGraphBuilder.SetFiltergraph(this.m_graphBuilder); 87 DsError.ThrowExceptionForHR(hr); 88 //注册事件到应用程序的窗体上 89 hr = this.m_mediaEventEx.SetNotifyWindow(this.hwnPropertyPageOwner, WM_GRAPHNOTIFY, IntPtr.Zero); 90 DsError.ThrowExceptionForHR(hr); 91 } 92 93 //3、开始视频预览 94 public void VideoPreview() 95 { 96 try 97 { 98 99 int hr = 0; 100 hr = this.m_graphBuilder.AddFilter(theVideoDevice, "Video Capture"); 101 DsError.ThrowExceptionForHR(hr); 102 103 // 通过theVideoDevice(IBaseFilter)视频接口对象的Preview Pin预览 104 hr = this.m_captureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, theVideoDevice, null, null); 105 DsError.ThrowExceptionForHR(hr); 106 var 107 108 //插入SampleGrabber 109 m_pinStill = DsFindPin.ByCategory(theVideoDevice, PinCategory.Still, 0); 110 if (m_pinStill == null) 111 { 112 m_pinStill = DsFindPin.ByCategory(theVideoDevice, PinCategory.Capture, 0); 113 } 114 115 116 // 获取theVideoDevice的IAMVideoControl对象,对于具有Still Pin的对象可以获到,采集设备不具备Still Pin,那么该对象将为Null 117 m_VidControl = theVideoDevice as IAMVideoControl; 118 119 // 设置采集视频参数 120 if (this.videoHeight + this.videoWidth + this.videoStride > 0) 121 { 122 SetConfigParms(m_pinStill, this.videoWidth, this.videoHeight, 24); 123 } 124 125 var 126 127 //开始拍照功能所需的接口对象 128 // 获得SampleGrabber对象接口 129 sampGrabber = new SampleGrabber() as ISampleGrabber; 130 131 // 配置sample grabber 132 baseGrabFlt = sampGrabber as IBaseFilter; 133 ConfigureSampleGrabber(sampGrabber); 134 135 // 将sample grabber添加到图形过滤器中 136 hr = m_graphBuilder.AddFilter(baseGrabFlt, "Ds.NET Grabber"); 137 DsError.ThrowExceptionForHR(hr); 138 139 //通过渲染将采集设备的相关输出Pin与sample grabber对象的输入Pin连接起来 140 //如果采集设备提供Still Pin,则通过Still Pin连接,否则直接使用Capture Pin连接 141 if (m_VidControl != null) 142 { 143 hr = this.m_captureGraphBuilder.RenderStream(PinCategory.Still, MediaType.Video, theVideoDevice, null, baseGrabFlt); 144 DsError.ThrowExceptionForHR(hr); 145 146 } 147 else 148 { 149 hr = this.m_captureGraphBuilder.RenderStream(PinCategory.Capture, MediaType.Video, theVideoDevice, null, baseGrabFlt); 150 DsError.ThrowExceptionForHR(hr); 151 } 152 //设置抓取图片相关参数 153 SaveSizeInfo(sampGrabber); 154 //拍照功能所需的接口对象添加结束 155 156 157 // 开始将视频窗口绑定到主窗体上 158 hr = this.m_videoWindow.put_Owner(this.hwnVideoWindowOwner); 159 DsError.ThrowExceptionForHR(hr); 160 161 hr = this.m_videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren); 162 DsError.ThrowExceptionForHR(hr); 163 164 if (this.m_videoWindow != null) 165 { 166 this.m_videoWindow.SetWindowPosition(0, 0, this.videoWidth, this.videoHeight); 167 } 168 169 170 hr = this.m_videoWindow.put_Visible(OABool.True); 171 DsError.ThrowExceptionForHR(hr); 172 173 // 开始预览采集设备采集到的视频 174 hr = this.m_mediaControl.Run(); 175 176 DsError.ThrowExceptionForHR(hr); 177 m_IsPreview = true; 178 } 179 catch 180 { 181 m_IsPreview = false; 182 throw new Exception("VideoPreview函数出现异常,视频预览失败!"); 183 184 } 185 } 186 187 private void SaveSizeInfo(ISampleGrabber sampGrabber) 188 { 189 throw new NotImplementedException(); 190 } 191 192 private void SetConfigParms(object m_pinStill, int videoWidth, int videoHeight, int v) 193 { 194 throw new NotImplementedException(); 195 } 196 197 private void ConfigureSampleGrabber(ISampleGrabber sampGrabber) 198 { 199 throw new NotImplementedException(); 200 } 201 } 202 }