视频的获取问题?(300分)

  • 主题发起人 主题发起人 Undefine
  • 开始时间 开始时间
U

Undefine

Unregistered / Unconfirmed
GUEST, unregistred user!
请问如何象netmeeting一样从外部设备(例如:摄象头.....)获取视频.
 
VFW或者Direct Show,是不是很精炼呀,呵呵.
 
给你个实例,要安装directx8.1!
在delphi6.0+directshow+dspack2.1下调试通过!
unit videocap;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DSUtil, StdCtrls, DSPack, DirectShow, Menus, ExtCtrls,Buttons;

type
TVideoForm = class(TForm)
FilterGraph: TFilterGraph;
Filter: TFilter;
SampleGrabber: TSampleGrabber;
Panel1: TPanel;
videocapture: TBitBtn;
Panel2: TPanel;
videocut: TButton;
Panel3: TPanel;
GroupBox1: TGroupBox;
VideoWindow: TVideoWindow;
GroupBox2: TGroupBox;
Image: TImage;
GroupBox3: TGroupBox;
Label1: TLabel;
videosource: TComboBox;
setvideo: TBitBtn;
setformat: TBitBtn;
Label2: TLabel;
videodevices: TComboBox;
videosave: TBitBtn;
savestop: TBitBtn;
Label3: TLabel;
Edit1: TEdit;
setsave: TBitBtn;
procedure FormCreate(Sender: TObject);
procedure FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
procedure videocutClick(Sender: TObject);
procedure videocaptureClick(Sender: TObject);
procedure videosourceChange(Sender: TObject);
procedure setvideoClick(Sender: TObject);
private
{ D閏larations priv閑s }
public
{ D閏larations publiques }
end;


var
VideoForm: TVideoForm;
SysDev: TSysDevEnum;
CapFile: WideString = 'd:/capture.avi';
implementation
uses activex, format;

{$R *.dfm}

procedure TVideoForm.FormCreate(Sender: TObject);
var
i: integer;

begin

SysDev:= TSysDevEnum.Create(CLSID_VideoInputDeviceCategory);
if (SysDev.CountFilters = 0) then

begin

Messagebox(0,'没安装视频采集卡或没开启视频输入设备!','视频初始化错误',id_ok);
SysDev.Destroy;
// CaptureGraph.Disconnect;
Application.Terminate;
exit;
end;

if SysDev.CountFilters > 0 then

for i := 0 to SysDev.CountFilters - 1do

begin

videodevices.Items.Add(SysDev.Filters.FriendlyName);
videodevices.ItemIndex:=0;
end;

end;


procedure TVideoForm.FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
begin

SysDev.Free;
FilterGraph.ClearGraph;
FilterGraph.Active := false;
end;


procedure TVideoForm.videocutClick(Sender: TObject);
begin

SampleGrabber.GetBitmap(Image.Picture.Bitmap);
end;


procedure TVideoForm.videocaptureClick(Sender: TObject);
var
in_type:ToleEnum;
tmp_crossbar:IAMCrossbar;
multiplexer: IBaseFilter;
Writer: IFileSinkFilter;
begin

FilterGraph.ClearGraph;
FilterGraph.Active := false;
SysDev:= TSysDevEnum.Create(CLSID_VideoInputDeviceCategory);
Filter.BaseFilter.Moniker := SysDev.GetMoniker(0);
Filter.FilterGraph := FilterGraph;
FilterGraph.Active := true;

with FilterGraph as IcaptureGraphBuilder2do

// set the output filename
SetOutputFileName(MEDIASUBTYPE_Avi, PWideChar(CapFile), multiplexer, Writer);
// Connect Video preview (VideoWindow)
with FilterGraph as IcaptureGraphBuilder2do

if Filter.BaseFilter.DataLength > 0 then

RenderStream(@PIN_CATEGORY_PREVIEW, nil, Filter as IBaseFilter,
SampleGrabber as IBaseFilter , VideoWindow as IBaseFilter);
// Connect Video capture streams
with FilterGraph as IcaptureGraphBuilder2do

if Filter.FilterGraph <> nil then

