none
DirectShowで動画を再生できない RRS feed

  • 質問

  • VisualStudio2019 MFCでDirectShowプログラムを作っています。

    単純に某サイトから持ってきた動画再生サンプル(もとはマイクロソフトのサンプルらしい)を表示しようとしているのですが再生できません。

    提示したソースは MFCプロジェクトのダイアルベースにボタンを1つだけ作って、そのボタンクリックのコールバックメソッドになってます。
    一部はしょってますがなにか不足しているところがあったら教えてください

    void CDirectShowTestDlg::OnPlay()
    {
    	HRESULT		hRslt;
    	IGraphBuilder* pGrph;
    	IMediaControl* pMdaCtrl;
    
    	// COMライブラリの初期化
    	hRslt = CoInitialize(NULL);
    
    	// フィルタ グラフ マネージャの生成
    	CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, ( LPVOID* ) &pGrph);
    
    	// フィルタ グラフ マネージャに公開されている IMediaControlインターフェースを取得する
    	hRslt = pGrph->QueryInterface(IID_IMediaControl, ( void** ) &pMdaCtrl);
    
    	// 再生するファイルを指定して、フィルタ グラフを構築する
    	pGrph->RenderFile(L"C:\\TEST\\test.avi", NULL);
    
    	// ストリームの再生(グラフの実行)
    	pMdaCtrl->Run();
    
    	AfxMessageBox(_T("OK"));
    
    	//解放
    	pMdaCtrl->Stop();
    	pMdaCtrl->Release();
    	pGrph->Release();
    	CoUninitialize();
    }


    ビルドは成功しています。
    mpeg1/mp4/aviで試しましたが、なにも表示しません。


    2020年10月8日 5:29

回答

  • RenderFileRunの戻り値を無視せずに調べましょう

    HRESULT hr1 = pGrph->RenderFile(L"C:\\TEST\\test.avi", NULL);
    
    const TCHAR* pmsg1;
    switch (hr1)
    {
    case S_OK:pmsg1 = L"成功。"; break;
    case VFW_S_AUDIO_NOT_RENDERED:pmsg1 = L"不完全な成功。オーディオがレンダリングされなかった。"; break;
    case VFW_S_DUPLICATE_NAME: pmsg1 = L"成功。フィルタ グラフ マネージャがフィルタ名が重複しないようにフィルタ名を変更した。"; break;
    case VFW_S_PARTIAL_RENDER: pmsg1 = L"このムービーにサポートされないフォーマットのストリームが含まれている。"; break;
    case VFW_S_VIDEO_NOT_RENDERED: pmsg1 = L"不完全な成功。このムービーにサポートされないフォーマットのストリームが含まれている。"; break;
    case E_ABORT: pmsg1 = L"操作が中止された。"; break;
    case E_FAIL:pmsg1 = L"失敗。"; break;
    case E_INVALIDARG: pmsg1 = L"引数が無効。"; break;
    case E_OUTOFMEMORY:pmsg1 = L"メモリ不足。"; break;
    case E_POINTER:pmsg1 = L"NULL ポインタ引数。"; break;
    case VFW_E_CANNOT_CONNECT:pmsg1 = L"接続を確立する中間フィルタの組み合わせが見つからなかった。"; break;
    case VFW_E_CANNOT_LOAD_SOURCE_FILTER: pmsg1 = L"このファイルのソース フィルタをロードできなかった。"; break;
    case VFW_E_CANNOT_RENDER: pmsg1 = L"ストリームをレンダリングするフィルタの組み合わせが見つからなかった。"; break;
    case VFW_E_INVALID_FILE_FORMAT:pmsg1 = L"ファイル フォーマットが無効である。"; break;
    case VFW_E_NOT_FOUND:pmsg1 = L"オブジェクトまたは名前が見つからなかった。"; break;
    case VFW_E_UNKNOWN_FILE_TYPE: pmsg1 = L"このファイルのメディア タイプが認識されない。"; break;
    case VFW_E_UNSUPPORTED_STREAM: pmsg1 = L"ファイルを再生できない。フォーマットがサポートされていない。"; break;
    default: pmsg1 = L"UNKNOWN";
    }
    AfxMessageBox(pmsg1);
    
    if (SUCCEEDED(hr1))
    {
        HRESULT hr2 = pMdaCtrl->Run();
    
        const TCHAR* pmsg2;
        switch (hr2)
        {
        case S_FALSE: pmsg2 = L"グラフは実行の準備をしているが、実行状態への移行が完了していないフィルタがある。"; break;
        case S_OK: pmsg2 = L"グラフのフィルタがすべて実行状態への移行を完了した。"; break;
        default: pmsg2 = L"UNKNOWN"; break;
        }
        AfxMessageBox(pmsg2);
    }


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク AppKey 2020年10月9日 7:06
    2020年10月9日 3:35

