用directshow, 采集视频和音频, 预览的同时同时保存为wmv文件.保存完毕之后, 打开保存的wmv文件, 播放一秒钟就卡住了, 画面不动, 声音也没有.但是如果点一下进度条跳到其他时刻又可以播放.网上查了资料, 说要用IConfigAsfWriter来设置AsfWriter的profile, 不知道这个原因.谁知道是怎么回事呢? 在线等.

解决方案 »

  1.   

    是啊,都是在网上找的一些代码.我贴在这把.
    /*  设置视频捕获设备过滤器  */
    HRESULT CollectionController::setVideoDevice()
    {
    HRESULT hr = S_OK; do
    {
    /*  创建系统设备枚举器  */
    ICreateDevEnum * pCreateDevEnum;
    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void * *)&pCreateDevEnum);
    if(FAILED(hr))  break; /*  创建视频采集设备枚举器  */
    IEnumMoniker * pEnumMoniker;
    hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumMoniker, 0);
    if(FAILED(hr))  break; ULONG ulFetched = 0;
    IMoniker * pMoniker = NULL; if(pEnumMoniker->Next(1, &pMoniker, &ulFetched) == S_OK)
    {
    /*  得到视频捕获设备  */
    hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void * *)&m_pVideoCapture);
    if(FAILED(hr))  break; pMoniker->Release();
    }
    pEnumMoniker->Release();
    pCreateDevEnum->Release(); /*  把设备添加到过滤器通道中  */
    hr = m_pFilterGraph->AddFilter(m_pVideoCapture, L"Video Capture Filter");
    if(FAILED(hr))  break; }while(FALSE);

    return hr;
    }
    /*  设置音频捕获设备过滤器  */
    HRESULT CollectionController::setAudioDevice()
    {
    /*  标记返回值  */
    HRESULT hr = S_OK; do
    {
    /*  创建系统设备枚举器  */
    CComPtr<ICreateDevEnum> pCreateDevEnum;
    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void * *)&pCreateDevEnum);
    if(FAILED(hr))  break; /*  创建音频采集设备枚举器  */
    CComPtr<IEnumMoniker> pEnumMoniker;
    hr = pCreateDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory, &pEnumMoniker, 0);
    if(FAILED(hr))  break; ULONG ulFetched = 0;
    IMoniker * pMoniker = NULL; if(pEnumMoniker->Next(1, &pMoniker, &ulFetched) == S_OK)
    {
    /*  得到音频捕获设备  */
    hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void * *)&m_pAudioCapture);
    if(FAILED(hr))  break; pMoniker->Release();
    }
    pEnumMoniker.Release();
    pCreateDevEnum.Release();

    /*  把设备添加到过滤器通道中  */
    hr = m_pFilterGraph->AddFilter(m_pAudioCapture, L"Audio Capture Filter");
    if(FAILED(hr))  break;

    }while(FALSE); return hr;
    }
    /*  采集,预览并且保存为文件  */
    HRESULT CollectionController::start(HWND hWnd)
    {
    HRESULT hr = S_OK; do
    {
    /*  设置音频捕获设备过滤器  */
    hr = setAudioDevice();
    if(FAILED(hr))  break; /*  设置视频捕获设备过滤器   */
    hr = setVideoDevice();
    if(FAILED(hr))  break; /*  将filter加入到graph中  */
    hr = addFilter();
    if(FAILED(hr))  break; /*  预览  */
    hr = m_pCaptureGB->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Audio, m_pAudioCapture, NULL, NULL);
    if(FAILED(hr))  break; hr = m_pCaptureGB->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, m_pVideoCapture, NULL, NULL);
    if(FAILED(hr))  break;
    /*  设置窗口  */
    hr = setDisplayWnd(hWnd);
    if(FAILED(hr))  break; /*  
        写到文件  
    */
    IBaseFilter * pWriter;

    hr = m_pCaptureGB->SetOutputFileName(&MEDIASUBTYPE_Asf, L"e:\\1.asf", &pWriter, NULL);
    if(FAILED(hr))  break; /*  对pWriter(AsfWriter)进行设置  */
    IConfigAsfWriter *pConfig = 0;   
    hr = pWriter->QueryInterface(IID_IConfigAsfWriter, (void**)&pConfig);   
    if(SUCCEEDED(hr))   
    {   
    pConfig->Release();
    }

    hr = m_pCaptureGB->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, m_pAudioCapture, NULL, pWriter);
    if(FAILED(hr))  break; hr = m_pCaptureGB->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pVideoCapture, NULL, pWriter);
    if(FAILED(hr))  break; /*  开始采集  */
    hr = m_pMediaControl->Run();
    if(FAILED(hr))  break; }while(FALSE); return hr;
    }
      

  2.   


    ============================/* 设置视频捕获设备过滤器 */
    HRESULT CollectionController::setVideoDevice()
    {
    HRESULT hr = S_OK;do
    {
    /* 创建系统设备枚举器 */
    ICreateDevEnum * pCreateDevEnum;
    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void * *)&pCreateDevEnum);
    if(FAILED(hr)) break;/* 创建视频采集设备枚举器 */
    IEnumMoniker * pEnumMoniker;
    hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumMoniker, 0);
    if(FAILED(hr)) break;ULONG ulFetched = 0;
    IMoniker * pMoniker = NULL;if(pEnumMoniker->Next(1, &pMoniker, &ulFetched) == S_OK)
    {
    /* 得到视频捕获设备 */
    hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void * *)&m_pVideoCapture);
    if(FAILED(hr)) break;pMoniker->Release();
    }
    pEnumMoniker->Release();
    pCreateDevEnum->Release();/* 把设备添加到过滤器通道中 */
    hr = m_pFilterGraph->AddFilter(m_pVideoCapture, L"Video Capture Filter");
    if(FAILED(hr)) break;}while(FALSE);return hr;
    }
    /* 设置音频捕获设备过滤器 */
    HRESULT CollectionController::setAudioDevice()
    {
    /* 标记返回值 */
    HRESULT hr = S_OK;do
    {
    /* 创建系统设备枚举器 */
    CComPtr<ICreateDevEnum> pCreateDevEnum;
    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void * *)&pCreateDevEnum);
    if(FAILED(hr)) break;/* 创建音频采集设备枚举器 */
    CComPtr<IEnumMoniker> pEnumMoniker;
    hr = pCreateDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory, &pEnumMoniker, 0);
    if(FAILED(hr)) break;ULONG ulFetched = 0;
    IMoniker * pMoniker = NULL;if(pEnumMoniker->Next(1, &pMoniker, &ulFetched) == S_OK)
    {
    /* 得到音频捕获设备 */
    hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void * *)&m_pAudioCapture);
    if(FAILED(hr)) break;pMoniker->Release();
    }
    pEnumMoniker.Release();
    pCreateDevEnum.Release();/* 把设备添加到过滤器通道中 */
    hr = m_pFilterGraph->AddFilter(m_pAudioCapture, L"Audio Capture Filter");
    if(FAILED(hr)) break;}while(FALSE);return hr;
    }
    /* 采集,预览并且保存为文件 */
    HRESULT CollectionController::start(HWND hWnd)
    {
    HRESULT hr = S_OK;do
    {
    /* 设置音频捕获设备过滤器 */
    hr = setAudioDevice();
    if(FAILED(hr)) break;/* 设置视频捕获设备过滤器 */
    hr = setVideoDevice();
    if(FAILED(hr)) break;/* 将filter加入到graph中 */
    hr = addFilter();
    if(FAILED(hr)) break;/* 预览 */
    hr = m_pCaptureGB->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Audio, m_pAudioCapture, NULL, NULL);
    if(FAILED(hr)) break;hr = m_pCaptureGB->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, m_pVideoCapture, NULL, NULL);
    if(FAILED(hr)) break;
    /* 设置窗口 */
    hr = setDisplayWnd(hWnd);
    if(FAILED(hr)) break;/*   
    写到文件   
    */
    IBaseFilter * pWriter;hr = m_pCaptureGB->SetOutputFileName(&MEDIASUBTYPE_Asf, L"e:\\1.asf", &pWriter, NULL);
    if(FAILED(hr)) break;/* 对pWriter(AsfWriter)进行设置 */
    IConfigAsfWriter *pConfig = 0;   
    hr = pWriter->QueryInterface(IID_IConfigAsfWriter, (void**)&pConfig);   
    if(SUCCEEDED(hr))   
    {   
    pConfig->Release();
    }hr = m_pCaptureGB->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, m_pAudioCapture, NULL, pWriter); 
    if(FAILED(hr)) break;hr = m_pCaptureGB->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pVideoCapture, NULL, pWriter); 
    if(FAILED(hr)) break;/* 开始采集 */
    hr = m_pMediaControl->Run();
    if(FAILED(hr)) break; }while(FALSE);return hr;
    }
      

  3.   

    你保存的文件用windows自带的播放器能否正常播放?
      

  4.   

    你的代码,我试了,挺好,没问题啊!只是我保存的AVI格式
      

  5.   

    楼主,在renderstream之前要进行对ASF writer进行配置,就是IConfigAsfWriter,我看楼主也获得了这个接口,接下调用接口函数ConfigureFilterUsingProfile,或者SetIndexMode配置下就ok了,不会出现卡屏的问题。
    DX SDK里面也说的很明确了,在渲染之前要进行接口配置、。
    原文:it must be configured before it can be connected to upstream filters