' Questa funzione avvia il flusso video su un handle di finestra.
' I parametri 2 e 3 permettono di definire da dove acquisisire e cosa
Public Sub StartVideoOnHandle(ByRef __dstHandle As System.IntPtr, ByVal MediaT As DsGuid, Optional ByVal MustSaveAs Boolean = False, Optional ByVal FilePath As String = Nothing, Optional byval showPreview as boolean=true)
Dim ErrH As Integer
If Me.IsDisposed Then
Throw New Exception("Questo oggetto è stato eliminato. E' necessario istanziare un nuovo oggetto.")
End If
If Not IsRender Then
' Qui controlla se è stato effettuato il flush su disco. In caso positivo inizia a scrivere da ZERO il file
' quindi se si esegue il flush è opportuno rinominare il file già acquisito pena la sovrascrittura.
If IsFlushed Then
IsFlushed = False
MyMediaControl.Run()
Exit Sub
End If
' Deve anche salvare il flusso?
If MustSave Then
' Avvia l'acquisizione -> notare il mediasubtype e il PIN specificati
ErrH = MyCaptureGraphBuilder.SetOutputFileName(MediaSubType.Avi, FilePath, pMux, Nothing)
DsError.ThrowExceptionForHR(ErrH)
ErrH = MyCaptureGraphBuilder.RenderStream(PinCategory.Capture, MediaT, MyHardware, Nothing, pMux)
DsError.ThrowExceptionForHR(ErrH)
End If
' Prepara il flusso di preview
ErrH = MyCaptureGraphBuilder.RenderStream(PinCategory.Preview, MediaT, MyHardware, Nothing, Nothing)
DsError.ThrowExceptionForHR(ErrH)
ErrH = MyMediaControl.Run()
DsError.ThrowExceptionForHR(ErrH)
' Controlla se mostrare o meno la finestra di preview.
If Not ShowPreview Then 'la nasconde
ErrH = MyWinDevice.put_AutoShow(OABool.False)
DsError.ThrowExceptionForHR(ErrH)
ErrH = MyWinDevice.put_Visible(OABool.False)
DsError.ThrowExceptionForHR(ErrH)
Else 'invia il preview sull'handle passato in argomento
' Manda il flusso sul __dstHandle e si salva il riferimento x usi successivi
ErrH = MyWinDevice.put_Owner(__dstHandle)
__currentVideoHandler = __dstHandle
DsError.ThrowExceptionForHR(ErrH)
ErrH = MyWinDevice.put_WindowStyle(WindowStyle.Child Or WindowStyle.ClipChildren)
DsError.ThrowExceptionForHR(ErrH)
ErrH = MyWinDevice.put_Visible(OABool.True)
DsError.ThrowExceptionForHR(ErrH)
End If
Marshal.ReleaseComObject(MyHardware)
IsRender = True
Else ' se il grafo è in pausa lo riavvia soltanto
MyMediaControl.Run()
End If
La scrittura su disco avviene quando il grafo viene fermato ovvero quando si richiama MyMediaControl.Stop
Ridefiniamo quindi la funzione StopVideo aggiungendo un parametro che permetta di specificare se vogliamo
scrivere su disco oppure bloccare temporaneamente l'acquisizione
Public Sub StopVideo(Optional ByVal Flush As Boolean = False)
If Me.IsDisposed Then
Throw New Exception("Questo oggetto è stato eliminato. E' necessario istanziare un nuovo oggetto.")
End If
Dim errh As Integer
If Not Flush Then ' se non è richiesto il flush viene bloccata l'acquisizione ma ripartirà scrivendo
' sul file senza sovrascriverlo.
errh = MyMediaControl.Pause()
DsError.ThrowExceptionForHR(errh)
Else
errh = MyMediaControl.Stop() ' se effettuiamo il flush quando ripartirà l'acquisizione sovrascriverà il file
DsError.ThrowExceptionForHR(errh)
IsRender = False
IsFlushed = True
End If
End Sub
Una dll per testare queste nuove modifiche è disponibile qui. Purtroppo non l'ho testata a fondo quindi se sono presenti bug (sempre presenti) vi prego di segnalarmeli.