native webrtc支持切换音频采集设备和获取裸流

这篇具有很好参考价值的文章主要介绍了native webrtc支持切换音频采集设备和获取裸流。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

https://www.yuque.com/caokunchao/rtendq/oq8w3qgs3g59whru

前言

版本webrtc m96
1、修改webrtc m96代码,向外提供一个adm指针的接口出来
2、外部来获取指针进行设备的选择
3、外部获取音频裸流,麦克风或者扬声器的数据

修改webrtc代码

1、修改H:\webrtc\webrtc-checkout\webrtc\api\peer_connection_interface.h,PeerConnectionFactoryInterface类
添加接口

class AudioDeviceModule;
virtual rtc::scoped_refptr<AudioDeviceModule> GetAdmPtr() = 0;

2、修改H:\webrtc\webrtc-checkout\webrtc\pc\peer_connection_factory.h,
PeerConnectionFactory类,该类继承PeerConnectionFactoryInterface,实现GetAdmPtr()接口

#include "modules/audio_device/include/audio_device.h"
#include "media/base/media_engine.h"

  rtc::scoped_refptr<AudioDeviceModule> GetAdmPtr() override {
	 return context_->channel_manager()->media_engine()->voice().GetAdm();
  }

3、修改代理,H:\webrtc\webrtc-checkout\webrtc\pc\peer_connection_factory_proxy.h

#include "modules/audio_device/include/audio_device.h"

在 BEGIN_PROXY_MAP(PeerConnectionFactory) 下面添加代理方法
***
PROXY_METHOD0(rtc::scoped_refptr<AudioDeviceModule>,
       GetAdmPtr)
***
END_PROXY_MAP(PeerConnectionFactory)

4、修改H:\webrtc\webrtc-checkout\webrtc\media\base\media_engine.h,VoiceEngineInterface类
添加接口

 virtual rtc::scoped_refptr <webrtc::AudioDeviceModule> GetAdm() = 0;

5、修改H:\webrtc\webrtc-checkout\webrtc\media\engine\webrtc_voice_engine.h,WebRtcVoiceEngine类
实现接口

rtc::scoped_refptr<webrtc::AudioDeviceModule> GetAdm() override { return adm_; }

外部切换设备

看我的krtcsdk源码

void MicImpl::Start() {
    RTC_LOG(LS_INFO) << "MicImpl Start call";

    KRTCGlobal::Instance()->worker_thread()->PostTask(webrtc::ToQueuedTask([=]() {

        RTC_LOG(LS_INFO) << "MicImpl Start PostTask";

        KRTCError err = KRTCError::kNoErr;

        do {

            // 1. 如果麦克风已经启动采集,直接停止
            if (has_start_) {
                RTC_LOG(LS_WARNING) << "mic already start, mic_id: " << mic_id_;
                break;
            }

            // 2. 直接从webrtc获取adm模块指针
            rtc::scoped_refptr<webrtc::AudioDeviceModule> audio_device =
               KRTCGlobal::Instance()->push_peer_connection_factory()->GetAdmPtr();


            // 3. 检查系统是否存在麦克风设备
            int total = audio_device->RecordingDevices();
            if (total <= 0) {
                RTC_LOG(LS_WARNING) << "no audio device";
                err = KRTCError::kNoAudioDeviceErr;
                break;
            }

            // 4. 检查关联的mic_id是否能够在系统设备中找到
            int device_index = -1;
            for (int i = 0; i < total; ++i) {
                char name[128];
                char guid[128];
                audio_device->RecordingDeviceName(i, name, guid);
                if (0 == strcmp(guid, mic_id_.c_str())) {
                    device_index = i;
                    break;
                }
            }

            if (device_index <= -1) {
                RTC_LOG(LS_WARNING) << "audio device not found, mic_id: " << mic_id_;
                err = KRTCError::kAudioNotFoundErr;
                break;
            }

            // 5. 设置启用的麦克风设备
            if (audio_device->SetRecordingDevice(device_index)) {
                RTC_LOG(LS_WARNING) << "SetRecordingDevice failed, mic_id: " << mic_id_;
                err = KRTCError::kAudioSetRecordingDeviceErr;
                break;
            }

            // 6. 设置为立体声采集
            audio_device->SetStereoRecording(true);

            // 7. 初始化麦克风
            if (audio_device->InitRecording() || !audio_device->RecordingIsInitialized()) {
                RTC_LOG(LS_WARNING) << "InitRecording failed, mic_id: " << mic_id_;
                err = KRTCError::kAudioInitRecordingErr;
                break;
            }

            bool ok = false;
            audio_device->PlayoutIsAvailable(&ok);
            if (!ok) {
                RTC_LOG(LS_WARNING) << "PlayoutIsAvailable failed, mic_id: " << mic_id_;
                err = KRTCError::kAudioInitRecordingErr;
                break;
            }

            int32_t ret = audio_device->InitPlayout();
            if (audio_device->StartPlayout()) {
                RTC_LOG(LS_WARNING) << "StartPlayout failed!!!";
                err = KRTCError::kAudioStartRecordingErr;
                break;
            }

            // 8. 启动麦克风采集
            if (audio_device->StartRecording()) {
                RTC_LOG(LS_WARNING) << "StartRecording failed, mic_id: " << mic_id_;
                err = KRTCError::kAudioStartRecordingErr;
                break;
            }

            has_start_ = true;

        } while (0);

        if (err == KRTCError::kNoErr) {
            if (KRTCGlobal::Instance()->engine_observer()) {
                KRTCGlobal::Instance()->engine_observer()->OnAudioSourceSuccess();
            }
        }
        else {
            if (KRTCGlobal::Instance()->engine_observer()) {
                KRTCGlobal::Instance()->engine_observer()->OnAudioSourceFailed(err);
            }
        }

    })); 
}

