创建MediaPlayer
。
特定类具有播放,暂停和恢复的功能。我正在尝试制作一个显示进度的SeekBar
。
SeekBar
要求maxlength
的值从getDuration()
函数中获取,该函数调用mediaplayer.getDuration()
函数并返回值。
SeekBar
还需要从getCurrentPostion()
函数获取的当前位置的值。
他们俩都返回NullPointerException
。
public class PlayMedia extends AsyncTask<Void, Void, Void>
implements MediaPlayer.OnPreparedListener {
private MediaPlayer mediaPlayer;
int length;
int duration =0;
int currentPosition=0;
@Override
protected Void doInBackground(Void... params) {
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(Environment.getExternalStorageDirectory().getAbsolutePath().toString()+"/Notate/"+MainActivity.filepath+".wav");
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.prepareAsync();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
}
return null;
}
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
public int getDuration(){
duration=mediaPlayer.getDuration();
Log.d("Position",Integer.toString(duration));
return duration;
}
public int getPresentDuration(){
currentPosition=mediaPlayer.getCurrentPosition();
Log.d("CurrentPosition",Integer.toString(currentPosition));
return currentPosition;
}
@Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
if(mediaPlayer != null && mediaPlayer.isPlaying()){
mediaPlayer.pause();
}
else if(mediaPlayer != null){
mediaPlayer.start();
}
Log.d("Shivram", "Started Playing");
}
public void pause(){
mediaPlayer.pause();
length=mediaPlayer.getCurrentPosition();
Log.d("Shivram","Paused");
}
public void resume(){
mediaPlayer.seekTo(length);
mediaPlayer.start();
Log.d("Shivram","Resume");
此Fragment类调用创建异常的getDuration()
函数。
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
contentViewC = inflater.inflate(R.layout.fragment_fragment_b, container, false);
final SeekBar seekBar;
Button button = (Button) contentViewC.findViewById(R.id.button1);
Button button2 = (Button) contentViewC.findViewById(R.id.button2);
textToChange=(TextView)contentViewC.findViewById(R.id.textView1);
final PlayMedia play=new PlayMedia();
boolean pause=false;
seekBar = (SeekBar) contentViewC.findViewById(R.id.SeekBar01);
final int[] recordingDuration = new int[1];
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (MainActivity.filepath != "Nothing") {
if(play.getStatus()==AsyncTask.Status.FINISHED || play.getStatus()==AsyncTask.Status.RUNNING){
Log.d("Shivram-FragmentA", "Resume");
play.resume();
}
if(play.getStatus()==AsyncTask.Status.PENDING) {
play.execute();
recordingDuration[0] =play.getDuration();
seekBar.setMax(recordingDuration[0]);
}
Frequency getFreq=new Frequency();
getFreq.execute();
}
}
});
stackTrace如下
01-13 21:44:15.182 16263-16263/com.example.shivram.notate E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.shivram.notate, PID: 16263
java.lang.NullPointerException
at com.example.shivram.notate.PlayMedia.getDuration(PlayMedia.java:43)
at com.example.shivram.notate.FragmentC$1.onClick(FragmentC.java:66)
at android.view.View.performClick(View.java:4456)
at android.view.View$PerformClick.run(View.java:18465)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5086)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:5)
您的问题所在:
play.execute();
recordingDuration[0] =play.getDuration();
无法保证AsyncTask在执行 play.execute()后完成,因为这是线程并且有自己的生命。因此,到那时您的MediaPlayer可能尚未初始化。尝试做部分:
recordingDuration[0] =play.getDuration();
seekBar.setMax(recordingDuration[0]);
AsyncTask完成后台作业后。这应该在您的 PostExecute 方法中完成,并将解决异常。
但经过一番思考后,让我们意识到设计是错误的。 您不需要在AsyncTask中维护MediaPlayer 。
在您的活动中创建和管理MediaPlayer。让您的Activity实现 OnPreparedListener 。获取持续时间并通过 onPrepared 设置搜索栏(请查看下面的示例代码)。只有在加载文件且播放器准备就绪后才能获得持续时间。
将“暂停”和“恢复”方法移至“活动”。 AsyncTask主要用于完成长时间运行的任务。我在下面放了一个示例代码,这有助于理解这一点。
public class MainActivity implements MediaPlayer.OnPreparedListener{
private MediaPlayer mediaPlayer;
boolean isReady;
boolean paused;
.....
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Your logic to play, pause and initialize if needed
if (!MainActivity.filepath.equals("Nothing")) {
if(mediaPlayer != null && mediaPlayer.isPlaying()){
pause();
paused = true;
}else if(paused){
resume();
paused = false;
}
// initialize again when player is stopped and another file is set
// in that case put logic so that mediaPlayer is disposed and set to null
if (mediaPlayer == null){
initializeMediaPlayer();
}
}
}
});
public void initializeMediaPlayer(){
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(Environment.getExternalStorageDirectory().getAbsolutePath().toString()+"/Notate/"+MainActivity.filepath+".wav");
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.prepareAsync(); // this is important so that UI is not stuck
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
}
}
// You need to listen for when the Media Player is finished preparing and is ready
@Override
public void onPrepared(MediaPlayer mp) {
recordingDuration[0] = mediaPlayer.getDuration();
//Called when the media file is ready for playback.
isReady = true;
// Start the player
mediaPlayer.start();
}
public void pause(){
if (mediaPlayer != null){
mediaPlayer.pause();
length=mediaPlayer.getCurrentPosition();
}
}
public void resume(){
if (mediaPlayer != null){
mediaPlayer.seekTo(length);
mediaPlayer.start();
}
}
@Override
public void onDestroy() {
if (mediaPlayer != null) mediaPlayer.release();
}
}
答案 1 :(得分:1)
获取当前位置的Java代码:
mediaPlayer.getCurrentPosition();
获取持续时间Java代码:
private int getAudioDuration() {
FFmpegMediaMetadataRetriever fFmpegMediaMetadataRetriever = new FFmpegMediaMetadataRetriever();
fFmpegMediaMetadataRetriever.setDataSource(MP3);
fFmpegMediaMetadataRetriever.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_ALBUM);
fFmpegMediaMetadataRetriever.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_ARTIST);
int duration = Integer.parseInt(fFmpegMediaMetadataRetriever.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_DURATION));
Log.v(TAG, "getDuration= " + duration);
fFmpegMediaMetadataRetriever.release();
return duration;
}
Build.Gradle(:app)
dependencies {
implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever-core:1.0.15'
implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever-native:1.0.15'
}