📄 jvavicapture.pas
字号:
{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is: JvAVICapture.PAS, released 2003-07-05.
The Initial Developer of the Original Code is Olivier Sannier <obones att altern dott org>
Portions created by Olivier Sannier are Copyright (C) 2003 Olivier Sannier.
All Rights Reserved.
Contributor(s): none to date
Current Version: 0.4
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
located at http://jvcl.sourceforge.net
Description: This unit defines a component that you can drop on any form or
frame and that will display the video stream captured by a video
device installed under Windows. You can perform live previews,
record movies (and save them to avi files) or even capture
single frames. A direct access is provided to the frames so that
you can process them if you want. This is an encapsulation of the
AVICap API from Win32.
Known Issues: none known
-----------------------------------------------------------------------------}
// $Id: JvAVICapture.pas,v 1.27 2005/02/17 10:19:58 marquardt Exp $
unit JvAVICapture;
{$I jvcl.inc}
{$I windowsonly.inc}
interface
uses
{$IFDEF UNITVERSIONING}
JclUnitVersioning,
{$ENDIF UNITVERSIONING}
Windows, Messages, VFW, MMSystem, SysUtils, Classes, Graphics, Controls,
JvTypes;
type
TJvScrollPos = class(TPersistent)
protected
FLeft: Integer;
FTop: Integer;
published
property Left: Integer read FLeft write FLeft;
property Top: Integer read FTop write FTop;
end;
// The video format used by the video device
TJvVideoFormat = class(TPersistent)
protected
FHWnd: HWND; // the AVICap window using this format
FWidth: Cardinal; // width of the image
FHeight: Cardinal; // height of the image
FBitDepth: Cardinal; // bits per pixel (8-16-24-32...)
FPixelFormat: TPixelFormat; // pixel format (RGB, BGR, YUV...)
FCompression: Integer; // compression used
public
constructor Create; // Create the video format
procedure Update; // Update from the AVICap window
property Width: Cardinal read FWidth;
property Height: Cardinal read FHeight;
property BitDepth: Cardinal read FBitDepth;
property PixelFormat: TPixelFormat read FPixelFormat;
property Compression: Integer read FCompression;
end;
// The audio format used by the device
TJvAudioFormat = class(TPersistent)
protected
FHWnd: HWND; // the AVICap window using this format
FFormatTag: Cardinal; // the format tag (PCM or others...)
FChannels: Cardinal; // number of channels (usually 1 or 2)
FSamplesPerSec: Cardinal; // number of samples per second in the stream
FAvgBytesPerSec: Cardinal; // the average number of bytes per second
FBlockAlign: Cardinal; // size of the block to align on
FBitsPerSample: Cardinal; // number of bits per sample
FExtraSize: Cardinal; // size of the extra data
FExtra: Pointer; // extra data for formats other than PCM
public
// creates the audio format object and initializes it
constructor Create;
// updates from the AVICap window
procedure Update;
// apply the format to the window, returns True if successfull
function Apply: Boolean;
// fill in a PWaveFormatEx structure to use with API calls
procedure FillWaveFormatEx(var wfex: PWaveFormatEx);
// run-time only property, see FSize
property ExtraSize: Cardinal read FExtraSize write FExtraSize;
// run-time only property, see FExtra
property Extra: Pointer read FExtra write FExtra;
published
// see the relevant fields for details on the following properties
property FormatTag: Cardinal read FFormatTag write FFormatTag;
property Channels: Cardinal read FChannels write FChannels;
property SamplesPerSec: Cardinal read FSamplesPerSec write FSamplesPerSec;
property AvgBytesPerSec: Cardinal read FAvgBytesPerSec write FAvgBytesPerSec;
property BlockAlign: Cardinal read FBlockAlign write FBlockAlign;
property BitsPerSample: Cardinal read FBitsPerSample write FBitsPerSample;
end;
// a percentage
TJvPercent = 0..100;
// the number of audio buffers to use (maximum 10)
TJvNumAudioBuffer = 0..10;
// the type of a virtual key
TJvVirtualKey = type Integer;
// the capture settings to use to save a video stream to an AVI file
TJvCaptureSettings = class(TPersistent)
protected
// the AVICap window that will use these settings and from which
// we will get the values when we update them
FHWnd: HWND;
// if True, the API will popup a confirmation window when starting the
// capture session allowing the user to choose to continue or not.
FConfirmCapture: Boolean;
// the delay in microsecond between two frames. This is a requested
// value, it may not be fully respected by the driver when capturing
FFrameDelay: Cardinal;
// the percentage of frames dropped above which the capture will end
// in an error state (too many drops having occured)
FPercentDropForError: TJvPercent;
// if True the capture session will be launched in a separate background
// thread, not disabling the caller. Reentrance issues must then be
// considered to avoid the user to launch twice the capture, for instance
FYield: Boolean;
// the requested number of video buffers. The actual number of allocated
// buffers may well be smaller because of hardware limitations
FNumVideoBuffer: Cardinal;
// the requested number of audio buffers. The actual number of allocated
// buffers may well be smaller because of hardware limitations
FNumAudioBuffer: TJvNumAudioBuffer;
// if True, the audio stream will also be captured
FCaptureAudio: Boolean;
// if True, a left mouse click will stop the capture session
FAbortLeftMouse: Boolean;
// if True, a right mouse click will stop the capture session
FAbortRightMouse: Boolean;
// if different from 0, a press on that virtual key will stop the
// capture session
FKeyAbort: TJvVirtualKey;
// if True, the FTimeLimit parameter will be considered
FLimitEnabled: Boolean;
// the time limit for the capture session (in seconds). Will only be
// considered if FLimitEnabled is True
FTimeLimit: Cardinal;
// if True, the capture will occur at twice the size specified in the
// other parameters of this class.
FStepCapture2x: Boolean;
// the number of frames to sample and make the average of when using
// a step capture
FStepCaptureAverageFrames: Cardinal;
// the size of an audio buffer
FAudioBufferSize: Cardinal;
// if True, the audio stream is the master one with respect to time
// alignment. if False, the video stream is the master (recommanded)
FAudioMaster: Boolean;
// if True, the capture will controll a MCI device as its source
FMCIControl: Boolean;
// if True, the step capture is enabled on the MCI device
// this is only considered if FMCIControl is True
FMCIStep: Boolean;
// time of the MCI device to start capture at
// this is only considered if FMCIControl is True
FMCIStartTime: Cardinal;
// time of the MCI device to stop capture at
// this is only considered if FMCIControl is True
FMCIStopTime: Cardinal;
// sets the FKeyAbort field
procedure SetKeyAbort(nKeyAbort: TJvVirtualKey);
// get and set the FPS property
function GetFPS: Double;
procedure SetFPS(const Value: Double);
// set the FrameDelay property, ensuring the value is always
// greater than 0
procedure SetFrameDelay(const Value: Cardinal);
public
// creates and initializes the class
constructor Create;
// updates the class fields from the AVICap window
procedure Update;
// applies the class fields to the AVICap window, returns True if successful
function Apply: Boolean;
published
// (rom) default values would be a good idea
// please refer to the relevant field declarations for detail on the following properties
property ConfirmCapture: Boolean read FConfirmCapture write FConfirmCapture;
property FrameDelay: Cardinal read FFrameDelay write SetFrameDelay;
property FPS: Double read GetFPS write SetFPS;
property PercentDropForError: TJvPercent read FPercentDropForError write FPercentDropForError;
property Yield: Boolean read FYield write FYield;
property NumVideoBuffer: Cardinal read FNumVideoBuffer write FNumVideoBuffer;
property NumAudioBuffer: TJvNumAudioBuffer read FNumAudioBuffer write FNumAudioBuffer;
property CaptureAudio: Boolean read FCaptureAudio write FCaptureAudio;
property AbortLeftMouse: Boolean read FAbortLeftMouse write FAbortLeftMouse;
property AbortRightMouse: Boolean read FAbortRightMouse write FAbortRightMouse;
property KeyAbort: TJvVirtualKey read FKeyAbort write SetKeyAbort;
property LimitEnabled: Boolean read FLimitEnabled write FLimitEnabled;
property TimeLimit: Cardinal read FTimeLimit write FTimeLimit;
property StepCapture2x: Boolean read FStepCapture2x write FStepCapture2x;
property StepCaptureAverageFrames: Cardinal read FStepCaptureAverageFrames write FStepCaptureAverageFrames;
property AudioBufferSize: Cardinal read FAudioBufferSize write FAudioBufferSize;
property AudioMaster: Boolean read FAudioMaster write FAudioMaster;
property MCIControl: Boolean read FMCIControl write FMCIControl;
property MCIStep: Boolean read FMCIStep write FMCIStep;
property MCIStartTime: Cardinal read FMCIStartTime write FMCIStartTime;
property MCIStopTime: Cardinal read FMCIStopTime write FMCIStopTime;
end;
// the type for the number of colors a palette can have
TJvPaletteNbColors = 0..256;
TJvPalette = class(TPersistent)
protected
FHWnd: HWND; // the AVICap window that will use these settings
public
// create the object
constructor Create;
// save the palette associated with the driver into the given file
// and returns True upon success.
function Save(FileName: string): Boolean;
// loads the palette from the given file and returns True upon success
// FHWnd must not be null
function Load(FileName: string): Boolean;
// paste the palette from the clipboard
function PasteFromClipboard: Boolean;
// automatically create the best palette from the first nbFrames frames with
// a maximum of nbColors colors
function AutoCreate(nbFrames: Integer; nbColors: TJvPaletteNbColors): Boolean;
// Use this call from a frame callback and set the Flag to True to indicate that
// the current frame must be considered when creating the palette. Continue
// calling this method with Flag set to True as long as you need it.
// Then call it again with Flag set to False, to finalize the palette and pass
// it to the capture driver that will now use it.
function ManuallyCreate(Flag: Boolean; nbColors: TJvPaletteNbColors): Boolean;
end;
// the driver index (-1 if not connected, 0-9 if connected as there are at most 10 drivers
// according to Microsoft documentation. But there can be more than 1 source per driver...
TJvDriverIndex = -1..9;
// The exception triggered when an invalid index driver index is given
EInvalidDriverIndexError = class(EJVCLException)
public
constructor Create(Index: TJvDriverIndex; MaxIndex: TJvDriverIndex);
end;
// what a driver can do on the system
TJvDriverCaps = set of
(dcOverlay, // overlay rendering
dcDlgVideoSource, // display a dialog to choose video source
dcDlgVideoFormat, // display a dialog to choose video format
dcDlgVideoDisplay, // display a dialog to choose video display
dcCaptureInitialized, // is the capture initialized
dcSuppliesPalettes); // if the driver supplies palettes
TJvUsedEvents = set of
(ueCapControl, // the OnCapControl event will be triggered
ueError, // the OnError event will be triggered
ueFrame, // the OnFrame event will be triggered
ueStatus, // the OnStatus event will be triggered
ueVideoStream, // the OnVideoStream event will be triggered
ueWaveStream, // the OnWaveStream event will be triggered
ueYield); // the OnYield event will be triggered
// the video dialog to display
TJvVideoDialog =
(vdSource, // the source dialog (only if dcDlgVideoSource is in the caps)
vdFormat, // the format dialog (only if dcDlgVideoFormat is in the caps)
vdDisplay, // the display dialog (only if dcDlgVideoDisplay is in the caps)
vdCompression); // the compression dialog (with all the installed video codecs)
// local type for the events
PJvVideoHdr = PVIDEOHDR;
PJvWaveHdr = PWaveHdr;
// forward declaration for the events
TJvAVICapture = class;
// the event triggered in case of an error
// Sender is the TJvAVICapture component triggering the event
// nErr is the error number
// Str is the string associated with that error
TOnError = procedure(Sender: TJvAVICapture; nErr: Integer; Str: string) of object;
// the event triggered in case of a status change (use it to follow progress)
// Sender is the TJvAVICapture component triggering the event
// nId is the id of the status change (see win32 API for more details)
// Str is the string associated with that status change
TOnStatus = procedure(Sender: TJvAVICapture; nId: Integer; Str: string) of object;
// the event triggerred when the driver is yielding. a good place to put a
// call to Application.ProcessMessages
// Sender is the TJvAVICapture component triggering the event
TOnYield = procedure(Sender: TJvAVICapture) of object;
// the event trigerred when a frame is ready to be written to disk during streaming capture
// Sender is the TJvAVICapture component triggering the event
// videoHdr is the video header describing the stream
TOnVideoStream = procedure(Sender: TJvAVICapture; videoHdr: PJvVideoHdr) of object;
// the event trigerred when a frame is ready, in a non streaming capture session
TOnFrame = TOnVideoStream;
// the event trigerred when an audio buffer is ready to be written do disk during streaming capture
// Sender is the TJvAVICapture component triggering the event
// audioHdr is the audio header describing the stream
TOnWaveStream = procedure(Sender: TJvAVICapture; waveHdr: PJvWaveHdr) of object;
// the event triggered when you want to use precise capture control
// Sender is the TJvAVICapture component triggering the event
// state is the state in which the capture is (refer to API for details)
// Result is to be set to True if capture must continue, False if it must stop
TOnCapControl = procedure(Sender: TJvAVICapture; nState: Integer; var Result: Boolean) of object;
// the main component. Just drop it on a form or a frame, set the driver property, set previewing to
// True and you should see the video coming through (even in design mode !)
TJvAVICapture = class(TWinControl)
protected
FCaptureSettings: TJvCaptureSettings; // the capture settings
FCapturing: Boolean; // True if capture is happening
FConnected: Boolean; // True if connected to a driver
FDrivers: TStringList; // the available drivers as a TStringList
FDriverCaps: TJvDriverCaps; // the current driver capabilities
FHWnd: HWND; // the handle to the AviCap window
FNoFile: Boolean; // True if not capturing to a file
FOverlaying: Boolean; // True if using overlay display
FPreviewFrameDelay: Cardinal; // the time between two preview frames (ms)
FPreviewing: Boolean; // True if previewing
FSingleFrameCapturing: Boolean; // True if capturing using single frame capture
FTitle: string; // the title of the AVICap window
FVideoLeft: Integer; // the left coordinate of the displayed video
FVideoTop: Integer; // the top coordinate of the displayed video
// the user supplied event handlers
// see respective types for details
FOnError: TOnError;
FOnStatus: TOnStatus;
FOnYield: TOnYield;
FOnFrame: TOnFrame;
FOnVideoStream: TOnVideoStream;
FOnWaveStream: TOnWaveStream;
FOnCapControl: TOnCapControl;
FFileName: string; // the filename for the capture file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -