美文网首页
android R 控制设备媒体输出通道

android R 控制设备媒体输出通道

作者: gale_小米 | 来源:发表于2022-09-23 18:15 被阅读0次

1.定制需求,合入第三方蓝牙模块,发送媒体数据传输到第三方设备上;
(遇到问题:第三方蓝牙模块发送数据过到第三方设备,但是本机的媒体应用还走了当前设备的喇叭,需要切换到耳机模式)

2.走AudioManager 模块只能配置当前进程的媒体输出方式;

        if(mAudioManager==null) {
            mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        }
        mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
//        mAudioManager.setMode(AudioManager.MODE_INVALID);
//        mAudioManager.stopBluetoothSco();        //停止蓝牙耳机
//        mAudioManager.setBluetoothScoOn(false);  //设蓝牙ScoOn关闭,蓝牙耳机则会停止
//        mAudioManager.setSpeakerphoneOn(false);  //设置外放话筒关闭

3.通过AudioSystem设置时好像也没有效果,当设备走设备系统蓝牙的时候才有效;

/*
try {
            @SuppressLint("PrivateApi") Class audioSystemClass = Class.forName("android.media.AudioSystem");
            Method setForceUse = audioSystemClass.getMethod("setForceUse", int.class, int.class);
            setForceUse.invoke(null, FOR_MEDIA, FORCE_SPEAKER);
            setForceUse.invoke(null, FOR_COMMUNICATION, FORCE_SPEAKER);

           // setForceUse.invoke(null, FOR_MEDIA, FORCE_NONE);
            //setForceUse.invoke(null, FOR_COMMUNICATION, FORCE_NONE);
        } catch (Exception e) {
            e.printStackTrace();
        }
*/

通过日志定位

audio_platform: mode(0),devices(0x2):platform device:OUT_DULSPK(0x4)

4.为了简易处理,直接添加一个属性配置,来控制hal层的获取的通道
\hardware\aw\audio\hal\platform.c

int get_platform_device(audio_mode_t mode, audio_devices_t devices,
                        const struct platform *platform)
{
    struct platform_info *info = platform->info;
    int pdev = OUT_NONE;

    /* 1. get platform device */
    if (devices & AUDIO_DEVICE_BIT_IN) {
        audio_devices_t indev = devices & (~AUDIO_DEVICE_BIT_IN);
        /* record device */
        if (indev & AUDIO_DEVICE_IN_BUILTIN_MIC) {
            pdev = (platform->uc & UC_DMIC) ? IN_DMIC : IN_AMIC;
        } else if (indev & AUDIO_DEVICE_IN_WIRED_HEADSET) {
            pdev = IN_HPMIC;
        } else if (indev & AUDIO_DEVICE_IN_ALL_SCO) {
            pdev = IN_BTSCO;
        } else {
            pdev = IN_AMIC;
        }
    } else {
        /* playback device */
        int headphone = AUDIO_DEVICE_OUT_WIRED_HEADSET |
                        AUDIO_DEVICE_OUT_WIRED_HEADPHONE;

        if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
            pdev = OUT_EAR;
        } else if (devices & AUDIO_DEVICE_OUT_SPEAKER &&
                   devices & headphone) {
            pdev = (platform->uc & UC_DUAL_SPK) ? OUT_DULSPK_HP : OUT_SPK_HP;
        } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
            pdev = (platform->uc & UC_DUAL_SPK) ? OUT_DULSPK : OUT_SPK;
        } else if (devices & headphone) {
            pdev = OUT_HP;
        } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
            pdev = OUT_BTSCO;
        } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
            pdev = OUT_HDMI;
        } else {
            pdev = OUT_SPK;
        }
    }
    /* phone record and playback */
    if (AUDIO_MODE_IN_CALL == mode) {
        if (devices & AUDIO_DEVICE_BIT_IN) {
            pdev = (platform->uc & UC_DPHONE)? IN_DPH_REC : IN_APH_REC;
        } else {
            pdev = (platform->uc & UC_DPHONE)? OUT_DPH_PLAY : OUT_APH_PLAY;
        }
    }
    /* TODO: force use platform device */
    /* add attribute start */
    char str[50] = "null";
    char djgd_speaker[10];
    char djgd_fm_speaker[10];
    property_get("persist.sys.djgd_speaker", djgd_speaker, "");
    property_get("persist.sys.djgd_fm_speaker", djgd_fm_speaker, "");
    ALOGV("persist.sys.djgd_speaker :%s(%d)",djgd_speaker, strstr(djgd_speaker, "1"));
    ALOGV("persist.sys.djgd_fm_speaker :%s(%d)",djgd_fm_speaker, strstr(djgd_fm_speaker, "1"));
    if (strstr(djgd_speaker, "1") !=NULL || strstr(djgd_fm_speaker, "1") !=NULL)
    {
        pdev = OUT_HP;
    }
    /* add attribute end*/
    ALOGV("mode(%#x),devices(%#x):platform device:%s(%#x)",
          mode, devices, pdev2str(str, pdev), pdev);

    return pdev;
}

5.经测试发现,只修改上面的位置还会有些问题,就是当有媒体还在播放时会有占用通道没有没被释放,导致媒体通道没有切花过来;

Index: \hardware\aw\audio\hal\audio_hw.c
===================================================================
  */
 
 #define LOG_TAG "audio_hw_primary"
-//#define LOG_NDEBUG 0
+#define LOG_NDEBUG 0

+static int m_platform_device = 4;
+
 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
                          size_t bytes)
 {
@@ -999,6 +1001,24 @@
     int platform_device = 0;
     ALOGV("out_write");
 
+    platform_device = get_platform_device(adev->mode, adev->out_devices,
+                                          adev->platform);
+    ALOGV("platform_device :%d,m_platform_device %d",platform_device,m_platform_device);
+    if (platform_device != m_platform_device )
+    {
+        m_platform_device=platform_device;
+        ALOGV("m_platform_device :%d",m_platform_device);
+        /*pthread_mutex_lock(&out->lock);
+        out->standby = 0;
+        pthread_mutex_lock(&adev->lock);
+        ret = start_output_stream(out);
+        pthread_mutex_unlock(&adev->lock);*/
+        out_standby(&out->stream.common);
+        usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
+               out_get_sample_rate(&out->stream.common));
+        pthread_mutex_unlock(&out->lock);
+        return bytes;
+    }
     pthread_mutex_lock(&out->lock);
     if (out->standby) {
         out->standby = 0;
@@ -1021,6 +1041,7 @@
     platform_plugins_process_read_write(adev->platform, ON_OUT_WRITE,
                                         out->config, (void*)buffer,
                                         out_frames * frame_size);
+
     /* audio dump data write */
     debug_dump_data(buf, out_frames * frame_size, &out->dd_write_out);
     if(out->equalizer != NULL)

相关文章

网友评论

      本文标题:android R 控制设备媒体输出通道

      本文链接:https://www.haomeiwen.com/subject/fhvnortx.html