2011-10-07 141 views
0

我正在編寫使用DirectShow庫在C#中捕獲音頻並將其寫入ogg容器的程序。我在GraphEditPlus中創建了一個圖表。它生成一個GraphBuilder方法代碼,我將其複製到我的代碼中。此代碼是:使用DirectShow捕獲音頻

class AudioCapture 
{ 
    public static void checkHR(int hr, string msg) 
    { 
    if (hr < 0) 
    { 
     MessageBox.Show(msg); 
     DsError.ThrowExceptionForHR(hr); 
    } 
    } 

    public static void BuildGraph (IGraphBuilder pGraph, string dstFile) 
    { 
    int hr = 0; 

    //graph builder 
    ICaptureGraphBuilder2 pBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); 
    hr = pBuilder.SetFiltergraph(pGraph); 
    checkHR(hr, "Can't SetFiltergraph"); 

    Guid CLSID_XiphOrgVorbisEncoder = new Guid("{5C94FE86-B93B-467F-BFC3-BD6C91416F9B}"); 
    Guid CLSID_XiphOrgOggMuxer = new Guid("{1F3EFFE4-0E70-47C7-9C48-05EB99E20011}"); 

    //add microphone 
    IBaseFilter pMicrophone = (IBaseFilter) new AudioRecord(); 
    hr = pGraph.AddFilter(pMicrophone, "Microphone"); 
    checkHR(hr, "Can't add microphone to graph"); 

    //add Vorbis Encoder 
    IBaseFilter pVorbisEncoder = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_XiphOrgVorbisEncoder)); 
    checkHR(hr, "Can't add Vorbis Encoder to graph"); 

    //connect Microphone and Vorbis Encoder 
    hr = pGraph.ConnectDirect(GetPin(pMicrophone, "Capture"), GetPin(pVorbisEncoder, "PCM In"), null); 
    checkHR(hr, "Can't connect Microphone and Vorbis Encoder"); 

    //add Ogg Muxer 
    IBaseFilter pOggMuxer = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_XiphOrgOggMuxer)); 
    checkHR(hr, "Can't add Ogg Muxer to graph"); 

    //set destination filename 
    IFileSinkFilter pOggMuxer_sink = pOggMuxer as IFileSinkFilter; 
    if (pOggMuxer_sink == null) 
     checkHR(unchecked((int)0x80004002), "Can't get IFileSinkFilter"); 
    hr = pOggMuxer_sink.SetFileName(dstFile, null); 
    checkHR(hr, "Can't set filename"); 

    //connect Vorbis Encoder and Ogg Muxer 
    hr = pGraph.ConnectDirect(GetPin(pVorbisEncoder, "VorbisOut"), GetPin(pOggMuxer, "Ogg Packet In"), null); 
    checkHR(hr, "Can't connect Vorbis Encoder and Ogg Muxer"); 
    } 

    static IPin GetPin(IBaseFilter filter, string pinname) 
    { 
    IEnumPins epins; 
    int hr = filter.EnumPins(out epins); 
    checkHR(hr, "Can't enumerate pins"); 
    IntPtr fetched = Marshal.AllocCoTaskMem(4); 
    IPin[] pins = new IPin[1]; 
    while (epins.Next(1, pins, fetched) == 0) 
    { 
     PinInfo pinfo; 
     pins[0].QueryPinInfo(out pinfo); 
     bool found = (pinfo.name == pinname); 
     DsUtils.FreePinInfo(pinfo); 
     if (found) 
     return pins[0]; 
    } 
    checkHR(-1, "Pin not found"); 
    return null; 
    } 
} 

當我試圖執行該代碼程序拋出我的消息「品無法找到」試圖連接麥克風和Vorbis編碼器過濾後。調試後,我發現它找不到麥克風引腳。有誰知道我的錯誤在哪裏?

+0

最好搜索音頻輸入設備。只是'新的AudioRecord()'不會自動創建micropone輸入。 – wimh

+0

嗨如何錄製視頻和音頻並將其保存到一個視頻文件?我可以通過分離文件來完成。你能幫我嗎。 – Vijayaraghavan

回答

0

你不應該找他們的名字引腳,因爲這不是很可靠。如果你完全確定你正在處理的濾波器/類,它可能還是可以接受的,但它絕對不是用通用音頻源濾波器處理的方式(更具體地說:沒有人承諾捕獲引腳被命名「捕獲」,而不是引腳實施IKsPropertySet表示)。

你最好的辦法是使用ICaptureGraphBuilder::RenderStreamPIN_CATEGORY_CAPTURE的參數,以便它可以爲你拾取捕獲引腳。有關詳細信息,請參閱MSDN http://msdn.microsoft.com/en-us/library/dd311932%28v=vs.85%29.aspx,我確信您也可以輕鬆找到用於此目的的示例代碼。

0

嘗試做這樣的事情,當你尋找銷

pinout = FindPinByDirection(Source, PinDirection.Output); 
    pinin = FindPinByDirection(Target, PinDirection.Input); 

    Graph.Connect(pinout, pinin); 

這則根據名字更好的辦法。