MFC實現ffmpeg流媒體數據推送與接收(1.獲取設備)

MFC實現ffmpeg流媒體數據推送與接收(1.獲取設備)

         本篇文章是基於ffmpeg的一個應用實例。做過流媒體的同學對於ffmepg比較瞭解,這裏就不做介紹。直接進入實例分析:

         我們這次實現ffmpeg.exe解析桌面,攝像頭,麥克風設備推送rtmp流到nginx,通過代碼從流媒體服務器接收數據流解析並播放。那麼第一步我們就要獲取我們設備。桌面我們可以使用gdigrab來獲取,考慮一些原因攝像頭麥克風使用的dshow。那麼本節就用MFC代碼獲取dshow相關的設備名稱。

         CStringGetFirstCaptureDevices(const GUID devicesCLSID)

{

         //enumerate all video capture devices

         ICreateDevEnum*pCreateDevEnum = NULL;

         HRESULThr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,

                   IID_ICreateDevEnum,(void**)&pCreateDevEnum);

 

         IEnumMoniker*pEm = NULL;

         hr= pCreateDevEnum->CreateClassEnumerator(devicesCLSID, &pEm, 0);

         if(hr != NOERROR)

                   return0;

 

         CStringstrDevicesName;

         ULONGcFetched;

         IMoniker*pM = NULL;

         if(hr= pEm->Next(1, &pM, &cFetched), hr==S_OK)

         {

                   LPOLESTRstrPidvid = NULL;

                   hr= pM->GetDisplayName(0, 0, &strPidvid); //獲取ID信息

                   if(SUCCEEDED(hr))

                   {

                            //這裏獲取了一下設備的ID

                            USES_CONVERSION;//OLE2T

                            CStringsPidvid = strPidvid;

                            stringstr = T2A(sPidvid);

                            stringresult;

                            staticconst regex re("(vid_[0-9a-f]{4}&pid_[0-9a-f]{4})",regex::icase);

                            smatchmatch;

                            if(regex_search(str, match, re) && match.size() > 1)

                            {

                                     result= match.str(1);

                            }

                            else

                            {

                                     result= string("");

                            }

                            CStringstrPid(result.c_str());

                            strPid.MakeUpper();//全部大寫

 

                            IPropertyBag*pBag=0;

                            hr= pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);

                            if(SUCCEEDED(hr))

                            {

                                     VARIANTvar;

                                     var.vt= VT_BSTR;

                                     hr= pBag->Read(L"FriendlyName", &var, NULL); //還有其他屬性,像描述信息等等...

                                     if(hr== NOERROR)

                                     {

                                               //獲取設備名稱     

                                               chardevices_name[1024];

                                               WideCharToMultiByte(CP_ACP,0,var.bstrVal,-1,devices_name, sizeof(devices_name) ,"",NULL);

                                               strDevicesName= CString(devices_name);

 

                                               SysFreeString(var.bstrVal);                                 

                                     }

                                     pBag->Release();

                            }

                   }

                   pM->Release();

         }

         pEm->Release();

         pCreateDevEnum->Release();

         returnstrDevicesName;

}

通過傳遞CLSID_VideoInputDeviceCategory獲取第一個攝像頭設備名,傳遞CLSID_AudioInputDeviceCategory獲取第一個麥克風設備名。由於簡單應用我們就只獲取第一設備。使用時加上頭文件Dshow.h,regex.h及strmiids.lib;quartz.lib;dmoguids.lib。至此我們獲取到了我們需要的設備名稱,接下來我們就可以通過ffmpeg.exe解析推流了。

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章