AudioFlinger не смог создать дорожку. статус: -12

Я программирую для Android 2.2 и пытаюсь использовать класс SoundPool для воспроизводить несколько звуков одновременно, но в случайное время звук перестанет исходить из динамиков.

для каждого звука, который должен был быть воспроизведен, это печатается в логарифме:

AudioFlinger could not create track. status: -12 
Error creating AudioTrack
Audio track delete

Никаких исключений не выдается, и программа продолжает выполняться без каких-либо изменений, за исключением отсутствия объема. Мне было очень трудно отследить, какие условия вызывают ошибку, или воссоздать ее после того, как она произошла. Я нигде не могу найти ошибку в документации и почти в недоумении.

Любая помощь будет принята с благодарностью!

Изменить: я забыл упомянуть, что загружаю файлы mp3, а не ogg.


person user1599837    schedule 15.08.2012    source источник
comment
Сколько треков вы создаете? AFAIK -12 - это NO_MEMORY, что может означать, что у вас закончились треки (я думаю, что максимальное количество открытых треков раньше было 32 - не уверен, что это все еще правда).   -  person Michael    schedule 15.08.2012
comment
Хмммм, я загружаю много треков, но они разбиты на 5 саундпулов. каждый звуковой пул будет иметь максимум ~ 15 загруженных звуков. вы знаете, были ли 32 максимальные дорожки общесистемными или для звукового пула?   -  person user1599837    schedule 16.08.2012
comment
Это на поток микшера (из которых у вас есть один на выходной поток AFAIK). Но поскольку многие платформы используют один выходной поток для всего воспроизведения, отличного от A2DP, это по существу становится глобальным ограничением.   -  person Michael    schedule 16.08.2012
comment
Я получил это, когда я сказал стоп, но не смог вызвать релиз на своих треках.   -  person Alexander Pruss    schedule 02.11.2014


Ответы (9)


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

я даже разбил его на загрузку одного mp3, который вызывал эту ошибку.

я заметил одну вещь: когда я загружался с циклом -1, он терпел неудачу с ошибкой «статус 12», но когда я загружал его в цикл 0 раз, он завершался успешно. даже попытка загрузить 1 раз не удалась.

окончательное решение состояло в том, чтобы открыть mp3 в аудиоредакторе и повторно отредактировать его с немного меньшим качеством, так что теперь файл меньше и, похоже, не занимает столько ресурсов в системе.

наконец, есть это обсуждение, которое поощряет выполнение выпуска объектов, которые вы используете, потому что действительно существует жесткое ограничение на ресурсы, которые можно использовать, и оно общесистемное, поэтому, если вы используете несколько ресурсов, другие приложения не смогут их использовать.

https://groups.google.com/forum/#!topic/android-platform/tyITQ09vV3s/discussion%5B1-25%5D

Для аудио существует жесткое ограничение в 32 активных объекта AudioTrack на устройство (не на приложение: эти 32 объекта должны использоваться совместно с остальной системой), а AudioTrack используется внутри SoundPool, ToneGenerator, MediaPlayer. , нативное аудио на основе OpenSL ES и т. д. Но фактическое ограничение AudioTrack составляет ‹ 32; это больше зависит от мягких факторов, таких как память, загрузка процессора и т. д. Также обратите внимание, что ограничитель в звуковом микшере Android в настоящее время не имеет сжатия динамического диапазона, поэтому можно обрезать, если у вас есть большое количество активных звуков, и они все громко.

Для видеоплееров лимит намного ниже из-за сильной нагрузки, которую видео оказывает на устройство.

Я воспользуюсь этим как возможностью напомнить разработчикам мультимедиа: не забывайте вызывать release() для объектов мультимедиа, когда ваше приложение приостановлено. Это освобождает базовые ресурсы, которые потребуются другим приложениям. Не полагайтесь на очистку медиа-объектов при финализации сборщиком мусора, так как это имеет непредсказуемое время.

person john.k.doe    schedule 19.08.2012

У меня была аналогичная проблема, когда музыкальный трекер в моей игре для Android отбрасывал ноты, и я получал ошибку Audioflinger (хотя мой статус был -22). Однако у меня это работает, так что это может помочь некоторым людям.

Проблема возникла, когда один семпл выводился несколько раз одновременно. Так что в моем случае это был один семпл, воспроизводимый на двух или более дорожках. Иногда казалось, что это заходит в тупик или что-то в этом роде, и одна из двух заметок будет отброшена. Решение состояло в том, чтобы иметь две копии образца (два фактических файла ogg - идентичные, но оба в активах). Затем на каждом треке, хотя я проигрывал один и тот же семпл, он исходил из разных файлов. Это полностью решило проблему для меня.

Не уверен, почему это работает, когда я кэширую сэмплы в памяти, но даже загрузка одного и того же файла в два разных звука не исправила ситуацию. Только когда образцы вышли из двух разных файлов, ошибки исчезли.

Я уверен, что это не поможет всем, и это не самое красивое исправление, но это может помочь кому-то.

