0

我正在使用 MediaPlayer 和自定义 TextureView 制作一个 android 视频播放器。

但是我的代码在mContext.sendBroadcast(i);openVideo() 的函数中出现了错误;

private void openVideo()
{

    Log.e(TAG, "openVideo");
    if (mUri == null || mSurfaceTexture == null)
    {
        // not ready for playback just yet, will try again later
        return;
    }
    // Tell the music playback service to pause
    // TODO: these constants need to be published somewhere in the
    // framework.
    Intent i = new Intent("com.android.music.musicservicecommand");
    i.putExtra("command", "pause");
    mContext.sendBroadcast(i);
    Log.e(TAG, "openVideo passed"  );

    // we shouldn't clear the target state, because somebody might have
    // called start() previously
    release(false);
    try
    {
        mMediaPlayer = new MediaPlayer(mContext);
        mMediaPlayer.setOnPreparedListener(mPreparedListener);
        mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
        mDuration = -1;
        mMediaPlayer.setOnCompletionListener(mCompletionListener);
        mMediaPlayer.setOnErrorListener(mErrorListener);
        mMediaPlayer.setOnInfoListener(mInfoListener);
        mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
        mCurrentBufferPercentage = 0;
        mMediaPlayer.setDataSource(mContext, mUri);

        mMediaPlayer.setSurface(new Surface(mSurfaceTexture));
    //  mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mMediaPlayer.setScreenOnWhilePlaying(true);
        mMediaPlayer.prepareAsync();
        // we don't set the target state here either, but preserve the
        // target state that was there before.
        mCurrentState = STATE_PREPARING;
        attachMediaController();
    }
    catch (IOException ex)
    {
        Log.w(TAG, "Unable to open content: " + mUri, ex);
        mCurrentState = STATE_ERROR;
        mTargetState = STATE_ERROR;
        mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
        return;
    }
    catch (IllegalArgumentException ex)
    {
        Log.w(TAG, "Unable to open content: " + mUri, ex);
        mCurrentState = STATE_ERROR;
        mTargetState = STATE_ERROR;
        mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
        return;
    }
}

下面是VideoView的内容

public class VideoView extends TextureView implements VideoController.VideoPlayerControl {
private String TAG = "VideoView2";
private final VideoSizeCalculator videoSizeCalculator;

private Uri mUri;
private int mDuration;
private FullScreenControl mScreenControl;
// all possible internal states
private static final int STATE_ERROR = -1;
private static final int STATE_IDLE = 0;
private static final int STATE_PREPARING = 1;
private static final int STATE_PREPARED = 2;
private static final int STATE_PLAYING = 3;
private static final int STATE_PAUSED = 4;
private static final int STATE_PLAYBACK_COMPLETED = 5;
private static final int STATE_STOP = 6;

// mCurrentState is a VideoView object's current state.
// mTargetState is the state that a method caller intends to reach.
// For instance, regardless the VideoView object's current state,
// calling pause() intends to bring the object to a target state
// of STATE_PAUSED.
private int mCurrentState = STATE_IDLE;
private int mTargetState = STATE_IDLE;

// All the stuff we need for playing and showing a video
private SurfaceTexture  mSurfaceTexture = null;
private MediaPlayer mMediaPlayer = null;
private int mVideoWidth;
private int mVideoHeight;
private int mSurfaceWidth;
private int mSurfaceHeight;
private VideoController mVideoController;
private OnCompletionListener mOnCompletionListener;
private OnPreparedListener mOnPreparedListener;
private int mCurrentBufferPercentage;
private OnErrorListener mOnErrorListener;
private OnInfoListener mOnInfoListener;
private int mSeekWhenPrepared; // recording the seek position while
                               // preparing

private Context mContext;

public VideoView2(final Context context, final AttributeSet attrs) {
    this(context, attrs, 0);
}

public VideoView2(final Context context, final AttributeSet attrs, final int defStyle) {
    super(context, attrs, defStyle);
    videoSizeCalculator = new VideoSizeCalculator();
    initVideoView();
}

@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
    VideoSizeCalculator.Dimens dimens = videoSizeCalculator.measure(widthMeasureSpec, heightMeasureSpec);
    setMeasuredDimension(dimens.getWidth(), dimens.getHeight());
}

