当前位置: 首页 > news >正文

我想建立一个网站不知道怎么做啊/免费广告推广软件

我想建立一个网站不知道怎么做啊,免费广告推广软件,i岗网站建设,seo关键词优化报价上一篇实现了windows的音视频设备热插拔功能,这一篇集成到SDK中。我的对外接口类是HCMDesktopRecorder,该篇主要讲如何集成热插拔功能,其他代码忽略。 1、开启并注册热插拔 int HCMDesktopRecorder::init(/* 忽略 */) {/* 忽略 */// Create…

上一篇实现了windows的音视频设备热插拔功能,这一篇集成到SDK中。我的对外接口类是HCMDesktopRecorder,该篇主要讲如何集成热插拔功能,其他代码忽略。

1、开启并注册热插拔

int HCMDesktopRecorder::init(/* 忽略 */)
{/* 忽略 */// Create thread for detect device callbackm_detectDeviceThread = std::thread(std::bind(&HCMDesktopRecorder::detectDeviceProcess, this));// Start detecting deviceDEVICE::DeviceDetector::GetInstance().startDetect();m_deviceDetectCbId = DEVICE::DeviceDetector::GetInstance().registerCallback(std::bind(&HCMDesktopRecorder::deviceDetectCb,this, std::placeholders::_1, std::placeholders::_2));/* 忽略 */
}

向DeviceDetector注册的回调,一旦收到设备变更通知就触发自己的函数detectDeviceProcess

void HCMDesktopRecorder::deviceDetectCb(DEVICE::DeviceDetectType type, DEVICE::DeviceDetectAction action)
{std::unique_lock<std::mutex> lock(m_detectDeviceMutex);m_detectDeviceInfoList.push_back({ type, action });m_detectDeviceFlag = true;m_detectDeviceCond.notify_all();
}

detectDeviceProcess的线程函数实现如下:

void HCMDesktopRecorder::detectDeviceProcess()
{while (m_inited) {std::unique_lock<std::mutex> lock(m_detectDeviceMutex);while (!m_detectDeviceFlag && m_inited) {m_detectDeviceCond.wait_for(lock, std::chrono::microseconds(1000));}while (!m_detectDeviceInfoList.empty()) {auto info = m_detectDeviceInfoList.front();m_detectDeviceInfoList.pop_front();handleAudioDevice(info.type, info.action);handleVideoDevice(info.type, info.action);}m_detectDeviceFlag = false;}
}

其中handleAudioDevice和handleVideoDevice实现有点长,如下。
如果发现当前使用的设备被拔掉了,那么先销毁内存,并找可用的新设备,如果找到了,则开启新设备并更新到muxer中,实现见replaceAudioCaptor和replaceVideoCaptor;如果监测到插入了新设备并且当前无相同类型设备在使用,那么同样创建新设备并更新到muxer,同样详见replaceAudioCaptor和replaceVideoCaptor

void HCMDesktopRecorder::handleAudioDevice(DEVICE::DeviceDetectType type, DEVICE::DeviceDetectAction action)
{DEVICE::AUDIO_DEVICE defaultDevice = {};std::list<DEVICE::AUDIO_DEVICE> devices;if (type == DEVICE::DeviceDetectType::DEVICE_DDETECT_TYPE_MIC) {DEVICE::AudioDevice::getMicDevices(devices);if (action == DEVICE::DeviceDetectAction::DEVICE_DDETECT_ACTION_REMOVE) {bool removed = true;for each (auto device in devices) {if (device.id == m_setting.mic.id) {removed = false;break;}if (device.isDefault) {defaultDevice = device;}}if (removed) {memset(m_setting.mic.id, 0, sizeof(m_setting.mic.id));if (m_micCaptor != nullptr) {m_fileMuxer->replaceAudioCaptor(m_micCaptor, true, false);CAPTOR::destroyAudioCaptor(&m_micCaptor);m_micCaptor = nullptr;}if (!devices.empty()) {memcpy_s(m_setting.mic.id, sizeof(m_setting.mic.id), defaultDevice.id.c_str(), defaultDevice.id.size());memcpy_s(m_setting.mic.name, sizeof(m_setting.mic.name), defaultDevice.name.c_str(), defaultDevice.name.size());CAPTOR::createAudioCaptor((CAPTOR::AUDIO_CAPTURE_TYPE)m_setting.amCaptorId, &m_micCaptor);m_micCaptor->init(true, m_setting.mic.id);m_fileMuxer->replaceAudioCaptor(m_micCaptor, true, true);}}}else if (action == DEVICE::DeviceDetectAction::DEVICE_DDETECT_ACTION_ADD) {bool added = false;if (devices.size() > 0 && strlen(m_setting.mic.id) == 0) {for each (auto device in devices) {if (device.isDefault) {defaultDevice = device;added = true;break;}}if (added) {memcpy_s(m_setting.mic.id, sizeof(m_setting.mic.id), defaultDevice.id.c_str(), defaultDevice.id.size());memcpy_s(m_setting.mic.name, sizeof(m_setting.mic.name), defaultDevice.name.c_str(), defaultDevice.name.size());CAPTOR::createAudioCaptor((CAPTOR::AUDIO_CAPTURE_TYPE)m_setting.amCaptorId, &m_micCaptor);m_micCaptor->init(true, m_setting.mic.id);m_fileMuxer->replaceAudioCaptor(m_micCaptor, true, true);}}}}else if (type == DEVICE::DeviceDetectType::DEVICE_DDETECT_TYPE_SPEAKER) {DEVICE::AudioDevice::getSpeakerDevices(devices);if (action == DEVICE::DeviceDetectAction::DEVICE_DDETECT_ACTION_REMOVE) {bool removed = true;for each (auto device in devices) {if (device.id == m_setting.speaker.id) {removed = false;break;}if (device.isDefault) {defaultDevice = device;}}if (removed) {memset(m_setting.speaker.id, 0, sizeof(m_setting.speaker.id));if (m_speakerCaptor != nullptr) {m_fileMuxer->replaceAudioCaptor(m_speakerCaptor, false, false);CAPTOR::destroyAudioCaptor(&m_speakerCaptor);m_speakerCaptor = nullptr;}if (!devices.empty()) {memcpy_s(m_setting.speaker.id, sizeof(m_setting.speaker.id), defaultDevice.id.c_str(), defaultDevice.id.size());memcpy_s(m_setting.speaker.name, sizeof(m_setting.speaker.name), defaultDevice.name.c_str(), defaultDevice.name.size());CAPTOR::createAudioCaptor((CAPTOR::AUDIO_CAPTURE_TYPE)m_setting.asCaptorId, &m_speakerCaptor);m_speakerCaptor->init(false, m_setting.speaker.id);m_fileMuxer->replaceAudioCaptor(m_speakerCaptor, false, true);}}}else if (action == DEVICE::DeviceDetectAction::DEVICE_DDETECT_ACTION_ADD) {bool added = false;if (devices.size() > 0 && strlen(m_setting.speaker.id) == 0) {for each (auto device in devices) {if (device.isDefault) {defaultDevice = device;added = true;break;}}if (added) {memcpy_s(m_setting.speaker.id, sizeof(m_setting.speaker.id), defaultDevice.id.c_str(), defaultDevice.id.size());memcpy_s(m_setting.speaker.name, sizeof(m_setting.speaker.name), defaultDevice.name.c_str(), defaultDevice.name.size());CAPTOR::createAudioCaptor((CAPTOR::AUDIO_CAPTURE_TYPE)m_setting.asCaptorId, &m_speakerCaptor);m_speakerCaptor->init(false, m_setting.speaker.id);m_fileMuxer->replaceAudioCaptor(m_speakerCaptor, false, true);}}}}if (m_callbacks.onDeviceChanged != nullptr) {m_callbacks.onDeviceChanged(type);}
}
void HCMDesktopRecorder::handleVideoDevice(DEVICE::DeviceDetectType type, DEVICE::DeviceDetectAction action)
{DEVICE::VIDEO_DEVICE defaultDevice = {};std::list<DEVICE::VIDEO_DEVICE> devices;if (type == DEVICE::DeviceDetectType::DEVICE_DDETECT_TYPE_CAMERA) {DEVICE::VideoDevice::getCameraDevices(devices);if (action == DEVICE::DeviceDetectAction::DEVICE_DDETECT_ACTION_REMOVE) {bool removed = true;for each (auto device in devices) {if (device.id == m_setting.camera.id) {removed = false;break;}if (device.isDefault) {defaultDevice = device;}}if (removed) {memset(m_setting.camera.id, 0, sizeof(m_setting.camera.id));// Remove camera captorif (m_cameraCaptor != nullptr) {m_fileMuxer->replaceVideoCaptor(m_cameraCaptor, true, false);CAPTOR::destroyVideoCaptor(&m_cameraCaptor);m_cameraCaptor = nullptr;}if (!devices.empty()) {memcpy_s(m_setting.camera.id, sizeof(m_setting.camera.id), defaultDevice.id.c_str(), defaultDevice.id.size());memcpy_s(m_setting.camera.name, sizeof(m_setting.camera.name), defaultDevice.name.c_str(), defaultDevice.name.size());// Create camera captorCAPTOR::createVideoCaptor((CAPTOR::VIDEO_CAPTURE_TYPE)m_setting.vcCaptorId, &m_cameraCaptor);m_cameraCaptor->init(m_setting.camera.id, m_setting.framerate);m_fileMuxer->replaceVideoCaptor(m_cameraCaptor, true, true);}}}else if (action == DEVICE::DeviceDetectAction::DEVICE_DDETECT_ACTION_ADD) {bool added = false;if (devices.size() > 0 && strlen(m_setting.camera.id) == 0) {for each (auto device in devices) {if (device.isDefault) {defaultDevice = device;added = true;break;}}if (added) {memcpy_s(m_setting.camera.id, sizeof(m_setting.camera.id), defaultDevice.id.c_str(), defaultDevice.id.size());memcpy_s(m_setting.camera.name, sizeof(m_setting.camera.name), defaultDevice.name.c_str(), defaultDevice.name.size());// Create camera captorCAPTOR::createVideoCaptor((CAPTOR::VIDEO_CAPTURE_TYPE)m_setting.vcCaptorId, &m_cameraCaptor);m_cameraCaptor->init(m_setting.camera.id, m_setting.framerate);m_fileMuxer->replaceVideoCaptor(m_cameraCaptor, true, true);}}}}else if (type == DEVICE::DeviceDetectType::DEVICE_DDETECT_TYPE_MONITOR) {}if (m_callbacks.onDeviceChanged != nullptr) {m_callbacks.onDeviceChanged(type);}
}

2、Muxer类关于replaceAudioCaptor和replaceVideoCaptor的实现

FfmpegMuxer实现详见《【音视频】保存同步的音视频文件-ffmpeg(九)》,这里只做热插拔实现的介绍。
replaceAudioCaptor的实现,详见代码。
amCaptor是麦克风采集器,asCaptor是扬声器采集器,aFilter是音频重采样|混流过滤器

int FfmpegMuxer::replaceAudioCaptor(CAPTOR::AudioCaptor* audioCaptor, bool isMic, bool add)
{/* 没有启动过audio流程,就不再启动(重启流程比较麻烦,就不做了,反正主要为了测试audio设备的热插拔) */if (m_audioStream == nullptr) {return ERROR_CODE_UNINITIALIZED;}int err = ERROR_CODE_OK;std::lock_guard<std::mutex> lock(m_mutex);if (add) {bool hasDevice = false;if ((m_audioStream->amCaptor != nullptr && isMic) || (m_audioStream->asCaptor != nullptr && !isMic)) {hasDevice = true;}if (!hasDevice) {if (m_audioStream->amCaptor == nullptr && isMic) {m_audioStream->amCaptor = audioCaptor;}else if (m_audioStream->asCaptor == nullptr && !isMic) {m_audioStream->asCaptor = audioCaptor;}/* 销毁filter */FILTER::destroyAudioFilter(&m_audioStream->aFilter);/* 重新创建filter */err = createAudioFilter(m_audioStream->amCaptor, m_audioStream->asCaptor);if (err == ERROR_CODE_OK) {/* 启动captor和filter */if (m_audioStream->amCaptor != nullptr) {m_audioStream->amCaptor->start();}if (m_audioStream->asCaptor != nullptr) {m_audioStream->asCaptor->start();}if (m_audioStream->aFilter != nullptr) {m_audioStream->aFilter->start();}}}}else {if (isMic && m_audioStream->amCaptor == audioCaptor) {err = m_audioStream->amCaptor->stop();m_audioStream->amCaptor = nullptr;}else if (!isMic && m_audioStream->asCaptor == audioCaptor) {err = m_audioStream->asCaptor->stop();m_audioStream->asCaptor = nullptr;}}return err;
}

replaceVideoCaptor实现,详见代码。
vmCaptor是显示器采集器,vcCaptor是摄像头采集器,vTranscoder是视频转码器,vFilter是视频混流过滤器

int FfmpegMuxer::replaceVideoCaptor(CAPTOR::VideoCaptor* videoCaptor, bool isCamera, bool add)
{/* 没有启动过video流程,就不再启动(重启流程比较麻烦,就不做了,反正主要为了测试video设备的热插拔) */if (m_videoStream == nullptr) {return ERROR_CODE_UNINITIALIZED;}int err = ERROR_CODE_OK;std::lock_guard<std::mutex> lock(m_mutex);if (add) {bool hasDevice = false;if ((m_videoStream->vmCaptor != nullptr && !isCamera) || (m_videoStream->vcCaptor != nullptr && isCamera)) {hasDevice = true;}if (!hasDevice) {if (m_videoStream->vmCaptor == nullptr && !isCamera) {m_videoStream->vmCaptor = videoCaptor;}else if (m_videoStream->vcCaptor == nullptr && isCamera) {m_videoStream->vcCaptor = videoCaptor;}/* 销毁filter */TRANSCODER::destroyVideoTranscoder(&m_videoStream->vTranscoder);FILTER::destroyVideoFilter(&m_videoStream->vFilter);/* 重新创建filter */err = createVideoFilter(m_videoStream->vmCaptor, m_videoStream->vcCaptor);if (err == ERROR_CODE_OK) {/* 启动captor和filter */if (m_videoStream->vmCaptor != nullptr) {m_videoStream->vmCaptor->start();}if (m_videoStream->vcCaptor != nullptr) {m_videoStream->vcCaptor->start();}if (m_videoStream->vFilter != nullptr) {m_videoStream->vFilter->start();}}}}else {if (isCamera && m_videoStream->vcCaptor == videoCaptor) {err = m_videoStream->vcCaptor->stop();m_videoStream->vcCaptor = nullptr;}else if (!isCamera && m_videoStream->vmCaptor == videoCaptor) {err = m_videoStream->vmCaptor->stop();m_videoStream->vmCaptor = nullptr;}}return err;
}

3、停止热插拔监测

删除热插拔回调并停止监测

void HCMDesktopRecorder::release()
{/* 忽略 */DEVICE::DeviceDetector::GetInstance().removeCallback(m_deviceDetectCbId);DEVICE::DeviceDetector::GetInstance().stopDetect();
}
http://www.jmfq.cn/news/5109733.html

相关文章:

  • 一级a做爰片阿v祥仔网站/泰安百度公司代理商
  • 我的世界做rpg网站/怎样推广自己的app
  • 连云港网站建设公司/拉新app推广平台
  • 做美女图片网站挣钱么/五年级下册数学优化设计答案
  • 合优网站建设/子域名大全查询
  • 做淘客网站用备案吗/如何注册一个网站
  • 建设网站的具体步骤/友情链接交换群
  • 湖南省城乡与住房建设厅网站/seo优化点击软件
  • 坑梓网站建设咨询/百度官方免费下载
  • 如何做适合手机访问的网站/网络广告人社区官网
  • 哈尔滨制作网站多少钱/常州seo第一人
  • 柳林网站建设/关键词优化快排
  • 赣州网站优化制作/网店推广策划方案
  • 企业建设网站个人总结报告/线上营销培训
  • 湖南长沙网站建设公司电话/企业培训计划
  • 社区网站优化/网络推广平台收费不便宜
  • 行业网站推广怎么做/seo的基本步骤顺序正确的是
  • 哪里有网站可以做动态视频倒计时/高级搜索引擎技巧
  • 找晚上做的工作去哪个网站/现在最火的推广平台
  • 外贸电商做俄罗斯市场网站/电话百度
  • 西南大学校园网站建设往年考试卷/游戏交易平台
  • 苏州网站建设要点/1688关键词排名查询工具
  • 本单位政府网站建设的个性化需求/恶意点击软件哪个好
  • 南昌网站建设报价/营销宝
  • 拉萨市建设局网站/成都自动seo
  • 湖州 网站建设公司/关键词搜索量排名
  • 网站出现搜索/网站收录查询工具
  • 做网站卖赚钱吗/郑州seo软件
  • 网上商城平台开发/seo公司厦门
  • 成都专业的网站建设公司/如何在百度搜索到自己的网站