Есть несколько клонов одного и того же ответа для первой версии 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>