【问题标题】:AudioFlinger could not create track, status: -12; Error creating AudioTrackAudioFlinger 无法创建轨道,状态:-12;创建 AudioTrack 时出错
【发布时间】:2012-03-24 20:06:49
【问题描述】:

我在使用 SoundPool 时遇到问题,因为它拒绝使用我的 .ogg 文件。我收到此错误:

AudioFlinger could not create track, status: -12
 Error creating AudioTrack

我找到了一个关于这个的帖子,(可能的)answer 是:

确保您使用具有恒定比特率的 .ogg 媒体文件!

是这样吗?如果是 - 使用哪个应用程序(Audacity 不支持 .ogg 自定义导出设置)。如果不是 - 还有什么问题?

附带说明 - 在我使用 MediaPlayer 之前,但现在我想并行播放一些声音。

【问题讨论】:

  • 如果使用 ogg OR mp3 并将 play() 中的循环 arg 设置为除 0 以外的任何值,我会收到此错误 - 使用 wav 似乎可以对其进行排序

标签: android soundpool


【解决方案1】:

主要编辑:找到解决问题的方法!!向下滚动!!

我和你在同一条船上。在阅读之前,我必须让您知道我未能提供可以解决此问题的答案。

我已经看到了很多关于 SoundPool 的 Stack Overflow 主题,但我还没有从 Android 书籍中看到很多关于 Java 代码的 SoundPool 问题:

AudioTrack:AudioFlinger 无法创建轨道,状态 -12。
SoundPool:创建 AudioTrack 时出错。

这里是从这里提供的Beginning Android 4 Game Development 源代码中截取的代码(见下文)。你会得到explosion.ogg 文件(在trunk 中,找到Chapter 4 - Android Basics 的/asset 文件夹)。您必须点击右侧的“查看原始文件”才能获取文件。

我所做的只是将源代码直接复制到 Eclipse 中,并将主干提供的explosion.ogg 文件添加到我的项目中。我执行了 Android 模拟器,尝试播放该文件,但我可以告诉你,我仍然得到上面引用的相同 Logcat 错误。

有人在 Youtube 上提供了一段视频,说明 SoundPool 工作正常。视频链接如下。我按照视频的指示进行了编码,我从上面提供的第二个链接中获取了相同的爆炸.ogg 文件。我仍然收到这些错误:

03-13 05:17:10.143:E/AudioTrack(3370):AudioFlinger 无法创建轨道,状态:-12
03-13 05:17:10.143: E/SoundPool(3370): 创建 AudioTrack 时出错

我确实知道 SoundPool 从 Android 1.0 开始就存在,处于 API 级别 1。SoundPool 没有任何原因无法工作,即使我有证据证明 SoundPool 工作(视频链接,第二个)。

这些是我的发现,可能会或可能不会以好的方式帮助他人。简而言之,你并不孤单。

来源:

  1. http://code.google.com/p/beginning-android-games/source/browse/trunk/ch04-android-basics/src/com/badlogic/androidgames/SoundPoolTest.java
  2. http://www.youtube.com/watch?v=ioGWpu8Ud7A

编辑:我可以从 SoundPool 播放声音。

这是我的代码:

package nttu.edu.test;

import nttu.edu.R;
import android.app.Activity;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

public class SoundPoolTest extends Activity implements OnClickListener {
    SoundPool soundPool = null;
    int explosionId = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TextView v = new TextView(this);
        v.setOnClickListener(this);
        setContentView(v);
        this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
        v.setText("Click anywhere to play the sound.");
    }

    protected void onResume() {
        super.onResume();
        if (soundPool == null) {
            soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
            explosionId = soundPool.load(this, R.raw.explosion, 1);
        }
    }

    protected void onPause() {
        super.onPause();
        if (soundPool != null) {
            soundPool.release();
            soundPool = null;
        }
    }

    public void onClick(View v) {
        if (explosionId != 0)
            soundPool.play(explosionId, 1, 1, 0, 0, 1);
    }
}

我所做的是重构我的代码。我从 Youtube 视频链接中的一个 cmets 中学到了这个技巧,其中评论的作者名为“ErichLancaster”。所有学分都归他所有。我希望这对您有所帮助。

我还将 Android 模拟器的分辨率大小设置为 QVGA,不管它是否真的重要。

【讨论】:

  • 我还重构了我的代码(几次),现在它可以工作了!怎么会这样?也许应该就 SoundPool 类联系开发人员,但我没有明确的信息说明出了什么问题。
  • 还有一个小问题仍然存在 - 在播放过程中,我可以在 Logcat 中看到这个错误:Heap size overflow! req size: 1049280, max size: 1048576 为什么?
  • @PrimožKralj 至于 Logcat 错误,我不知道如何修复它。我的简单故障排除是增加模拟器中的堆大小。如果这不起作用,那么剩下的唯一选择就是联系其中一位 Android SDK 开发人员,并让开发人员知道这一点。
  • 当我们重构代码时,我们从未真正围绕 Activity 的工作流程重构它们。我能掌握的唯一明确信息是 SoundPool 类需要“重新加载”或“重新创建”才能工作。当 Activity 暂停时,我猜想 Activity 将无法保留内存的重要部分。这只是我的两分钱。
  • 你好,谢谢你的代码,无论如何我意识到文件的长度或大小很重要,在我的第一种情况下,长度是 10 秒,它不起作用,但是当我修剪它时到 1 秒现在它的工作。
