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

时间:2012-02-22 23:16:44

标签: android session audio global effects

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

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

如果不推荐这样做,那么什么是替代API?我的目标将效果附加到全局输出组合......

3 个答案:

答案 0 :(得分:4)

是的,由于side-effects isues,它已被弃用。

Android Developers网站指出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();

答案 1 :(得分:1)

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

IntentFilter()
    .apply { addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) }
    .apply { addAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION) }
    .run { registerReceiver(mAudioSessionReceiver, this) } `

其中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)
        }
    }
}`

然后,您可以在onStartCommand中获得意图:

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
}`

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

unregisterReceiver(mAudioSessionReceiver)`

答案 2 :(得分:0)

根据Android,您可以使用ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION接收正在播放的音频会话的ID:

  

旨在向效果控制应用程序或服务发出信号,表明已打开一个新的音频会话并要求应用音频效果。

我尝试在清单中添加常量,但是没有用:

<receiver android:name=".receivers.AudioSessionReceiver">
        <intent-filter>
            <action android:name="android.media.action.OPEN_AUDIO_EFFECT_CONTROL_SESSION"/>
        </intent-filter>
</receiver>

如果您知道如何使用该常数,则该意图将包含音频会话ID,可用于应用所需的均衡器设置。 (如果您在所有这些年中都找到了解决方法,您愿意分享吗?)