📄 capture.cs
字号:
BitmapInfoHeader bmiHeader;
bmiHeader = (BitmapInfoHeader) getStreamConfigSetting( videoStreamConfig, "BmiHeader" );
bmiHeader.Width = value.Width;
bmiHeader.Height = value.Height;
setStreamConfigSetting( videoStreamConfig, "BmiHeader", bmiHeader );
}
}
/// <summary>
/// Get or set the number of channels in the waveform-audio data.
/// </summary>
/// <remarks>
/// Monaural data uses one channel and stereo data uses two channels.
///
/// <para>
/// Not all devices support getting/setting this property.
/// If this property is not supported, accessing it will
/// throw and exception. </para>
///
/// <para>
/// This property cannot be changed while capturing. Changing
/// this property while preview is enabled will cause some
/// fickering while the internal filter graph is partially
/// rebuilt. Changing this property while cued will cancel the
/// cue. Call Cue() again to re-cue the capture. </para>
/// </remarks>
public short AudioChannels
{
get
{
short audioChannels = (short) getStreamConfigSetting( audioStreamConfig, "nChannels" );
return( audioChannels );
}
set
{
setStreamConfigSetting( audioStreamConfig, "nChannels", value );
}
}
/// <summary>
/// Get or set the number of audio samples taken per second.
/// </summary>
/// <remarks>
/// Common sampling rates are 8.0 kHz, 11.025 kHz, 22.05 kHz, and
/// 44.1 kHz. Not all sampling rates are supported.
///
/// <para>
/// Not all devices support getting/setting this property.
/// If this property is not supported, accessing it will
/// throw and exception. </para>
///
/// <para>
/// This property cannot be changed while capturing. Changing
/// this property while preview is enabled will cause some
/// fickering while the internal filter graph is partially
/// rebuilt. Changing this property while cued will cancel the
/// cue. Call Cue() again to re-cue the capture. </para>
/// </remarks>
public int AudioSamplingRate
{
get
{
int samplingRate = (int) getStreamConfigSetting( audioStreamConfig, "nSamplesPerSec" );
return( samplingRate );
}
set
{
setStreamConfigSetting( audioStreamConfig, "nSamplesPerSec", value );
}
}
/// <summary>
/// Get or set the number of bits recorded per sample.
/// </summary>
/// <remarks>
/// Common sample sizes are 8 bit and 16 bit. Not all
/// samples sizes are supported.
///
/// <para>
/// Not all devices support getting/setting this property.
/// If this property is not supported, accessing it will
/// throw and exception. </para>
///
/// <para>
/// This property cannot be changed while capturing. Changing
/// this property while preview is enabled will cause some
/// fickering while the internal filter graph is partially
/// rebuilt. Changing this property while cued will cancel the
/// cue. Call Cue() again to re-cue the capture. </para>
/// </remarks>
public short AudioSampleSize
{
get
{
short sampleSize = (short) getStreamConfigSetting( audioStreamConfig, "wBitsPerSample" );
return( sampleSize );
}
set
{
setStreamConfigSetting( audioStreamConfig, "wBitsPerSample", value );
}
}
/// <summary>
/// Necesario para poder hacer una identificaci髇 cuando se lance el evento CaptureFrameCompleted
/// </summary>
/*public int Id
{
get
{
return id;
}
set
{
id = value;
}
}*/
// --------------------- Events ----------------------
/// <summary> Fired when a capture is completed (manually or automatically). </summary>
public event EventHandler CaptureComplete;
/// <summary> Fired when a frame was captured. </summary>
public delegate void FrameCapHandler(System.Windows.Forms.PictureBox Frame);
//public static event FrameCapHandler FrameCaptureComplete;
public event FrameCapHandler FrameCaptureComplete;
// ------------- Protected/private Properties --------------
protected GraphState graphState = GraphState.Null; // State of the internal filter graph
protected bool isPreviewRendered = false; // When graphState==Rendered, have we rendered the preview stream?
protected bool isCaptureRendered = false; // When graphState==Rendered, have we rendered the capture stream?
protected bool wantPreviewRendered = false; // Do we need the preview stream rendered (VideoDevice and PreviewWindow != null)
protected bool wantCaptureRendered = false; // Do we need the capture stream rendered
protected bool wantCaptureFrame = false;
protected int rotCookie = 0; // Cookie into the Running Object Table
protected Filter videoDevice = null; // Property Backer: Video capture device filter
protected Filter audioDevice = null; // Property Backer: Audio capture device filter
protected Filter videoCompressor = null; // Property Backer: Video compression filter
protected Filter audioCompressor = null; // Property Backer: Audio compression filter
protected string filename = ""; // Property Backer: Name of file to capture to
protected Control previewWindow = null; // Property Backer: Owner control for preview
protected VideoCapabilities videoCaps = null; // Property Backer: capabilities of video device
protected AudioCapabilities audioCaps = null; // Property Backer: capabilities of audio device
protected SourceCollection videoSources = null; // Property Backer: list of physical video sources
protected SourceCollection audioSources = null; // Property Backer: list of physical audio sources
protected PropertyPageCollection propertyPages = null; // Property Backer: list of property pages exposed by filters
protected Tuner tuner = null; // Property Backer: TV Tuner
protected IGraphBuilder graphBuilder; // DShow Filter: Graph builder
protected IMediaControl mediaControl; // DShow Filter: Start/Stop the filter graph -> copy of graphBuilder
protected IVideoWindow videoWindow; // DShow Filter: Control preview window -> copy of graphBuilder
protected ICaptureGraphBuilder2 captureGraphBuilder = null; // DShow Filter: building graphs for capturing video
protected ISampleGrabber sampGrabber = null;
protected IAMStreamConfig videoStreamConfig = null; // DShow Filter: configure frame rate, size
protected IAMStreamConfig audioStreamConfig = null; // DShow Filter: configure sample rate, sample size
protected IBaseFilter videoDeviceFilter = null; // DShow Filter: selected video device
protected IBaseFilter videoCompressorFilter = null; // DShow Filter: selected video compressor
protected IBaseFilter audioDeviceFilter = null; // DShow Filter: selected audio device
protected IBaseFilter audioCompressorFilter = null; // DShow Filter: selected audio compressor
protected IBaseFilter muxFilter = null; // DShow Filter: multiplexor (combine video and audio streams)
protected IBaseFilter baseGrabFlt = null;
protected IFileSinkFilter fileWriterFilter = null; // DShow Filter: file writer
protected VideoInfoHeader videoInfoHeader;
protected byte[] savedArray;
protected bool capturedFrame = false;
protected int bufferedSize;
protected bool captured = true;
protected bool firstFrame = true;
protected bool renderStream = false;
//protected int id; //Almacena un n鷐ero que identifica a la c醡ara
//protected CTee InfTee;
/// <summary> event when callback has finished (ISampleGrabberCB.BufferCB). </summary>
private delegate void CaptureDone();
private const int WM_GRAPHNOTIFY = 0x00008001; // message from graph
private IMediaEventEx mediaEvt; // event interface
protected System.Windows.Forms.PictureBox ImageCaptured;
// ------------- Constructors/Destructors --------------
/// <summary>
/// Create a new Capture object.
/// videoDevice and audioDevice can be null if you do not
/// wish to capture both audio and video. However at least
/// one must be a valid device. Use the <see cref="Filters"/>
/// class to list available devices.
/// </summary>
public Capture(Filter videoDevice, Filter audioDevice)
{
if ( videoDevice == null && audioDevice == null)
throw new ArgumentException( "The videoDevice and/or the audioDevice parameter must be set to a valid Filter.\n" );
this.videoDevice = videoDevice;
this.audioDevice = audioDevice;
this.Filename = getTempFilename();
this.ImageCaptured = new System.Windows.Forms.PictureBox();
createGraph();
}
/// <summary> Destructor. Dispose of resources. </summary>
~Capture()
{
Dispose();
}
// --------------------- Public Methods -----------------------
/// <summary>
/// Prepare for capturing. Use this method when capturing
/// must begin as quickly as possible.
/// </summary>
/// <remarks>
/// This will create/overwrite a zero byte file with
/// the name set in the Filename property.
///
/// <para>
/// This will disable preview. Preview will resume
/// once capture begins. This problem can be fixed
/// if someone is willing to make the change. </para>
///
/// <para>
/// This method is optional. If Cue() is not called,
/// Start() will call it before capturing. This method
/// cannot be called while capturing. </para>
/// </remarks>
public void Cue()
{
assertStopped();
// We want the capture stream rendered
wantCaptureRendered = true;
// Re-render the graph (if necessary)
renderGraph();
// Pause the graph
int hr = mediaControl.Pause();
//if ( hr != 0 ) Marshal.ThrowExceptionForHR( hr );
}
/// <summary> Begin capturing. </summary>
public void Start()
{
Stop();
// Para que cuando estemos capturando un video podamos capturar frames
firstFrame = false;
assertStopped();
// We want the capture stream rendered
wantCaptureRendered = true;
// Re-render the graph (if necessary)
renderStream = true;
renderGraph();
// Start the filter graph: begin capturing
int hr = mediaControl.Run();
//if ( hr != 0 ) Marshal.ThrowExceptionForHR( hr );
// Update the state
graphState = GraphState.Capturing;
}
/// <summary>
/// Stop the current capture capture. If there is no
/// current capture, this method will succeed.
/// </summary>
public void Stop()
{
// Stop the graph if it is running
// If we have a preview running we should only stop the
// capture stream. However, if we have a preview stream
// we need to re-render the graph anyways because we
// need to get rid of the capture stream. To re-render
// we need to stop the entire graph
if ( mediaControl != null )
{
mediaControl.Stop();
}
// Config is true when the parametres of the device are to be changed
wantCaptureRendered = false;
wantPreviewRendered = true;
// Update the state
if ( graphState == GraphState.Capturing )
{
graphState = GraphState.Rendered;
if ( CaptureComplete != null )
CaptureComplete( this, null );
}
// Para que cuando volvamos a capturar frames no haya problemas
firstFrame = true;
// So we destroy the capture stream IF
// we need a preview stream. If we don't
// this will leave the graph as it is.
renderStream = false;
try { renderGraph(); }
catch {}
try { startPreviewIfNeeded(); }
catch {}
}
/// <summary>
/// Calls Stop, releases all references. If a capture is in progress
/// it will be stopped, but the CaptureComplete event will NOT fire.
/// </summary>
public void DisposeCapture()
{
wantPreviewRendered = false;
wantCaptureRendered = false;
CaptureComplete = null;
try { destroyGraph(); }
catch {}
if ( videoSources != null )
videoSources.Dispose(); videoSources = null;
if ( audioSources != null )
audioSources.Dispose(); audioSources = null;
}
[STAThread]
public void CaptureFrame()
{
int hr;
if(firstFrame)
{
assertStopped();
// Re-render the graph (if necessary)
renderStream = true;
renderGraph();
// Start the filter graph: begin capturing
hr = mediaControl.Run();
//if ( hr != 0 ) Marshal.ThrowExceptionForHR( hr );
firstFrame = false;
}
captured = false;
if(savedArray == null )
{
int size = videoInfoHeader.BmiHeader.ImageSize;
if( (size<1000) || (size > 16000000) )
return;
savedArray = new byte[ size + 64000];
}
hr = sampGrabber.SetCallback( this, 1 );
}
/// <summary>
/// Esta funci髇 har
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -