C++Builder 11.1.5中如何获取同名摄像头的对应视频采集设备?
解决C++Builder中同名摄像头的设备获取问题
问题分析
核心问题点:
- 两个摄像头名称相同,
GetDevicesByName()仅返回第一个匹配设备,无法区分设备。 - 直接使用
TCaptureDeviceManager::Current->Devices[索引]返回NULL,因为Devices集合包含所有媒体设备(音频+视频),而你枚举时用GetDevicesByMediaType(TMediaType::Video)仅获取视频设备,两者索引序列不对应,取到的可能是音频设备,导致dynamic_cast转换失败。
正确解决方案
方案1:通过UniqueID获取(推荐)
每个摄像头的UniqueID是唯一标识,枚举时保存该值,后续通过GetDeviceByUniqueID()精准定位设备。
修改枚举代码
在窗体OnCreate事件中,将设备UniqueID关联到ComboBox选项(用AddObject存储额外标识):
NumbAvailableCameras = 0; DeviceList = TCaptureDeviceManager::Current->GetDevicesByMediaType(TMediaType::Video); for (int i = 0; i < DeviceList->Count; i++) { TVideoCaptureDevice* CamDevice = dynamic_cast<TVideoCaptureDevice*>(DeviceList->Items[i]); if (CamDevice) { // 显示设备名称,同时将UniqueID作为附加数据存入选项 ComboBox1->Items->AddObject(CamDevice->Name, (TObject*)CamDevice->UniqueID); // 可选:继续保存其他设备信息到数组 AvailableCameraNames[NumbAvailableCameras] = CamDevice->Name; AvailableCameraDescriptions[NumbAvailableCameras] = CamDevice->Description; AvailableCameraIdentifiers[NumbAvailableCameras] = CamDevice->UniqueID; NumbAvailableCameras++; } }
按钮点击时获取设备
if (ComboBox1->ItemIndex != -1) { String TargetUniqueID = (String)ComboBox1->Items->Objects[ComboBox1->ItemIndex]; CAM1VideoCamera = dynamic_cast<TVideoCaptureDevice*>( TCaptureDeviceManager::Current->GetDeviceByUniqueID(TargetUniqueID) ); // 此处添加启动采集的逻辑 }
方案2:直接保存设备指针
枚举时将视频设备的指针直接存入数组,后续通过ComboBox选中索引直接获取,避免二次查找出错。
定义类成员数组
在窗体类中添加私有成员变量:
private: TArray<TVideoCaptureDevice*> AvailableVideoCameras;
枚举时填充数组
NumbAvailableCameras = 0; DeviceList = TCaptureDeviceManager::Current->GetDevicesByMediaType(TMediaType::Video); AvailableVideoCameras.Clear(); for (int i = 0; i < DeviceList->Count; i++) { TVideoCaptureDevice* CamDevice = dynamic_cast<TVideoCaptureDevice*>(DeviceList->Items[i]); if (CamDevice) { ComboBox1->Items->Add(CamDevice->Name); AvailableVideoCameras.Add(CamDevice); NumbAvailableCameras++; } }
按钮点击时获取设备
if (ComboBox1->ItemIndex != -1 && ComboBox1->ItemIndex < AvailableVideoCameras.Length) { CAM1VideoCamera = AvailableVideoCameras[ComboBox1->ItemIndex]; // 此处添加启动采集的逻辑 }
注意事项
- 设备指针由
TCaptureDeviceManager管理生命周期,无需手动释放,只要管理器存在,指针就有效。 - 枚举时必须做
dynamic_cast校验,避免非视频设备混入集合。
内容的提问来源于stack exchange,提问作者Drewski7280
相关产品推荐
相关产品推荐