@Override
public void onInitializeAccessibilityEvent(final AccessibilityEvent event) {
    super.onInitializeAccessibilityEvent(event);
    event.setClassName(VideoView2.class.getName());
}

@Override
public void onInitializeAccessibilityNodeInfo(final AccessibilityNodeInfo info) {
    super.onInitializeAccessibilityNodeInfo(info);
    info.setClassName(VideoView2.class.getName());
}

public int resolveAdjustedSize(final int desiredSize, final int measureSpec) {
    return getDefaultSize(desiredSize, measureSpec);
}

@SuppressWarnings("deprecation")
private void initVideoView()
{
    mVideoWidth = 0;
    mVideoHeight = 0;
    videoSizeCalculator.setVideoSize(0, 0);
    setSurfaceTextureListener(mSTListener);

    setFocusable(true); 
    setFocusableInTouchMode(true);
    requestFocus();
    mCurrentState = STATE_IDLE;
    mTargetState = STATE_IDLE;
}
public void setFullScreenControll(FullScreenControl screenControl){
    mScreenControl = screenControl;
}
public void setVideoPath(String path)
{
    Log.e(TAG, "setVideoPath : " + path);
    setVideoURI(Uri.parse(path));
}

public void setVideoURI(Uri uri)
{
    Log.e(TAG, "setVideoURI : " );
    if (mVideoController != null)
        mVideoController.toggleLoading(true);
    mUri = uri;
    mSeekWhenPrepared = 0;
    openVideo();
    requestLayout();
    invalidate();
    //EasyTracker.getTracker().trackEvent(TAG, "Play video", uri.toString(), -1l);
}

public void stopPlayback()
{
    if (mMediaPlayer != null)
    {
        if (mCurrentState != STATE_PREPARING)
        {
            mMediaPlayer.stop();
            mMediaPlayer.release();
            mMediaPlayer = null;
            mCurrentState = STATE_IDLE;
            mTargetState = STATE_IDLE;
        }
        else
            mTargetState = STATE_STOP;
    }
}

private void openVideo()
{

    Log.e(TAG, "openVideo");
    if (mUri == null || mSurfaceTexture == null)
    {
        // not ready for playback just yet, will try again later
        return;
    }
    // Tell the music playback service to pause
    // TODO: these constants need to be published somewhere in the
    // framework.
    Intent i = new Intent("com.android.music.musicservicecommand");
    i.putExtra("command", "pause");
    mContext.sendBroadcast(i);
    Log.e(TAG, "openVideo passed"  );

    // we shouldn't clear the target state, because somebody might have
    // called start() previously
    release(false);
    try
    {
        mMediaPlayer = new MediaPlayer(mContext);
        mMediaPlayer.setOnPreparedListener(mPreparedListener);
        mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
        mDuration = -1;
        mMediaPlayer.setOnCompletionListener(mCompletionListener);
        mMediaPlayer.setOnErrorListener(mErrorListener);
        mMediaPlayer.setOnInfoListener(mInfoListener);
        mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
        mCurrentBufferPercentage = 0;
        mMediaPlayer.setDataSource(mContext, mUri);

        mMediaPlayer.setSurface(new Surface(mSurfaceTexture));
    //  mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mMediaPlayer.setScreenOnWhilePlaying(true);
        mMediaPlayer.prepareAsync();
        // we don't set the target state here either, but preserve the
        // target state that was there before.
        mCurrentState = STATE_PREPARING;
        attachMediaController();
    }
    catch (IOException ex)
    {
        Log.w(TAG, "Unable to open content: " + mUri, ex);
        mCurrentState = STATE_ERROR;
        mTargetState = STATE_ERROR;
        mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
        return;
    }
    catch (IllegalArgumentException ex)
    {
        Log.w(TAG, "Unable to open content: " + mUri, ex);
        mCurrentState = STATE_ERROR;
        mTargetState = STATE_ERROR;
        mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
        return;
    }
}

public void setVideoController(VideoController controller)
{
    if (mVideoController != null)
    {
        mVideoController.hide();
    }
    mVideoController = controller;
    attachMediaController();
}

