mediaPlayer.getDuration() returns 0 在 setDataSource 和崩溃应用程序之后

mediaPlayer.getDuration() returns 0 after setDataSource and crashes app

老实说,我不知道为什么会这样,当代码有意义并且按照相同的方式学习教程时。我首先设置数据源并将其包围在 try and catch 中,设置音频流类型,并尝试从媒体播放器获取持续时间,但它 returns 0。它不应该 return 0 因为它们确实是音频并且可以很好地播放音频。也许错误是因为数据源来自 Firebase 存储位置,但我不知道。此外,错误指向方法 mediaPlayer.prepareAsync(),但这不是问题,因为代码在没有 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.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()

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