簡體   English   中英

如何在DirectShow中將捕獲的視頻/音頻渲染並保存為自定義文件/過濾器格式?

[英]How to render and save captured Video/Audio into a custom file/filter format in DirectShow?

基本上,我想捕獲音頻/視頻。 通過mp4混合器運行它,並將其保存到磁盤上的文件中。 在使用ICaptureGraphBuilder2之前,但保存為自定義格式時似乎沒用。

到目前為止,我的代碼

我列舉了視頻/音頻設備。 在此示例中,我僅嘗試捕獲音頻。 我得到正確的設備,並使用GetPin枚舉過濾器引腳以獲取其輸出引腳。

hr = pMoniker2->BindToObject(0, 0, IID_IBaseFilter, (void**)&pSrc2);
hr = pGraph->AddFilter(pSrc2, L"AudioCap");

hr = GetPin(pSrc2, PINDIR_OUTPUT, &outPin);

這是自定義過濾器,一個MP4混合器。 它加載正確,我可以得到輸入引腳並將其連接到我的輸出引腳。 到現在為止還挺好。

HRESULT hr = CreateObjectFromPath(TEXT("c:\\filters\\mp4mux.dll"), clsid, &pUnk);
if (SUCCEEDED(hr))
{
    IBaseFilterPtr pFilter = pUnk;
    HRESULT hr = pGraph->AddFilter(pFilter, L"Private Filter");
    hr = GetPin(pFilter, PINDIR_INPUT, &inPin);
}

hr = pGraph->Connect(outPin, inPin);

這是我迷路的地方,我找不到如何執行下一步渲染並將輸出保存到磁盤上的文件的方法。 因此,在此先感謝您對下一步的任何幫助!

編輯:Filesink代碼

AM_MEDIA_TYPE mType;

mType.majortype = MEDIATYPE_Video;
mType.subtype = MEDIASUBTYPE_H264;
mType.bFixedSizeSamples = FALSE;
mType.bTemporalCompression = TRUE;
mType.lSampleSize = 0;
mType.formattype = FORMAT_None;
mType.pUnk = NULL;
mType.cbFormat = 0;
mType.pbFormat = NULL;
//Not 100% sure about the setup of the media format.

IBaseFilter * iFiltera = NULL; 
IFileSinkFilter* iFilter = NULL; 
IGraphBuilder *pGraph;

hr = pMoniker2->BindToObject(0, 0, IID_IBaseFilter, (void**)&pSrc2); //audio capture
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,  IID_IGraphBuilder, (void**)&pGraph);
hr = CoCreateInstance(CLSID_FileWriter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&iFiltera);

hr = pBuild->SetFiltergraph(pGraph);

hr = pGraph->AddFilter(pSrc2, L"AudioCap");
hr = GetPin(pSrc2, PINDIR_OUTPUT, &outPin); //ADDED

hr = pGraph->AddFilter(iFiltera, L"FileWriter");
hr = iFiltera->QueryInterface(IID_IFileSinkFilter, (void**)&iFilter);

iFilter->SetFileName((LPCOLESTR)"c:\\wav\\tester.mp4", NULL); //UPDATED mType set to NULL

HRESULT hr = CreateObjectFromPath(TEXT("c:\\filters\\mp4mux.dll"), clsid, &pUnk);

IBaseFilterPtr pFilter = pUnk;
if (SUCCEEDED(hr))
{

    HRESULT hr = pGraph->AddFilter(pFilter, L"Private Filter");
    hr = GetPin(pFilter, PINDIR_INPUT, &inPin); //mux in

    hr = GetPin(pFilter, PINDIR_OUTPUT, &mOutPin); //mux out
    hr = GetPin(iFiltera, PINDIR_INPUT, &filePin); // filewriter in
}

hr = pGraph->Connect(outPin, inPin); //connect audio out and mux in
hr = pGraph->Connect(mOutPin, filePin); //connect mux out and file in; Error 0x80040217(VFW_E_CANNOT_CONNECT?) //works now

//ADDED code
IMediaControl *pMC = NULL;
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pMC);

hr = pMC->Run();
Sleep(4000);
hr = pMC->Stop();  

您需要了解特定任務需要哪種過濾器圖拓撲。 您正在捕獲,在這里-很好。 因此,您有提供了代碼段的音頻捕獲過濾器。 然后,要么壓縮音頻(如果要生成MP4文件,則首選為AAC AKA MPEG-4第3部分),或者使音頻保持未壓縮的PCM。 然后,您就可以連接MPEG-4多路復用器了。 多路復用器產生輸出流,您應該使用File Writer Filter完成流水線。

您可以在GraphEdit SDK應用程序中手動構建鏈(或者有其他更豐富的工具)。 您的過濾器圖形如下所示:

篩選圖

請注意,您可以在應用程序中公開過濾器圖,然后遠程連接到它並檢查拓撲。 這使調試更加容易。 啟動/停止過濾器圖形(代碼中的IMediaControl::Run::Stop )將為您創建文件。

我的理解是,添加多路復用器后,您會立即迷路。 現在,您需要找到其輸出引腳,添加File Writer ,查詢其IFileSinkFilter ,使用它設置目標文件名,找到其輸入引腳,連接兩個未連接的引腳(多路復用器輸出,寫入器輸入)。 您的管道已准備就緒,可以運行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM