2012-08-15 30 views
35

Tôi đang lập trình cho android 2.2 và đang cố gắng sử dụng lớp học SoundPool để phát nhiều âm thanh cùng một lúc nhưng với cảm giác như âm thanh ngẫu nhiên sẽ ngừng phát ra từ loa.AudioFlinger không thể tạo bản nhạc. trạng thái: -12

cho mỗi âm thanh mà có thể đã được chơi này được in trong logcat:

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

Không có ngoại lệ được ném và chương trình tiếp tục thực thi mà không bất kỳ thay đổi ngoại trừ việc thiếu khối lượng. Tôi đã có một thời gian thực sự khó khăn theo dõi những điều kiện gây ra lỗi hoặc tái tạo nó sau khi nó xảy ra. Tôi không thể tìm thấy lỗi trong tài liệu ở bất cứ nơi nào và khá nhiều lúc mất mát.

Bất kỳ trợ giúp nào sẽ được đánh giá rất nhiều!

Chỉnh sửa: Tôi quên đề cập đến việc tôi đang tải các tệp mp3 chứ không phải ogg.

+5

Bạn tạo bao nhiêu bản nhạc? AFAIK -12 là 'NO_MEMORY', điều này có nghĩa là bạn đã hết bài hát (tôi nghĩ số bài hát mở tối đa được sử dụng là 32 - không chắc chắn nếu điều đó vẫn đúng). – Michael

+0

Hmmmmm, tôi đang tải rất nhiều bản nhạc nhưng chúng được chia ra thành 5 soundpool. mỗi soundpool sẽ có tối đa ~ 15 âm thanh được tải. Bạn có biết nếu các bài hát tối đa 32 là hệ thống rộng hoặc mỗi hồ bơi âm thanh? – user1599837

+0

Đó là mỗi chủ đề máy trộn (trong đó bạn đã có một cho mỗi chủ đề đầu ra AFAIK). Nhưng vì nhiều nền tảng sử dụng một chuỗi đầu ra duy nhất cho tất cả phát lại không phải là A2DP, về cơ bản nó trở thành một giới hạn toàn cầu. – Michael

Trả lời

20

tôi đã gần như chính xác cùng một vấn đề này với một số âm thanh tôi đã cố gắng tải và phát gần đây.

tôi thậm chí đã phá vỡ nó xuống để tải một mp3 duy nhất đã gây ra lỗi này.

một điều tôi lưu ý: khi tôi nạp với một vòng lặp -1, nó sẽ thất bại với lỗi "trạng thái 12", nhưng khi tôi tải nó vào vòng lặp 0 lần, nó sẽ thành công. thậm chí cố gắng tải 1 lần không thành công.

giải pháp cuối cùng là mở mp3 trong trình chỉnh sửa âm thanh và chỉnh sửa lại với chất lượng kém hơn một chút để tệp giờ đây nhỏ hơn và dường như không chiếm nhiều tài nguyên trong hệ thống.

cuối cùng, có thảo luận này khuyến khích thực hiện bản phát hành trên các đối tượng bạn đang sử dụng, vì thực sự có giới hạn cứng về tài nguyên có thể được sử dụng và toàn hệ thống, vì vậy nếu bạn sử dụng một số các tài nguyên, các ứng dụng khác sẽ không thể sử dụng chúng.

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

Đối với âm thanh, có một giới hạn cứng của 32 đối tượng AudioTrack tích cực mỗi thiết bị (không cho mỗi ứng dụng: bạn cần phải chia sẻ những 32 với phần còn lại của hệ thống), và AudioTrack được sử dụng bên trong bên dưới SoundPool, ToneGenerator, MediaPlayer, âm thanh gốc dựa trên ES OpenSL, v.v. Tuy nhiên, giới hạn AudioTrack thực tế là < 32; nó phụ thuộc nhiều hơn vào các yếu tố mềm chẳng hạn như bộ nhớ, tải CPU, v.v. Cũng lưu ý rằng bộ giới hạn trong bộ trộn âm thanh Android hiện không có tính năng nén dải động, để có thể clip nếu bạn có số lượng lớn hoạt động âm thanh và tất cả đều to.

Đối với trình phát video, giới hạn thấp hơn nhiều do tải dữ dội video đó đặt trên thiết bị.

Tôi sẽ sử dụng cơ hội này để nhắc nhở các nhà phát triển phương tiện truyền thông: vui lòng nhớ gọi phát hành() cho các đối tượng phương tiện khi ứng dụng của bạn bị tạm dừng. Điều này giải phóng các tài nguyên cơ bản mà các ứng dụng khác sẽ cần. Không dựa vào các đối tượng đa phương tiện đang được dọn dẹp hoàn thiện bởi bộ thu gom rác , vì thời gian này không thể đoán trước được.

0

Hãy thử

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

Releasing nên giữ nguồn tài nguyên của bạn.

2

Tôi gặp vấn đề tương tự khi trình theo dõi nhạc trong trò chơi Android của tôi sẽ xóa ghi chú và tôi gặp lỗi Audioflinger (mặc dù trạng thái của tôi là -22). Tôi đã nhận nó làm việc tuy nhiên vì vậy điều này có thể giúp một số người.

