I have an ImageView which is set to scaleType=fitCenter and a TextureSurface inside a framelayout:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorBackground"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <ImageView
        android:id="@+id/imageStart"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:srcCompat="@drawable/splash_image_start"
        android:padding="0dp"
        android:scaleType="fitCenter"
        android:adjustViewBounds="false"/>

    <TextureView
        android:id="@+id/surfaceView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="invisible"/>
</FrameLayout>

When the Activity loads I wish to show splash_image_start image whilst the video is loading and immediately start playing the video.

The splash_image_start is 1080x1920 pixels which matches exactly the video size.

It all works fine but the the video kicks in there is a slight increase on the width of the first frame shown in the ImageView.

In specific to match exactly the first frame with the video when playing I need to transform the media player by 1% on the x scale:

    mediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
        @Override
        public void onVideoSizeChanged(MediaPlayer mp, int videoWidth, int videoHeight) {
            Log.v(TAG, "MediaPlayer video size changed");
            float viewWidth = sv.getWidth();
            float viewHeight = sv.getHeight();

            int pivotPointX = (int) (viewWidth / 2);
            int pivotPointY = (int) (viewHeight / 2);

            Matrix matrix = new Matrix();
            // Completely unknown as to why but when trying to match a video render against
            // a static frame render there is a 0.1% difference in scale X
            matrix.setScale(0.9f, 1.0f, pivotPointX, pivotPointY);

            sv.setTransform(matrix);
        }
    }); 

I have tried various configurations in ImageView as well as playing with mediaPlayer.setVideoScalingMode with absolutely no result.

Unless I actually set the video scaleX to 0.9f there is always a difference. Tried on multiple devices.

So my question is, is there an explanation at to why I need to set the scaleX to 0.9f for the video to exactly match the first frame image? Is there a better way of precisely matching the first frame in an ImageView with a video playback?

PS: I am starting with a hidden TextureView and when the video loads I show and play in that view. Works fine.

0 Answers