ExoPlayer2 Zoomable View? - PullRequest
       8

ExoPlayer2 Zoomable View?

0 голосов
/ 28 мая 2018

Есть несколько клонов одного и того же ответа для первой версии Exoplayer и оригинального медиапроигрывателя Android, но они не компилируются в Exoplayer2, который реорганизовал значительную часть внутреннего кода.

Достаточно тщательный поиск не нашел ничего подобного библиотечному или примерному коду для этого (например, масштабирование, прокрутка и т. Д.). Существует много кода, чтобы сделать это для неподвижных изображений (например, полученных через Пикассо,и т.д.)

Есть ли у кого-нибудь пример, который будет собираться и работать с ExoPlayer2?

Заранее спасибо!

Обновление: проблема в том, что я не могу подкласс илиприсоедините VideoListener к экземпляру SimpleExoPlayer;попытка сделать это не оставляет вас ни с чем, так как экземпляр уже подключил своего собственного слушателя, который обращает ровно нулевое внимание на соотношение сторон, когда задействован TextureView.Это делает видео совершенно непригодным для использования;слушатель мог бы исправить это довольно легко, но, кажется, нет никакого способа его прикрепить (методы для этого помечены как устаревшие, и если вы попытаетесь их использовать в любом случае, вы не получите видеовыход.)

Этокод нарисует и запустит ua.pohohalo.zoomabletextureview (или просто обычный TextureView), но я не могу прикрепить к нему видеолистер и по умолчанию, когда он инициализируется, подходит видео к размеру представления по вертикали в портретном режиме, который разрушает соотношение сторон.Это также имеет серьезные глюки, если вы измените размер видео ниже размера окна дисплея, но я могу проверить и исправить это в коде Полохало.То, что я не понял, как это сделать, это заставить исходный экран соответствовать исходному соотношению сторон или присоединить VideoListener, чтобы установить его на init - он отлично работает, если я использую PlayerView, но это не может быть расширеноподдерживать переводы.Прототип «VideoListener» в этом кодовом блоке должен исправить проблему с соотношением сторон - это то, что я не смог прикрепить или найти способ установить флаг в исходном представлении (что также сделало бы эту работу), который говорит ExoPlayer соблюдатьисходное соотношение сторон и размер экрана.

Вызов simpleExoPlayerView.setResizeMode (AspectRatioFrameLayout.RESIZE_MODE_FIT), который работает с PlayerView, недопустим для TextureView - кажется, что режим по умолчанию равенRESIZE_MODE_FILL и я не могу найти метод для установки его в FIT.

package net.cudasystems.android.videotest;

import android.graphics.Matrix;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.TextureView;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;

import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.VideoListener;


public class MainActivity extends AppCompatActivity {

    private String mURL = "http://point-at-an-mp4-file";

    TextureView mPlayerView;

    SimpleExoPlayer player = null;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mPlayerView = findViewById(R.id.video_view2);
    }

    private void initializePlayer() {

        DefaultRenderersFactory renderersFactory =
                new DefaultRenderersFactory(this, DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON);

        VideoListener mVideoListener = new VideoListener() {
            @Override
            public void onRenderedFirstFrame() {

            }
            @Override
            public void onVideoSizeChanged(int width, int height, int rotation, float pixelWidthHeightRatio ) {
                String TAG = "VideoSizeChange";
                int viewWidth = mPlayerView.getWidth();
                int viewHeight = mPlayerView.getHeight();
                double aspectRatio = (double) height / width;

                int newWidth, newHeight;
                if (viewHeight > (int) (viewWidth * aspectRatio)) {
                    // limited by narrow width; restrict height
                    newWidth = viewWidth;
                    newHeight = (int) (viewWidth * aspectRatio);
                } else {
                    // limited by short height; restrict width
                    newWidth = (int) (viewHeight / aspectRatio);
                    newHeight = viewHeight;
                }
                int xoff = (viewWidth - newWidth) / 2;
                int yoff = (viewHeight - newHeight) / 2;
                Log.v(TAG, "video=" + width + "x" + height +
                        " view=" + viewWidth + "x" + viewHeight +
                        " newView=" + newWidth + "x" + newHeight +
                        " off=" + xoff + "," + yoff);

                Matrix txform = new Matrix();
                mPlayerView.getTransform(txform);
                txform.setScale((float) newWidth / viewWidth, (float) newHeight / viewHeight);
                txform.postTranslate(xoff, yoff);
                mPlayerView.setTransform(txform);
            }

        };

        player = ExoPlayerFactory.newSimpleInstance(
                renderersFactory,
                new DefaultTrackSelector(), new DefaultLoadControl());


        player.setVideoTextureView(mPlayerView);

        // mPlayerView.setPlayer(player);

        player.setPlayWhenReady(true);

        Uri uri = Uri.parse(mURL);
        MediaSource mediaSource = buildMediaSource(uri);
        player.prepare(mediaSource, true, true);
    }


    private MediaSource buildMediaSource(Uri uri) {

        return new ExtractorMediaSource.Factory(
                new DefaultHttpDataSourceFactory("exoplayer-codelab")).
                createMediaSource(uri);
    }


    @Override
    public void onStart() {
        super.onStart();
        if (Util.SDK_INT > 23) {
            if (player == null) {
                initializePlayer();
            }
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if ((Util.SDK_INT <= 23 || player == null)) {
            initializePlayer();
        }
    }
    @Override
    public void onPause() {
        super.onPause();
        if (Util.SDK_INT <= 23) {
            releasePlayer();
        }
    }
    @Override
    public void onStop() {
        super.onStop();
        if (Util.SDK_INT > 23) {
            releasePlayer();
        }
    }
    private void releasePlayer() {
        if (player != null) {
            player.release();
            player = null;
        }
    }

}

