在setDataSource之后mediaPlayer.getDuration()返回0并导致应用崩溃 [英] mediaPlayer.getDuration() returns 0 after setDataSource and crashes app

查看:158
本文介绍了在setDataSource之后mediaPlayer.getDuration()返回0并导致应用崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

老实说,我不知道为什么会发生这种情况,因为代码很有意义,并且按照相同的方式进行教程.我首先设置数据源,然后尝试捕获它,设置音频流类型,然后尝试从媒体播放器获取持续时间,但它返回0.它不应该返回0,因为它们确实是音频并且可以播放声音很好.可能是由于数据源来自Firebase Storage位置而引起的错误,但是我不知道.错误也指向mediaPlayer.prepareAsync()方法,但这不是问题,因为没有mediaPlayer.getDuration()的代码也可以工作.

I honestly have no idea why this is happening, when the code makes sense and following tutorials the same way. I first set the data source and surround it in a try and catch, set the audio stream type, and attempt to get the duration from the media player but it returns 0. It shouldn't return 0 because their is indeed audio and it plays the audio fine. Maybe the error is caused because the data source is from Firebase Storage location, but I wouldn't know. Also the error points to the method mediaPlayer.prepareAsync(), but that's not the issue as the code works without mediaPlayer.getDuration().

@Override
public void onBindViewHolder(@NonNull final TrackHolder holder, final int position) {
    final Track track =tracks.get(position) ;
    holder.mInstrumentalName.setText(tracks.get(position).getInstrumentalName());
    holder.mProducer.setText(tracks.get(position).getProducer());



    holder.mPlayButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (start_notifying > 0) {
                notifyItemChanged(previous_position, false);

                previous_position = holder.getAdapterPosition();
                Log.d("adapter", Integer.toString(holder.getAdapterPosition()));
                holder.mPlayButton.change(false);
            } else {
                start_notifying++;
                holder.mPlayButton.change(false);
                previous_position = holder.getAdapterPosition();
            }


            if (mediaPlayer.isPlaying()) {
                Log.d("playing", "is_playing");
                mediaPlayer.reset();
                holder.mMusicSeekbar.setEnabled(true);
                try {
                    mediaPlayer.setDataSource(tracks.get(position).getMusicLink());

                } catch (IOException e) {
                    e.printStackTrace();
                }
                mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mediaPlayer) {
                        mediaPlayer.start();
                    }
                });
                mediaPlayer.prepareAsync();

            } else {
                Log.d("playing", "just_started");
                current_position = holder.getAdapterPosition();
                mediaPlayer.reset();
                holder.mMusicSeekbar.setEnabled(true);
                try {
                    mediaPlayer.setDataSource(tracks.get(position).getMusicLink());
                    previous_link = tracks.get(position).getMusicLink();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                Log.d("playing", Integer.toString(mediaPlayer.getDuration())); // Error here, and causes crash. 
                mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mediaPlayer) {
                        mediaPlayer.start();
                    }
                });
                mediaPlayer.prepareAsync();
            }



        }
    });

    track.isPlaying = start_notifying < 0;

    mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mediaPlayer) {
            mediaPlayer.stop();
            notifyItemChanged(previous_position, false);
            previous_position = -1;
            start_notifying = 0;
        }
    });

    holder.setItemClickListener(new ItemClickListener() {
        @Override
        public void onItemClick(View v, int pos) {
            Toast.makeText(context, Integer.toString(position), Toast.LENGTH_SHORT).show();
        }
    });
}

错误日志

09-14 12:37:27.275 6401-6401/? E/AndroidRuntime: FATAL EXCEPTION: main
                                             Process: maginate.net.thebestrapper, PID: 6401
                                             java.lang.IllegalStateException
                                                 at android.media.MediaPlayer.prepareAsync(Native Method)
                                                 at maginate.net.thebestrapper.essentials.TrackAdapter$1.onClick(TrackAdapter.java:130)
                                                 at android.view.View.performClick(View.java:5697)
                                                 at android.view.View$PerformClick.run(View.java:22526)
                                                 at android.os.Handler.handleCallback(Handler.java:739)
                                                 at android.os.Handler.dispatchMessage(Handler.java:95)
                                                 at android.os.Looper.loop(Looper.java:158)
                                                 at android.app.ActivityThread.main(ActivityThread.java:7224)
                                                 at java.lang.reflect.Method.invoke(Native Method)
                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

推荐答案

一旦准备好OnPreparedListener回调内的数据源,就应该调用mediaPlayer.getDuration().

You should call mediaPlayer.getDuration() once data source is prepared that is inside OnPreparedListener call back

            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mediaPlayer) {
                    mediaPlayer.getDuration()
                    mediaPlayer.start();
                }
            });

这篇关于在setDataSource之后mediaPlayer.getDuration()返回0并导致应用崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