Giter Site home page Giter Site logo

zoomabletextureview's Introduction

ZoomableTextureView

Enables pinch to zoom and scroll gestures on video while it's playing. Can be used with MediaPlayer and the new ExoPlayer API. Inspired by similar implementation for ImageView http://stackoverflow.com/questions/6650398/android-imageview-zoom-in-and-zoom-out

Usage

Library is distributed via jCenter

dependencies {
  implementation 'ua.polohalo.zoomabletextureview:zoomabletextureview:1.0.0'
}

Just include the custom view in your XML layout:

    <ua.polohalo.zoomabletextureview.ZoomableTextureView
        android:id="@+id/textureView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:maxScale="6" />

app:maxScale="6" determines that the max zooming factor will be 600%.

Main limitation of this library is the fact that it doesn't properly handle "wrap_content" size so you need to set it manually

In case you want to use it with the new SimpleExoPlayerView instead of ExoPlayer(provides controls out of the box) there is a sample on how to do just that here.

License

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

zoomabletextureview's People

Contributors

kaidul avatar manuiq avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

zoomabletextureview's Issues

How to prevent resize below original size?

Setting "minScale='1'" does not do it. You can still resize below the original TextureView size, which looks very odd and also glitches badly if you have a light theme background.

I have figured out how to set the original view's parameters to maintain the aspect ratio (which for a SurfaceView appears to initialize properly automatically, but does not for a TextureView even with orientation set explicitly to vertical) but I cannot find the original scale value of the view in initView and, if someone tries to resize the view smaller than that cap the scale to the original level when the view was established.

It appears that "minScale" and "maxScale" are intended to prevent this but they don't -- the code looks right in onScale but isn't preventing the problem.

In addition it would be nice to have a double-tap reset scaling to the original value.

Example code demonstrating the problem -- play something in landscape and try to pinch it smaller. You can't. Then pinch zoom it LARGER, then back to smaller below the original "fills the screen" width. You should not be able to with the minScale set to 1 but you can in fact shrink the view below the screen width.

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://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_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));

        player.setVideoTextureView(mPlayerView);
        mPlayerView.invalidate();

        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;
        }
    }

}

and the XML for this:

<?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>

How to get zoomed preview (Bitmap) ??

I'm able to zoom the image using this library but unable to capture zoomed image . when I capture it returned the default image (before zoomed preview) always. Please help me to resolve this.

This has been of great help - open to pull requests?

Hello hello!

First, just gotta say this is a great utility class. I have very little experience with matrix manipulation and transformation on Android, and your use case spells out a lot of the details that I'm still reading over (ha!)

I noticed that you had a {TODO: fix ugly code;} in there, and I was wondering if I could be of any help. I have a slightly different use case of a zooming texture view, but I think we share a lot of the fundamentals. I'll (sadly) leave up to you the aspect ratio issue, but I can offer a little bit of abstraction / cleaning help if you're interested. I'm not master architect (far from it), but I reorganized things while reading through to get a clearer picture of what was happening between the ZoomOnTouchListeners and the TextureView itself. A couple interfaces, little bit of separation, variable naming, that kinda thing.

If you're interested in perhaps rejiggering your structure around a bit, I would love to share and get some feedback on the changes I've made. Just let me know!

Why is it slow to render 720p streams and verry slow to render 1080p video streams.

Hi ,

The panning and zooming work nicely especially on low resolution streams, but it shows large delays on 1080p streams.
To find the bottleneck that drives these delays I have tested rendering a 1080p stream on a simple textureView without panning and zooming methods. It ended up working without delays. I tested it on Galaxy s20+ with 12 GB of RAM.

I wonder what can I do to speed up the rendering of larger resolution streams like 1080p with panning and zooming.

Thank you

Hide The Controls in Exoplayer.!!!

When i try to implement this with Exoplayer, it didn't show the Play/Pause, seekbar like controls..
Can anyone help me out with this.

Why is mScaleFactor determined twice?

Very good open source library. Thank you in advance. But when I looked at the source code, I found that the same judgment was made twice. Is there any special reason? Here's the code:
ua.polohalo.zoomabletextureview.ZoomableTextureView:

                    if (mScaleFactor < 1) {
                        matrix.getValues(m);
                        float x = m[Matrix.MTRANS_X];
                        float y = m[Matrix.MTRANS_Y];
                        if (mScaleFactor < 1) {
                            if (0 < getWidth()) {
                                if (y < -bottom)
                                    matrix.postTranslate(0, -(y + bottom));
                                else if (y > 0)
                                    matrix.postTranslate(0, -y);
                            } else {
                                if (x < -right)
                                    matrix.postTranslate(-(x + right), 0);
                                else if (x > 0)
                                    matrix.postTranslate(-x, 0);
                            }
                        }
                    }