【解决方案2】:

对我来说,状态 -12 是由于我在实例化 SoundPool 时指定了太多通道造成的。因此,试图保留太多频道可能只是内存不足。

【讨论】:

  • 感谢您的输入,可能是其他人的解决方案。
【解决方案3】:

我必须为 Drumkit-Simulation 并行播放大约 10 个声音。因此,我将每个声音都放在自己的声音池中,并使用 StreamIds 来识别和停止任何相同的声音,以防它已经在播放。

int newStreamID = soundPool.play(soundIDs.get(0), volume, volume, 1, 0, randomFloatRate);
if (StreamID != null) {
    soundPool.stop(StreamID);
}
StreamID = newStreamID;

据我所知,Soundpool 会解压缩音频文件,因此您可以使用 .wav 格式来节省 CPU 使用率。

为了改变音频格式,我使用FormatFactory

【讨论】:

    【解决方案4】:

    我最近也遇到了这个错误。我的碰撞实际上在一个循环中发生了多次,所以它实际上会堆叠声音直到它们退出,这会导致错误,但它会继续播放。我通过在反弹发生时将其注册为 1 来解决此问题。

     // bouncecount=
     // 0=no bounce
     // 1=set when bounce occurs and plays the sound
     // 21=reset
    

    由于游戏以大约 60fps 的速度运行,这仅允许一个声音实例每秒 3 次,并且可以通过更改 20 轻松调整。这不仅减少了游戏中的抖动,而且一点也不显。

    if(bouncecount==1){
       sounds.play(sbump,1,1, 0, 0, 1);bouncecount++;}
    else{if(bouncecount<20&&bouncecount!=0){bouncecount++;}
         else{bouncecount=0;}}
    

    希望这对某人有所帮助。

    【讨论】:

      【解决方案5】:

      循环存在问题:当我将重复设置为 -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);
      

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

      【讨论】:

        【解决方案6】:

        我刚刚在我的游戏中遇到了这个问题。我正在使用 java 在 android native 中构建它。我的问题是 2 倍。 1st我在创建我的音池时使用了太多频道,然后我在游戏结束时从未释放音池并进入游戏结束屏幕。当游戏结束时,我使用 onStop 方法释放了 soundpool 和 audiomanager,这为我解决了问题。

        // in GameActivity
            @Override
            protected void onStop() {
                gameView.audioHandler.release();
                super.onStop();
            }
        
        // in AudioHandler class
            public void release() {
                soundPool.release(); // this is my SoundPool
                battleMusic.release(); // this is my AudioManager
            }
        

        更新:经过更多测试后,该问题仍然再次出现。然而,最终完全消除该问题的最终结果是结合了先前的代码,然后将声音池限制为最大 10 个流,并降低了使用的声音 MP3 的质量。问题主要出现在屏幕上有 10 多个敌人都使用相同的声音发射激光时。根据 SoundPool 文档,当达到最大流时,它在逻辑上将消除旧流。鉴于 -12 代码表示已达到 soundpool 的 1 MB 限制,我得出的结论是它的声音负担过重,因此通过将其设置为 10 的流限制,它永远无法达到 1 MB 限制,并且必须开始骑自行车离开旧溪流。这很奇怪,因为我的音效持续时间没有那么长,但仍然达到了极限。我希望这对某人有帮助!自从减少流后,我再也没有遇到过这个问题。

        【讨论】:

          【解决方案7】:

          我遵循这个答案:http://www.andengine.org/forums/gles2/sound-not-playing-t10820.html

          主要思想是 SoundManager 类有一个 SoundPool,允许的内存很少(与 MusicManager 不同),所以在 logcat 中的“所有消息”中“内存不足” “ 看得到。

          我想,每个 声音 调用的每个“.play()”(不知道音乐怎么样) - 在池中分配新的内存空间,并且为避免这种情况,您可以执行以下操作:

          - 仅使用 .play() 一次,然后使用 .seekTo(0),然后使用 .resume()(从头开始播放)

          - 或者只使用 .play() 一次,然后是 .pause(),然后是 .resume()(例如用于循环)

          【讨论】:

          • 欢迎来到 Stack Overflow。请尽量不提供外部链接,将尽可能多的信息存储在答案正文中。仅当确实需要时,才发布外部链接。这里的人通常不相信它,但有理由相信它。
          • soundpool 没有 seekto 方法。
          猜你喜欢
          • 2012-08-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-01-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多