webrtc之视频设备枚举及封装
2019-07-19 本文已影响0人
hijiang
有一小段时间没研究webrtc,写点笔记。
webrtc的视频设备处理,基本都在VideoCatpureFactory中(它会根据不同的平台:window,linux,ios,android,生成不同的VideoCaptureModule 对象);
我们封装出一个VideoDeviceManager单例对象,该对象可以实现:
- 视频设备枚举
- 视频设备支持格式查询
在webrtc中,设备主要使用设备id标识一个设备,而device_name为设备名称(中文或英文都可),并将视频设备抽象表示如下:
//视频设备支持的格式信息,暂时只提取如下
struct VideoFormat {
size_t width;
size_t height;
size_t interval;
};
class VideoDevice {
public:
VideoDevice(const std::string& id, const std::string& name) :device_id(id), device_name(name) {
}
public:
std::string device_id;
std::string device_name;
std::vector<VideoFormat> support_formats;
};
设备集合:
class VideoDeviceCollection
{
public:
VideoDeviceCollection();
virtual ~VideoDeviceCollection();
size_t getCount();
int getDevice(int index, std::string& deviceName, std::string& deviceId);
std::shared_ptr<VideoDevice> getDevice(size_t index);
std::shared_ptr<VideoDevice> searchDevice(const std::string& deviceId);
private:
void addVideoDevice(std::shared_ptr<VideoDevice> device);
std::vector<std::shared_ptr<VideoDevice>> video_devices_;
friend class XXX::VideoDeviceManager;
};
枚举设备的方法(返回设备集合):
std::shared_ptr<XXX_PUBLIC::VideoDeviceCollection> VideoDeviceManager::enumerateVideoDevices()
{
std::unique_ptr<webrtc::VideoCaptureModule::DeviceInfo> info(webrtc::VideoCaptureFactory::CreateDeviceInfo());
if (!info) {
return nullptr;
}
int num_devices = info->NumberOfDevices();
for (int i = 0; i < num_devices; ++i) {
const uint32_t kSize = 256;
char name[kSize] = { 0 };
char id[kSize] = { 0 };
if (info->GetDeviceName(i, name, kSize, id, kSize) != -1) {
std::shared_ptr<XXX_PUBLIC::VideoDevice> device = std::make_shared<XXX_PUBLIC::VideoDevice>(id, name);
getVideoFormat(device);
if (device->support_formats.size() <= 0) {
continue;
}
video_collection_->addVideoDevice(device);
}
}
return video_collection_;
}
获取某个设备支持的格式消息:
void VideoDeviceManager::getVideoFormat(std::shared_ptr<XXX_PUBLIC::VideoDevice>video_device)
{
cricket::WebRtcVideoDeviceCapturerFactory factory;
std::unique_ptr<cricket::VideoCapturer> capturer;//这里这个轨道用来采集,不输入,输入创建一个新的ExternalCapturer;
capturer = factory.Create(cricket::Device(video_device->device_name, video_device->device_id));
if (!capturer) {
return;
}
video_device->support_formats.clear();
const std::vector<cricket::VideoFormat> *formats = capturer->GetSupportedFormats();
for (const auto video_format : *formats) {
XXX_PUBLIC::VideoFormat format;
format.width = video_format.width;
format.height = video_format.height;
format.interval = video_format.interval;
video_device->support_formats.push_back(format);
}
}
至于这个模块的运作机制,以后写。