ffmpeg下无法枚举摄像头的解决方案

一般ffmpeg是这样枚举的:

//Show Device  
void show_dshow_device(){
    AVFormatContext *pFmtCtx = avformat_alloc_context();
    AVDictionary* options = NULL;
    av_dict_set(&options, "list_devices", "true", 0);
    AVInputFormat *iformat = av_find_input_format("dshow");
    printf("Device Info=============\n");
    avformat_open_input(&pFmtCtx, "video=dummy", iformat, &options);
    printf("========================\n");
}
但是只能显示到命令行,代码无法直接获取(当然也可以通过获取命令行获取),这种反人类设计,有点无语。能不能直接获取呢?

答案是用DirectShow枚举:条条大路通罗马

int CCapVideo::GetAllCapDevice(CStringArray &Devices)//得到所有的视频捕获设备
{
    HRESULT hr;

    CComPtr< IBaseFilter > pCap;
    IBaseFilter **ppCap = &pCap;
    *ppCap = NULL;

    // 构造一个枚举器
    //
    CComPtr< ICreateDevEnum > pCreateDevEnum;
    pCreateDevEnum.CoCreateInstance( CLSID_SystemDeviceEnum );

    ASSERT(pCreateDevEnum);
    if( !pCreateDevEnum )
        return 0;

    // 枚举视频捕获设备
    //
    CComPtr< IEnumMoniker > pEm;
    pCreateDevEnum->CreateClassEnumerator( CLSID_VideoInputDeviceCategory, &pEm, 0 );

   // ASSERT(pEm);
    if( !pEm )
        return 0;

    pEm->Reset( );
 
    // 寻找第一个视频捕获设备
    //
    while( 1 )
    {
        ULONG ulFetched = 0;
        CComPtr< IMoniker > pM;

        hr = pEm->Next( 1, &pM, &ulFetched );
        if( hr != S_OK )
            break;

      // 从moniker中取得property bag interface
        
        CComPtr< IPropertyBag > pBag;
        hr = pM->BindToStorage( 0, 0, IID_IPropertyBag, (void**) &pBag );
        if( hr != S_OK )
            continue;


        CComVariant var;
        var.vt = VT_BSTR;
        hr = pBag->Read( L"FriendlyName", &var, NULL );
        if( hr != S_OK )
            continue;


        // 需要现行的过滤器
        //
        hr = pM->BindToObject( 0, 0, IID_IBaseFilter, (void**) ppCap );
        if( *ppCap )
        {
            CString szName=(CString)var.bstrVal;
            Devices.Add(szName);
        }
    }

    return (int)Devices.GetCount();    
}

然后:

    sprintf(device_name, "video=这里填写前面获取的摄像头列表即可");
    //sprintf(device_name, "video=aoni Webcam");
    //sprintf(device_name, "video=screen-capture-recorder");


    ifmt=av_find_input_format("dshow");
    
    //Set own video device's name
    if (avformat_open_input(&ifmt_ctx, device_name, ifmt, NULL) != 0){
        printf("Couldn't open input stream.(无法打开输入流)\n");
        return -1;
    }

打完收工!

猜你喜欢

转载自blog.csdn.net/xjb2006/article/details/98307338