person user2016617    schedule 28.01.2013
comment
Большое тебе спасибо! Это действительно помогло мне :) У меня была ошибка, упомянутая в вопросе, при переключении на динамик при воспроизведении голоса (с exo player). И проблема заключалась в том, что на самом деле «одновременно» воспроизводился голос сразу после вызова паузы без какой-либо задержки. - person Masoud Maleki; 05.05.2021

john.k.doe прав. Вы должны уменьшить размер вашего mp3 файла. Вы должны сохранить размер до 100 КБ на файл. Мне пришлось уменьшить файл размером 200 КБ до 72 КБ, используя постоянную скорость передачи данных (CBR) 32 кбит/с вместо обычных 128 кбит/с. Это сработало для меня!

person rotterick    schedule 09.05.2013

Пытаться

 final ToneGenerator tg = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 50);
 tg.startTone(ToneGenerator.TONE_PROP_BEEP, 200);
 tg.release();

Освобождение должно сохранить ваши ресурсы.

person Cléssio Mendes    schedule 27.12.2012

Я был с этой проблемой. Чтобы решить эту проблему, я запускаю метод .release() объекта SoundPool после завершения воспроизведения звука.

Вот мой код:

SoundPool pool = new SoundPool(10, AudioManager.STREAM_MUSIC, 50);
final int teste = pool.load(this.ctx,this.soundS,1);
pool.setOnLoadCompleteListener(new OnLoadCompleteListener(){

@Override 
    public void onLoadComplete(SoundPool sound,int sampleId,int status){
        pool.play(teste, 20,20, 1, 0, 1);
        new Thread(new Runnable(){
@Override                       
     public void run(){
         try {
        Thread.sleep(2000);
                pool.release();
         } catch (InterruptedException e) { e.printStackTrace(); }
         }
        }).start();
    }
});

Обратите внимание, что в моем случае мои звуки имели длину максимум 1-2 секунды, поэтому я установил значение 2000 миллисекунд в Thread.sleep(), чтобы освобождать ресурсы только после того, как проигрыватель закончил.

person Afaria    schedule 06.11.2013

Как сказано выше, есть проблема с зацикливанием: когда я устанавливаю повтор на -1, я получаю эту ошибку, но с 0 все работает правильно. Я заметил, что некоторые звуки выдают эту ошибку, когда я пытаюсь воспроизвести их один за другим. Например:

mSoundPool.stop(mStreamID);
mStreamID = mSoundPool.play(mRandID, mVolume, mVolume, 1, -1, 1f);

В таком случае первый трек воспроизводится нормально, но когда я переключаю звуки, следующий трек выдает эту ошибку. Похоже, при использовании зацикливания буфер каким-то образом перегружается, и mSoundPool.stop не может сразу освободить ресурсы.

Решение:

final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
   @Override
   public void run() {
      mStreamID = mSoundPool.play(mRandID, mVolume, mVolume, 1, -1, 1f);
}, 350);

И это работает, но задержка разная для разных устройств.

person Oleksandr Albul    schedule 01.07.2015

В моем случае снижения качества и, следовательно, размера файлов MP3 до менее чем 100 КБ было недостаточно, поскольку некоторые файлы размером 51 КБ работали, а некоторые файлы большей продолжительности 41 КБ по-прежнему не работали.

Нам помогло снижение частоты выборки с 44 100 до 22 050 или сокращение продолжительности до менее чем 5 секунд.

person Steve Castro    schedule 03.09.2015

Я вижу слишком много сложных ответов. Ошибка -12 означает, что вы не освободили переменные. У меня была такая же проблема после того, как я воспроизвел аудиофайл OGG 8 раз. Это сработало для меня:

SoundPoolPlayer onBeep; //Global variable 

    if(onBeep!=null){
       onBeep.release();
    }
    onBeep = SoundPoolPlayer.create(getContext(), R.raw.micon);
    onBeep.setOnCompletionListener(
       new MediaPlayer.OnCompletionListener() {
          @Override
          public void onCompletion(MediaPlayer mp) {    //mp will be null here
             loge("ON Beep! END");
             startGoogleASR_API_inner();
             }
                        }
          );
    onBeep.play();

Освобождение переменной сразу после .play() может все испортить, и невозможно освободить переменную внутри onCompletion, поэтому обратите внимание, как я освобождаю переменную перед ее использованием (и проверяю значение null, чтобы избежать исключений нулевого указателя).

Это работает как шарм!

person Josh    schedule 30.10.2017

Один саундпул имеет ограничение внутренней памяти 1 (один) Мб. Вы можете попасть в это, если ваш звук очень высокого качества. Если у вас много звуков и вы достигаете этого предела, просто создайте больше звуковых пулов и распределите по ним свои звуки.

Возможно, вы даже не сможете достичь предела жёсткой дорожки, если у вас заканчивается память до того, как вы туда доберётесь.

Эта ошибка появляется не только при достижении предела потока или трека, но и при достижении предела памяти. Soundpool перестанет воспроизводить старые и/или лишенные приоритета звуки, чтобы воспроизвести новый звук.

person Dominic Cerisano    schedule 08.10.2013