湘丰模具材料 發表於 2021-1-13 01:20:00

Delphi USBCamera DirectShow 预览录像截图

<p>参照:https://www.haolizi.net/example/view_37332.html</p>
<h2>实例介绍</h2>
<p>【实例简介】用DirectShow 的方式,视频输入设备枚举、视频支持格式枚举、视频预览、视频录像、视频截图。Delphi 源代码</p>
<p>【实例截图】</p>
<p><img src="https://img2020.cnblogs.com/blog/1107379/202101/1107379-20210113011835981-809799159.png" alt="" loading="lazy"></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;<img src="https://img2020.cnblogs.com/blog/1107379/202101/1107379-20210113011845180-101801103.png" alt="" loading="lazy"></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;【核心代码】</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">unit</span><span style="color: rgba(0, 0, 0, 1)"> untUSBCamera;

</span><span style="color: rgba(0, 0, 255, 1)">interface</span>

<span style="color: rgba(0, 0, 255, 1)">uses</span><span style="color: rgba(0, 0, 0, 1)">
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, DirectShow9, ActiveX, Dialogs, StdCtrls, ExtCtrls;

</span><span style="color: rgba(0, 0, 255, 1)">type</span><span style="color: rgba(0, 0, 0, 1)">
PVideoInputInfo</span>=<span style="color: rgba(0, 0, 0, 1)"> ^TVideoInputInfo;
PVideoFormatInfo </span>=<span style="color: rgba(0, 0, 0, 1)"> ^TVideoFormatInfo;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 视频输入设备 </span><span style="color: rgba(0, 128, 0, 1)">}</span><span style="color: rgba(0, 0, 0, 1)">
TVideoInputInfo </span>= <span style="color: rgba(0, 0, 255, 1)">record</span><span style="color: rgba(0, 0, 0, 1)">
    id: TGUID;
    strName: ShortString;
    index: Integer;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 视频支持格式 </span><span style="color: rgba(0, 128, 0, 1)">}</span><span style="color: rgba(0, 0, 0, 1)">
TVideoFormatInfo </span>= <span style="color: rgba(0, 0, 255, 1)">record</span><span style="color: rgba(0, 0, 0, 1)">
    id: TGUID;
    iWidth, iHeight: Integer;
    iMod: TGUID;
    Frame: Int64;
    format: ShortString;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">type</span><span style="color: rgba(0, 0, 0, 1)">
IAMStreamConfig </span>= <span style="color: rgba(0, 0, 255, 1)">interface</span><span style="color: rgba(0, 0, 0, 1)">(IUnknown)
    [</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">{C6E13340-30AC-11d0-A18C-00A0C9118956}</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">]
    </span><span style="color: rgba(0, 0, 255, 1)">function</span> SetFormat(<span style="color: rgba(0, 0, 255, 1)">const</span> pmt: TAMMediaType): HResult; <span style="color: rgba(0, 0, 255, 1)">stdcall</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">function</span> GetFormat(<span style="color: rgba(0, 0, 255, 1)">out</span> ppmt: PAMMediaType): HResult; <span style="color: rgba(0, 0, 255, 1)">stdcall</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">function</span> GetNumberOfCapabilities(<span style="color: rgba(0, 0, 255, 1)">out</span> piCount, piSize: Integer): HResult; <span style="color: rgba(0, 0, 255, 1)">stdcall</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> Delphi 声明有误,修改声明 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
    <span style="color: rgba(0, 0, 255, 1)">function</span> GetStreamCaps(iIndex: Integer; <span style="color: rgba(0, 0, 255, 1)">var</span> ppmt: PAMMediaType; pSCC: PVideoStreamConfigCaps): HResult; <span style="color: rgba(0, 0, 255, 1)">stdcall</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