360 Playbacks not available,

is there any way to play 360 videos with ZoomableTextureView, what kind of change required in available ZoomableTextureView?

When zoom the video,controller of playerview is hide

I have a custom exoplayback control view layout for my playerview. I use ZoomableExoPlayerView class. When I zoom video linear_layout_play_pause and linear_layout_bottom hide.
This is my custom control view:

`
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_black_gradient"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root_layout">
<android.support.constraint.ConstraintLayout
android:id="@+id/constraint_layout_options"
android:layout_width="match_parent"
android:layout_height="36dp"
android:padding="10dp"
app:layout_constraintBottom_toTopOf="@+id/linear_layout_play_pause"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.115">

  <TextView
      android:id="@+id/exo_speed"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginEnd="16dp"
      android:scaleType="fitCenter"
      android:text="1.0X"
      android:textColor="#FFF"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintHorizontal_bias="0.0"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="parent"
      tools:ignore="ContentDescription" />

</android.support.constraint.ConstraintLayout>

  <!--<TextView-->
  <!--android:id="@+id/text_minus_10_seconds"-->
  <!--android:layout_width="wrap_content"-->
  <!--android:layout_height="wrap_content"-->
  <!--android:padding="14dp"-->
  <!--android:text="@string/minus_10"-->
  <!--android:textSize="18sp"-->
  <!--android:textColor="@color/colorWhite" />-->

  <ImageButton
      android:id="@id/exo_prev"
      style="@style/ExoMediaButton.Previous"
      tools:ignore="ContentDescription" />

  <ImageButton
      android:id="@id/exo_rew"
      style="@style/ExoMediaButton.Rewind" />

  <ImageButton
      android:id="@id/exo_play"
      style="@style/ExoMediaButton.Play"
      tools:ignore="ContentDescription" />

  <ImageButton
      android:id="@id/exo_pause"
      style="@style/ExoMediaButton.Pause"
      tools:ignore="ContentDescription" />

  <ImageButton
      android:id="@id/exo_ffwd"
      style="@style/ExoMediaButton.FastForward" />

  <ImageButton
      android:id="@id/exo_next"
      style="@style/ExoMediaButton.Next"
      tools:ignore="ContentDescription" />

  <!--<TextView-->
  <!--android:id="@+id/text_plus_10_seconds"-->
  <!--android:layout_width="wrap_content"-->
  <!--android:layout_height="wrap_content"-->
  <!--android:padding="14dp"-->
  <!--android:text="@string/plus_10"-->
  <!--android:textSize="18sp"-->
  <!--android:textColor="@color/colorWhite" />-->

  <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_marginTop="4dp"
      android:gravity="center_vertical"
      android:orientation="horizontal">

     <TextView
         android:id="@id/exo_position"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:includeFontPadding="false"
         android:paddingLeft="4dp"
         android:paddingRight="4dp"
         android:textColor="#FFBEBEBE"
         android:textSize="14sp"
         android:textStyle="bold" />

     <com.google.android.exoplayer2.ui.DefaultTimeBar
         android:id="@id/exo_progress"
         android:layout_width="0dp"
         android:layout_height="26dp"
         android:layout_weight="1"
         app:played_color="@color/colorPrimary" />

     <TextView
         android:id="@id/exo_duration"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:includeFontPadding="false"
         android:paddingLeft="4dp"
         android:paddingRight="4dp"
         android:textColor="#FFBEBEBE"
         android:textSize="14sp"
         android:textStyle="bold" />

     <ImageView
         android:id="@+id/exo_fullscreen_icon"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginTop="8dp"
         android:layout_marginEnd="8dp"
         android:layout_marginBottom="8dp"
         android:src="@drawable/ic_fullscreen_expand"
         tools:ignore="ContentDescription" />

  </LinearLayout>

</android.support.constraint.ConstraintLayout>

Zoom in and out is not recorded

During recording video using VideoCapture with ZoomableTextureView, zoom in and out is not recorded instead simple video is recorded with out zoom in and out. is there any solution for this ?

Rotation

Hi bro!
After calling matrix.postRotate(90) the image goes out of screen area.
Can you share a solution for this case. Really need it but can't solve the problem.
Thanks for any response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.