AudioFlinger无法创建曲目。状态:-12

时间:2012-08-15 05:44:18

标签: android soundpool

我正在为Android 2.2编程,我正在尝试使用 SoundPool课程可同时播放多种声音,但在随机时间感觉声音将不再从扬声器中传出。

对于本来会播放的每个声音都会打印在logcat中:

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

不会抛出任何异常,程序会继续执行而不会因为缺少音量而进行任何更改。我很难跟踪导致错误的条件或在错误发生后重新创建错误。我无法在任何地方找到文档中的错误,而且几乎不知所措。

非常感谢任何帮助!

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

9 个答案:

答案 0 :(得分:21)

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

我甚至将其分解为加载导致此错误的单个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;它更多地取决于软因素   如内存,CPU负载等。另请注意限制器中的   Android音频混音器目前没有动态范围压缩,   因此,如果您有大量活动声音,则可以剪辑   他们都很响亮。

     

对于视频播放器,由于负载过重,限制要低得多   该视频放在设备上。

     

我会以此为契机提醒媒体开发者:拜托   记得在应用暂停时为媒体对象调用release()。   这释放了其他应用程序所需的底层资源。   不要依赖于最终确定的被清理的媒体对象   垃圾收集器,因为它具有不可预测的时间。

答案 1 :(得分:2)

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

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

不确定为什么它可以正常工作,因为我将样本缓存到内存中,但即使将相同的文件加载到两个不同的声音也无法修复它。只有当样本来自两个不同的文件时,错误才会消失。

我确信这对每个人都没有帮助,这不是最漂亮的解决方案,但它可能对某人有所帮助。

答案 2 :(得分:2)

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

答案 3 :(得分:1)

如上所述,循环存在问题:当我将repeat设置为-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);

并且它正在工作,但不同设备的延迟是不同的。

答案 4 :(得分:1)

在我的情况下,将MP3的质量和文件大小降低到100kb以下是不够的,因为一些51kb的文件工作,而一些较长的41kb文件仍然没有。

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

答案 5 :(得分:1)

我看到太多过于复杂的答案。错误-12表示您没有释放变量。 我播放8次OGG音频文件后遇到了同样的问题。 这对我有用:

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异常)。

它就像魅力一样!

答案 6 :(得分:0)

尝试

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

发布应保留您的资源。

答案 7 :(得分:0)

单个soundPool的内部存储器限制为1(一)Mb。如果您的声音质量非常高,您可能会遇到这种情况。如果你有很多声音并达到这个限制,只需创建更多的音池,并在它们之间分配声音。

如果在到达目的地之前内存不足,您甚至可能无法达到硬限制。

该错误不仅会在达到流或曲目限制时出现,还会出现内存限制。 Soundpool将停止播放旧的和/或去优先级的声音以播放新的声音。

答案 8 :(得分:0)

我遇到了这个问题。为了解决这个问题,我在完成播放声音后运行了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毫秒的值,以便在播放器完成后才释放资源。