Android webrtc SurfaceViewRenderer preview goes blank when I start the Activity in landscape/reverse landscape

1.4k views Asked by At

I'm facing this weird issue where SurfaceViewRenderer preview goes blank whenever I run activity in landscape/reverse landscape/sensor landscape. The weird problem is, in some phones video preview works in reverse landscape mode and in some phones landscape mode. For example, when I run activity in Android 5.0, the video preview in landscape mode works fine but not in reverse landscape mode. Then I tried to do the same in my Oneplus phone which is running Android 10. Here the video preview in SurfaceViewRenderer works fine in reverse landscape mode but not in landscape mode.

Note: Remote streaming works fine without any issues even though the preview goes blank, only video preview doesn't work. It is somehow failing to update the SurfaceViewRenderer but no issue streaming to remote participants.

<androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".ui.session.activities.LiveSessionActivity">

  
        <org.webrtc.SurfaceViewRenderer
            android:id="@+id/localGLSurfaceView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="visible" />

        <View
            android:id="@+id/vBackground"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:alpha="0.4"
            android:background="@android:color/black"
            android:visibility="visible"
            app:layout_constraintBottom_toBottomOf="@+id/localGLSurfaceView"
            app:layout_constraintEnd_toEndOf="@+id/localGLSurfaceView"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="@+id/localGLSurfaceView"
            app:layout_constraintTop_toTopOf="@+id/localGLSurfaceView"
            app:layout_constraintVertical_bias="0.0" />

        <View
            android:id="@+id/vShadow"
            android:layout_width="wrap_content"
            android:layout_height="@dimen/_42sdp"
            android:background="@drawable/ic_rectangle_shadow"
            app:layout_constraintEnd_toEndOf="@+id/localGLSurfaceView"
            app:layout_constraintStart_toStartOf="@+id/localGLSurfaceView"
            app:layout_constraintTop_toTopOf="@+id/localGLSurfaceView" />

        <ImageView
            android:id="@+id/ivBackButton"
            android:layout_width="@dimen/_8sdp"
            android:layout_height="@dimen/_13sdp"
            android:layout_marginStart="@dimen/_12sdp"
            android:layout_marginTop="@dimen/_16sdp"
            android:src="@drawable/ic_back"
            app:layout_constraintStart_toStartOf="@+id/localGLSurfaceView"
            app:layout_constraintTop_toTopOf="@+id/localGLSurfaceView" />

        <TextView
            android:id="@+id/tvLiveClassName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="@dimen/_12sdp"
            android:text="Live Class 10"
            android:textColor="@android:color/white"
            android:textSize="@dimen/medium_text"
            app:layout_constraintBottom_toBottomOf="@+id/ivBackButton"
            app:layout_constraintStart_toEndOf="@+id/ivBackButton"
            app:layout_constraintTop_toTopOf="@+id/ivBackButton" />

        <TextView
            android:id="@+id/tvCountDown"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="5"
            android:textColor="@android:color/white"
            android:textSize="@dimen/xxx_large_text"
            app:layout_constraintBottom_toTopOf="@+id/tvTestAudio"
            app:layout_constraintEnd_toEndOf="@+id/localGLSurfaceView"
            app:layout_constraintStart_toStartOf="@+id/localGLSurfaceView" />

        <TextView
            android:id="@+id/tvGoLiveIn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/_18sdp"
            android:text="Going Live in"
            android:textColor="@android:color/white"
            android:textSize="@dimen/xx_large_text"
            app:layout_constraintBottom_toTopOf="@+id/tvCountDown"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="@+id/localGLSurfaceView" />

        <ImageView
            android:id="@+id/ivStrengthIcon"
            android:layout_width="@dimen/_19sdp"
            android:layout_height="@dimen/_19sdp"
            android:layout_marginTop="@dimen/_14sdp"
            android:layout_marginEnd="@dimen/_12sdp"
            android:src="@drawable/ic_network_strength"
            app:layout_constraintEnd_toEndOf="@+id/localGLSurfaceView"
            app:layout_constraintTop_toTopOf="@+id/localGLSurfaceView" />

        <TextView
            android:id="@+id/tvNetworkStrength"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="@dimen/_8sdp"
            android:layout_marginBottom="@dimen/_2sdp"
            android:text="Good"
            android:textColor="@android:color/white"
            android:textSize="@dimen/small_text"
            app:layout_constraintBottom_toBottomOf="@+id/ivStrengthIcon"
            app:layout_constraintEnd_toStartOf="@+id/ivStrengthIcon"
            app:layout_constraintTop_toTopOf="@+id/ivStrengthIcon" />

        <Button
            android:id="@+id/btnCancelLive"
            android:layout_width="@dimen/_108sdp"
            android:layout_height="@dimen/_29sdp"
            android:layout_marginBottom="@dimen/_25sdp"
            android:background="@drawable/ic_rectangle_button"
            android:gravity="center"
            android:text="Cancel Live"
            android:textAllCaps="false"
            android:textSize="@dimen/medium_text"
            app:backgroundTint="@null"
            app:layout_constraintBottom_toBottomOf="@+id/localGLSurfaceView"
            app:layout_constraintEnd_toEndOf="@+id/localGLSurfaceView"
            app:layout_constraintStart_toStartOf="@+id/localGLSurfaceView" />

        <TextView
            android:id="@+id/tvTestAudio"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/_12sdp"
            android:text="Speak to test the audio"
            android:textColor="@android:color/white"
            android:textSize="@dimen/medium_text"
            app:layout_constraintBottom_toTopOf="@+id/btnCancelLive"
            app:layout_constraintEnd_toEndOf="@+id/localGLSurfaceView"
            app:layout_constraintStart_toStartOf="@+id/localGLSurfaceView" />

        <androidx.constraintlayout.widget.Group
            android:id="@+id/groupTopView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:visibility="gone"
            app:constraint_referenced_ids="ivBackButton,
            tvLiveClassName,tvNetworkStrength,ivStrengthIcon,vShadow" />

        <androidx.constraintlayout.widget.Group
            android:id="@+id/groupVideoView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:visibility="gone"
            app:constraint_referenced_ids="localGLSurfaceView,
            tvCountDown,tvGoLiveIn,btnCancelLive,tvTestAudio,
            vBackground,preview" />

        <Button
            android:id="@+id/btnJoinSession"
            style="@style/Widget.MaterialComponents.Button.OutlinedButton"
            android:layout_width="@dimen/_130sdp"
            android:layout_height="@dimen/_40sdp"
            android:text="Join Session"
            app:backgroundTint="@color/colorAccent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <include
            android:id="@+id/include"
            layout="@layout/video_bottom_menu_layout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:visibility="gone"
            app:layout_constraintBottom_toBottomOf="@id/localGLSurfaceView"
            app:layout_constraintEnd_toEndOf="@id/localGLSurfaceView"
            app:layout_constraintStart_toStartOf="@id/localGLSurfaceView" />
    </androidx.constraintlayout.widget.ConstraintLayout>

