我使用SurfaceView和MediaPlayer来传输来自RTSP和MJPEG的视频,这两种协议都是独立工作的,也就是说,当我只从RTSP或MJPEG over HTTP流时。我遇到的问题是,当我试图从MJPEG协议切换到另一个协议时,即当prepare()方法抛出一个IllegalStateException时。
对于RTSP流,我使用MediaPlayer类,因为它默认支持RTSP流。对于MJPEG,我有一个AsyncTask,它调用HTTP并返回用于设置对SurfaceView的SurfaceHolder Canvas进行绘制的JPEG。我认为当我试图解锁SurfaceHolder Canvas时,问题就在某个地方
当我试图将流从MJPEG更改为RTSP时,第一步是:
MjpegThread.isRunning = false;
mediaPlayer.release();
mediaPlayer = null;
setMediaPlayer();MjpegThread是AsyncTask,它在调用的doInBackground方法的末尾停止AsyncTask之后,发出HTTP请求并更新SurfaceHolder的Canvas。
surfaceHolder.unlockCanvasAndPost(canvas);该过程的最后一步是显示RTSP流(这里是我的代码):
mediaPlayer.setDisplay(vidHolder);
mediaPlayer.setDataSource(OZOptions.RTSP_URL);
mediaPlayer.prepare(); // <- IllegalStateException HERE
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);上面的代码在我最初使用RTSP机器人时起作用,而不是当我从MJPEG切换到RTSP时。
发布于 2015-10-02 16:23:39
unlockCanvasAndPost是用来用软件渲染到曲面上的。MediaPlayer希望直接将帧发送到Surface。由于Android的Surface类的限制,一旦您执行了软件呈现,您就不能使用Surface做任何其他事情。(如果其他东西已经附加到Surface上,您也不能进行软件渲染。)
您的问题中没有显示logcat输出,但这是一个非常常见的问题。(这类似于人们在播放视频后询问删除SurfaceView曲面的其他问题,例如这一个。)
你有几个选择:
setZOrderMediaOverlay()将其中一个定位于另一个。invalidate()和onDraw()渲染您的MJPEG,就像一个自定义视图。这与#1类似,但可能更高效,因为自定义视图可以被硬件加速。当您完成MJPEG时,您可以将View清除为透明,以显示Surface内容。您还可以使用单独的自定义视图,并使用一个SurfaceView与FrameLayout重叠。
https://stackoverflow.com/questions/32903627
复制相似问题