Sự cố xảy ra khi một mẫu đơn được xuất nhiều lần cùng một lúc. Vì vậy, trong trường hợp của tôi nó là một mẫu đơn được chơi trên hai hoặc nhiều bài hát. Điều này dường như đôi khi bế tắc hoặc một cái gì đó và một trong hai ghi chú sẽ được giảm xuống. Giải pháp là có hai bản sao của mẫu (hai tệp ogg thực tế - giống hệt nhau nhưng cả trong các tài sản). Sau đó, trên mỗi bản nhạc mặc dù tôi đang chơi cùng một mẫu, nó đến từ một tập tin khác. Điều này hoàn toàn cố định vấn đề cho tôi.

Không chắc chắn lý do tại sao nó hoạt động khi tôi lưu mẫu vào bộ nhớ, nhưng thậm chí tải cùng một tệp vào hai âm thanh khác nhau cũng không khắc phục được. Chỉ khi các mẫu ra khỏi hai tập tin khác nhau đã làm các lỗi biến mất.

Tôi chắc chắn điều này sẽ không giúp mọi người và nó không phải là sửa chữa đẹp nhất nhưng nó có thể giúp ai đó.

2

john.k.doe là đúng. Bạn phải giảm kích thước tệp mp3 của mình. Bạn nên giữ kích thước dưới 100kb cho mỗi tệp. Tôi đã phải giảm 200kb tập tin của tôi để 72kb sử dụng một tỷ lệ bit constante (CBR) của 32kbps thay vì 128kbps thông thường. Điều đó làm việc cho tôi!

0

Một soundPool đơn lẻ có giới hạn bộ nhớ trong 1 (một) Mb. Bạn có thể nhấn nếu âm thanh của bạn có chất lượng rất cao. Nếu bạn có nhiều âm thanh và đang đạt đến giới hạn này, chỉ cần tạo thêm soundpool và phân phối âm thanh của bạn trên chúng.

Bạn thậm chí không thể đạt tới giới hạn bản nhạc cứng nếu bạn sắp hết bộ nhớ trước khi đến đó.

Lỗi đó không chỉ xuất hiện khi đã đạt đến giới hạn luồng hoặc bản nhạc mà còn giới hạn bộ nhớ. Soundpool sẽ ngừng phát âm thanh cũ và/hoặc không được ưu tiên để phát âm thanh mới.

0

Tôi đã gặp phải sự cố này. Để giải quyết nó, tôi chạy phương thức .release() của đối tượng SoundPool sau khi kết thúc phát âm thanh.

Dưới đây là mã của tôi:

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

Lưu ý rằng trong trường hợp của tôi những âm thanh của tôi có chiều dài 1-2 giây tối đa, vì vậy tôi đặt giá trị năm 2000 miliseconds trong Thread.sleep(), để chỉ phát hành các nguồn lực sau khi người chơi đã hoàn thành.

1

Như đã nói ở trên, có sự cố với vòng lặp: khi tôi đặt lặp lại -1 tôi nhận được lỗi này, nhưng với 0 mọi thứ đang hoạt động bình thường. Tôi đã nhận thấy rằng một số âm thanh cho lỗi này khi tôi cố gắng phát từng video một. Ví dụ:

mSoundPool.stop(mStreamID); 
mStreamID = mSoundPool.play(mRandID, mVolume, mVolume, 1, -1, 1f); 

Trong trường hợp như vậy, bài hát đầu tiên được phát ok, nhưng khi tôi chuyển âm thanh, bài hát tiếp theo sẽ đưa ra lỗi này. Dường như sử dụng vòng lặp, một bộ đệm bằng cách nào đó bị quá tải và mSoundPool.stop không thể giải phóng tài nguyên ngay lập tức.

Giải pháp:

final Handler handler = new Handler(); 
handler.postDelayed(new Runnable() { 
    @Override 
    public void run() { 
     mStreamID = mSoundPool.play(mRandID, mVolume, mVolume, 1, -1, 1f); 
}, 350); 

Và nó làm việc, nhưng chậm trễ là khác nhau cho các thiết bị khác nhau.

1

Trong trường hợp của tôi, giảm chất lượng và do đó kích thước tệp của MP3 dưới 100kb không đủ, vì một số tệp 51kb hoạt động trong khi một số tệp dài hơn 41kb vẫn không hoạt động.

Điều gì đã giúp chúng tôi giảm tỷ lệ mẫu từ 44100 xuống 22050 hoặc rút ngắn thời lượng xuống dưới 5 giây.

0

Tôi thấy quá nhiều câu trả lời quá phức tạp. Lỗi -12 có nghĩa là bạn đã không phát hành các biến. Tôi đã gặp vấn đề tương tự sau khi tôi phát một tệp âm thanh OGG 8 lần. này đã làm việc cho tôi:

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

Releasing biến ngay sau khi .play() những thứ dơ sẽ lên, và nó không phải là khả năng để giải phóng biến bên onCompletion, vì vậy nhận thấy làm thế nào tôi nhả biến trước khi sử dụng nó (và kiểm tra null để tránh ngoại lệ nullpointer).

Nó hoạt động như sự quyến rũ!

Các vấn đề liên quan