private void attachMediaController()
{
    if (mMediaPlayer != null && mVideoController != null)
    {
        mVideoController.setMediaPlayer(this);
        mVideoController.setEnabled(isInPlaybackState());
    }
}

MediaPlayer.OnVideoSizeChangedListener mSizeChangedListener = new MediaPlayer.OnVideoSizeChangedListener()
{
    @Override
    public void onVideoSizeChanged(MediaPlayer mp, int width, int height)
    {
        Log.e(TAG, "mSizeChangedListener");

        mVideoWidth = mp.getVideoWidth();
        mVideoHeight = mp.getVideoHeight();

            videoSizeCalculator.setVideoSize(mVideoWidth, mVideoHeight);
            if (videoSizeCalculator.hasASizeYet()) {
                requestLayout();
            }

    }
};

MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener()
{
    public void onPrepared(MediaPlayer mp)
    {
        Log.e(TAG, "mPreparedListener");

        if (mTargetState == STATE_STOP)
        {
            release(true);
            return;
        }
        mCurrentState = STATE_PREPARED;

        if (mOnPreparedListener != null)
        {
            mOnPreparedListener.onPrepared(mMediaPlayer);
        }
        if (mVideoController != null)
        {
            mVideoController.setEnabled(true);
        }
        mVideoWidth = mp.getVideoWidth();
        mVideoHeight = mp.getVideoHeight();

        int seekToPosition = mSeekWhenPrepared; // mSeekWhenPrepared may be
                                                // changed after seekTo()
                                                // call
        if (seekToPosition != 0)
        {
            seekTo(seekToPosition);
        }
        if (mVideoWidth != 0 && mVideoHeight != 0)
        {
            // Log.i("@@@@", "video size: " + mVideoWidth +"/"+
            // mVideoHeight);
        //  getHolder().setFixedSize(mVideoWidth, mVideoHeight);
            videoSizeCalculator.setVideoSize(mVideoWidth, mVideoHeight);
            if (mSurfaceWidth == mVideoWidth && mSurfaceHeight == mVideoHeight)
            {
                // We didn't actually change the size (it was already at the
                // size
                // we need), so we won't get a "surface changed" callback,
                // so
                // start the video here instead of in the callback.
                if (mTargetState == STATE_PLAYING)
                {
                    start();
                }
                else
                {
                    if (mVideoController != null)
                    {
                        // Show the media controls when we're paused into a
                        // video and make 'em stick.
                        mVideoController.toggleLoading(false);
                        mVideoController.show();
                    }
                }
            }
        }
        else
        {
            // We don't know the video size yet, but should start anyway.
            // The video size might be reported to us later.
            if (mTargetState == STATE_PLAYING)
            {
                start();
            }
            else
            {
                if (mVideoController != null)
                {
                    mVideoController.toggleLoading(false);
                    mVideoController.show();
                }
            }

        }
    }
};

private MediaPlayer.OnInfoListener mInfoListener = new MediaPlayer.OnInfoListener()
{
    @Override
    public boolean onInfo(MediaPlayer mp, int what, int extra)
    {
        Log.e(TAG, "mInfoListener");
        switch (what)
        {

            case MediaPlayer.MEDIA_INFO_BUFFERING_START:
                mVideoController.toggleLoading(true);
                break;
            case MediaPlayer.MEDIA_INFO_BUFFERING_END:
                mVideoController.toggleLoading(false);
                break;

            default:
                break;
        }
        if (mOnInfoListener != null)
            mOnInfoListener.onInfo(mp, what, extra);
        return true;
    }
};

private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener()
{
    public void onCompletion(MediaPlayer mp)
    {
        Log.e(TAG, "mCompletionListener");
        mCurrentState = STATE_PLAYBACK_COMPLETED;
        mTargetState = STATE_PLAYBACK_COMPLETED;
        if (mVideoController != null)
        {
            if(mVideoController.isShowing())
                mVideoController.hide();
            mVideoController.show();
        }
        if (mOnCompletionListener != null)
        {
            mOnCompletionListener.onCompletion(mMediaPlayer);
        }
    }
};