すべての返信

  • RenderFileRunの戻り値を無視せずに調べましょう

    HRESULT hr1 = pGrph->RenderFile(L"C:\\TEST\\test.avi", NULL);
    
    const TCHAR* pmsg1;
    switch (hr1)
    {
    case S_OK:pmsg1 = L"成功。"; break;
    case VFW_S_AUDIO_NOT_RENDERED:pmsg1 = L"不完全な成功。オーディオがレンダリングされなかった。"; break;
    case VFW_S_DUPLICATE_NAME: pmsg1 = L"成功。フィルタ グラフ マネージャがフィルタ名が重複しないようにフィルタ名を変更した。"; break;
    case VFW_S_PARTIAL_RENDER: pmsg1 = L"このムービーにサポートされないフォーマットのストリームが含まれている。"; break;
    case VFW_S_VIDEO_NOT_RENDERED: pmsg1 = L"不完全な成功。このムービーにサポートされないフォーマットのストリームが含まれている。"; break;
    case E_ABORT: pmsg1 = L"操作が中止された。"; break;
    case E_FAIL:pmsg1 = L"失敗。"; break;
    case E_INVALIDARG: pmsg1 = L"引数が無効。"; break;
    case E_OUTOFMEMORY:pmsg1 = L"メモリ不足。"; break;
    case E_POINTER:pmsg1 = L"NULL ポインタ引数。"; break;
    case VFW_E_CANNOT_CONNECT:pmsg1 = L"接続を確立する中間フィルタの組み合わせが見つからなかった。"; break;
    case VFW_E_CANNOT_LOAD_SOURCE_FILTER: pmsg1 = L"このファイルのソース フィルタをロードできなかった。"; break;
    case VFW_E_CANNOT_RENDER: pmsg1 = L"ストリームをレンダリングするフィルタの組み合わせが見つからなかった。"; break;
    case VFW_E_INVALID_FILE_FORMAT:pmsg1 = L"ファイル フォーマットが無効である。"; break;
    case VFW_E_NOT_FOUND:pmsg1 = L"オブジェクトまたは名前が見つからなかった。"; break;
    case VFW_E_UNKNOWN_FILE_TYPE: pmsg1 = L"このファイルのメディア タイプが認識されない。"; break;
    case VFW_E_UNSUPPORTED_STREAM: pmsg1 = L"ファイルを再生できない。フォーマットがサポートされていない。"; break;
    default: pmsg1 = L"UNKNOWN";
    }
    AfxMessageBox(pmsg1);
    
    if (SUCCEEDED(hr1))
    {
        HRESULT hr2 = pMdaCtrl->Run();
    
        const TCHAR* pmsg2;
        switch (hr2)
        {
        case S_FALSE: pmsg2 = L"グラフは実行の準備をしているが、実行状態への移行が完了していないフィルタがある。"; break;
        case S_OK: pmsg2 = L"グラフのフィルタがすべて実行状態への移行を完了した。"; break;
        default: pmsg2 = L"UNKNOWN"; break;
        }
        AfxMessageBox(pmsg2);
    }


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク AppKey 2020年10月9日 7:06
    2020年10月9日 3:35
  • ありがとうございました。

    パスにゴミ文字が入ってました。 ゴミを取ったらaviは再生する事ができました。

    2020年10月9日 7:07