web-dev-qa-db-ja.com

AudioFlingerはトラックを作成できませんでした。ステータス:-12

私はAndroid 2.2をプログラミングしていて、 SoundPool クラスを使用して複数のサウンドを同時に再生しようとしていますが、ランダムな時間のように感じると、スピーカーから音が出なくなります。

再生される各サウンドについて、これはlogcatに出力されます。

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

例外はスローされず、ボリュームがないことを除いて、プログラムは変更なしで実行を続けます。エラーの原因となっている状況を追跡したり、エラーが発生した後にエラーを再作成したりするのは本当に大変でした。ドキュメントのどこにもエラーが見つからず、ほとんど途方に暮れています。

どんな助けでも大歓迎です!

編集:私は、oggではなくmp3ファイルをロードしていることを忘れていました。

38
user1599837

最近ロードして再生しようとしたいくつかのサウンドで、ほぼ同じ問題が発生しました。

私はそれを壊して、このエラーを引き起こしていた単一のmp3をロードしました。

私が指摘したことの1つ:-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()を呼び出すことを忘れないでください。これにより、他のアプリが必要とする基本的なリソースが解放されます。予測できないタイミングがあるため、ガベージコレクターによってファイナライズでクリーンアップされるメディアオブジェクトに依存しないでください。

22
john.k.doe

john.k.doeは正しいです。 mp3ファイルのサイズを小さくする必要があります。ファイルあたりのサイズは100kb未満にしてください。通常の128kbpsではなく、32kbpsのコンスタントビットレート(CBR)を使用して、200kbファイルを72kbに削減する必要がありました。それは私のために働いた!

2
rotterick

私のAndroid=ゲーム内のミュージックトラッカーがノートをドロップし、ステータスが-22でしたが、Audioflingerエラーが発生しました)という同様の問題がありました。人。

この問題は、単一のサンプルが同時に複数回出力されたときに発生しました。つまり、私の場合、2つ以上のトラックで1つのサンプルが再生されていました。これは時々デッドロックまたは何かのように見え、2つのノートの1つが削除されます。解決策は、サンプルの2つのコピーを持つことでした(2つの実際のoggファイル-同一ですが、両方ともアセットにあります)。その後、同じサンプルを再生していても、各トラックで別のファイルからのものでした。これで問題は完全に修正されました。

サンプルをメモリにキャッシュするときになぜ機能するのかはわかりませんが、同じファイルを2つの異なるサウンドにロードしても修正されませんでした。サンプルが2つの異なるファイルから取得された場合のみ、エラーは解消されました。

これはすべての人に役立つわけではなく、最もきれいな修正ではありませんが、誰かに役立つかもしれません。

2
user2016617

私はこの問題を抱えていました。それを解決するために、サウンドの再生が終了した後、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秒だったので、プレーヤーが終了した後にのみリソースを解放するために、2000ミリ秒の値をThread.sleep()に入れていることに注意してください。

1
Afaria

私の場合、品質を下げてMP3のファイルサイズを100 kb未満にするだけでは十分ではありませんでした。

私たちを助けたのは、サンプルレートを44100から22050に減らしたり、期間を5秒未満に短縮したことです。

1
Steve Castro

複雑すぎる解答が多すぎます。エラー-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ポインター例外を回避するためにnullをチェックします)。

それは魅力のように機能します!

1
Josh

試す

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

解放してもリソースは保持されます。

1
Cléssio Mendes

上記のように、ループに問題があります。繰り返しを-1に設定すると、このエラーが発生しますが、0を指定すると、すべてが正常に機能します。 1つずつ再生しようとすると、一部のサウンドでこのエラーが発生することに気づきました。例えば:

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);

そして、それは機能していますが、遅延はデバイスによって異なります。

1
Oleksandr Albul

単一のsoundPoolの内部メモリ制限は1 Mbです。あなたの音が非常に高品質であるならば、あなたはこれを打っているかもしれません。多くのサウンドがあり、この制限に達している場合は、サウンドプールをさらに作成し、サウンドをそれらに分散させます。

到達する前にメモリが不足している場合は、ハードトラックの制限に到達できないこともあります。

このエラーは、ストリームまたはトラックの制限に達したときに表示されるだけでなく、メモリの制限にも表示されます。 Soundpoolは、新しいサウンドを再生するために、古いサウンドや優先順位を下げたサウンドの再生を停止します。

0