C# 如何使用DirectShow NET捕获音频和视频?

C# 如何使用DirectShow NET捕获音频和视频?,c#,directshow.net,C#,Directshow.net,我正在努力学习C#net。因为我已经知道了OO PHP一些java和C++(我从来没有真正使用过因为手动内存处理) 我想我会从一些有用的东西开始,而不是另一本充满人为问题的书。我在考虑简单的房屋监控。 我用谷歌搜索并抓取。 编译它当然我在win7 64b上。 编译后的CaptureWMV示例,看一下代码,12个小时以来,我一直试图将音频捕获添加到其中,但当我尝试不使用仅视频编解码器时,它总是崩溃。 我在谷歌上搜索工作示例,但找不到任何示例。(只有音频是的,只有视频是的,但两者都没有) 这是我稍微

我正在努力学习C#net。因为我已经知道了OO PHP一些java和C++(我从来没有真正使用过因为手动内存处理) 我想我会从一些有用的东西开始,而不是另一本充满人为问题的书。我在考虑简单的房屋监控。
我用谷歌搜索并抓取。 编译它当然我在win7 64b上。 编译后的CaptureWMV示例,看一下代码,12个小时以来,我一直试图将音频捕获添加到其中,但当我尝试不使用仅视频编解码器时,它总是崩溃。 我在谷歌上搜索工作示例,但找不到任何示例。(只有音频是的,只有视频是的,但两者都没有) 这是我稍微修改过的代码。我肯定会做一些愚蠢的事情,但如果有人给我指出正确的方向,我会非常高兴

请仔细查看附近的注释代码

