2012-05-29 29 views
10

Tôi có hai thiết bị tôi có thể thử nghiệm trò chơi của mình: Điện thoại Celluar của Mỹ (SCH-R880) và Kindle Fire, Kindle Fire mạnh hơn rất nhiều so với điện thoại.Mediaplayer Cắt âm thanh quá sớm

Tôi có một số hiệu ứng âm thanh ngắn (Ít hơn hoặc khoảng 1 giây). Để tiết kiệm bộ nhớ, tôi tải, phát và phát hành một số hiệu ứng âm thanh này. Trên điện thoại họ chơi (chủ yếu) như mong đợi. Tuy nhiên, trên Kindle Fire, chúng bị cắt ngắn. Những âm thanh ngắn thực sự bị cắt đứt nhanh đến nỗi tôi không nghe thấy gì cả. Những người được tải tại thiết lập và vẫn còn, tuy nhiên, chơi tốt.

Bất kỳ ai có ý tưởng gì đang xảy ra ở đây? Tôi bằng cách nào đó phát hành phương tiện truyền thông của tôi quá sớm? Dưới đây là một ví dụ về điều này. Trên điện thoại, tôi nghe thấy "Cấp hai!" nhưng trên Kindle tôi nghe thấy một cái gì đó như "Lev tw."

mpNum = null; 

try 
{ 
    switch (level) 
    { 
     case 2: 
      mpNum = MediaPlayer.create(contxt, R.raw.l2); break; 
     case 3: 
      mpNum = MediaPlayer.create(contxt, R.raw.l3); break; 
     case 4: 
      mpNum = MediaPlayer.create(contxt, R.raw.l4); break; 
     case 5: 
      mpNum = MediaPlayer.create(contxt, R.raw.l5); break; 
     case 6: 
      mpNum = MediaPlayer.create(contxt, R.raw.l6); break; 
     case 7: 
      mpNum = MediaPlayer.create(contxt, R.raw.l7); break; 
     case 8: 
      mpNum = MediaPlayer.create(contxt, R.raw.l8); break; 
     default: 
      return; 
    } 

    MediaPlayer vLevel = MediaPlayer.create(contxt, R.raw.level); 

    vLevel.setOnPreparedListener(new MediaPlayer.OnPreparedListener() 
    { 
     public void onPrepared(MediaPlayer mp) 
     { 
      mp.start(); 
     } 
    }); 

    vLevel.setOnCompletionListener(new MediaPlayer.OnCompletionListener() 
    { 
      public void onCompletion(MediaPlayer mpl) 
      { 
      mpNum.start(); 
      mpl.release(); 
      } 
     }); 

     mpNum.setOnCompletionListener(new MediaPlayer.OnCompletionListener() 
     { 
      public void onCompletion(MediaPlayer mp) 
      { 
       mp.release(); 
      } 
     }); 
    } 
    catch (Exception e) {} 

Để cố khắc phục điều này, tôi đã thử SoundPool nhưng không hoạt động; Tôi chẳng nghe được gì cả. Dưới đây là những gì tôi đã làm để cố gắng để chơi nhạc với Soundpool:

SoundPool soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 100); 
    soundPool.load(contxt, R.raw.song2, 1); 
    AudioManager mgr = (AudioManager)contxt.getSystemService(Context.AUDIO_SERVICE); 
    float streamVolumeCurrent = mgr.getStreamVolume(AudioManager.STREAM_MUSIC); 
    float streamVolumeMax = mgr.getStreamMaxVolume(AudioManager.STREAM_MUSIC); 
    float volume = streamVolumeMax; 

    soundPool.play(1, volume, volume, 1, 5, 2); 

CẬP NHẬT

tôi đã nhận thấy khi một âm thanh cần được chơi (nhưng không) có lỗi này mà đến lên:

AudioPolicyManager: stopOutput() oldDevice 2 
AudioPolicyManager: [getDeviceForStrategy] strategy : 0,forceUse(0) 
+0

Tôi nhận thấy sự cố này trên thiết bị Nexus 5. Về cơ bản ứng dụng của tôi truyền trực tuyến âm thanh và MediaPlayer đang cắt giảm khoảng. 1- 5 giây quá sớm. Bất cứ ai khác nhận thấy điều này? – clu

+0

Ứng dụng tôi đang làm việc cũng có vấn đề này, điều đó khiến tôi phát điên vì tôi không thể tái tạo nó với các điện thoại tôi có, nhưng có vẻ như thất bại trên Galaxy S4. Dường như lỗi này đã được giới thiệu trong kitkat và chỉ xuất hiện trong những trường hợp rất đặc biệt. – German

Trả lời

0

Điều này thật lạ và không phải là sửa lỗi tốt, mà chỉ là bản sửa lỗi mà tôi đã tìm thấy cho đến nay. Nếu tôi xóa mp.setOnPreparedListenermp.setOnCompletionListener và chỉ có mp.start(), nó hoạt động.

+0

Điều này cũng không hiệu quả đối với tôi (thử nghiệm trên Android 4.1 và 6.0.1) – m0skit0

3

