在一个Activity中准备MediaPlayer的同步,在另一个Activity中播放

时间:2012-09-06 19:02:00

标签: android asynchronous streaming media-player

我正在开发一个应用程序,除其他外,它播放一些视频文件(流媒体)。我想在一个活动中准备MediaPlayer,但是在另一个活动准备就绪后播放视频,这样用户就可以浏览第一个活动的内容以消磨一些时间。这可能吗?

Application类中定义了一个静态MediaPlayer,如下所示:

public class EGDF_App extends Application {

    private static MediaPlayer mediaPlayer = null;

    public static MediaPlayer getMediaPlayer() {
        if(mediaPlayer == null)
            return new MediaPlayer();
        else
            return mediaPlayer;
    }

}

我有一个带文字的按钮(加载视频)。视频准备就绪时会更改此文本,当用户点击该文本时,会触发以下活动。

问题是我在LogCat中收到以下错误:

09-06 20:43:34.606: D/ChapterPlayer(31999): surfaceCreated called
09-06 20:43:34.684: V/ChapterPlayer(31999): startVideoPlayback
09-06 20:43:34.684: E/MediaPlayer(31999): start called in state 1
09-06 20:43:34.684: E/MediaPlayer(31999): error (-38, 0)
09-06 20:43:34.684: D/ChapterPlayer(31999): surfaceChanged called
09-06 20:43:34.700: E/MediaPlayer(31999): Attempt to call getDuration without a valid mediaplayer
09-06 20:43:34.715: E/MediaPlayer(31999): Error (-38,0)
09-06 20:43:34.715: D/ChapterPlayer(31999): onCompletion called
09-06 20:43:34.751: E/MediaPlayer(31999): Attempt to call getDuration without a valid mediaplayer

这是第一个Activity中包含的代码:

public void watchChapter(View view){
    Log.i("Button", "Watch chapter button PRESSED");
    Button b = (Button) view;
    String loadChapter = getString(R.string.load_chapter_button_text);
    String watchChapter = getString(R.string.watch_chapter_button_text);

    if(((String) b.getText()).equals(loadChapter)){ 
        prepareVideo(view);

    }else if(((String) b.getText()).equals(watchChapter)){  

        Intent intent = new Intent(this,ChapterAsyncMediaPlayerActivity.class);
        intent.putExtra(Constants.chapterVideoResParse, getIntent().getExtras().getString(Constants.chapterVideoResParse));
        intent.putExtra("duration", String.valueOf(duration));
        startActivity(intent);
    }


}

