将SurfaceView传递给android.media.MediaPlayer的最佳方法

时间:2014-05-14 03:09:25

标签: android video android-mediaplayer android-mediarecorder

我正在编写一个消费媒体(音频/视频)并允许用户回复和/或发布新媒体的应用。

我的问题与用于显示视频的SurfaceView有关。此MediaView对象在MediaRecorder(录制视频)和MediaPlayer(使用/播放视频)之间共享。

根据NPR示例,MediaPlayer位于自己的服务上,该服务在自己的线程上运行:PlaybackService.java

由于NPR示例不涉及视频,因此我不确定如何使服务上的MediaPlayer知道UI中的SurfaceView。我最终使用静态变量来解决这个问题:

// MyFragmentClass.java

// CameraPreview is the sample class shown int he media section
// of the Android Developer site:
// http://developer.android.com/guide/topics/media/camera.html#camera-preview
private static CameraPreview sCameraPreview;

@Override
public void onStart() {
    super.onStart();

    CameraPreview cameraPreview = new CameraPreview(getActivity());
    FrameLayout preview = (FrameLayout) getView().findViewById(R.id.video_preview);
    preview.addView(cameraPreview);
    setCameraPreview(cameraPreview);  // a static setter. 

    // Other classes are initialized afterwards, not relevant to this question...
}

public static CameraPreview getCameraPreview() {
    return sCameraPreview;
}

public static void setCameraPreview(CameraPreview cameraPreview) {
    sCameraPreview = cameraPreview;
}

以下是PlaybackService上用于准备播放视频的方法:

// Params url and isVideo were extras on an Intent that triggers
// this method
synchronized private void prepareMediaPlayer(String url, boolean isVideo) {
    if (mMediaPlayer == null) {
        mMediaPlayer = new MediaPlayer();
        mMediaPlayer.setOnCompletionListener(this);
        mMediaPlayer.setOnErrorListener(this);
        mMediaPlayer.setOnInfoListener(this);
        mMediaPlayer.setOnPreparedListener(this);
    } else {
        mMediaPlayer.reset();
    }       

    mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    mMediaPlayer.setDataSource(mediaUrl);
    if (isVideo) {
       // this is the important line
       mMediaPlayer.setDisplay(MyFragmentClass.getCameraPreview().getHolder());
       mMediaPlayer.setScreenOnWhilePlaying(true);
    }
    mMediaPlayer.prepareAsync();

    sendIntent(STATUS_PLAYBACK_PREPARED);
}

它完成了工作,但我想知道是否有更好的方法来做,特别是因为我正在调试一个随机错误,共享表面没有被释放,它让我想到了:

  1. 有没有更好的方法让我的服务类知道服务?
  2. 在录制和播放时使用单个SurfaceView是一种好方法吗?
  3. 谢谢!

0 个答案:

没有答案