[Ansatz gelöst] Video- und Audio-Capturing in File

  • VB.NET

Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von Radium.

    [Ansatz gelöst] Video- und Audio-Capturing in File

    Also, ich beschäftige mich jetzt schon einige Wochen mit DirectShow. Ich kann zwar mittlerweile auf verschiedenste Weisen mein VideoCaptureDevice einbinden und sowohl ein Videofile speichern mit gleichzeitiger Preview anzeigen lassen. Aber dabei kann ich weder berücksichtigen, dass von der Audioquelle mit aufgezeichnet wird, noch dass ich das Video in MPEG2 abgespeichert wird. Ich weiß nur, dass ich eine Filterkette erstellen muss.
    Ich dachte, dass ich da bei GraphEdit vielleicht ein Codebeispiel bekomme, wie genau das geht. Immerhin kann ich da Filterketten testen und mir die ClassID etc. anzeigen lassen um diese dann entsprechend einbinden zu können. Eigentlich finde ich das DirectShowLib-2005.dll inklusive Samples ganz hilfreich. Aber ich habe das Gefühl, dass ich damit bei meinem Video/Audio-Projekt nicht mehr weiterkomme. Ich weiß nur, dass es ohne Filterkette nicht geht. Aber Infos dazu sind recht spärlich und verwirrend.


    Hier mal der Quelltext mit dem Anfang der Filterkette:

    VB.NET-Quellcode

    1. Imports System.Drawing
    2. Imports System.Collections
    3. Imports System.ComponentModel
    4. Imports System.Windows.Forms
    5. Imports System.Data
    6. Imports System.Runtime.InteropServices
    7. Imports System.Diagnostics
    8. Imports DirectShowLib
    9. Public Class Form1
    10. Implements ISampleGrabberCB
    11. Implements IDisposable
    12. Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    13. Dim hr As Integer
    14. Dim m_graphBuilder As IFilterGraph2 = Nothing
    15. Dim m_mediaCtrl As IMediaControl = Nothing
    16. Dim m_videoWindow As IVideoWindow = Nothing
    17. Dim m_videoWidth As Integer = Panel1.Width
    18. Dim m_videoHeight As Integer = Panel1.Height
    19. Dim AllVideoInputDevices As DsDevice() = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice)
    20. Dim VideoInput As DsDevice = AllVideoInputDevices(0)
    21. Dim capFilter As IBaseFilter = Nothing
    22. Dim capGraph As ICaptureGraphBuilder2 = Nothing
    23. m_graphBuilder = DirectCast(New FilterGraph(), IFilterGraph2)
    24. m_mediaCtrl = DirectCast(m_graphBuilder, IMediaControl)
    25. capGraph = DirectCast(New CaptureGraphBuilder2(), ICaptureGraphBuilder2)
    26. m_videoWindow = DirectCast(m_graphBuilder, IVideoWindow)
    27. hr = capGraph.SetFiltergraph(DirectCast(m_graphBuilder, IGraphBuilder))
    28. hr = m_graphBuilder.AddSourceFilterForMoniker(VideoInput.Mon, Nothing, VideoInput.Name, capFilter)
    29. ' Microsoft MPEG2 Encoder-Filter erstellen
    30. Dim MPEG2EncoderGuid As Guid = New Guid("5F5AFF4A-2F7F-4279-88C2-CD88EB39D144")
    31. Dim t As Type = Type.GetTypeFromCLSID(MPEG2EncoderGuid)
    32. Dim encoder As IBaseFilter = DirectCast(Activator.CreateInstance(t), IBaseFilter)
    33. Dim encoderIn1 As IPin = Nothing
    34. Dim encoderIn2 As IPin = Nothing
    35. Dim encoderOut As IPin = Nothing
    36. hr = encoder.FindPin("In", encoderIn1)
    37. hr = encoder.FindPin("In", encoderIn2)
    38. hr = encoder.FindPin("Out", encoderOut)
    39. hr = m_graphBuilder.AddFilter(encoder, "Microsoft MPEG-2 Encoder")
    40. ' File Writer erstellen
    41. Dim pinInfo As PinInfo = Nothing
    42. Dim fetched As Integer = 0
    43. Dim fileWriterIn As IPin = Nothing
    44. Dim pin As IPin = Nothing
    45. Dim pins As IEnumPins = Nothing
    46. Dim FileWriterGuid As Guid = New Guid("8596E5F0-0DA5-11D0-BD21-00A0C911CE86")
    47. t = Type.GetTypeFromCLSID(FileWriterGuid)
    48. Dim fileWriter As IBaseFilter = DirectCast(Activator.CreateInstance(t), IBaseFilter)
    49. Dim sink As IFileSinkFilter = DirectCast(fileWriter, IFileSinkFilter)
    50. Dim MT As AMMediaType = New AMMediaType()
    51. MT.majorType = MediaType.Stream
    52. MT.subType = MediaSubType.RGB24
    53. MT.formatType = FormatType.MpegStreams
    54. sink.SetFileName("D:\newTest.mpg", MT)
    55. hr = m_graphBuilder.AddFilter(fileWriter, "File Writer")
    56. fileWriter.EnumPins(pins)
    57. pins.Next(1, fileWriterIn, fetched)
    58. ' Hole Video Capture Out
    59. Dim videoCaptureOut As IPin = Nothing
    60. While (fetched > 0)
    61. pins.Next(1, pin, fetched)
    62. If (fetched > 0) Then
    63. pin.QueryPinInfo(pinInfo)
    64. If pinInfo.dir = PinDirection.Output Then
    65. videoCaptureOut = pin
    66. End If
    67. End If
    68. End While
    69. ' Verbinde die Filterkette
    70. m_graphBuilder.Connect(videoCaptureOut, encoderIn1)
    71. m_graphBuilder.Connect(encoderOut, fileWriterIn)
    72. hr = capGraph.RenderStream(PinCategory.Preview, MediaType.Video, capFilter, Nothing, Nothing)
    73. If hr > 0 Then MsgBox(hr.ToString)
    74. ' VideoWindow initialisieren
    75. hr = m_videoWindow.put_Top(0)
    76. hr = m_videoWindow.put_Left(0)
    77. hr = m_videoWindow.put_Width(m_videoWidth)
    78. hr = m_videoWindow.put_Height(m_videoHeight)
    79. hr = m_videoWindow.put_WindowStyle(WindowStyle.Visible)
    80. hr = m_videoWindow.put_Owner(Panel1.Handle)
    81. m_mediaCtrl.Run()
    82. End Sub
    83. Public Function BufferCB(ByVal SampleTime As Double, ByVal pBuffer As System.IntPtr, ByVal BufferLen As Integer) As Integer Implements DirectShowLib.ISampleGrabberCB.BufferCB
    84. End Function
    85. Public Function SampleCB(ByVal SampleTime As Double, ByVal pSample As DirectShowLib.IMediaSample) As Integer Implements DirectShowLib.ISampleGrabberCB.SampleCB
    86. End Function
    87. End Class


    Ich hoffe, dass ich jetzt niemanden überfordere ;(
    Gibt es vielleicht bezüglich DirectShow eine verständlichere Documentation als das MSDN oder vielleicht gute Lektüre?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Radium“ ()

    Ok, ich hab ein anderes Programm gefunden, mit dem FilterGraphen getestet und entsprechend der SourceCode ausgegeben werden kann. Den gibt es zwar nur in C#/C++ aber dank Convert C# to VB.Net läßt sich das schnell beheben.

    Der GraphEditor nennt sich übrigens GraphEditPlus und ist als Freeversion eingeschränkt im Kopieren des Quellcodes. Man muß also abtippen. Aber das ist auch nicht schlimm, immerhin geht mir mehr um die Funktionsweise, wie so ein Filtergraph erstellt, verbunden und lauffähig gemacht wird.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Radium“ ()