ExoPlayer always automatically stops when playing videos

359 Views Asked by At

I am using ExoPlayer as follows: import androidx.media3.exoplayer.ExoPlayer;

I am attempting to use SurfaceTexture to retrieve video frames from ExoPlayer and render them in openGL ES. However, after playing the video for a while or when switching videos, the playback automatically stops. I have attempted error handling using onPlayerError, but no exceptions are being caught. Instead, I have noticed the following exception in my Logcat:

E/ExoPlayerImplInternal: Disable failed.
    java.lang.IllegalStateException
        at android.media.MediaCodec.native_flush(Native Method)
        at android.media.MediaCodec.flush(MediaCodec.java:2388)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.flushOrReleaseCodec(MediaCodecRenderer.java:773)
        at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.flushOrReleaseCodec(MediaCodecVideoRenderer.java:724)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.onDisabled(MediaCodecRenderer.java:634)
        at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.onDisabled(MediaCodecVideoRenderer.java:569)
        at com.google.android.exoplayer2.BaseRenderer.disable(BaseRenderer.java:168)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.disableRenderer(ExoPlayerImplInternal.java:1136)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.resetInternal(ExoPlayerImplInternal.java:891)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.releaseInternal(ExoPlayerImplInternal.java:864)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:373)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loopOnce(Looper.java:240)
        at android.os.Looper.loop(Looper.java:351)
        at android.os.HandlerThread.run(HandlerThread.java:67)

E/ExoPlayerImplInternal: Reset failed.
    java.lang.IllegalStateException
        at android.media.MediaCodec.native_stop(Native Method)
        at android.media.MediaCodec.stop(MediaCodec.java:2338)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.releaseCodec(MediaCodecRenderer.java:668)
        at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.releaseCodec(MediaCodecVideoRenderer.java:714)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.onReset(MediaCodecRenderer.java:641)
        at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.onReset(MediaCodecVideoRenderer.java:578)
        at com.google.android.exoplayer2.BaseRenderer.reset(BaseRenderer.java:175)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.resetInternal(ExoPlayerImplInternal.java:900)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.releaseInternal(ExoPlayerImplInternal.java:864)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:373)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loopOnce(Looper.java:240)
        at android.os.Looper.loop(Looper.java:351)
        at android.os.HandlerThread.run(HandlerThread.java:67)

I don't know what attempts to make that would be helpful in this case. Here is my code snippet:

In the onSurfaceCreated method, I create and bind the frame texture:

        mVideoTextureId = TextureUtil.genTextureObj();
        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mVideoTextureId);
        GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER,
                GLES20.GL_NEAREST);
        GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER,
                GLES20.GL_LINEAR);
        mVideoSurfaceTexture = new SurfaceTexture(mVideoTextureId);
        mVideoSurfaceTexture.setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() {
            @Override
            public void onFrameAvailable(SurfaceTexture surfaceTexture) {
                mVideoFrameAvailable = true;
            }
        });
        mVideoSurface = new Surface(mVideoSurfaceTexture);

In the onDrawFrame method, I update the video frames:

        if (mVideoFrameAvailable) {
            synchronized (this) {
                mVideoSurfaceTexture.updateTexImage();
                mVideoSurfaceTexture.getTransformMatrix(mVideoSTMatrix);
                mVideoFrameAvailable = false;
            }
        }

I have also exposed a method externally, which is used to set my video file and display position:

    public void setVideoPath(String videoPath, RectF normalCropRectF) {
        if (!Objects.isNull(normalCropRectF)) {
            mNormalCropRectF = normalCropRectF;
            convertToGL(mNormalCropRectF, true);
        }
        try {
            if (!Objects.isNull(mExoplayer)) {
                mExoplayer.clearVideoSurface();
                mExoplayer.setPlayWhenReady(false);
                mExoplayer.release();
                mExoplayer = null;
            }
            mExoplayer = new ExoPlayer.Builder(mContext).build();
            mExoplayer.setVideoSurface(mVideoSurface);
            mExoplayer.setVolume(0);
            mExoplayer.setRepeatMode(Player.REPEAT_MODE_ALL);
            MediaItem mediaItem = MediaItem.fromUri(Uri.parse(String.valueOf(new File(videoPath).toURI())));
            mExoplayer.setMediaItem(mediaItem);
            mExoplayer.prepare();
            mExoplayer.setPlayWhenReady(true);
            mExoplayer.addListener(new Player.Listener() {
                @Override
                public void onPlaybackStateChanged(int playbackState) {
                    Player.Listener.super.onPlaybackStateChanged(playbackState);
                    switch (playbackState) {
                        case Player.STATE_READY:
                            if (!Objects.isNull(mRenderCommonCallbackImpl)) {
                                mRenderCommonCallbackImpl.startPlay();
                            }
                            break;
                    }
                }

                @Override
                public void onPlayerError(PlaybackException error) {
                    Player.Listener.super.onPlayerError(error);
                    Log.d("=====", "error : " + error.getMessage());
                }

                @Override
                public void onVideoSizeChanged(VideoSize videoSize) {
                    Player.Listener.super.onVideoSizeChanged(videoSize);
                    updateProjection(videoSize.width, videoSize.height);
                }
            });
        } catch (Exception e) {
        }
    }

Any help or guidance on this issue would be greatly appreciated. I have provided the relevant code snippets and exception details above. If anyone has encountered a similar problem or has insights into why the ExoPlayer stops automatically during video playback, I would be grateful for your input. Thank you in advance for your time and assistance.

0

There are 0 best solutions below