我正在使用SurfaceView
和MediaPlayer
来传输来自RTSP
和MJPEG的视频,这两个协议都是独立工作的,当我仅从RTSP
或MJPEG 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();
MjpegThread
是AsyncTask
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.....
机器人时,上述代码无效。
答案 0 :(得分:1)
unlockCanvasAndPost
用于通过软件渲染到Surface。 MediaPlayer希望将帧直接发送到Surface。由于Android的Surface类的限制,一旦您执行了软件渲染,您就无法对Surface执行任何其他操作。 (如果其他东西已附加到Surface,您也无法进行软件渲染。)
你没有在你的问题中显示logcat输出,但这是一个非常常见的问题。 (这类似于人们在播放视频后询问有关擦除SurfaceView曲面的其他问题,例如this one。)
您有几个选择:
使用多个SurfaceView。将视频合二为一,将MJPEG帧写入另一帧,并使非活动帧透明。使用setZOrderMediaOverlay()
将一个放在另一个上面。
使用SurfaceView的两个部分。使用invalidate()
和onDraw()
呈现您的MJPEG,就像custom View一样。这类似于#1,但可能更有效,因为自定义视图可以是硬件加速的。当您完成MJPEG后,将视图清除为透明以显示Surface内容。
您还可以使用单独的自定义视图,并使用FrameLayout将其与SurfaceView重叠。