I'm working on PiP mode in my app. In fact it is working pretty fine, but I have a problem with blinking/disappearing video for a split second.
I have VideoActivity in "fullscreen"/normal mode. I'm calling enterPictureInPictureMode();
and Activity
is collapsing to small PiP-frame. At the moment when animation is ending shrinking layout then video get transparent for a split second/one frame. Also exacly in this frame whole PiP-frame gets shadow under (elevation). When I touch this small PiP-frame it expands a bit to big PiP-frame (not fullscreen) and this anim is smooth, but when auto-collapse to small PiP-frame it blinks again on the end... Everytime when Activity
is animating to small PiP-frame (no matter if is collapsing from big PiP-frame or fullscreen Activity
) one-frame transparency-blink occurs when reaching final "small bounds". No impact to sound, video is playing steady, no calls to onPlayerStateChanged
.
With newer API version we can create animation with bounds and thats how I know the video view is blinking... Using no-attribute method makes whole layout collapses and I can see blink only on area with video/player/surface view (black stripes above and below video). When I use newer method and setSourceRectHint
I can see whole PiP-frame disapears without respecting black background of its parent. In fact I've added dummy View
with fixed size, background color and centerInParent
like PlayerView
- it blinks/hides just like player when is placed below (first in parent) PlayerView
layer, but placed above doesn't blink at all and is showing above PlayerView
even when it disappears for split sec.
How to fix that blink or maybe though set black background, not transparent...
if (Build.VERSION.SDK_INT >= 26) {
Rect bounds = new Rect();
playerView.getVideoSurfaceView().getDrawingRect(bounds);
int toTop = (playerView.getMeasuredHeight() - bounds.height()) / 2,
toLeft = (playerView.getMeasuredWidth() - bounds.width()) / 2;
bounds.top += toTop;
bounds.left += toLeft;
bounds.bottom += toTop;
bounds.right += toLeft;
enterPictureInPictureMode(new PictureInPictureParams.Builder().
setSourceRectHint(bounds).
setAspectRatio(new Rational(bounds.width(), bounds.height())).
build());
} else
enterPictureInPictureMode();
xml:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black">
<com.google.android.exoplayer2.ui.PlayerView
android:id="@+id/activity_video_player_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:background="@android:color/black"
app:controller_layout_id="@layout/exo_custom_control_view"
app:fastforward_increment="10000"
app:rewind_increment="10000"
app:show_timeout="100" />
...
PS. Above problem also appears when using usual VideoView
played in WebView
and got into fullscreen by VideoEnabledWebChromeClient. But in this case blink reveals for a split second part of WebView
s content
edit: I've just found a workaround for blinking ExoPlayer - by replacing SurfaceView
with TextureView
, adding app:surface_type="texture_view"
- but I'm reading that TextureView
is a bit less efficient and also this is not fixing VideoView
blink (fullscreen from WebView
)
edit2: can confirm blinks on Android 8 (Xiaomi) and 9 (Pixel)