AudioFlinger无法创build轨道。 状态:-12

我正在为android 2.2进行编程,并试图使用SoundPool类同时播放几个声音,但是随机时间的声音会停止从扬声器中传出。

对于每个将要播放的声音,都会在logcat中打印出来:

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

没有exception抛出,程序继续执行没有任何变化,除了缺乏音量。 我很难追查哪些情况会导致错误,或者在发生错误后重新创build。 我无法find任何地方的文档中的错误,几乎是在一个损失。

任何帮助将不胜感激!

编辑:我忘了提及,我正在加载MP3文件,而不是ogg。

我几乎和我最近试图加载和播放的一些声音完全相同的问题。

我甚至打破了加载一个导致这个错误的单一的MP3。

有一件事我注意到:当我加载-1的循环,它会失败,“状态12”的错误,但是当我加载它循环0次,它会成功。 甚至试图加载1次失败。

最后的解决scheme是在audio编辑器中打开mp3,然后用略低的质量重新编辑,这样文件就变小了,而且似乎不占用系统中相当多的资源。

最后,这个讨论鼓励对正在使用的对象执行一个释放,因为确实可以使用的资源有严格的限制,并且是系统范围的,所以如果使用多个资源,其他应用程序将无法使用它们。

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

对于audio,每个设备有32个活动AudioTrack对象的硬性限制(不是每个应用程序:您需要与系统的其余部分共享这32个),并且AudioTrack在SoundPool,ToneGenerator,MediaPlayer,基于OpenSL ES的本地audio但是实际的AudioTrack限制是<32; 它更多地取决于内存,CPU负载等软性因素。另外请注意,Androidaudio混音器中的限制器当前没有dynamic范围压缩,所以如果您有大量主动声音,则可以剪辑大声说话。

对于video播放器来说,由于video放在设备上的强烈负载,极限要低得多。

我将以此为契机来提醒媒体开发者:请记住,当您的应用程序暂停时,请为媒体对象调用release()。 这释放了其他应用程序将需要的底层资源。 不要依靠垃圾收集器进行最终清理的媒体对象,因为这具有不可预知的时间。

我有一个类似的问题,我的Android游戏中的音乐跟踪器会掉落音符,我得到Audioflinger错误(虽然我的状态是-22)。 我得到了它的工作,所以这可能会帮助一些人。

单个样品同时输出多次时出现问题。 所以在我的情况下,这是一个单一的样品正在两个或两个以上的轨道上播放。 这似乎偶尔会出现僵局或者其他问题,两个音符中的一个将被删除。 解决scheme是有两个样本副本(两个实际的ogg文件 – 相同,但在资产)。 然后,即使我正在播放同一个样本,但在每个轨道上,它都来自不同的文件。 这完全解决了我的问题。

不知道为什么它会将样本caching到内存中,但即使将相同的文件加载到两个不同的声音中也没有修复它。 只有当样本从两个不同的文件中出来时,错误才会消失。

我相信这不会帮助每个人,这不是最漂亮的解决scheme,但它可以帮助别人。

john.k.doe是对的。 你必须减less你的MP3文件的大小。 你应该保持每个文件大小在100kb以下。 我必须使用32kbps的常量比特率(CBR)而不是通常的128kbps将我的200kb文件减less到72kb。 这对我有效!

就像上面说的那样,循环存在一个问题:当我设置重复-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); 

它的工作,但延迟是不同的设备。

就我而言,把MP3的质量和档案大小降低到100kb以下是不够的,因为一些51kb的文件起作用,而一些更长的41kb的文件仍然没有。

帮助我们的是将采样率从44100降低到22050,或者将持续时间缩短到不到5秒。

尝试

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

释放应该保持你的资源。

一个soundPool具有1(Mb)的内部内存限制。 如果你的声音质量很高,你可能会碰到这个。 如果你有很多声音,并且正在达到这个极限,只需要创build更多的声音库,然后在你的声音之间分配声音。

如果您在到达之前耗尽内存,您甚至可能无法达到硬轨限制。

该错误不仅在达到stream或跟踪限制时才会出现,而且还会出现内存限制。 Soundpool将停止播放旧的和/或优先级降低的声音以播放新声音。

我遇到了这个问题。 为了解决它,我完成播放声音后运行SoundPool对象的方法.release()。

这是我的代码:

 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秒,所以我在Thread.sleep()中放了2000毫秒的值,以便在玩家完成之后才释放资源。

我看到太多太复杂的答案。 错误-12意味着你没有释放variables。 在播放8次OGGaudio文件后,我遇到了同样的问题。 这对我工作:

 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()之后释放variables会搞砸了,而且不可能在onCompletion里面释放variables,所以请注意我在释放variables之前如何释放variables(并检查null以避免出现空指针exception)。

它的作品像魅力!