将AudioEffect附加到全球组合的首选方式?

yan*_*ano 14 audio session android global effects

在Android,AudioEffect API中,所有内置效果(如均衡器)都会出现警告

"注意:不推荐使用会话0将均衡器附加到全局音频输出混音."

如果不推荐这样做,那么什么是替换API?我的目标对全球产出组合产生影响......

Hal*_*oum 6

是的,由于副作用问题,它已被弃用。

Android 开发者网站指出 Equalizer 类的第二个参数应该是:

系统范围内唯一的音频会话标识符。均衡器将附加到同一音频会话中的 MediaPlayer 或 AudioTrack。

你应该改用这个:

MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource( _your_data_source_ );
Equalizer equalizer = new Equalizer(0, mediaPlayer.getAudioSessionId());
equalizer.setEnabled(true);
/* Do your stuff ... */
mediaPlayer.start();
Run Code Online (Sandbox Code Playgroud)


Tho*_* W. 5

没有其他方法可以将 AudioEffect 附加到全局输出。相反,您应该做的是注册一个接收所有音频会话的广播接收器,以便您可以对其应用音频效果。可以在此处找到示例。包含会话ID的意图是在这个BroadcastReceiver中获取的。请记住,只有当您在清单中注册了接收者时,这才有效。或者,您可以在服务 onCreate() 中以编程方式注册接收器,如下所示:

IntentFilter()
    .apply { addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) }
    .apply { addAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION) }
    .run { registerReceiver(mAudioSessionReceiver, this) } `
Run Code Online (Sandbox Code Playgroud)

其中 mAudioSessionReceiver 看起来像这样:

private val mAudioSessionReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        if (intent == null || context == null) {
            return
        }

        val sessionStates = arrayOf(
            AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION,
            AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION
        )
        if (sessionStates.contains(intent.action)) {
            val service = Intent(context, WaveletService::class.java)
            val sessionID = intent.getIntExtra(AudioEffect.EXTRA_AUDIO_SESSION, AudioEffect.ERROR)
            service
                .apply { action = intent.action }
                .apply { putExtra(AudioEffect.EXTRA_AUDIO_SESSION, sessionID) }
            context.startService(service)
        }
    }
}`
Run Code Online (Sandbox Code Playgroud)

然后,您可以在onStartCommand中获取Intent:

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    if (intent == null)
        return START_STICKY

    val sessionID = intent.getIntExtra(AudioEffect.EXTRA_AUDIO_SESSION, AudioEffect.ERROR)

    when (intent.action) {
        AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION -> {
            // create new instance of the AudioEffect using the sessionID
        }
        AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION -> {
            // Release instance of the AudioEffect connected to this sessionID 
        }
    }

    return START_REDELIVER_INTENT
}`
Run Code Online (Sandbox Code Playgroud)

最后,不要忘记在 onDestroy() 中注销接收器:

unregisterReceiver(mAudioSessionReceiver)`
Run Code Online (Sandbox Code Playgroud)