This is how I'm initializing the video preview.

private fun initVideoView() {
        val rootEglBase = EglBase.create()
        mLiveSessionBinding.localGLSurfaceView.init(rootEglBase.eglBaseContext, null)
        mLiveSessionBinding.localGLSurfaceView.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL)
        mLiveSessionBinding.localGLSurfaceView.setMirror(true)
        mLiveSessionBinding.localGLSurfaceView.setEnableHardwareScaler(true)
        mLiveSessionBinding.localGLSurfaceView.setZOrderMediaOverlay(true)
    }

My video camera settings to preview and also stream

public VideoTrack MakeCameraSettingsReady() {
        final EglBase.Context eglBaseContext = EglBase.create().getEglBaseContext();
        PeerConnectionFactory peerConnectionFactory = this.sessionManager.getPeerConnectionFactory();

        // create AudioSource
        AudioSource audioSource = peerConnectionFactory.createAudioSource(new MediaConstraints());
        this.audioTrack = peerConnectionFactory.createAudioTrack("101", audioSource);

        surfaceTextureHelper = SurfaceTextureHelper.create("CaptureThread", eglBaseContext);
        // create VideoCapturer
        VideoCapturer videoCapturer = createCameraCapturer();
        VideoSource videoSource = peerConnectionFactory.createVideoSource(videoCapturer.isScreencast());
        videoCapturer.initialize(surfaceTextureHelper, context, videoSource.getCapturerObserver());
        videoCapturer.startCapture(480, 640, 30);

        return peerConnectionFactory.createVideoTrack("100", videoSource);
    }

This is how I'm creating camera capturer

private VideoCapturer createCameraCapturer() {
        CameraEnumerator enumerator;
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
            enumerator = new Camera2Enumerator(this.context);
        } else {
            enumerator = new Camera1Enumerator(false);
        }
        final String[] deviceNames = enumerator.getDeviceNames();

        // Try to find front facing camera
        for (String deviceName : deviceNames) {
            if (enumerator.isFrontFacing(deviceName)) {
                videoCapturer = enumerator.createCapturer(deviceName, null);
                if (videoCapturer != null) {
                    return videoCapturer;
                }
            }
        }
        // Front facing camera not found, try something else
        for (String deviceName : deviceNames) {
            if (!enumerator.isFrontFacing(deviceName)) {
                videoCapturer = enumerator.createCapturer(deviceName, null);
                if (videoCapturer != null) {
                    return videoCapturer;
                }
            }
        }
        return null;
    }

This is the activity that I have declared in manifest file.

<activity android:name=".ui.session.activities.LiveSessionActivity"
            android:configChanges="orientation|screenSize"
            android:screenOrientation="sensorLandscape">

I tried to check if that happens with CameraX preview. Using CameraX in androidx.camera.view.PreviewView video preview works fine in all kind of orientation. However SurfaceViewRenderer video preview do not work.

Any help in this regard will be really appreciated. Thanks in advance.

0

There are 0 answers