【问题标题】:IllegalStateException on mediaplayer prepare() methodmediaplayer prepare() 方法上的 IllegalStateException
【发布时间】:2015-10-02 08:50:37
【问题描述】:

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

对于 RTSP 流,我使用 MediaPlayer 类,因为它默认支持 RTSP 流。对于MJPEG,我有一个AsyncTask,它调用一个HTTP url 并返回JPEG,我用它来设置SurfaceViews SurfaceHolderCanvas。我认为当我尝试解锁 SurfaceHolder Canvas 时问题出在某个地方

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

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

MjpegThreadAsyncTask,它在我调用的doInBackground 方法结束时停止AsyncTask 后发出HTTP 请求并更新SurfaceHolders Canvas

surfaceHolder.unlockCanvasAndPost(canvas);

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

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

上面的代码在我最初使用RTSP bot 时有效,而不是当我从MJPEG 切换到RTSP 时。

【问题讨论】:

    标签: java android multithreading android-mediaplayer surfaceview


    【解决方案1】:

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

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

    你有几个选择:

    1. 使用多个 SurfaceView。将视频播放到一个,将 MJPEG 帧写入另一个,并使非活动的一个透明。使用setZOrderMediaOverlay() 将一个置于另一个之上。

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

    您还可以使用单独的自定义 View 并使用 FrameLayout 将其与 SurfaceView 重叠。

    【讨论】:

    • 太好了,您详细介绍了surfaceview 的工作原理。但是为什么有时当线程在我尝试切换到媒体播放器之前停止时,我将其更改为媒体播放器它可以工作。我只是确定由于某种原因,从我的线程和 MediaPlayer 切换时,在我的代码中未正确解锁表面视图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-08
    • 2017-01-02
    • 1970-01-01
    • 2017-02-12
    相关资源
    最近更新 更多