mediaplayer prepare()方法的IllegalStateException

时间:2015-10-02 08:50:38

标签: java android multithreading android-mediaplayer surfaceview

我正在使用SurfaceViewMediaPlayer来传输来自RTSP和MJPEG的视频,这两个协议都是独立工作的,当我仅从RTSPMJPEG over HTTP流式传输时只要。我遇到的问题是当我尝试从MJPEG协议切换到另一个时,prepare()方法抛出IllegalStateException

对于RTSP流,我使用MediaPlayer类,因为它默认支持RTSP流。对于MJPEG,我有一个调用HTTP网址的AsyncTask,并返回JPEG,用于在SurfaceView SurfaceHolder Canvas上设置绘图。我认为当我试图解锁SurfaceHolder Canvas

时,问题就出现了

当我尝试将流从MJPEG更改为RTSP时的第一步:

MjpegThread.isRunning = false;
mediaPlayer.release();
mediaPlayer = null;
setMediaPlayer();

MjpegThreadAsyncTask HTTP发出SurfaceHolder个请求,并在Canvas结束后停止AsyncTask doInBackground我调用的surfaceHolder.unlockCanvasAndPost(canvas); 方法

mediaPlayer.setDisplay(vidHolder);
mediaPlayer.setDataSource(OZOptions.RTSP_URL);
mediaPlayer.prepare(); // <- IllegalStateException HERE
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

此过程的最后一步是显示RTSP流,这是我的代码:

RTSP

当我从MJPEG切换到RTSP时,我最初使用rsync -rvvv --no-p --chmod=ugo=rwX --delete --append --include=*_T_*.pdx..... 机器人时,上述代码无效。

1 个答案:

答案 0 :(得分:1)

unlockCanvasAndPost用于通过软件渲染到Surface。 MediaPlayer希望将帧直接发送到Surface。由于Android的Surface类的限制,一旦您执行了软件渲染,您就无法对Surface执行任何其他操作。 (如果其他东西已附加到Surface,您也无法进行软件渲染。)

你没有在你的问题中显示logcat输出,但这是一个非常常见的问题。 (这类似于人们在播放视频后询问有关擦除SurfaceView曲面的其他问题,例如this one。)

您有几个选择:

  1. 使用多个SurfaceView。将视频合二为一,将MJPEG帧写入另一帧,并使非活动帧透明。使用setZOrderMediaOverlay()将一个放在另一个上面。

  2. 使用SurfaceView的两个部分。使用invalidate()onDraw()呈现您的MJPEG,就像custom View一样。这类似于#1,但可能更有效,因为自定义视图可以是硬件加速的。当您完成MJPEG后,将视图清除为透明以显示Surface内容。

  3. 您还可以使用单独的自定义视图,并使用FrameLayout将其与SurfaceView重叠。