2015-11-07 44 views
0

我有一些非常标准的代码来运行MP3,但它需要2秒钟来播放它。这个应用程序非常简单。这个应用程序应该播放1-2秒的声音。另外,有没有办法将应用程序加载时的mp3缓存到RAM中,以便它可以非常快速地播放(无延迟)?请帮忙!Android的媒体播放器lib的问题

package com.kindust.karsey.johncenabutton.johncenabutton; 

import android.content.Context; 
import android.media.MediaPlayer; 
import android.support.v7.app.ActionBarActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 


public class MainActivity1 extends ActionBarActivity { 

    MediaPlayer mediaPlayer; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main_activity1); 
    } 


    public void playSound(View v)throws Exception{ 
     mediaPlayer = MediaPlayer.create(this, R.raw.john_cena); 
     mediaPlayer.setLooping(false); 
     mediaPlayer.start(); 
     Thread.sleep(1500); 
     //mediaPlayer.stop(); 
     mediaPlayer.reset(); 
     mediaPlayer.release(); 
     Log.d("1234FIND", "STOP RELEASE RESET"); 

    } 
} 

回答

0

如果您希望避免媒体文件加载时出现轻微延迟,您应该提前准备媒体播放器实例。您的媒体文件加载并准备播放时有延迟。您有几种选择:

  • 继续使用MediaPlayer.create(),但这样做的越早,你就可以打电话playSound()之前。在您提供的简单示例中,请尝试在onCreate()方法中调用MediaPlayer.create()
  • 您也可以使用prepareAsync()setOnPreparedListener()方法在后台准备媒体文件,并在准备就绪时设置通知。这更复杂,但为您提供更多的控制和更好的用户体验。如果你需要加载一个大文件,这是使它工作的最好方法。小型音频文件可能不是什么大问题。
  • 如果您要一遍又一遍播放同一个媒体文件,则无需立即释放MediaPlayer。如果您没有重置或释放,媒体将仍然在内存中,并可以立即再次播放。但是一定要在之后以及onPause()onStop()等生命周期事件中致电release()

See the documentation for details

让它几秒钟播放,然后停止,使用Android的CountDownTimer:

// Will call onFinish() after 2 seconds. Second parameter is 
// for onTick() which we don't need and can ignore. 
new CountDownTimer(2000, 2000) { 

    public void onTick(long millisUntilFinished) { 
     // Do nothing... 
    } 

    public void onFinish() { 
     mediaPlayer.stop(); 
     // Decide here if you need to prepare a new clip 
     // or release the media player 
    } 

}.start(); 

下面是一个完整的例子:

package com.example.matthew.somediaplayer; 

import android.content.res.AssetFileDescriptor; 
import android.media.AudioManager; 
import android.media.MediaPlayer; 
import android.os.Bundle; 
import android.os.CountDownTimer; 
import android.support.v7.app.AppCompatActivity; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 

import java.io.IOException; 

public class MainActivity extends AppCompatActivity { 
    private static final String TAG = "TEST"; 
    private MediaPlayer mediaPlayer; 
    private boolean isMediaPlayerPrepared = false; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     Button button = (Button) findViewById(R.id.button); 
     button.setEnabled(false); 
     button.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       if (mediaPlayer.isPlaying() == false) { 
        playSound(); 
       } 
      } 
     }); 

    } 

    @Override 
    public void onResume(){ 
     super.onResume(); 
     Log.d(TAG, "In onResume()"); 
     createAndPrepareMediaPlayer(); 
    } 

    @Override 
    public void onStop() { 
     super.onStop(); 
     Log.d(TAG, "In onStop()"); 
     mediaPlayer.release(); 
     isMediaPlayerPrepared = false; 
    } 

    @Override 
    public void onPause(){ 
     Log.d(TAG, "In onPause()"); 
     super.onPause(); 
    } 

    public void createAndPrepareMediaPlayer() { 
     Log.d(TAG, "In createAndPrepareMediaPlayer()"); 
     mediaPlayer = new MediaPlayer(); 
     mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 

     if(isMediaPlayerPrepared == false) { 
      try { 
       AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.test); 
       mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); 
       mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { 
        @Override 
        public void onPrepared(MediaPlayer mp) { 
         Log.d(TAG, "Media player is prepared."); 
         isMediaPlayerPrepared = true; 
         Button button = (Button) findViewById(R.id.button); 
         button.setEnabled(true); 
        } 
       }); 
       Log.d(TAG, "Beginning to prepare media player."); 
       mediaPlayer.prepareAsync(); 

      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

     } 
    } 

    public void playSound() { 

     Log.d(TAG, "In playSound()"); 
     if(isMediaPlayerPrepared) { 
      // Will call onFinish() after 2 seconds. Second parameter is 
      // for onTick() which we don't need and can ignore. 
      new CountDownTimer(2000, 2000) { 

       public void onTick(long millisUntilFinished) { 
        // Do nothing... 
       } 

       public void onFinish() { 
        Log.d(TAG, "In onFinish()"); 
        // We can't call a method like pause on an unprepared MediaPlayer instance. 
        if(isMediaPlayerPrepared) { 
         mediaPlayer.pause(); 
        } else { 
         Log.d(TAG, "Media player isn't prepared, and isn't allowed to pause."); 
        } 
       } 

      }.start(); 

      mediaPlayer.setLooping(false); 
      mediaPlayer.seekTo(0); // set to beginning of track (if not already) 
      mediaPlayer.start(); 
      Log.d(TAG, "Starting to play a sound."); 
     } 
    } 

} 
+0

应该在哪里prepareAsync()去?在oncreate/resume/start方法中? – Bobdabiulder

+0

这取决于您的应用程序,但我可能会使用onResume()来准备并发布onPause()。 – matsuzine