Android audio设置投屏和喇叭双输出

业务场景:

在 Android13 平台上,使用 USB 投屏工具scrcpy,投屏到电脑端时,声音被截到 电脑端播放,Android设备 端静音,在Android11及之前都是 在Android设备端正常播放。

分析:

scrcpy 支持 Android11以上版本的工具。投屏时有设置设备端AudioSource.REMOTE_SUBMIX属性,音频输出设备是 AUDIO_DEVICE_OUT_REMOTE_SUBMIX 

音频设备输出选择源码中在 Engine.cpp中

frameworks/av/services/audiopolicy/enginedefault/src/Engine.cpp
    
    case STRATEGY_MEDIA: {
        DeviceVector devices2;
        if (strategy != STRATEGY_SONIFICATION) {
            // no sonification on remote submix (e.g. WFD)
            sp<DeviceDescriptor> remoteSubmix;
            if ((remoteSubmix = availableOutputDevices.getDevice(
                    AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0"),
                    AUDIO_FORMAT_DEFAULT)) != nullptr) {
                devices2.add(remoteSubmix);
            }
        }

若项目需要投屏时喇叭也正常播放,需要修改此处为

    case STRATEGY_MEDIA: {
        DeviceVector devices2;
        if (strategy != STRATEGY_SONIFICATION) {
            // no sonification on remote submix (e.g. WFD)
            sp<DeviceDescriptor> remoteSubmix;
            if ((remoteSubmix = availableOutputDevices.getDevice(
                    AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0"),
                    AUDIO_FORMAT_DEFAULT)) != nullptr) {

                    //需要在这里添加 SPEAKER 输出设备
					devices2 = availableOutputDevices.getDevicesFromTypes({
                        AUDIO_DEVICE_OUT_REMOTE_SUBMIX, AUDIO_DEVICE_OUT_SPEAKER});
            }
        }

至此,声音即可从电脑播放,Android设备喇叭本身也可正常播放。

注:

Android10 以下版本参考:

修改前:

frameworks/av/services/audiopolicy/enginedefault/src/Engine.cpp

if(mAvailableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0")) != 0) {
       device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
}

修改后:

if (mAvailableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0")) != 0) {
       device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
                               
       device2 |= (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE);
                               
       device2 |= (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER);
} 

也就是说 device2的获取方式有点差异。

如果此文章解答了您的相关疑惑,节约了您的宝贵时间,可以Shang小编鸡腿哟!

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Android上使用AudioRecord设置输出路径,可以使用AudioRecord类来录制音频,然后使用FileOutputStream类将录制的音频保存到指定路径的文件中。下面是一个简单的示例代码: ``` // 音频源 int audioSource = MediaRecorder.AudioSource.MIC; // 采样率 int sampleRateInHz = 44100; // 声道数 int channelConfig = AudioFormat.CHANNEL_IN_MONO; // 音频格式 int audioFormat = AudioFormat.ENCODING_PCM_16BIT; // 缓冲区大小 int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat); // 创建AudioRecord对象 AudioRecord recorder = new AudioRecord(audioSource, sampleRateInHz, channelConfig, audioFormat, bufferSizeInBytes); // 设置输出文件路径 String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/test.pcm"; FileOutputStream os = new FileOutputStream(filePath); // 开始录制 recorder.startRecording(); // 录制数据 byte[] buffer = new byte[bufferSizeInBytes]; while (recorder.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) { int len = recorder.read(buffer, 0, bufferSizeInBytes); os.write(buffer, 0, len); } // 停止录制 recorder.stop(); // 释放资源 recorder.release(); os.flush(); os.close(); ``` 在上述代码中,`AudioRecord`类的构造函数设置音频源、采样率、声道数、音频格式和缓冲区大小。`getMinBufferSize()`方法可以获取最小的缓冲区大小。`startRecording()`方法开始录制,`read()`方法读取录制的数据,`stop()`方法停止录制,`release()`方法释放资源。`FileOutputStream`类的构造函数设置输出文件路径,`write()`方法将数据写入文件中。 注意,在使用AudioRecord录制音频前,需要添加录音权限。可以在AndroidManifest.xml文件中添加以下权限: ``` <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ``` 其中`RECORD_AUDIO`权限用于录音,`WRITE_EXTERNAL_STORAGE`权限用于保存文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值