и XML-файл, чтобы идти с ним .... Декларация масштабирования сейчас "вкл", но код может легко использовать либоне масштабируемый или PlayerView (изменяя тип и не прикрепляя текстуру);это прекрасно работает, включая правильную обработку поворота.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/root"
    android:focusable="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:keepScreenOn="true">

    <TextureView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:visibility="gone"
        android:id="@+id/video_view3" />

    <ua.polohalo.zoomabletextureview.ZoomableTextureView
        android:id="@+id/video_view2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        app:maxScale="4"/>

    <com.google.android.exoplayer2.ui.PlayerView
        android:id="@+id/video_view"
        android:visibility="gone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:use_controller="false"/>

</FrameLayout>

Обновление: после долгих ударов следующий код работает, КРОМЕ ТОГО, если вы пытаетесь использовать его во фрагменте, и в этом случае расширение TextView имеет проблемыиз-за того, как подбираются минимальные и максимальные значения шкалы.Очевидный ответ «взломать» состоит в том, чтобы проверить minScale = 0 и установить его равным 1,0, если вы обнаружите, что он не инициализирован.

Надеюсь, это поможет кому-то еще.

package net.cudasystems.android.videotest;

import android.net.Uri;
import android.os.Bundle;
import android.support.constraint.ConstraintLayout;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.view.TextureView;

import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;

import com.google.android.exoplayer2.util.Util;


public class MainActivity extends AppCompatActivity {

    private String mURL = "http://set-to-an-mp4-URL"

    TextureView mPlayerView;

    SimpleExoPlayer player = null;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mPlayerView = findViewById(R.id.video_view);
    }

    private void initializePlayer() {

        DefaultRenderersFactory renderersFactory =
                new DefaultRenderersFactory(this, DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON);


        player = ExoPlayerFactory.newSimpleInstance(
                renderersFactory,
                new DefaultTrackSelector(), new DefaultLoadControl());


        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);


        // Make sure the initial aspect ratio is 16:9 (otherwise a TextureView init's to the LARGER of
        // the two dimensions of the video irrespective of the orientation setting and screws the aspect ratio!)
        int width = metrics.widthPixels;
        int newHeight = (width * 9) / 16;
        mPlayerView.setLayoutParams(new ConstraintLayout.LayoutParams(width, newHeight));
        mPlayerView.invalidate();

        player.setVideoTextureView(mPlayerView);

        player.setPlayWhenReady(true);

        Uri uri = Uri.parse(mURL);
        MediaSource mediaSource = buildMediaSource(uri);
        player.prepare(mediaSource, true, true);
    }


    private MediaSource buildMediaSource(Uri uri) {

        return new ExtractorMediaSource.Factory(
                new DefaultHttpDataSourceFactory("exoplayer-codelab")).
                createMediaSource(uri);
    }


    @Override
    public void onStart() {
        super.onStart();
        if (Util.SDK_INT > 23) {
            if (player == null) {
                initializePlayer();
            }
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if ((Util.SDK_INT <= 23 || player == null)) {
            initializePlayer();
        }
    }
    @Override
    public void onPause() {
        super.onPause();
        if (Util.SDK_INT <= 23) {
            releasePlayer();
        }
    }
    @Override
    public void onStop() {
        super.onStop();
        if (Util.SDK_INT > 23) {
            releasePlayer();
        }
    }
    private void releasePlayer() {
        if (player != null) {
            player.release();
            player = null;
        }
    }

}

Ирабочий XML, чтобы идти с этим:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/root"
    android:focusable="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:keepScreenOn="true">

    <ua.polohalo.zoomabletextureview.ZoomableTextureView
        android:id="@+id/video_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        app:maxScale="4"
        app:minScale="1"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Does This work?"
        android:textColor="@android:color/holo_red_dark"
        app:layout_constraintBottom_toBottomOf="parent" />

</android.support.constraint.ConstraintLayout>
...