Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android 7 and bellow problem displaying a player over another using surfaceView #7999

Closed
fgl27 opened this issue Sep 27, 2020 · 4 comments
Closed

Comments

@fgl27
Copy link

fgl27 commented Sep 27, 2020

Issue description

On my app I display a player in front of another, on Android 7 or bellow when using surfaceView the player that is in front can't be seen, using textureView no problem see video bellow....

https://www.youtube.com/watch?v=tIcyWjiVhLg&feature=youtu.be

On that video the player first start using textureView all the player are visible, even when front of it other, after I change from textureView to surfaceView (disabling the app settings "Picture in Picture old OS workaround") we can't see the player that is front anymore.

Yes the layout is properly created, meaning that the player that must be in front is in always in front.

I know this is probably a old OS problem, but maybe can be improved and surfaceView can be used, so old devices using my app don't need workarounds.

I have this issue fgl27/SmartTwitchTV#13, where a old device Amazon Fire Stick Gen 2 (running android SDK 22) lags (drops a lot of frames) when using textureView wiling playing a single video, that may be a device issue, but the user needs to force disable the settings "Picture in Picture old OS workaround" to avoid lags, and after that can't use any Picture in Picture mode that the app has as the players aren't visible as there is the old OS issue.

Reproduction steps

Try to display a PlayerView over another using surfaceView on Android 7 or bellow.

Link to test content

I'm playing HLS live streams, I assume the link is not applicable, as my link do expire I share one on request.

A full bug report captured from the device

As this is a visual problem that can be reproduce on the emulator of Android Studio, I assume a bug report is not applicable, if requested I generate one from the emulator

Version of ExoPlayer being used

dev-v2

Device(s) and version(s) of Android being used

Android emulator X86 API 23
Android 6

Also tested on devices as for example Moto G second generation running Android 6, same problem

@krocard
Copy link
Contributor

krocard commented Sep 30, 2020

@andrewlewis, @ojw28 then you seem to have the most experience with dealing with surfaceView vs textureView on old devices. Do you have an idea if a workaround exist for overlaying surfaceView on old Android devices?

@andrewlewis
Copy link
Collaborator

In case you haven't tried them already, here are a couple of suggestions:

  1. Based on this Stack Overflow answer, try setting the z-order using the SurfaceView's setZOrderOnTop or setZOrderMediaOverlay methods. This Stack Overflow answer has more details about how the SurfaceView's rendering layer works.
  2. If you make the picture-in-picture view a TextureView I think it will be drawn like a normal piece of UI (with the SurfaceView underneath). I'm not sure if that will fix the device-specific issue you mentioned though.

If those don't work then I'm not aware of other easy ways that might fix this, as it seems like a limitation of the underlying windowing/graphics system.

The only other suggestion I have is to have the videos render to off-screen SurfaceTextures and then composite them yourself, drawing into a GLSurfaceView. This is going to be a lot of work though, especially if there is anything to draw apart from video in the composited view. It does result in having a single SurfaceView though. It might also suffer from the same performance issue you saw with TextureView. There is more info in #6617 and some sample code that may be useful as a starting point in gldemo.

@fgl27
Copy link
Author

fgl27 commented Oct 1, 2020

Thank you I'll revise all of that, if I find a solution I post here a update with it.

@fgl27
Copy link
Author

fgl27 commented Oct 9, 2020

The function I endup using is the bellow only use for PlayerView using SurfaceView

    private void ResetViewOrder(PlayerView ViewOnTop, PlayerView ViewOnBottom) {
        //Make sure both views are inside the same layout, pass the parent or use the below to get it
        ViewGroup parent = (ViewGroup) ViewOnTop.getParent();

        parent.bringChildToFront(ViewOnTop);

        SurfaceView TopSurfaceView = (SurfaceView) ViewOnTop.getVideoSurfaceView();
        SurfaceView BottomSurfaceView = (SurfaceView) ViewOnBottom.getVideoSurfaceView();

        if (TopSurfaceView != null && BottomSurfaceView != null) {

            //Remove both PlayerView to fully reset the order, with just setZOrderMediaOverlay or even setZOrderOnTop the effect will not work on Android 7 and older OS
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
                parent.removeView(ViewOnBottom);
                parent.removeView(ViewOnTop);
            }

            TopSurfaceView.setZOrderMediaOverlay(true);
            BottomSurfaceView.setZOrderMediaOverlay(false);

            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
                parent.addView(ViewOnBottom);
                parent.addView(ViewOnTop);
            }
        }

    }

@google google locked and limited conversation to collaborators Dec 1, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants