Solved

Capture video, interval images from a webcam (USB)

Posted on 2003-10-30
7
754 Views
Last Modified: 2013-11-18
Hi, i am trying to create a delphi 7 project which can capture an image from a webcam at intervals and save them on the local hard drive. As BMP/JPG files. how do i go about starting this without paying for delphi plug-ins/components?

Thanks, Dave.
0
Comment
Question by:djlittle2002
  • 2
  • 2
7 Comments
 
LVL 11

Accepted Solution

by:
robert_marquardt earned 65 total points
ID: 9649423
Such webcams are usually accessed through DirectShow.
The starting point for that is http://www.progdigy.com
Despite the .com it is free.
0
 
LVL 5

Assisted Solution

by:paulb1989
paulb1989 earned 65 total points
ID: 9650258
There is a set of freeware components called DSPack that can use webcams, and can use audio with them too if you need it. It can save video files in various qualitys, and I think it shouldn't be too hard to make it save a still image.
0
 
LVL 11

Expert Comment

by:robert_marquardt
ID: 9650430
Prodigy IS DSPack :-)
0
 

Author Comment

by:djlittle2002
ID: 9650531
can anyone post a simple example script that i caould use/adapt please?

Thanks
0
 
LVL 5

Expert Comment

by:paulb1989
ID: 9650632
Below is the source for a demo app which comes with DSPack called VideoCap.


unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, DSPack, DSUtil, DirectShow9, ComCtrls, ExtCtrls;

type
  TMainForm = class(TForm)
    CaptureGraph: TFilterGraph;
    VideoWindow: TVideoWindow;
    VideoCapFilters: TListBox;
    VideoSourceFilter: TFilter;
    StartButton: TButton;
    CapFileButton: TButton;
    SaveDialog: TSaveDialog;
    OutPutFileName: TLabel;
    StatusBar: TStatusBar;
    Timer: TTimer;
    StopButton: TButton;
    AudioCapFilters: TListBox;
    AudioSourceFilter: TFilter;
    Label1: TLabel;
    Label2: TLabel;
    VideoFormats: TListBox;
    AudioFormats: TListBox;
    Label3: TLabel;
    Label4: TLabel;
    InputLines: TComboBox;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure VideoCapFiltersClick(Sender: TObject);
    procedure StartButtonClick(Sender: TObject);
    procedure CapFileButtonClick(Sender: TObject);
    procedure StopButtonClick(Sender: TObject);
    procedure TimerTimer(Sender: TObject);
    procedure AudioCapFiltersClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  MainForm: TMainForm;
  CapEnum: TSysDevEnum;
  VideoMediaTypes, AudioMediaTypes: TEnumMediaType;
  CapFile: WideString = 'c:\capture.avi';
implementation

{$R *.dfm}

{ TMainForm }

procedure TMainForm.FormCreate(Sender: TObject);
var i: integer;
begin
  CapEnum := TSysDevEnum.Create(CLSID_VideoInputDeviceCategory);
  for i := 0 to CapEnum.CountFilters - 1 do
    VideoCapFilters.Items.Add(CapEnum.Filters[i].FriendlyName);

  CapEnum.SelectGUIDCategory(CLSID_AudioInputDeviceCategory);
  for i := 0 to CapEnum.CountFilters - 1 do
    AudioCapFilters.Items.Add(CapEnum.Filters[i].FriendlyName);

  VideoMediaTypes := TEnumMediaType.Create;
  AudioMediaTypes := TEnumMediaType.Create;
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  CapEnum.Free;
  VideoMediaTypes.Free;
  AudioMediaTypes.Free;
end;

// Select the video Source
procedure TMainForm.VideoCapFiltersClick(Sender: TObject);
var
  PinList: TPinList;
  i: integer;
begin
  CapEnum.SelectGUIDCategory(CLSID_VideoInputDeviceCategory);
  if VideoCapFilters.ItemIndex <> -1 then
  begin
    VideoSourceFilter.BaseFilter.Moniker := CapEnum.GetMoniker(VideoCapFilters.ItemIndex);
    VideoSourceFilter.FilterGraph := CaptureGraph;
    CaptureGraph.Active := true;
    PinList := TPinList.Create(VideoSourceFilter as IBaseFilter);
    VideoFormats.Clear;
    VideoMediaTypes.Assign(PinList.First);
    for i := 0 to VideoMediaTypes.Count - 1 do
      VideoFormats.Items.Add(VideoMediaTypes.MediaDescription[i]);
    CaptureGraph.Active := false;
    PinList.Free;
    StartButton.Enabled := true;
  end;
end;

// Select the audio Source
procedure TMainForm.AudioCapFiltersClick(Sender: TObject);
var
  PinList: TPinList;
  i, LineIndex: integer;
  ABool: LongBool;
begin
  CapEnum.SelectGUIDCategory(CLSID_AudioInputDeviceCategory);
  if AudioCapFilters.ItemIndex <> -1 then
  begin
    AudioSourceFilter.BaseFilter.Moniker := CapEnum.GetMoniker(AudioCapFilters.ItemIndex);
    AudioSourceFilter.FilterGraph := CaptureGraph;
    CaptureGraph.Active := true;
    PinList := TPinList.Create(AudioSourceFilter as IBaseFilter);
    AudioFormats.Clear;
    i := 0;
    while i < PinList.Count do
      if PinList.PinInfo[i].dir = PINDIR_OUTPUT then
        begin
          AudioMediaTypes.Assign(PinList.Items[i]);
          PinList.Delete(i);
        end else inc(i);

    for i := 0 to AudioMediaTypes.Count - 1 do
    begin
      AudioFormats.Items.Add(AudioMediaTypes.MediaDescription[i]);
    end;

    CaptureGraph.Active := false;
    InputLines.Clear;
    LineIndex := -1;
    for i := 0 to PinList.Count - 1 do
    begin
      InputLines.Items.Add(PinList.PinInfo[i].achName);
      with (PinList.Items[i] as IAMAudioInputMixer) do get_Enable(ABool);
      if ABool then LineIndex := i;
    end;
    InputLines.ItemIndex := LineIndex;
    PinList.Free;
    StartButton.Enabled := true;
  end;
end;

// Start Capture
procedure TMainForm.StartButtonClick(Sender: TObject);
var
  multiplexer: IBaseFilter;
  Writer: IFileSinkFilter;
  PinList: TPinList;
  i: integer;
begin

  // Activate the filter graph, at this stage the source filters are added to the graph
  CaptureGraph.Active := true;

  // configure output Audio media type + source
  if AudioSourceFilter.FilterGraph <> nil then
  begin
    PinList := TPinList.Create(AudioSourceFilter as IBaseFilter);
    i := 0;
    while i < PinList.Count do
      if PinList.PinInfo[i].dir = PINDIR_OUTPUT then
        begin
          if AudioFormats.ItemIndex <> -1 then
            with (PinList.Items[i] as IAMStreamConfig) do
              SetFormat(AudioMediaTypes.Items[AudioFormats.ItemIndex].AMMediaType^);
          PinList.Delete(i);
        end else inc(i);
    if InputLines.ItemIndex <> -1 then
      with (PinList.Items[InputLines.ItemIndex] as IAMAudioInputMixer) do
        put_Enable(true);
    PinList.Free;
  end;

  // configure output Video media type
  if VideoSourceFilter.FilterGraph <> nil then
  begin
    PinList := TPinList.Create(VideoSourceFilter as IBaseFilter);
    if VideoFormats.ItemIndex <> -1 then
      with (PinList.First as IAMStreamConfig) do
        SetFormat(VideoMediaTypes.Items[VideoFormats.ItemIndex].AMMediaType^);
    PinList.Free;
  end;


  // now render streams
  with CaptureGraph as IcaptureGraphBuilder2 do
  begin
    // set the output filename
    SetOutputFileName(MEDIASUBTYPE_Avi, PWideChar(CapFile), multiplexer, Writer);

    // Connect Video preview (VideoWindow)
    if VideoSourceFilter.BaseFilter.DataLength > 0 then
      RenderStream(@PIN_CATEGORY_PREVIEW, nil, VideoSourceFilter as IBaseFilter,
        nil , VideoWindow as IBaseFilter);

    // Connect Video capture streams
    if VideoSourceFilter.FilterGraph <> nil then
      RenderStream(@PIN_CATEGORY_CAPTURE, nil, VideoSourceFilter as IBaseFilter,
        nil, multiplexer as IBaseFilter);

    // Connect Audio capture streams
    if AudioSourceFilter.FilterGraph <> nil then
    begin

      RenderStream(nil, nil, AudioSourceFilter as IBaseFilter,
        nil, multiplexer as IBaseFilter);
    end;
  end;
  CaptureGraph.Play;
  StopButton.Enabled := true;
  StartButton.Enabled := false;
  AudioFormats.Enabled := false;
  AudioCapFilters.Enabled := false;
  VideoFormats.Enabled := false;
  VideoCapFilters.Enabled := false;
  Timer.Enabled := true;
end;

// Select the Ouput file
procedure TMainForm.CapFileButtonClick(Sender: TObject);
begin
  if SaveDialog.Execute then
  begin
    CapFile := SaveDialog.FileName;
    OutPutFileName.Caption := 'c:\capture.avi';
  end;
end;

// Stop Capture
procedure TMainForm.StopButtonClick(Sender: TObject);
begin
  Timer.Enabled := false;
  StopButton.Enabled := false;
  StartButton.Enabled := true;
  CaptureGraph.Stop;
  CaptureGraph.Active := False;
  AudioFormats.Enabled := true;
  AudioCapFilters.Enabled := true;
  VideoFormats.Enabled := true;
  VideoCapFilters.Enabled := true;

end;

// Timer
procedure TMainForm.TimerTimer(Sender: TObject);
var
  position: int64;
  Hour, Min, Sec, MSec: Word;
const MiliSecInOneDay = 86400000;
begin
  if CaptureGraph.Active then
  begin
    with CaptureGraph as IMediaSeeking do
      GetCurrentPosition(position);
    DecodeTime(position div 10000 / MiliSecInOneDay, Hour, Min, Sec, MSec);
    StatusBar.SimpleText := Format('%d:%d:%d:%d',[Hour, Min, Sec, MSec]);
  end;

end;


end.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
The purpose of this video is to demonstrate how to set up the WordPress backend so that each page automatically generates a Mailchimp signup form in the sidebar. This will be demonstrated using a Windows 8 PC. Tools Used are Photoshop, Awesome…
Delivering innovative fully-managed cloud services for mission-critical applications requires expertise in multiple areas plus vision and commitment. Meet a few of the people behind the quality services of Concerto.

930 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now