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.