Tôi đã đọc rằng lớp SoundPool phù hợp hơn với những âm thanh ngắn như thế này hơn MediaPlayer, nhưng đó có thể không phải là vấn đề. (here's một liên kết đến ví dụ SoundPool).

Bạn cũng có thể đăng mã cho trình xử lý nhấp chuột của mình không? Ngoài ra, tôi khuyên bạn nên thay vì phát hành và lấy lại các phiên bản MediaPlayer, sử dụng một phiên bản MediaPlayer và chỉ cần làm theo trình tự thiết lập lại(), setDataSource(), chuẩn bị(), start() bất cứ khi nào bạn cần sử dụng lại nó . Nó sẽ hiệu quả hơn việc xây dựng một cá thể mới mỗi lần. tức là:

MediaPlayer mp = new MediaPlayer(); 
AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.sound1); 
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength(); 
mp.prepare(); 
mp.start(); 

//to reuse 
mp.reset(); 
afd = getResources().openRawResourceFd(R.raw.sound2); 
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength(); 
mp.prepare(); 
mp.start(); 
+0

Trình xử lý ... của tôi? –

+0

Có, phương thức onClick() của bạn ... ít nhất tôi giả sử đó là cách bạn kích hoạt các hiệu ứng âm thanh này? Về cơ bản chỉ là bất cứ điều gì bạn đang sử dụng để kích hoạt phát lại âm thanh. Không có mã nào của bạn ở trên thực hiện điều đó. – kcoppock

+0

Thực ra, không. Đó là một trò chơi, vì vậy những hiệu ứng âm thanh này được gọi khi có sự kiện cụ thể. Tôi có thể chỉ cho bạn, nhưng hãy tin tôi đi, nó sẽ không giúp được gì. Hiển thị cuộc gọi phương thức chính nó sẽ không giúp được gì, và để đưa ra một bức tranh tốt hơn, nó sẽ yêu cầu hiển thị nhiều mã. –

2

tôi cũng có những vấn đề tương tự trong một dự án và là bởi vì trong KindleFire những âm thanh cắt trước khi kết thúc như vậy để khắc phục điều đó (với việc phát hành) Tôi đã thêm một sự chậm trễ trong việc phát hành:

mpNum.setOnCompletionListener(new MediaPlayer.OnCompletionListener() 
    { 
     public void onCompletion(MediaPlayer mp) 
     { 
      // Add a handler delay 
      new Timer().schedule(new TimerTask() { 

       @Override 
       public void run() { 
        mp.release(); 
       } 
      }, DELAY_TIME); 
     } 
    }); 

Nó không phải là giải pháp tốt nhất nhưng tôi nghĩ rằng có thể sẽ giúp bạn.

+0

Tôi nghĩ đây cũng là vấn đề, nhưng tôi đã xóa mã phát hành() của tôi và nó vẫn xảy ra. – rrbrambley

+0

Điều này cũng không giải quyết được vấn đề trong trường hợp của tôi ... – m0skit0

0

Tôi gặp sự cố này và đã giải quyết vấn đề này làm cho đối tượng MediaPlayer của tôi ở chế độ riêng tư, do đó trình thu thập rác không làm sạch cá thể. Hy vọng nó sẽ giúp ai đó!

+4

Tôi ... không nghĩ đó là cách GC hoạt động. –

+0

Tôi không chắc chắn về nó, nhưng âm thanh dừng lại bị cắt. – JerothKP

+0

Đó không phải là cách GC hoạt động. Có lẽ là một trường hợp tương quan chứ không phải là quan hệ nhân quả. – m0skit0

10

Tôi đã gặp vấn đề tương tự và nó thực sự là một vấn đề thu gom rác! Nếu bạn gán thể hiện của trình phát media vào một số biến cục bộ bên trong một phương thức, cá thể không còn tồn tại sau khi rời khỏi phương thức đó, do đó GC có thể xóa ngẫu nhiên nó bất cứ lúc nào.

Để tránh điều này, bạn cần giữ ít nhất một con trỏ đến cá thể ở một nơi khác.Tôi đã tạo ra một bộ tĩnh để giữ tất cả các con trỏ, nó trông như thế này:

private static Set<MediaPlayer> activePlayers = new HashSet<MediaPlayer>(); 

Sau đó, tạo ra các máy nghe nhạc phương tiện truyền thông đang theo:

MediaPlayer player = MediaPlayer.create(context, context.getResources().getIdentifier(id, "raw", pkg)); 
activePlayers.add(player); 
player.setOnCompletionListener(releaseOnFinishListener); 
player.start(); 

đâu releaseOnFinishListener là một người biết lắng nghe mà phát hành media player về kết thúc giống như của bạn nhưng cũng loại bỏ con trỏ khỏi activePlayers thiết lập:

MediaPlayer.OnCompletionListener releaseOnFinishListener = new MediaPlayer.OnCompletionListener() { 
    public void onCompletion(MediaPlayer mp) { 
     mp.release(); 
     activePlayers.remove(mp); 
    } 
}; 

Tôi hy vọng điều này sẽ giúp bạn.

+0

Hoạt động. Cảm ơn bạn :) –

+0

Thực ra đó là vấn đề về GC! Đối với trường hợp của tôi, tuyên bố danh sách MediaPlayer trên toàn cầu thực hiện công việc. Cảm ơn ~ – Jiyeh

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