欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

AudioTrack获取进程修改指定app的StreamType

程序员文章站 2022-06-16 18:40:58
android车机设备为了特定的区别于手机终端设备的应用场景,需要将部分特殊的音频流在系统框架层强制进行转换,针对这一需求,所以我们可以在音频数据流生产之处,强制改变。首先看看系统定义多少种Audio StreamType上源码system/media/audio/include/system/audio-base.htypedef enum { AUDIO_STREAM_DEFAULT = -1, // (-1) AUDIO_STREAM_MIN = 0, AUDIO_STR...

android车机设备为了特定的区别于手机终端设备的应用场景,需要将部分特殊的音频流在系统框架层强制进行转换,针对这一需求,所以我们可以在音频数据流生产之处,强制改变。

首先看看系统定义多少种Audio StreamType
上源码system/media/audio/include/system/audio-base.h

typedef enum {
    AUDIO_STREAM_DEFAULT = -1, // (-1)
    AUDIO_STREAM_MIN = 0,
    AUDIO_STREAM_VOICE_CALL = 0,
    AUDIO_STREAM_SYSTEM = 1,
    AUDIO_STREAM_RING = 2,
    AUDIO_STREAM_MUSIC = 3,
    AUDIO_STREAM_ALARM = 4,
    AUDIO_STREAM_NOTIFICATION = 5,
    AUDIO_STREAM_BLUETOOTH_SCO = 6,
    AUDIO_STREAM_ENFORCED_AUDIBLE = 7,
    AUDIO_STREAM_DTMF = 8,
    AUDIO_STREAM_TTS = 9,
    AUDIO_STREAM_ACCESSIBILITY = 10,
    AUDIO_STREAM_REROUTING = 11,
    AUDIO_STREAM_PATCH = 12,
    AUDIO_STREAM_PUBLIC_CNT = 11, // (ACCESSIBILITY + 1)
    AUDIO_STREAM_FOR_POLICY_CNT = 12, // PATCH
    AUDIO_STREAM_CNT = 13, // (PATCH + 1)
} audio_stream_type_t;

下面以导航app为例,导航在车机的应用场景的数据流级别高于普通的媒体播放,所以我们把导航app默认设置的music type强制修改为alarm流,这样以备后续的车机音频策略的实施。

音频数据的生产者AudioTrack可以助我们一臂之力,简单的描述下思路便直接上代码,直接获取到对应导航app的进程,当前进程活跃(导航在进行tts语音播报的时刻),强制修改为AUDIO_STREAM_ALARM .

frameworks\av\media\libaudioclient\AudioTrack.cpp
增加函数获取

static int get_pack_from_cmdline(int pid, char *buf, int len) {
   char filename[256];
   int n = 0;
   int fd;
   if (pid < 1 || buf == NULL || len < 256) {
       return -1;
   }
   memset(filename, 0, 256);
   sprintf(filename, "/proc/%d/cmdline", pid);
   fd = open(filename, O_RDONLY);
   if (fd < 0) {
       perror("open:");
       return -1;
   }
   int ret = read(fd, buf, len);
   close(fd);
   memset(filename, 0, 256);
   while (1) {
       if (buf[n] == ' '||buf[n] == ':')
           break;
       filename[n] = buf[n];
       n++;
       if (n == ret)
           break;
   }
   memset(buf, 0, len);
   memcpy(buf, filename, n + 1);
   return ret;
}

AudioTrack最初设置playback参数的set函数具体实施流类型的转变

  status_t AudioTrack::set(
        audio_stream_type_t streamType,
        uint32_t sampleRate,
        audio_format_t format,
        audio_channel_mask_t channelMask,
        size_t frameCount,
        audio_output_flags_t flags,
        callback_t cbf,
        void* user,
        int32_t notificationFrames,
        const sp<IMemory>& sharedBuffer,
        bool threadCanCallJava,
        audio_session_t sessionId,
        transfer_type transferType,
        const audio_offload_info_t *offloadInfo,
        uid_t uid,
        pid_t pid,
        const audio_attributes_t* pAttributes,
        bool doNotReconnect,
        float maxRequiredSpeed)
{
    MTK_ALOGI("set(): %p, streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
          "flags #%x, notificationFrames %d, sessionId %d, transferType %d, uid %d, pid %d",
          this, streamType, sampleRate, format, channelMask, frameCount, flags,
          notificationFrames, sessionId, transferType, uid, pid);
    ALOGV("set(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
          "flags #%x, notificationFrames %d, sessionId %d, transferType %d, uid %d, pid %d",
          streamType, sampleRate, format, channelMask, frameCount, flags, notificationFrames,
          sessionId, transferType, uid, pid);
...
...

   //获取进程
	char pidName[256];
	memset(pidName, 0, 256);
	get_pack_from_cmdline(getpid(), pidName, 256);
	if (strcmp(pidName,"具体的导航app进程名,eg.高德com.autonavi.amapauto")== 0){
		mSteamType = AUDIO_STREAM_ALARM ;
	}

如此一来,就可以将导航的audio数据流和媒体播放的数据流区别,以便车机上的音频策略的实现.

本文地址:https://blog.csdn.net/jeephao/article/details/107302285