ISampleGrabber </span>= <span style="color: rgba(0, 0, 255, 1)">interface</span><span style="color: rgba(0, 0, 0, 1)">(IUnknown)
    [</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">{6B652FFF-11FE-4FCE-92AD-0266B5D7C78F}</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">]
    </span><span style="color: rgba(0, 0, 255, 1)">function</span> SetOneShot(OneShot: BOOL): HResult; <span style="color: rgba(0, 0, 255, 1)">stdcall</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> Delphi 声明有误,修改声明 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
    <span style="color: rgba(0, 0, 255, 1)">function</span> SetMediaType(pType: PAMMediaType): HResult; <span style="color: rgba(0, 0, 255, 1)">stdcall</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">function</span> GetConnectedMediaType(<span style="color: rgba(0, 0, 255, 1)">out</span> pType: TAMMediaType): HResult; <span style="color: rgba(0, 0, 255, 1)">stdcall</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">function</span> SetBufferSamples(BufferThem: BOOL): HResult; <span style="color: rgba(0, 0, 255, 1)">stdcall</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">function</span> GetCurrentBuffer(<span style="color: rgba(0, 0, 255, 1)">var</span> pBufferSize: longint; pBuffer: Pointer): HResult; <span style="color: rgba(0, 0, 255, 1)">stdcall</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">function</span> GetCurrentSample(<span style="color: rgba(0, 0, 255, 1)">out</span> ppSample: IMediaSample): HResult; <span style="color: rgba(0, 0, 255, 1)">stdcall</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">function</span> SetCallback(pCallback: ISampleGrabberCB; WhichMethodToCallback: longint): HResult; <span style="color: rgba(0, 0, 255, 1)">stdcall</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 枚举所有视频输入设备 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">procedure</span><span style="color: rgba(0, 0, 0, 1)"> EnumAllUSBCamera(strsList: TStrings);

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 枚举视频支持格式 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">function</span> EnumVideoFormat(<span style="color: rgba(0, 0, 255, 1)">const</span> strFriendlyName: String; <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> intIndex: Integer; strsList: TStrings): Boolean;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 视频预览 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">function</span> USBVideoPreview(<span style="color: rgba(0, 0, 255, 1)">var</span> FIGraphBuilder: IGraphBuilder; <span style="color: rgba(0, 0, 255, 1)">var</span> FICaptureGraphBuilder2: ICaptureGraphBuilder2; <span style="color: rgba(0, 0, 255, 1)">var</span> FSysDevEnum: IBaseFilter; <span style="color: rgba(0, 0, 255, 1)">var</span> FIVideoWindow: IVideoWindow; <span style="color: rgba(0, 0, 255, 1)">var</span> FIMediaControl: IMediaControl; <span style="color: rgba(0, 0, 255, 1)">var</span> FISampleGrabber: ISampleGrabber; pv: PVideoInputInfo; pf: PVideoFormatInfo; pnl: TPanel; <span style="color: rgba(0, 0, 255, 1)">const</span> bSnapBmp: Boolean =<span style="color: rgba(0, 0, 0, 1)"> False): Boolean;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 视频录制 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">function</span> USBVideoRecord(<span style="color: rgba(0, 0, 255, 1)">var</span> FIGraphBuilder: IGraphBuilder; <span style="color: rgba(0, 0, 255, 1)">var</span> FICaptureGraphBuilder2: ICaptureGraphBuilder2; <span style="color: rgba(0, 0, 255, 1)">var</span> FSysDevEnum: IBaseFilter; <span style="color: rgba(0, 0, 255, 1)">var</span> FIVideoWindow: IVideoWindow; <span style="color: rgba(0, 0, 255, 1)">var</span> FIMediaControl: IMediaControl; <span style="color: rgba(0, 0, 255, 1)">var</span> FISampleGrabber: ISampleGrabber; pv: PVideoInputInfo; pf: PVideoFormatInfo; pnl: TPanel; <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> strSaveFileName: String): Boolean;

</span><span style="color: rgba(0, 0, 255, 1)">implementation</span>

<span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)">
IID_IPropertyBag: TGUID </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">{55272A00-42CB-11CE-8135-00AA004BB851}</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;

c_arrVideoFormatGUID: </span><span style="color: rgba(0, 0, 255, 1)">array</span> [<span style="color: rgba(128, 0, 128, 1)">0</span> .. <span style="color: rgba(128, 0, 128, 1)">35</span>] <span style="color: rgba(0, 0, 255, 1)">of</span> PGUID = (                                                                                 <span style="color: rgba(0, 128, 0, 1)">//
</span>    @MEDIASUBTYPE_CLPL, @MEDIASUBTYPE_YUYV, @MEDIASUBTYPE_IYUV, @MEDIASUBTYPE_YVU9, @MEDIASUBTYPE_Y411, @MEDIASUBTYPE_Y41P,          <span style="color: rgba(0, 128, 0, 1)">//
</span>    @MEDIASUBTYPE_YUY2, @MEDIASUBTYPE_YVYU, @MEDIASUBTYPE_UYVY, @MEDIASUBTYPE_Y211, @MEDIASUBTYPE_YV12, @MEDIASUBTYPE_CLJR,          <span style="color: rgba(0, 128, 0, 1)">//
</span>    @MEDIASUBTYPE_IF09, @MEDIASUBTYPE_CPLA, @MEDIASUBTYPE_MJPG, @MEDIASUBTYPE_TVMJ, @MEDIASUBTYPE_WAKE, @MEDIASUBTYPE_CFCC,          <span style="color: rgba(0, 128, 0, 1)">//
</span>    @MEDIASUBTYPE_IJPG, @MEDIASUBTYPE_Plum, @MEDIASUBTYPE_DVCS, @MEDIASUBTYPE_DVSD, @MEDIASUBTYPE_MDVF, @MEDIASUBTYPE_RGB1,          <span style="color: rgba(0, 128, 0, 1)">//
</span>    @MEDIASUBTYPE_RGB4, @MEDIASUBTYPE_RGB8, @MEDIASUBTYPE_RGB565, @MEDIASUBTYPE_RGB555, @MEDIASUBTYPE_RGB24, @MEDIASUBTYPE_RGB32,    <span style="color: rgba(0, 128, 0, 1)">//
</span>    @MEDIASUBTYPE_ARGB1555, @MEDIASUBTYPE_ARGB4444, @MEDIASUBTYPE_ARGB32, @MEDIASUBTYPE_AYUV, @MEDIASUBTYPE_AI44, @MEDIASUBTYPE_IA44 <span style="color: rgba(0, 128, 0, 1)">//
</span><span style="color: rgba(0, 0, 0, 1)">    );

c_arrVideoFormatName: </span><span style="color: rgba(0, 0, 255, 1)">array</span> [<span style="color: rgba(128, 0, 128, 1)">0</span> .. <span style="color: rgba(128, 0, 128, 1)">35</span>] <span style="color: rgba(0, 0, 255, 1)">of</span> AnsiString = (    <span style="color: rgba(0, 128, 0, 1)">//
</span>    <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">CLPL</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">YUYV</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">IYUV</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">YVU9</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Y411</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Y41P</span><span style="color: rgba(128, 0, 0, 1)">'</span>,          <span style="color: rgba(0, 128, 0, 1)">//
</span>    <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">YUY2</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">YVYU</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">UYVY</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Y211</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">YV12</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">CLJR</span><span style="color: rgba(128, 0, 0, 1)">'</span>,          <span style="color: rgba(0, 128, 0, 1)">//
</span>    <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">IF09</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">CPLA</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">MJPG</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">TVMJ</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">WAKE</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">CFCC</span><span style="color: rgba(128, 0, 0, 1)">'</span>,          <span style="color: rgba(0, 128, 0, 1)">//
</span>    <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">IJPG</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Plum</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">DVCS</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">DVSD</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">MDVF</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">RGB1</span><span style="color: rgba(128, 0, 0, 1)">'</span>,          <span style="color: rgba(0, 128, 0, 1)">//
</span>    <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">RGB4</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">RGB8</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">RGB565</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">RGB555</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">RGB24</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">RGB32</span><span style="color: rgba(128, 0, 0, 1)">'</span>,    <span style="color: rgba(0, 128, 0, 1)">//
</span>    <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">ARGB1555</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">ARGB4444</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">ARGB32</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">AYUV</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">AI44</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">IA44</span><span style="color: rgba(128, 0, 0, 1)">'</span> <span style="color: rgba(0, 128, 0, 1)">//
</span><span style="color: rgba(0, 0, 0, 1)">    );