private MediaPlayer.OnErrorListener mErrorListener = new MediaPlayer.OnErrorListener()
{
    public boolean onError(MediaPlayer mp, int framework_err, int impl_err)
    {
        Log.e(TAG, "mErrorListener");

        Log.d(TAG, "Error: " + framework_err + "," + impl_err);
        mCurrentState = STATE_ERROR;
        mTargetState = STATE_ERROR;
        if (mVideoController != null)
        {
            mVideoController.show();
        }

        /* If an error handler has been supplied, use it and finish. */
        if (mOnErrorListener != null)
        {

        }
        return true;
    }
};

private MediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener = new MediaPlayer.OnBufferingUpdateListener()
{
    public void onBufferingUpdate(MediaPlayer mp, int percent)
    {
        Log.e(TAG, "mBufferingUpdateListener");

        mCurrentBufferPercentage = percent;
    }
};

/**
 * Register a callback to be invoked when the media file is loaded and ready
 * to go.
 * 
 * @param l
 *            The callback that will be run
 */
public void setOnPreparedListener(MediaPlayer.OnPreparedListener l)
{
    mOnPreparedListener = l;
}

/**
 * Register a callback to be invoked when the end of a media file has been
 * reached during playback.
 * 
 * @param l
 *            The callback that will be run
 */
public void setOnCompletionListener(OnCompletionListener l)
{
    mOnCompletionListener = l;
}

/**
 * Register a callback to be invoked when an error occurs during playback or
 * setup. If no listener is specified, or if the listener returned false,
 * VideoView will inform the user of any errors.
 * 
 * @param l
 *            The callback that will be run
 */
public void setOnErrorListener(OnErrorListener l)
{
    mOnErrorListener = l;
}

/**
 * Register a callback to be invoked when an informational event occurs
 * during playback or setup.
 * 
 * @param l
 *            The callback that will be run
 */
public void setOnInfoListener(OnInfoListener l)
{
    mOnInfoListener = l;
}



private SurfaceTextureListener mSTListener = new SurfaceTextureListener() {
    @Override
    public void onSurfaceTextureAvailable(final SurfaceTexture surface, final int width, final int height) {

        Log.e(TAG, "onSurfaceTextureAvailable");

        mSurfaceTexture = surface;
        openVideo();
    }

    @Override
    public void onSurfaceTextureSizeChanged(final SurfaceTexture surface, final int width, final int height) {
        Log.e(TAG, "surfaceChanged " + width +" " +height);
        mSurfaceWidth = width;
        mSurfaceHeight = height;
        boolean isValidState = (mTargetState == STATE_PLAYING);
        boolean hasValidSize = (mVideoWidth ==width && mVideoHeight == height);
        if (mMediaPlayer != null && isValidState && hasValidSize)
        {
            if (mSeekWhenPrepared != 0)
            {
                seekTo(mSeekWhenPrepared);
            }
            start();
        }
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {

        Log.e(TAG, "onSurfaceTextureDestroyed");

        mSurfaceTexture = null;
        if (mVideoController != null)
            mVideoController.hide();
        release(true);
        return true;
    }

    @Override
    public void onSurfaceTextureUpdated(final SurfaceTexture surface) {
        Log.e(TAG, "onSurfaceTextureUpdated");

        mSurfaceTexture = surface;
    }
};

/*
 * release the media player in any state
 */
private void release(boolean cleartargetstate)
{
    if (mMediaPlayer != null)
    {
        mMediaPlayer.reset();
        mMediaPlayer.release();
        mMediaPlayer = null;
        mCurrentState = STATE_IDLE;
        if (cleartargetstate)
        {
            mTargetState = STATE_IDLE;
        }
    }
}

@Override
public boolean onTouchEvent(MotionEvent ev)
{
    //Log.e(TAG, "onTouchEvent");
    switch (ev.getAction())
    {
        case MotionEvent.ACTION_DOWN:
            if ((isInPlaybackState() || mCurrentState == STATE_ERROR) && mVideoController != null)
            {
                toggleMediaControlsVisiblity();
            }
            // if(mCurrentState == STATE_ERROR)
            // return true;
            return false;
            // case MotionEvent.ACTION_UP:
            // if(mCurrentState == STATE_ERROR)
            // {
            // restart();
            // return true;
            // }
            // return false;
        default:
            return false;
    }

}

@Override
public boolean onTrackballEvent(MotionEvent ev)
{
    if (isInPlaybackState() && mVideoController != null)
    {
        Log.e(TAG, "onTrackballEvent");

        toggleMediaControlsVisiblity();
    }
    return false;
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
    boolean isKeyCodeSupported = keyCode != KeyEvent.KEYCODE_BACK && keyCode != KeyEvent.KEYCODE_VOLUME_UP
            && keyCode != KeyEvent.KEYCODE_VOLUME_DOWN && keyCode != KeyEvent.KEYCODE_VOLUME_MUTE
            && keyCode != KeyEvent.KEYCODE_MENU && keyCode != KeyEvent.KEYCODE_CALL && keyCode != KeyEvent.KEYCODE_ENDCALL;
    if (isInPlaybackState() && isKeyCodeSupported && mVideoController != null)
    {
        if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)
        {
            if (mMediaPlayer.isPlaying())
            {
                pause();
                mVideoController.show();
            }
            else
            {
                start();
                mVideoController.hide();
            }
            return true;
        }
        else if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY)
        {
            if (!mMediaPlayer.isPlaying())
            {
                start();
                mVideoController.hide();
            }
            return true;
        }
        else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP || keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE)
        {
            if (mMediaPlayer.isPlaying())
            {
                pause();
                mVideoController.show();
            }
            return true;
        }
        else
        {
            toggleMediaControlsVisiblity();
        }
    }

    return super.onKeyDown(keyCode, event);
}