(…)addSourceFilterPerformoniker(devAudio.Mon(…)

这是错误的,我知道,但如何做它的权利

using System;
using System.Runtime.InteropServices;
using DirectShowLib;

namespace AsfFilter
{
    internal class Capture: IDisposable
    {
        #region Member variables

        /// <summary> graph builder interface. </summary>
        private IFilterGraph2 m_FilterGraph = null;
        IMediaControl m_mediaCtrl = null;
        /// <summary> Set by async routine when it captures an image </summary>
        private bool m_bRunning = false;
#if DEBUG
        DsROTEntry m_rot = null;
#endif

        #endregion

        /// <summary> release everything. </summary>
        public void Dispose()
        {
            GC.SuppressFinalize(this);
            CloseInterfaces();
        }

        ~Capture()
        {
            Dispose();
        }

        /// <summary>
        /// Create capture object
        /// </summary>
        /// <param name="iDeviceNum">Zero based index of capture device</param>
        /// <param name="szFileName">Output ASF file name</param>
        public Capture(int iDeviceNum, int iAudioNum,string szOutputFileName)
        {
            DsDevice [] capDevices;
            DsDevice [] audioCapDevices;

            // Get the collection of video devices
            capDevices = DsDevice.GetDevicesOfCat( FilterCategory.VideoInputDevice );
            audioCapDevices = DsDevice.GetDevicesOfCat(FilterCategory.AudioInputDevice);
            if (iDeviceNum + 1 > capDevices.Length)
            {
                throw new Exception("No video capture devices found at that index!");
            }
            if (iAudioNum + 1 > audioCapDevices.Length)
            {
                throw new Exception("No audio capture devices found at that index!");
            }
            try
            {
                // Set up the capture graph
                SetupGraph( capDevices[iDeviceNum], audioCapDevices[iDeviceNum], szOutputFileName);
                m_bRunning = false;
            }
            catch
            {
                Dispose();
                throw;
            }
        }

        // Start the capture graph
        public void Start()
        {
            if (!m_bRunning)
            {
                int hr = m_mediaCtrl.Run();
                Marshal.ThrowExceptionForHR( hr );
                m_bRunning = true;
            }
        }

        // Pause the capture graph.
        // Running the graph takes up a lot of resources.  Pause it when it
        // isn't needed.
        public void Pause()
        {
            if (m_bRunning)
            {
                IMediaControl mediaCtrl = m_FilterGraph as IMediaControl;
                int hr = mediaCtrl.Pause();
                Marshal.ThrowExceptionForHR( hr );
                m_bRunning = false;
            }
        }

        /// <summary> build the capture graph. </summary>
        private void SetupGraph(DsDevice dev, DsDevice devAudio, string szOutputFileName)
        {
            int hr;
            IBaseFilter capFilter = null;
            IBaseFilter asfWriter = null;
            IBaseFilter audFilter = null;
            ICaptureGraphBuilder2 capGraph = null;

            // Get the graphbuilder object
            m_FilterGraph = (IFilterGraph2)new FilterGraph();
#if DEBUG
            m_rot = new DsROTEntry( m_FilterGraph );
#endif
            try
            {
                // Get the ICaptureGraphBuilder2
                capGraph = (ICaptureGraphBuilder2) new CaptureGraphBuilder2();

                // Start building the graph
                hr = capGraph.SetFiltergraph( m_FilterGraph );
                Marshal.ThrowExceptionForHR( hr );

                // Add the capture device to the graph
                //hr = m_FilterGraph.AddSourceFilterForMoniker(devAudio.Mon, null, devAudio.Name, out capFilter);
                //Marshal.ThrowExceptionForHR(hr);
                hr = m_FilterGraph.AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out capFilter);
                Marshal.ThrowExceptionForHR( hr );
                asfWriter = ConfigAsf(capGraph, szOutputFileName);
                hr = capGraph.RenderStream(null, null, capFilter, null, asfWriter);
                Marshal.ThrowExceptionForHR( hr );
                m_mediaCtrl = m_FilterGraph as IMediaControl;
            }
            finally
            {
                if (capFilter != null)
                {
                    Marshal.ReleaseComObject(capFilter);
                    capFilter = null;
                }
                if (asfWriter != null)
                {
                    Marshal.ReleaseComObject(asfWriter);
                    asfWriter = null;
                }
                if (capGraph != null)
                {
                    Marshal.ReleaseComObject(capGraph);
                    capGraph = null;
                }
            }
        }

        private IBaseFilter ConfigAsf(ICaptureGraphBuilder2 capGraph, string szOutputFileName)
        {
            IFileSinkFilter pTmpSink = null;
            IBaseFilter asfWriter = null;
            int hr = capGraph.SetOutputFileName( MediaSubType.Asf, szOutputFileName, out asfWriter, out pTmpSink);
            Marshal.ThrowExceptionForHR( hr );

            try
            {
                IConfigAsfWriter lConfig = asfWriter as IConfigAsfWriter;

                // Windows Media Video 8 for Dial-up Modem (No audio, 56 Kbps)
                // READ THE README for info about using guids
                //WMProfile_V80_56VideoOnly
                Guid cat = new Guid(0x6e2a6955, 0x81df, 0x4943, 0xba, 0x50, 0x68, 0xa9, 0x86, 0xa7, 0x8, 0xf6);
                //WMProfile_V80_BESTVBRVideo
                Guid bat = new Guid(0x48439ba, 0x309c, 0x440e, 0x9c, 0xb4, 0x3d, 0xcc, 0xa3, 0x75, 0x64, 0x23);
                //WMProfile_V80_288VideoOnly
                Guid vot = new Guid(0x8c45b4c7, 0x4aeb, 0x4f78, 0xa5, 0xec, 0x88, 0x42, 0xb, 0x9d, 0xad, 0xef);
                //WMProfile_V80_56Video
                Guid vau = new Guid(0x254E8A96, 0x2612, 0x405C, 0x80, 0x39, 0xf0, 0xBF, 0x72, 0x5C, 0xED, 0x7D);
                //WMProfile_V80_288MonoAudio
                Guid aon = new Guid(0x7ea3126d, 0xe1ba, 0x4716, 0x89, 0xaf, 0xf6, 0x5c, 0xee, 0xc, 0xc, 0x67);

                hr = lConfig.ConfigureFilterUsingProfileGuid(cat);
                //hr = lConfig.ConfigureFilterUsingProfileGuid(W288Video);
                Marshal.ThrowExceptionForHR( hr );
            }
            finally
            {
                Marshal.ReleaseComObject(pTmpSink);
            }
            return asfWriter;
        }

        /// <summary> Shut down capture </summary>
        private void CloseInterfaces()
        {
            int hr;

            try
            {
                if( m_mediaCtrl != null )
                {
                    // Stop the graph
                    hr = m_mediaCtrl.Stop();
                    m_bRunning = false;
                }
            }
            catch {}
#if DEBUG
            // Remove graph from the ROT
            if ( m_rot != null )
            {
                m_rot.Dispose();
                m_rot = null;
            }
#endif
            if (m_FilterGraph != null)
            {
                Marshal.ReleaseComObject(m_FilterGraph);
                m_FilterGraph = null;
            }
        }
    }
}
使用系统;
使用System.Runtime.InteropServices;
使用DirectShowLib;
命名空间AsfFilter
{
内部类捕获:IDisposable
{
#区域成员变量
///图形生成器界面。
私有IFilterGraph2 m_FilterGraph=null;
IMediaControl m_mediaCtrl=null;
///由异步例程在捕获图像时设置
private bool m_bRunning=假;
#如果调试
dsroentry m_rot=null;
#恩迪夫
#端区
///释放一切。
公共空间处置()
{
总干事(本);
CloseInterfaces();
}
~Capture()
{
处置();
}
/// 
///创建捕获对象
/// 
///捕获设备的零基索引
///输出ASF文件名
公共捕获(int-iDeviceNum、int-iAudioNum、字符串szOutputFileName)
{
DsDevice[]设备;
DsDevice[]音频设备;
//获取视频设备的集合
capDevices=DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
audioCapDevices=DsDevice.GetDevicesOfCat(FilterCategory.AudioInputDevice);
if(iDeviceNum+1>capDevices.Length)
{
抛出新异常(“在该索引中未找到视频捕获设备!”);
}
if(iAudioNum+1>audioCapDevices.Length)
{
抛出新异常(“在该索引中未找到音频捕获设备!”);
}
尝试
{
//设置捕获图
SetupGraph(capDevices[iDeviceNum]、audioCapDevices[iDeviceNum]、szOutputFileName);
m_bRunning=错误;
}
抓住
{
处置();
投掷;
}
}
//启动捕获图
公开作废开始()
{
如果(!m_bRunning)
{
int hr=m_mediaCtrl.Run();
元帅。通过hr(hr)的例外情况;
m_bRunning=真;
}
}
//暂停捕获图。
//运行图表会占用大量资源。如果需要,请暂停它
//不需要。
公共空间暂停()
{
如果(穆布伦宁)
{
IMediaControl mediaCtrl=m_FilterGraph作为IMediaControl;
int hr=mediaCtrl.Pause();
元帅。通过hr(hr)的例外情况;
m_bRunning=错误;
}
}
///构建捕获图。
专用void设置图(DsDevice dev、DsDevice devAudio、字符串szOutputFileName)
{
国际人力资源;
IBaseFilter capFilter=null;
IBaseFilter asfWriter=null;
IBaseFilter audFilter=null;
ICaptureGraphBuilder2 capGraph=null;
//获取graphbuilder对象
m_FilterGraph=(IFilterGraph2)新的FilterGraph();
#如果调试
m_rot=新数据记录(m_FilterGraph);
#恩迪夫
尝试
{
//获取ICaptureGraphBuilder2
capGraph=(ICaptureGraphBuilder2)新CaptureGraphBuilder2();
//开始构建图表
hr=capGraph.SetFiltergraph(m_FilterGraph);
元帅。通过hr(hr)的例外情况;
//将捕获设备添加到图表中
//hr=m_FilterGraph.addSourceFilterPerformoniker(devAudio.Mon,null,devAudio.Name,out-capFilter);
//元帅。通过hr(hr)的例外情况;
hr=m_FilterGraph.addSourceFilterPerformoniker(dev.Mon,null,dev.Name,out-capFilter);
元帅。通过hr(hr)的例外情况;
asfWriter=ConfigAsf(capGraph,szOutputFileName);
hr=capGraph.RenderStream(null,null,capFilter,null,asfWriter);
元帅。通过hr(hr)的例外情况;
m_mediaCtrl=m_FilterGraph作为IMediaControl;
}
最后
{
if(capFilter!=null)
{
Marshal.ReleaseComObject(capFilter);
capFilter=null;
}
如果(asfWriter!=null)
{
发布对象元帅(asfWriter);
asfWriter=null;
}
if(capGraph!=null)
{
Marshal.ReleaseComObject(capGraph);
capGraph=null;
}
}
}
专用IBaseFilter配置ASF(ICaptureGraphBuilder2 capGraph,字符串szOutputFileName)
{
IFileSinkFilter pTmpSink=null;
IBaseFilter asfWriter=null;
int hr=capGraph.SetOutputFileName(MediaSubType.Asf,szOutputFileName,out asfWriter,out pTmpSink);
元帅。通过hr(hr)的例外情况;
tr
Dim classEnum As IEnumMoniker = Nothing
Dim moniker As IMoniker() = New IMoniker(0) {}
Dim devEnum As ICreateDevEnum = CType(New CreateDevEnum, ICreateDevEnum)
hr = devEnum.CreateClassEnumerator(FilterCategory.VideoInputDevice, classEnum, 0)
Marshal.ReleaseComObject(devEnum)
If classEnum.Next(moniker.Length, moniker, IntPtr.Zero) = 0 Then
    Dim iid As Guid = GetType(IBaseFilter).GUID
    moniker(0).BindToObject(Nothing, Nothing, iid, source)
End If
sourceFilt = CType(source, IBaseFilter)

Dim classEnum2 As IEnumMoniker = Nothing
Dim moniker2 As IMoniker() = New IMoniker(0) {}
Dim devEnum2 As ICreateDevEnum = CType(New CreateDevEnum, ICreateDevEnum)
hr = devEnum2.CreateClassEnumerator(FilterCategory.AudioInputDevice, classEnum2, 0)
Marshal.ReleaseComObject(devEnum2)
If classEnum2.Next(moniker2.Length, moniker2, IntPtr.Zero) = 0 Then
    Dim iid As Guid = GetType(IBaseFilter).GUID
    moniker2(0).BindToObject(Nothing, Nothing, iid, sobject)
End If
aufilter = CType(sobject, IBaseFilter)