Why does MediaPlayer.setLooping() cause an error when using VideoView?

谁都会走 提交于 2021-02-10 23:41:02

问题


We are trying to use a VideoView to play a video in an Android Activiy.

I've read the MediaPlayer documentation and studied its state diagram.

We get a Media Player error if we call this method:

MediaPlayer.setLooping()

from this listener method:

MediaPlayer.OnPreparedListener.onPrepared()

The error message from LogCat:

error (-38, 0)

Note:

We have tested on two physical devices and this only happens on our Motorola Xoom.

If I comment out this line: mp.setLooping(false); everything works fine on the Xoom.

(see code below)

According to the documentation, setLooping() can be called from the following Media Player states:

  • Idle
  • Initialized
  • Stopped
  • Prepared
  • Started
  • Paused
  • PlaybackCompleted

Although the documentation also includes this seemingly contradictory statement:

It is a programming error to invoke methods such as getCurrentPosition(), getDuration(), getVideoHeight(), getVideoWidth(), setAudioStreamType(int), setLooping(boolean), setVolume(float, float), pause(), start(), stop(), seekTo(int), prepare() or prepareAsync() in the Idle state...

Question 1:

Why can't we call setLooping() from onPrepared()?

Question 2:

Shouldn't the VideoView be handling the preparation of the underlying MediaPlayer?

Question 3:

Shouldn't the MediaPlayer be in its prepared state when onPrepared() is invoked?

Question 4:

How do I resolve the statements in the documentation that seem to contradict each other?

What really confuses me:

The quote above says none of these methods should be called when the MediaPlayer is in its idle state:

  • getCurrentPosition()
  • getDuration()
  • getVideoHeight()
  • getVideoWidth()
  • setAudioStreamType(int)
  • setLooping(boolean)
  • setVolume(float
  • float)
  • pause()
  • start()
  • stop()
  • seekTo(int)
  • prepare()
  • prepareAsync()

This statement (along with our error message) makes me think our error occurs because the MediaPlayer has not been successfully prepared.

But, for some reason there is no problem calling setAudioStreamType().

Question 5:

Why is there a problem with setLooping() but not with setAudioStreamType()?

Both methods are in the list of forbidden methods above.

(That said, I would've thought both are valid in the onPrepared() method...)

What am I missing?

Is there a bug with the Motorola Xoom?

I'd be happy to just get an answer to question 1, but I'm really perplexed by all of this.

I'll admit I'm pretty new to Android development...

Our Xoom is running Ice Cream Sandwich 4.0.4.

Here's some sample code:

class VideoActivity {

    VideoView mVidView;

    @Override
    protected void onCreate(Bundle b) {
        mVidView = new VideoView(this);
        ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(mWidth, mHeight);
        mVidView.setLayoutParams(params);
        mVidView.setVideoURI(mUri);
        mVidView.setZOrderOnTop(true);
        mMediaController = new MediaController(this, true);
        mMediaController.setAnchorView(null);
        mVidView.setMediaController(mMediaController);

        mVidView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            public boolean onError(MediaPlayer mp, int what, int extra) {
                .
                .
                .
            }
        });

        mVidView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            public void onCompletion(MediaPlayer mp) {
                .
                .
                .
            }
        });

        mVidView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            public void onPrepared(MediaPlayer mp) {
                mDialog.dismiss();
                mMediaPlayer = mp;
                mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
                mp.setLooping(false);
                mp.setScreenOnWhilePlaying(true);
                mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
                    public void onSeekComplete(MediaPlayer mp) {
                        mp.start();
                    }
                });

                if (mTimecode > 0) {
                    mp.seekTo(mTimecode * ONE_SEC);
                } else {
                    mp.start();
                }
                mMediaController.show(0);
            }
        });
        LinearLayout ll = (LinearLayout) this.findViewById(R.id.parentpopup);
        ll.addView(mVidView);
    }
}

来源:https://stackoverflow.com/questions/17461025/why-does-mediaplayer-setlooping-cause-an-error-when-using-videoview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!