这里音频audio_device->StartRecording之前,还必须加上audio_device->StartPlayout()否则会报错
(audio_device_core_win.cc:2351): Playout must be started before recording when using the built-in AEC
外部获取音频裸流
1、添加ADMDataObserver,继承自webrtc::AudioDeviceDataObserver

class ADMDataObserver : public webrtc::AudioDeviceDataObserver {
private:
    virtual void OnCaptureData(const void* audio_samples,
        const size_t num_samples,
        const size_t bytes_per_sample,
        const size_t num_channels,
        const uint32_t samples_per_sec) override {
        
        }
     
    virtual void OnRenderData(const void* audio_samples,
        const size_t num_samples,
        const size_t bytes_per_sample,
        const size_t num_channels,
        const uint32_t samples_per_sec) override {
        
    }

};

OnCaptureData 音频采集麦克风数据,OnRenderData需要播放的扬声器数据。。
2、创建webrtc::AudioDeviceModule

rtc::scoped_refptr<webrtc::AudioDeviceModule> audio_device_;

worker_thread_->Invoke<void>(RTC_FROM_HERE, [=]() {
        audio_device_ = webrtc::AudioDeviceModule::Create(
            webrtc::AudioDeviceModule::kPlatformDefaultAudio,
            task_queue_factory_.get());
        audio_device_ = webrtc::CreateAudioDeviceWithDataObserver(audio_device_, std::make_unique<ADMDataObserver>());
        audio_device_->Init();
    });

3、将audio_device_传入到webrtc::CreatePeerConnectionFactory即可。。