private void toggleMediaControlsVisiblity()
{
    mVideoController.toggleVisibility();
}

public void start()
{
    if (mCurrentState == STATE_ERROR)
    {
        restart();
        return;
    }
    if (isInPlaybackState())
    {
        mMediaPlayer.start();
        mCurrentState = STATE_PLAYING;
        mVideoController.toggleLoading(false);
    }
    mTargetState = STATE_PLAYING;

}

public void pause()
{
    if (isInPlaybackState())
    {
        if (mMediaPlayer.isPlaying())
        {
            mMediaPlayer.pause();
            mCurrentState = STATE_PAUSED;
        }
    }
    mTargetState = STATE_PAUSED;
}

public void restart()
{
    mVideoController.toggleLoading(true);
    openVideo();
    requestLayout();
    invalidate();
    start();
}

public void suspend()
{
    release(false);
}

public void resume()
{
    openVideo();
}

// cache duration as mDuration for faster access
public int getDuration()
{
    if (isInPlaybackState())
    {
        if (mDuration > 0)
        {
            return mDuration;
        }
        mDuration = (int) mMediaPlayer.getDuration();
        return mDuration;
    }
    mDuration = -1;
    return mDuration;
}

public int getCurrentPosition()
{
    if (isInPlaybackState())
    {
        return (int) mMediaPlayer.getCurrentPosition();
    }
    return 0;
}

public void seekTo(int msec)
{
    if (isInPlaybackState())
    {
        mMediaPlayer.seekTo(msec);
        mSeekWhenPrepared = 0;
    }
    else
    {
        mSeekWhenPrepared = msec;
    }
}

public boolean isPlaying()
{
    return isInPlaybackState() && mMediaPlayer.isPlaying();
}

public int getBufferPercentage()
{
    if (mMediaPlayer != null)
    {
        return mCurrentBufferPercentage;
    }
    return 0;
}

private boolean isInPlaybackState()
{
    return (mMediaPlayer != null && mCurrentState != STATE_ERROR && mCurrentState != STATE_IDLE && mCurrentState != STATE_PREPARING);
}


@Override
public boolean isFullScreen() {
    // TODO Auto-generated method stub
    return mScreenControl.checkFullScreen();
}

@Override
public void toggleFullScreen() {
    // TODO Auto-generated method stubsetRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    mScreenControl.toggleFullScreen();
}
public interface FullScreenControl
{
    public boolean checkFullScreen();

    public void toggleFullScreen();
    public int getHeight();
    public int getWidth();



}

}

请给我一些建议。提前致谢!

4

0 回答 0