Предпочитан начин за прикачване на AudioEffect към глобален микс?

В Android, AudioEffect API, всички вградени ефекти като Equalizer идват с предупреждение

„ЗАБЕЛЕЖКА: прикачването на еквалайзер към глобалния аудио изходен микс чрез използване на сесия 0 е отхвърлено.“

Ако това е отхвърлено, тогава какъв е заместващият API? Моята цел е да прикача ефект към глобалния изходен микс...


person yano    schedule 22.02.2012    source източник


Отговори (3)


Да, отхвърлено е поради проблеми със странични ефекти.

Уебсайтът на 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();
person Halim Qarroum    schedule 05.04.2013
comment
Както бе споменато в един от коментарите във връзката ви, това не е заобиколно, в случай че искате да приложите еквалайзер или друг ефект към съществуващ поток или всички потоци. - person yano; 06.04.2013
comment
Засега все още можете да използвате глобалната аудио сесия с Equalizer. Няма замяна, амортизацията не винаги идва със замяна. Те просто прецениха, че това изглежда не работи добре и решиха да запазят поддръжката за това до следващи версии на Android. Заобиколното решение във вашия случай е да прикачите еквалайзер към всеки екземпляр на MediaPlayer във вашите приложения. Ако не, поемете риска да запазите Equalizer прикачен към глобалната аудио сесия, знаейки, че със сигурност няма да работи при следващи версии. - person Halim Qarroum; 06.04.2013
comment
Здравейте Халим, Как да прикача еквалайзер към всеки екземпляр на MediaPlayer? Моля, споделете повече информация за това. Също така Каква е алтернативата за прикачване на ефект глобално в ICS? - person JRC; 24.07.2013

Няма алтернатива за прикачване на 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) } `

където 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)`
person Thomas W.    schedule 24.11.2019

Според Android можете да използвате ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION за получаване идентификаторът на възпроизвеждана аудио сесия:

Намерение да сигнализира на приложението или услугата за контрол на ефекта, че е отворена нова аудио сесия и изисква прилагането на аудио ефекти.

Опитах се да добавя константата в манифеста, но не се получи:

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

Ако разберете как да използвате константата, намерението ще съдържа идентификатора на аудио сесията, който можете да използвате, за да приложите настройките на еквалайзера, които искате. (Ако сте намерили решение през всичките тези години, бихте ли имали нещо против да споделите?)

person Dropin' Science    schedule 03.10.2019
comment
Това работи само със Spotify, получихте ли представа за това? - person Rishabh Sagar; 02.03.2021