webrtc::CreatePeerConnectionFactory(
        network_thread_.get(), /* network_thread */
        worker_thread_.get(), /* worker_thread */
        signaling_thread_.get(),  /* signaling_thread */
        audio_device_,  /* default_adm */
    ******

参考资料

https://blog.csdn.net/qq_22658119/article/details/117664188
https://blog.csdn.net/weixin_39343678/article/details/99948451文章来源地址https://www.toymoban.com/news/detail-615967.html

到了这里,关于native webrtc支持切换音频采集设备和获取裸流的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 使用ION-SFU和媒体设备在Golang中构建一个WebRTC视频和音频广播器

    在本教程中,您将构建一个视频广播应用程序,该应用程序在 Golang 中读取摄像头并将其发送到 ION-SFU(选择性转发单元),从而使 WebRTC 会话更有效地扩展。 WebRTC 是 Web Real-Time Communication 的缩写,是一种利用点对点连接在网络上实现实时音频、视频和数据传输的通信协议。

    2024年02月08日
    浏览(45)
  • 【Win下实现一键快速切换音频输出设备】

    装完新电脑后遇到一个烦恼,我在看视频时喜欢用音响外放,但打游戏时又需要用耳机听声辨位,每次切换都得用鼠标点右下角的小喇叭,对于我这样的懒狗来说,这个过程真的很麻烦,就想自己搞一个脚本,只需要按下一个按键就能快速在两个设备间切换,就像静音键那样

    2024年02月01日
    浏览(40)
  • ReactNative进阶(二十一)开源插件 react-native-device-info 获取设备信息

    项目开发过程中,需要获取设备信息,例如获取设备名称。可通过使用开源的第三方组件react-native-device-info,该组件适用于 iOS 和 Android 双平台。 在 ReactNative 项目中可通过 npm 命令下载 react-native-device-info 组件依赖包: android 需要在 AndroidManifest.xml 配置文件添加 android.permiss

    2024年02月07日
    浏览(40)
  • WebRTC Windows Native视频中的DirectShow介绍

    WebRTC视频采集,不同的平台由不同的公司开发设计: Linux系统使用V4L2(Video for Linux Version 2) Mac和IOS都是苹果公司开发的,都使用AVFoundation框架 Windows使用的是微软开发的DS(Direct Show)框架 Android使用camera2.0接口(Camera2Capturer)采集视频。 DirectShow (https://docs.microsoft.com/zh-cn/window

    2024年02月16日
    浏览(49)
  • LiveGBS流媒体平台GB/T28181功能-如何获取接入的海康大华宇视华为摄像头硬件NVR设备通道视频直播流地址HLS/HTTP-FLV/WS-FLV/WebRTC/RTMP/RTSP

    LiveGBS国标GB/T28181流媒体服务器软件,支持设备|平台GB28181注册接入、向上级联第三方国标平台, 可视化的WEB页面管理(页面源码开源);支持云台控制、设备录像检索、回放,支持语音对讲,用户管理, 多种协议流输出,实现浏览器无插件直播。 在项目过程中,需要播放视频

    2024年03月25日
    浏览(75)
  • 【WebRTC---源码篇】(三:一)音频轨

    音频轨的创建时序在Conductor::AddTracks()中 通过代码我们可以看出,创建音频轨需要两个参数,第二个参数为通过PcFactory构建的音频源 通过上面的代码我们可以看出,CreateAudioSource只是简单的创建了一个LocalAudioSource对象并返回

    2024年02月14日
    浏览(34)
  • WebRTC音视频采集和播放示例及MediaStream媒体流解析

    示例代码——同时打开摄像头和麦克风,并在页面显示画面和播放捕获的声音 API解析 mediaDevices MediaStream媒体流 代码 效果 1. mediaDevices mediaDevices 是 Navigator 只读属性,返回一个 MediaDevices 对象,该对象可提供对相机和麦克风等媒体输入设备的连接访问,也包括屏幕共享。 语法

    2023年04月08日
    浏览(40)
  • webrtc 入门第一章 基本设备操作

    一、介绍 1、webrtc是什么 webrtc是一个由google发起的开源实时通信方案,其中包括视频/音频采集、编解码、数据传输、音视频展示的功能。在浏览器,桌面应用,移动设备或者lot设备上都有可以运行的api接口,均可实现实时通信能力。web开发者可以基于web api开发基于视频、音

    2024年02月02日
    浏览(42)
  • WebRTC系列-Qos系列之音频设置丢包重传nack

    在目前的WebRTC各个版本中音频的重传目前都是默认处于关闭的,也就是音频的sdp里默认是没有NACK;设置打开音频NACK有两种方式: 修改源码的方式,通过前面的一系列文章我们知道WebRTC中收集音频编码信息是在 WebRtcVoiceEngine 的 CollectCodecs(...) 方法中,在这个方法里可以找到

    2023年04月16日
    浏览(38)
  • 【WebRTC---源码篇】(十一:一)采集编码发送期间使用时间戳的详细解读

    一、时间戳定义 1、 NTP时间 2、本地时间 从系统启动这一刻起开始计时,不受系统时间被用户改变的影响。

    2024年02月22日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包