AudioFlinger не смог создать трек. статус: -12
Я программирую для Android 2.2 и пытаюсь использовать
SoundPool класс для воспроизведения нескольких звуков одновременно, но при том, что кажется случайным, звук перестает выходить из динамиков.
для каждого воспроизводимого звука это будет напечатано в logcat:
AudioFlinger could not create track. status: -12
Error creating AudioTrack
Audio track delete
Никакое исключение не выбрасывается, и программа продолжает выполняться без каких-либо изменений, за исключением недостатка тома. Мне было очень трудно определить, какие условия вызывают ошибку или воссоздают ее после ее возникновения. Я не могу найти ошибку в документации в любом месте и в значительной степени потеряю.
Любая помощь будет принята с благодарностью!
Изменить: я забыл упомянуть, что загружаю файлы mp3, а не ogg.
Ответы
Ответ 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).
Он работает как шарм!