</span><span style="color: rgba(0, 0, 255, 1)">function</span> GetMaxIndex(<span style="color: rgba(0, 0, 255, 1)">const</span> strsList: TStrings; <span style="color: rgba(0, 0, 255, 1)">const</span> strUSBCameraName: <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">): Integer;
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
III, Count: Integer;
</span><span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
Result:</span>= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
Count   :</span>=<span style="color: rgba(0, 0, 0, 1)"> strsList.Count;
</span><span style="color: rgba(0, 0, 255, 1)">for</span> III := <span style="color: rgba(128, 0, 128, 1)">0</span> <span style="color: rgba(0, 0, 255, 1)">to</span> Count - <span style="color: rgba(128, 0, 128, 1)">1</span> <span style="color: rgba(0, 0, 255, 1)">do</span>
<span style="color: rgba(0, 0, 255, 1)">begin</span>
    <span style="color: rgba(0, 0, 255, 1)">if</span> CompareText(String(PVideoInputInfo(strsList.Objects)^.strName), strUSBCameraName) = <span style="color: rgba(128, 0, 128, 1)">0</span> <span style="color: rgba(0, 0, 255, 1)">then</span>
    <span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
      Result :</span>= Result   <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> CreateFilter(gid: TGUID; FriendlyName: AnsiString; instanceIndex: Integer): IBaseFilter;
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
pSysDevEnum: ICreateDevEnum;
pEnumCat   : IEnumMoniker;
pMoniker   : IMoniker;
cFetched   : ULONG;
pPropBag   : IPropertyBag;
bc         : IBindCtx;
mo         : IMoniker;
er         : IErrorLog;
ov         : OleVariant;
iIndex   : Integer;
</span><span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
Result :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;

pSysDevEnum :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;
pEnumCat    :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;
pMoniker    :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">if</span> CocreateInstance(CLSID_SystemDeviceEnum, <span style="color: rgba(0, 0, 255, 1)">nil</span>, CLSCTX_INPROC, IID_ICreateDevEnum, pSysDevEnum) = S_OK <span style="color: rgba(0, 0, 255, 1)">then</span>
<span style="color: rgba(0, 0, 255, 1)">begin</span>
    <span style="color: rgba(0, 0, 255, 1)">if</span> pSysDevEnum.CreateClassEnumerator(gid, pEnumCat, <span style="color: rgba(128, 0, 128, 1)">0</span>) = S_OK <span style="color: rgba(0, 0, 255, 1)">then</span>
    <span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
      iIndex :</span>= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
      </span><span style="color: rgba(0, 0, 255, 1)">while</span> (pEnumCat.Next(<span style="color: rgba(128, 0, 128, 1)">1</span>, pMoniker, @cFetched) = S_OK) <span style="color: rgba(0, 0, 255, 1)">and</span> (cFetched &gt; <span style="color: rgba(128, 0, 128, 1)">0</span>) <span style="color: rgba(0, 0, 255, 1)">and</span> (pMoniker &lt;&gt; <span style="color: rgba(0, 0, 255, 1)">nil</span>) <span style="color: rgba(0, 0, 255, 1)">do</span>
      <span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
      bc :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;
      mo :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;
      pMoniker.BindToStorage(bc, mo, IID_IPropertyBag, pPropBag);
      er :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;
      pPropBag.Read(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">FriendlyName</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, ov, er);
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> AnsiString(ov) = FriendlyName <span style="color: rgba(0, 0, 255, 1)">then</span>
      <span style="color: rgba(0, 0, 255, 1)">begin</span>
          <span style="color: rgba(0, 0, 255, 1)">if</span> iIndex = instanceIndex <span style="color: rgba(0, 0, 255, 1)">then</span>
          <span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
            bc :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;
            mo :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;
            pMoniker.BindToObject(bc, mo, IID_IBaseFilter, Result);
          </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
          Inc(iIndex);
      </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
      pPropBag :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;
      pMoniker :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;
      </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
pEnumCat    :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;
pSysDevEnum :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> VideoMediaSubTypeToStr(mst: TGUID): AnsiString;
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
I: Integer;
</span><span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
Result :</span>= <span style="color: rgba(128, 0, 0, 1)">''</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">for</span> I:= <span style="color: rgba(128, 0, 128, 1)">0</span> <span style="color: rgba(0, 0, 255, 1)">to</span> <span style="color: rgba(128, 0, 128, 1)">35</span> <span style="color: rgba(0, 0, 255, 1)">do</span>
    <span style="color: rgba(0, 0, 255, 1)">if</span> CompareMem(c_arrVideoFormatGUID, @mst, sizeof(TGUID)) <span style="color: rgba(0, 0, 255, 1)">then</span>
    <span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
      Result :</span>=<span style="color: rgba(0, 0, 0, 1)"> c_arrVideoFormatName;
      </span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">procedure</span><span style="color: rgba(0, 0, 0, 1)"> FreeMediaType(mt: TAMMediaType);
</span><span style="color: rgba(0, 0, 255, 1)">begin</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> (mt.cbFormat &lt;&gt; <span style="color: rgba(128, 0, 128, 1)">0</span>) <span style="color: rgba(0, 0, 255, 1)">then</span>
<span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
    CoTaskMemFree(mt.pbFormat);
    mt.cbFormat :</span>= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
    mt.pbFormat :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (mt.pUnk &lt;&gt; <span style="color: rgba(0, 0, 255, 1)">nil</span>) <span style="color: rgba(0, 0, 255, 1)">then</span>
<span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
    mt.pUnk :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">procedure</span><span style="color: rgba(0, 0, 0, 1)"> DeleteMediaType(pmt: PAMMediaType);
</span><span style="color: rgba(0, 0, 255, 1)">begin</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> pmt &lt;&gt; <span style="color: rgba(0, 0, 255, 1)">nil</span> <span style="color: rgba(0, 0, 255, 1)">then</span>
<span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
    FreeMediaType(pmt^);
    CoTaskMemFree(pmt);
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> GetOutputPin(filter: IBaseFilter): IPin;
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
penum: IEnumPins;
f    : Integer;
d    : PIN_DIRECTION;
</span><span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
Result :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;
filter.EnumPins(penum);
</span><span style="color: rgba(0, 0, 255, 1)">while</span> (penum.Next(<span style="color: rgba(128, 0, 128, 1)">1</span>, Result, @f) = S_OK) <span style="color: rgba(0, 0, 255, 1)">and</span> (f &gt; <span style="color: rgba(128, 0, 128, 1)">0</span>) <span style="color: rgba(0, 0, 255, 1)">do</span>
<span style="color: rgba(0, 0, 255, 1)">begin</span>
    <span style="color: rgba(0, 0, 255, 1)">if</span> (Result.QueryDirection(d) = S_OK) <span style="color: rgba(0, 0, 255, 1)">and</span> (d = PINDIR_OUTPUT) <span style="color: rgba(0, 0, 255, 1)">then</span>
    <span style="color: rgba(0, 0, 255, 1)">begin</span>
      <span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 找到输出接口,返回 </span><span style="color: rgba(0, 128, 0, 1)">}</span><span style="color: rgba(0, 0, 0, 1)">
      Exit;
    </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
Result :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> StrToVideoMediaSubType(ss: AnsiString): TGUID;
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
I: Integer;
</span><span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
Result :</span>= c_arrVideoFormatGUID[<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">]^;
</span><span style="color: rgba(0, 0, 255, 1)">for</span> I:= <span style="color: rgba(128, 0, 128, 1)">0</span> <span style="color: rgba(0, 0, 255, 1)">to</span> <span style="color: rgba(128, 0, 128, 1)">35</span> <span style="color: rgba(0, 0, 255, 1)">do</span>
    <span style="color: rgba(0, 0, 255, 1)">if</span> ss = c_arrVideoFormatName <span style="color: rgba(0, 0, 255, 1)">then</span>
    <span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
      Result :</span>=<span style="color: rgba(0, 0, 0, 1)"> c_arrVideoFormatGUID^;
      </span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">function</span> CompareGUID(<span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> g1, g2: TGUID): Boolean;
</span><span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
Result :</span>=<span style="color: rgba(0, 0, 0, 1)"> CompareMem(@g1, @g2, sizeof(TGUID));
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> SetMediaType(filter: IBaseFilter; Width, Height: Integer; format: AnsiString): Boolean;
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
pmt            : PAMMediaType;
piCount, piSize: Integer;
I            : Integer;
pSCC         : PVideoStreamConfigCaps;
streamConfig   : IAMStreamConfig;
outPin         : IPin;
formatID       : TGUID;
selectedIndex: Integer;
ih             : PVIDEOINFOHEADER;
bitRate      : dword;
</span><span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
Result :</span>=<span style="color: rgba(0, 0, 0, 1)"> False;

</span><span style="color: rgba(0, 0, 255, 1)">if</span> (Width = <span style="color: rgba(128, 0, 128, 1)">0</span>) <span style="color: rgba(0, 0, 255, 1)">or</span> (Height = <span style="color: rgba(128, 0, 128, 1)">0</span>) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    Exit;

outPin :</span>=<span style="color: rgba(0, 0, 0, 1)"> GetOutputPin(filter);
outPin.QueryInterface(IID_IAMStreamConfig, streamConfig);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> assigned(streamConfig) <span style="color: rgba(0, 0, 255, 1)">then</span>
<span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
    selectedIndex :</span>= -<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
    bitRate       :</span>= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
    formatID      :</span>=<span style="color: rgba(0, 0, 0, 1)"> StrToVideoMediaSubType(format);
    streamConfig.GetNumberOfCapabilities(piCount, piSize);
    getmem(pSCC, piSize);
    </span><span style="color: rgba(0, 0, 255, 1)">try</span>
      <span style="color: rgba(0, 0, 255, 1)">for</span> I := <span style="color: rgba(128, 0, 128, 1)">0</span> <span style="color: rgba(0, 0, 255, 1)">to</span> piCount - <span style="color: rgba(128, 0, 128, 1)">1</span> <span style="color: rgba(0, 0, 255, 1)">do</span>
      <span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
      streamConfig.GetStreamCaps(I, pmt, pSCC);
      ih :</span>=<span style="color: rgba(0, 0, 0, 1)"> Pointer(pmt^.pbFormat);
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (pSCC^.MinOutputSize.cx = Width) <span style="color: rgba(0, 0, 255, 1)">and</span> (pSCC^.MinOutputSize.cy = Height) <span style="color: rgba(0, 0, 255, 1)">and</span> (ih^.bmiHeader.biWidth = Width) <span style="color: rgba(0, 0, 255, 1)">and</span> (ih^.bmiHeader.biheight = Height) <span style="color: rgba(0, 0, 255, 1)">and</span> ((format = <span style="color: rgba(128, 0, 0, 1)">''</span>) <span style="color: rgba(0, 0, 255, 1)">or</span> (CompareGUID(formatID, pmt^.subtype))) <span style="color: rgba(0, 0, 255, 1)">and</span> (ih^.dwBitRate &gt; bitRate) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> select format with maximum bitrate</span>
      <span style="color: rgba(0, 0, 255, 1)">then</span>
      <span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
          selectedIndex :</span>=<span style="color: rgba(0, 0, 0, 1)"> I;
          bitRate       :</span>=<span style="color: rgba(0, 0, 0, 1)"> ih^.dwBitRate;
      </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
      DeleteMediaType(pmt);
      </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> selectedIndex &gt; -<span style="color: rgba(128, 0, 128, 1)">1</span> <span style="color: rgba(0, 0, 255, 1)">then</span>
      <span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
      streamConfig.GetStreamCaps(selectedIndex, pmt, pSCC);
      </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">
          streamConfig.SetFormat(pmt^);
      </span><span style="color: rgba(0, 0, 255, 1)">finally</span><span style="color: rgba(0, 0, 0, 1)">
          DeleteMediaType(pmt);
      </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
      </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">finally</span><span style="color: rgba(0, 0, 0, 1)">
      FreeMem(pSCC);
    </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
Result :</span>=<span style="color: rgba(0, 0, 0, 1)"> True;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 枚举所有视频输入设备 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">procedure</span><span style="color: rgba(0, 0, 0, 1)"> EnumAllUSBCamera(strsList: TStrings);
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
SysDevEnum: ICreateDevEnum;
EnumCat   : IEnumMoniker;
hr      : Integer;
Moniker   : IMoniker;
Fetched   : ULONG;
PropBag   : IPropertyBag;
strName   : OleVariant;
strGuid   : OleVariant;
III       : Integer;
puInfo    : PVideoInputInfo;
intIndex: Integer;
</span><span style="color: rgba(0, 0, 255, 1)">begin</span>
<span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 创建系统枚举器对象 </span><span style="color: rgba(0, 128, 0, 1)">}</span><span style="color: rgba(0, 0, 0, 1)">
hr :</span>= CocreateInstance(CLSID_SystemDeviceEnum, <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">, CLSCTX_INPROC, IID_ICreateDevEnum, SysDevEnum);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> hr &lt;&gt; S_OK <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    Exit;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 用指定的 Filter 目录类型创建一个枚举器,并获得 IEnumMoniker 接口; </span><span style="color: rgba(0, 128, 0, 1)">}</span><span style="color: rgba(0, 0, 0, 1)">
hr :</span>= SysDevEnum.CreateClassEnumerator(CLSID_VideoInputDeviceCategory, EnumCat, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> hr &lt;&gt; S_OK <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    Exit;

</span><span style="color: rgba(0, 0, 255, 1)">try</span>
    <span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 释放内存 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
    <span style="color: rgba(0, 0, 255, 1)">if</span> strsList.Count &gt; <span style="color: rgba(128, 0, 128, 1)">0</span> <span style="color: rgba(0, 0, 255, 1)">then</span>
    <span style="color: rgba(0, 0, 255, 1)">begin</span>
      <span style="color: rgba(0, 0, 255, 1)">for</span> III := <span style="color: rgba(128, 0, 128, 1)">0</span> <span style="color: rgba(0, 0, 255, 1)">to</span> strsList.Count - <span style="color: rgba(128, 0, 128, 1)">1</span> <span style="color: rgba(0, 0, 255, 1)">do</span>
      <span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
      FreeMem(PVideoFormatInfo(strsList.Objects));
      </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
    strsList.Clear;

    </span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 获取指定类型目录下所有设备标识 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
    <span style="color: rgba(0, 0, 255, 1)">while</span> (EnumCat.Next(<span style="color: rgba(128, 0, 128, 1)">1</span>, Moniker, @Fetched) = S_OK) <span style="color: rgba(0, 0, 255, 1)">do</span>
    <span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
      Moniker.BindToStorage(</span><span style="color: rgba(0, 0, 255, 1)">nil</span>, <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">, IID_IPropertyBag, PropBag);
      PropBag.Read(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">CLSID</span><span style="color: rgba(128, 0, 0, 1)">'</span>, strGuid, <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">);
      PropBag.Read(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">FriendlyName</span><span style="color: rgba(128, 0, 0, 1)">'</span>, strName, <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">);
      New(puInfo);
      puInfo^.id      :</span>=<span style="color: rgba(0, 0, 0, 1)"> TGUID(strGuid);
      puInfo^.strName :</span>=<span style="color: rgba(0, 0, 0, 1)"> ShortString(strName);
      puInfo^.index   :</span>= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> strsList.IndexOf(strName) = -<span style="color: rgba(128, 0, 128, 1)">1</span> <span style="color: rgba(0, 0, 255, 1)">then</span>
      <span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
      strsList.AddObject(strName, TObject(puInfo));
      </span><span style="color: rgba(0, 0, 255, 1)">end</span>
      <span style="color: rgba(0, 0, 255, 1)">else</span>
      <span style="color: rgba(0, 0, 255, 1)">begin</span>
      <span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 相同名称的 USBCamera 相机,&lt;有可能有多个名称重复的相机&gt; </span><span style="color: rgba(0, 128, 0, 1)">}</span><span style="color: rgba(0, 0, 0, 1)">
      intIndex      :</span>=<span style="color: rgba(0, 0, 0, 1)"> GetMaxIndex(strsList, strName);
      puInfo^.index :</span>= intIndex   <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
      strsList.AddObject(strName   format(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">(%d)</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, ), TObject(puInfo));
      </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
      PropBag :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;
      Moniker :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">finally</span><span style="color: rgba(0, 0, 0, 1)">
    EnumCat    :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;
    SysDevEnum :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 枚举视频支持格式 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">function</span> EnumVideoFormat(<span style="color: rgba(0, 0, 255, 1)">const</span> strFriendlyName: String; <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> intIndex: Integer; strsList: TStrings): Boolean;
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
SysDevEnum          : IBaseFilter;
CaptureGraphBuilder2: ICaptureGraphBuilder2;
iunk                : IUnknown;
fStreamConfig       : IAMStreamConfig;
piCount, piSize   : Integer;
III               : Integer;
pmt               : PAMMediaType;
pSCC                : PVideoStreamConfigCaps;
pvInfo            : PVideoFormatInfo;
</span><span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
Result :</span>=<span style="color: rgba(0, 0, 0, 1)"> False;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 获取指定USB摄像头的 Filter </span><span style="color: rgba(0, 128, 0, 1)">}</span><span style="color: rgba(0, 0, 0, 1)">
SysDevEnum :</span>=<span style="color: rgba(0, 0, 0, 1)"> CreateFilter(CLSID_VideoInputDeviceCategory, AnsiString(strFriendlyName), intIndex);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> SysDevEnum = <span style="color: rgba(0, 0, 255, 1)">nil</span> <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    Exit;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 释放内存 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> strsList.Count &gt; <span style="color: rgba(128, 0, 128, 1)">0</span> <span style="color: rgba(0, 0, 255, 1)">then</span>
<span style="color: rgba(0, 0, 255, 1)">begin</span>
    <span style="color: rgba(0, 0, 255, 1)">for</span> III := <span style="color: rgba(128, 0, 128, 1)">0</span> <span style="color: rgba(0, 0, 255, 1)">to</span> strsList.Count - <span style="color: rgba(128, 0, 128, 1)">1</span> <span style="color: rgba(0, 0, 255, 1)">do</span>
    <span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
      FreeMem(PVideoFormatInfo(strsList.Objects));
    </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
strsList.Clear;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 创建 ICaptureGraphBuilder2 接口 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> Failed(CocreateInstance(CLSID_CaptureGraphBuilder2, <span style="color: rgba(0, 0, 255, 1)">nil</span>, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, CaptureGraphBuilder2)) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    Exit;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 获取 IID_IAMStreamConfig 接口 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> Failed(CaptureGraphBuilder2.FindInterface(<span style="color: rgba(0, 0, 255, 1)">nil</span>, <span style="color: rgba(0, 0, 255, 1)">nil</span>, SysDevEnum, IID_IAMStreamConfig, iunk)) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    Exit;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 获取 IAMStreamConfig 媒体类型接口 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> Failed(iunk.QueryInterface(IID_IAMStreamConfig, fStreamConfig)) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    Exit;

</span><span style="color: rgba(0, 0, 255, 1)">if</span> Failed(fStreamConfig.GetNumberOfCapabilities(piCount, piSize)) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    Exit;

</span><span style="color: rgba(0, 0, 255, 1)">if</span> piCount &lt;= <span style="color: rgba(128, 0, 128, 1)">0</span> <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    Exit;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 枚举支持的视频格式 </span><span style="color: rgba(0, 128, 0, 1)">}</span><span style="color: rgba(0, 0, 0, 1)">
pSCC :</span>=<span style="color: rgba(0, 0, 0, 1)"> AllocMem(piSize);
</span><span style="color: rgba(0, 0, 255, 1)">try</span>
    <span style="color: rgba(0, 0, 255, 1)">for</span> III := <span style="color: rgba(128, 0, 128, 1)">0</span> <span style="color: rgba(0, 0, 255, 1)">to</span> piCount - <span style="color: rgba(128, 0, 128, 1)">1</span> <span style="color: rgba(0, 0, 255, 1)">do</span>
    <span style="color: rgba(0, 0, 255, 1)">begin</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> fStreamConfig.GetStreamCaps(III, pmt, pSCC) = S_OK <span style="color: rgba(0, 0, 255, 1)">then</span>
      <span style="color: rgba(0, 0, 255, 1)">begin</span>
      <span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">
          New(pvInfo); </span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 注意释放内存 </span><span style="color: rgba(0, 128, 0, 1)">}</span><span style="color: rgba(0, 0, 0, 1)">
          pvInfo^.Frame   :</span>=<span style="color: rgba(0, 0, 0, 1)"> PVIDEOINFOHEADER(pmt^.pbFormat)^.AvgTimePerFrame;
          pvInfo^.id      :</span>=<span style="color: rgba(0, 0, 0, 1)"> pmt^.formattype;
          pvInfo^.iWidth:</span>=<span style="color: rgba(0, 0, 0, 1)"> pSCC^.MaxOutputSize.cx;
          pvInfo^.iHeight :</span>=<span style="color: rgba(0, 0, 0, 1)"> pSCC^.MaxOutputSize.cy;
          pvInfo^.iMod    :</span>=<span style="color: rgba(0, 0, 0, 1)"> pmt^.subtype;
          pvInfo^.format:</span>=<span style="color: rgba(0, 0, 0, 1)"> VideoMediaSubTypeToStr(pmt^.subtype);
          strsList.AddObject(format(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">类型:%s分辨率:%4d×%4d</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, ), TObject(pvInfo));
      </span><span style="color: rgba(0, 0, 255, 1)">finally</span><span style="color: rgba(0, 0, 0, 1)">
          DeleteMediaType(pmt);
      </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
      </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">finally</span><span style="color: rgba(0, 0, 0, 1)">
    FreeMem(pSCC);
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

SysDevEnum         :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;
CaptureGraphBuilder2 :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;
fStreamConfig      :</span>= <span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">;

Result :</span>=<span style="color: rgba(0, 0, 0, 1)"> True;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">function</span> CommonVideo(<span style="color: rgba(0, 0, 255, 1)">var</span> FIGraphBuilder: IGraphBuilder;               <span style="color: rgba(0, 128, 0, 1)">//
</span><span style="color: rgba(0, 0, 255, 1)">var</span> FICaptureGraphBuilder2: ICaptureGraphBuilder2;                  <span style="color: rgba(0, 128, 0, 1)">//
</span><span style="color: rgba(0, 0, 255, 1)">var</span> FSysDevEnum: IBaseFilter;                                       <span style="color: rgba(0, 128, 0, 1)">//
</span><span style="color: rgba(0, 0, 255, 1)">var</span> FIVideoWindow: IVideoWindow;                                    <span style="color: rgba(0, 128, 0, 1)">//
</span><span style="color: rgba(0, 0, 255, 1)">var</span> FIMediaControl: IMediaControl;                                  <span style="color: rgba(0, 128, 0, 1)">//
</span><span style="color: rgba(0, 0, 255, 1)">var</span> FISampleGrabber: ISampleGrabber;                              <span style="color: rgba(0, 128, 0, 1)">//
</span>pv: PVideoInputInfo; pf: PVideoFormatInfo;                        <span style="color: rgba(0, 128, 0, 1)">//
</span>pnl: TPanel;                                                      <span style="color: rgba(0, 128, 0, 1)">//
</span><span style="color: rgba(0, 0, 255, 1)">const</span> strSaveFileName: <span style="color: rgba(0, 0, 255, 1)">string</span> = <span style="color: rgba(128, 0, 0, 1)">''</span>; <span style="color: rgba(0, 0, 255, 1)">const</span> bRecord: Boolean = False; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 录像</span>
<span style="color: rgba(0, 0, 255, 1)">const</span> bSnapBmp: Boolean = False                                     <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 截图</span>
<span style="color: rgba(0, 0, 0, 1)">): Boolean;
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
SampleGrabberFilter: IBaseFilter;
mt               : TAMMediaType;
multiplexer      : IBaseFilter;
Writer             : IFileSinkFilter;
</span><span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
Result :</span>=<span style="color: rgba(0, 0, 0, 1)"> False;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 创建 IGraphBuilder 接口 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> Failed(CocreateInstance(CLSID_FilterGraph, <span style="color: rgba(0, 0, 255, 1)">nil</span>, CLSCTX_INPROC, IID_IGraphBuilder, FIGraphBuilder)) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    Exit;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 创建 ICaptureGraphBuilder2 接口 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> Failed(CocreateInstance(CLSID_CaptureGraphBuilder2, <span style="color: rgba(0, 0, 255, 1)">nil</span>, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, FICaptureGraphBuilder2)) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    Exit;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 调用 ICaptureGraphBuilder2 的 SetFilterGraph 方法将 FilterGraph 加入到Builder中 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> Failed(FICaptureGraphBuilder2.SetFiltergraph(FIGraphBuilder)) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    Exit;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 获取指定USB摄像头的 Filter </span><span style="color: rgba(0, 128, 0, 1)">}</span><span style="color: rgba(0, 0, 0, 1)">
FSysDevEnum :</span>=<span style="color: rgba(0, 0, 0, 1)"> CreateFilter(CLSID_VideoInputDeviceCategory, AnsiString(pv^.strName), pv^.index);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> FSysDevEnum = <span style="color: rgba(0, 0, 255, 1)">nil</span> <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    Exit;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 设置指定 Filter 的媒体格式类型 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(0, 0, 255, 1)">not</span> SetMediaType(FSysDevEnum, pf^.iWidth, pf^.iHeight, pf^.format) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    Exit;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 将视频捕捉 Filter 添加到 Filter 图中 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> Failed(FIGraphBuilder.AddFilter(FSysDevEnum, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">VideoCapture</span><span style="color: rgba(128, 0, 0, 1)">'</span>)) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    Exit;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 如果需要截图功能 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> bSnapBmp <span style="color: rgba(0, 0, 255, 1)">then</span>
<span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
    CocreateInstance(CLSID_SampleGrabber, </span><span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">, CLSCTX_INPROC, IID_IBaseFilter, SampleGrabberFilter);
    FIGraphBuilder.AddFilter(SampleGrabberFilter, </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">SampleGrabber</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
    SampleGrabberFilter.QueryInterface(IID_ISampleGrabber, FISampleGrabber);
    zeromemory(@mt, sizeof(AM_MEDIA_TYPE));
    mt.majortype :</span>=<span style="color: rgba(0, 0, 0, 1)"> MEDIATYPE_Video;
    mt.subtype   :</span>= MEDIASUBTYPE_RGB24;   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 24位,位图格式输出</span>
    FISampleGrabber.SetMediaType(@mt);      <span style="color: rgba(0, 128, 0, 1)">//
</span>    FISampleGrabber.SetBufferSamples(True); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 允许从 Buffer 中获取数据</span>
    <span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 渲染预览视频PIN </span><span style="color: rgba(0, 128, 0, 1)">}</span>
    <span style="color: rgba(0, 0, 255, 1)">if</span> Failed(FICaptureGraphBuilder2.RenderStream(@PIN_CATEGORY_PREVIEW, @MEDIATYPE_Video, FSysDevEnum, SampleGrabberFilter, <span style="color: rgba(0, 0, 255, 1)">nil</span>)) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
      Exit;
</span><span style="color: rgba(0, 0, 255, 1)">end</span>
<span style="color: rgba(0, 0, 255, 1)">else</span>
<span style="color: rgba(0, 0, 255, 1)">begin</span>
    <span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 渲染预览视频PIN </span><span style="color: rgba(0, 128, 0, 1)">}</span>
    <span style="color: rgba(0, 0, 255, 1)">if</span> Failed(FICaptureGraphBuilder2.RenderStream(@PIN_CATEGORY_PREVIEW, @MEDIATYPE_Video, FSysDevEnum, <span style="color: rgba(0, 0, 255, 1)">nil</span>, <span style="color: rgba(0, 0, 255, 1)">nil</span>)) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
      Exit;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 如果是视频录制 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> bRecord <span style="color: rgba(0, 0, 255, 1)">then</span>
<span style="color: rgba(0, 0, 255, 1)">begin</span>
    <span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 视频录制文件保持路径 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
    <span style="color: rgba(0, 0, 255, 1)">if</span> Failed(FICaptureGraphBuilder2.SetOutputFileName(MEDIASUBTYPE_Avi, PWideChar(strSaveFileName), multiplexer, Writer)) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
      Exit;

    </span><span style="color: rgba(0, 0, 255, 1)">if</span> Failed(FICaptureGraphBuilder2.RenderStream(@PIN_CATEGORY_CAPTURE, @MEDIATYPE_Video, FSysDevEnum, <span style="color: rgba(0, 0, 255, 1)">nil</span>, multiplexer)) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
      Exit;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 设置视频预览窗口 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> Failed(FIGraphBuilder.QueryInterface(IID_IVideoWindow, FIVideoWindow)) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    Exit;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 设置视频播放的WINDOWS窗口 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> Failed(FIVideoWindow.put_Owner(pnl.Handle)) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    Exit;

</span><span style="color: rgba(0, 0, 255, 1)">if</span> Failed(FIVideoWindow.put_windowstyle(WS_CHILD <span style="color: rgba(0, 0, 255, 1)">or</span> WS_Clipsiblings)) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    Exit;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 设置视频尺寸 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> Failed(FIVideoWindow.SetWindowposition(<span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">0</span>, pnl.Width, pnl.Height)) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    Exit;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 得到IMediaControl接口,用于控制流播放 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> Failed(FIGraphBuilder.QueryInterface(IID_IMediaControl, FIMediaControl)) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    Exit;

Result :</span>=<span style="color: rgba(0, 0, 0, 1)"> True;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 视频预览 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">function</span> USBVideoPreview(<span style="color: rgba(0, 0, 255, 1)">var</span> FIGraphBuilder: IGraphBuilder; <span style="color: rgba(0, 0, 255, 1)">var</span> FICaptureGraphBuilder2: ICaptureGraphBuilder2; <span style="color: rgba(0, 0, 255, 1)">var</span> FSysDevEnum: IBaseFilter; <span style="color: rgba(0, 0, 255, 1)">var</span> FIVideoWindow: IVideoWindow; <span style="color: rgba(0, 0, 255, 1)">var</span> FIMediaControl: IMediaControl; <span style="color: rgba(0, 0, 255, 1)">var</span> FISampleGrabber: ISampleGrabber; pv: PVideoInputInfo; pf: PVideoFormatInfo; pnl: TPanel; <span style="color: rgba(0, 0, 255, 1)">const</span> bSnapBmp: Boolean =<span style="color: rgba(0, 0, 0, 1)"> False): Boolean;
</span><span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
Result :</span>= CommonVideo(FIGraphBuilder, FICaptureGraphBuilder2, FSysDevEnum, FIVideoWindow, FIMediaControl, FISampleGrabber, pv, pf, pnl, <span style="color: rgba(128, 0, 0, 1)">''</span><span style="color: rgba(0, 0, 0, 1)">, False, True);
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> 视频录制 </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">function</span> USBVideoRecord(<span style="color: rgba(0, 0, 255, 1)">var</span> FIGraphBuilder: IGraphBuilder; <span style="color: rgba(0, 0, 255, 1)">var</span> FICaptureGraphBuilder2: ICaptureGraphBuilder2; <span style="color: rgba(0, 0, 255, 1)">var</span> FSysDevEnum: IBaseFilter; <span style="color: rgba(0, 0, 255, 1)">var</span> FIVideoWindow: IVideoWindow; <span style="color: rgba(0, 0, 255, 1)">var</span> FIMediaControl: IMediaControl; <span style="color: rgba(0, 0, 255, 1)">var</span> FISampleGrabber: ISampleGrabber; pv: PVideoInputInfo; pf: PVideoFormatInfo; pnl: TPanel; <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> strSaveFileName: String): Boolean;
</span><span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
Result :</span>=<span style="color: rgba(0, 0, 0, 1)"> CommonVideo(FIGraphBuilder, FICaptureGraphBuilder2, FSysDevEnum, FIVideoWindow, FIMediaControl, FISampleGrabber, pv, pf, pnl, strSaveFileName, True, True);
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">end</span>.</pre>
</div>
<p>&nbsp;</p>

</div>
<div id="MySignature" role="contentinfo">
    好的代码像粥一样,都是用时间熬出来的<br><br>
来源:https://www.cnblogs.com/jijm123/p/14270144.html
頁: [1]
查看完整版本: Delphi USBCamera DirectShow 预览录像截图