Подтвердить что ты не робот

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

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

для каждого воспроизводимого звука это будет напечатано в logcat:

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

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

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

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

4b9b3361

Ответ 1

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

я даже сломал его, чтобы загрузить один 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-микшере Android в настоящее время нет сжатия динамического диапазона, поэтому можно закрепить, если у вас есть большое количество активных звуков и все они громкие.

Для видеоплееров предел намного ниже из-за интенсивной нагрузки это видео помещается на устройство.

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

Ответ 2

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

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

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

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

Ответ 3

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

Ответ 4

Как сказано выше, есть проблема с циклом: когда я устанавливаю повторение -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);

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

Ответ 5

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

Что помогло нам снизить частоту дискретизации от 44100 до 22050 или сократить продолжительность до менее 5 секунд.

Ответ 6

Попробуйте

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

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

Ответ 7

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

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

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

Ответ 8

У меня была эта проблема. Чтобы решить эту проблему, я запускаю метод .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 miliseconds в Thread.sleep(), чтобы только освободить ресурсы после того, как игрок закончил.

Ответ 9

Я вижу слишком много сложного ответа. Ошибка -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, чтобы избежать исключений nullpointer).

Он работает как шарм!