RenderStream(@PIN_CATEGORY_CAPTURE, nil, Filter as IBaseFilter,
nil, multiplexer as IBaseFilter);

FilterGraph.Play;
end;


procedure TVideoForm.videosourceChange(Sender: TObject);
var
in_pinlist:integer;
in_type:ToleEnum;
tmp_crossbar:IAMCrossbar;
begin

SysDev:= TSysDevEnum.Create(AM_KSCATEGORY_CROSSBAR);//设置crossbar属性
FilterGraph.ClearGraph;
FilterGraph.Active := false;
Filter.BaseFilter.Moniker := SysDev.GetMoniker(0);
Filter.FilterGraph := FilterGraph;
FilterGraph.Active := true;

with FilterGraph as ICaptureGraphBuilder2do

FindInterface(nil,nil,Filter as IBaseFilter,IAMCrossbar,tmp_crossbar);

tmp_crossbar.get_CrossbarPinInfo(true,videosource.ItemIndex,in_pinlist,in_type);
tmp_crossbar.Route(0,in_type-1);

end;


procedure TVideoForm.setvideoClick(Sender: TObject);
begin

if FilterGraph.Active then

ShowFilterPropertyPage(Self.Handle, filter as IBaseFilter);

end;


end.
 
to LeeChange 兄:
vfw 我是通过avicap32.dll实现的,有更好的方式么?
to Oldfly 兄:
谢谢,非常感谢,结贴时送上200;
 
以下代码已经测试并通过。注意vfw.pas的版本,在Delphi的安装盘里找,默认安装是没有的。
uses vfw, Clipbrd;

var
Form1: TForm1;
m_hCapWnd:Hwnd;

procedure Tform1.capbmp;
begin

capEditCopy(m_hCapWnd);
//把图像拷到剪贴板
image1.Picture.Bitmap.LoadFromClipboardFormat(CF_BITMAP,Clipboard.GetAsHandle(CF_BITMAP), 0);
// 这时在image1里面的就是你需要的图片;
end;


procedure TForm1.FormCreate(Sender: TObject);
var
dwSize:Integer;
setBmp : BITMAPINFO ;
begin

try
m_hCapWnd:=capCreateCaptureWindow('',
WS_CHILD or WS_VISIBLE,0,0,AviPanel.width,AviPanel.height,AviPanel.Handle,0);
//avipanel 就是你要显示的视频窗口的;可以是form ,panel等
//AviPanel.width就是显示的宽度,AviPanel.height显示的高度;
if(capDriverConnect(m_hCapWnd,0)) then

begin

// capOverlay(m_hCapWnd,true);
//普通的摄像头不能用overlay的方式 主意;
capPreviewRate(m_hCapWnd,30);
//设置帧率为30
capPreview(m_hCapWnd,true);
// preview方式显示
dwSize:=capGetVideoFormatSize(m_hCapWnd);

capGetVideoFormat(m_hCapWnd,@setBmp, dwSize);
setBmp.bmiHeader.biWidth:=352;
//这个就是设置你捕捉图片的大小了 宽度 :)
setBmp.bmiHeader.biHeight:=288;
//这个就是设置你捕捉图片的大小了 高度 :)
capSetVideoFormat(m_hCapWnd,@setBmp,dwSize);

end;

except
end;

end;


procedure TForm1.Button1Click(Sender: TObject);
begin
//定像
capbmp;
end;

 
to wangzhi2兄:
我是用avicap32.dll实现的,代码基本差不多,但是所有的消息、变量都要自己的去申明,所以受限制比较大,才知道delphi里也有vfw申明,谢谢你,非常谢谢。结贴送分。
 
Undefine兄:
我这又一个视频采集的DEMO,如有想要的话留下你的MAIL。[:)]
 
to qince兄:
万分谢谢,ken_j@163.com
 
能否顺便给我发一份,最近也在研究。非常感谢 qince,
ypv8@163.com
 
邮件已发,请查收。
 
感谢qince ,已收到, dspack要版本的要求吗?
 
要求安装DX9
DSPACK现在的版本应该是2.31
你可以到他的网站上下载 www.progdigy.com
其他的没什么要求。
 
多人接受答案了。
 
后退
顶部