private void prepareVideo(View view){
    MediaPlayer mMediaPlayer;
    String path;
    final Button button = (Button) view;
    String resource = extras.getString(Constants.chapterVideoResParse);
    path = SecurityHandler.obtainURL(resource, this.getResources().openRawResource(R.raw.output), 10);

    try {
        // Gets the media player and set the listeners
        mMediaPlayer = EGDF_App.getMediaPlayer();
        mMediaPlayer.setDataSource(path);
        mMediaPlayer.prepareAsync();
        mMediaPlayer.setOnPreparedListener(new OnPreparedListener(){

            @Override
            public void onPrepared(MediaPlayer mp) {
                button.setText(getString(R.string.watch_chapter_button_text));
                Log.i("MediaPlayer", "MediaPlayer ready");
                duration = mp.getDuration();
                Log.i("Video duration", String.valueOf(mp.getDuration()));
            }

        });
        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    } catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalStateException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

这是第二个Activity中的代码:

public class ChapterAsyncMediaPlayerActivity extends Activity implements
OnBufferingUpdateListener, OnCompletionListener,
OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback, MediaPlayerControl {

    private static final String TAG = "ChapterPlayer";
    private int mVideoWidth;
    private int mVideoHeight;
    private MediaPlayer mMediaPlayer;
    private MediaController mController;
    private SurfaceView mPreview;
    private SurfaceHolder holder;
//  private String path;
//  private boolean mIsVideoSizeKnown = false;
    private boolean mIsVideoReadyToBePlayed = false;

    private Handler handler = new Handler();

    @SuppressWarnings("deprecation")
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chapter_media_player);
        mPreview = (SurfaceView) findViewById(R.id.mediaPlayerSurface);
        holder = mPreview.getHolder();
        holder.addCallback(this);
        holder.setKeepScreenOn(true);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mController.show();
        return false;
    }

    private void playVideo() {
        doCleanUp();
        try {

            // Create a new media player and set the listeners
            mMediaPlayer = EGDF_App.getMediaPlayer();
//          mMediaPlayer.setDataSource(path);
            mMediaPlayer.setDisplay(holder);
//          mMediaPlayer.prepareAsync();
            mMediaPlayer.setOnBufferingUpdateListener(this);
            mMediaPlayer.setOnCompletionListener(this);
            mMediaPlayer.setOnPreparedListener(this);
            mMediaPlayer.setOnVideoSizeChangedListener(this);
            mMediaPlayer.setScreenOnWhilePlaying(true);
            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mController = new MediaController(this);

        } catch (Exception e) {
            Log.e(TAG, "error: " + e.getMessage(), e);
        }
    }

    public void onPrepared(MediaPlayer mediaplayer) {
        Log.d(TAG, "onPrepared called");
        mIsVideoReadyToBePlayed = true;
        mController.setMediaPlayer(this);
        mController.setAnchorView(findViewById(R.id.mediaPlayerSurface));
        handler.post(new Runnable(){

            @Override
            public void run() {

                mController.setEnabled(true);
                mController.show();

            }
        });
        if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {

            startVideoPlayback();
        }
    }

    public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) {
        Log.d(TAG, "surfaceChanged called");

    }

    public void surfaceDestroyed(SurfaceHolder surfaceholder) {
        Log.d(TAG, "surfaceDestroyed called");
    }

    public void surfaceCreated(SurfaceHolder holder) {
        Log.d(TAG, "surfaceCreated called");
        playVideo();
        mIsVideoReadyToBePlayed = true;
        mController.setMediaPlayer(this);
        mController.setAnchorView(findViewById(R.id.mediaPlayerSurface));
        handler.post(new Runnable(){

            @Override
            public void run() {

                mController.setEnabled(true);
                mController.show();

            }
        });
        if (mIsVideoReadyToBePlayed) {
            startVideoPlayback();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        mMediaPlayer.pause();
    }

    @Override
    protected void onRestart() {
        super.onPause();
        mMediaPlayer.start();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        releaseMediaPlayer();
        doCleanUp();
    }

    private void releaseMediaPlayer() {
        if (mMediaPlayer != null) {
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }

    private void doCleanUp() {
        mVideoWidth = 0;
        mVideoHeight = 0;
        mIsVideoReadyToBePlayed = false;
    }

    private void startVideoPlayback() {
        Log.v(TAG, "startVideoPlayback");
        holder.setFixedSize(mVideoWidth, mVideoHeight);
        mMediaPlayer.start();
        mMediaPlayer.setScreenOnWhilePlaying(true);
    }

    @Override
    public boolean canPause() {
        return true;
    }

    @Override
    public boolean canSeekBackward() {
        return true;
    }

    @Override
    public boolean canSeekForward() {
        return true;
    }

    @Override
    public int getBufferPercentage() {
        return 0;
    }

    @Override
    public int getCurrentPosition() {
        if(mMediaPlayer != null)
            return mMediaPlayer.getCurrentPosition();
        else
            return 0;
    }

    @Override
    public int getDuration() {
        if(mMediaPlayer != null)
            return mMediaPlayer.getDuration();
        else
            return 0;
    }

    @Override
    public boolean isPlaying() {
        if(mMediaPlayer != null)
            return mMediaPlayer.isPlaying();
        else
            return false;
    }

    @Override
    public void pause() {
        if(mMediaPlayer != null)
            mMediaPlayer.pause();       
    }

    @Override
    public void seekTo(int pos) {
        mMediaPlayer.seekTo(pos);       
    }

    @Override
    public void start() {
        if(mMediaPlayer != null)
            mMediaPlayer.start();
    }

    public void onBufferingUpdate(MediaPlayer arg0, int percent) {
        Log.d(TAG, "onBufferingUpdate percent:" + percent);

    }

    public void onCompletion(MediaPlayer arg0) {
        Log.d(TAG, "onCompletion called");
    }

    @Override
    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
        Log.v(TAG, "onVideoSizeChanged called");
        if (width == 0 || height == 0) {
            Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")");
            return;
        }
        mVideoWidth = width;
        mVideoHeight = height;
        if (mIsVideoReadyToBePlayed) {
            startVideoPlayback();
        }
    }
}

我很感激一些帮助或建议。谢谢!

1 个答案:

答案 0 :(得分:1)

我不认为您在应用程序中保存MediaPlayer,而只是返回它的新实例。尝试改变它:

public static MediaPlayer getMediaPlayer() {
    if(mediaPlayer == null) {
        mediaPlayer = new MediaPlayer();
    }
    return mediaPlayer;
}