Tic*_*guy 5 android-layout exoplayer2.x
对于第一个版本的 Exoplayer 和原始的 Android 媒体播放器,似乎有几个相同答案的克隆,但它们不能在 Exoplayer2 上编译,后者重新组织了相当多的内部代码。
合理勤奋的搜索没有找到任何以库或示例代码的方式执行此操作的内容(例如捏缩放和滚动等)。有很多代码可以为静止图像执行此操作(例如通过毕加索检索等)
有没有人有可以构建和使用 ExoPlayer2 的示例?
提前致谢!
更新:问题似乎是我不能子类化或将 VideoListener 附加到 SimpleExoPlayer 实例;尝试这样做会让您一无所获,因为该实例已经附加了自己的侦听器,当涉及 TextureView 时,该侦听器对纵横比的关注度为零。这使得视频完全无法使用;听众可以很容易地纠正这一点,但似乎无法附加它(这样做的方法被标记为已弃用,如果您无论如何都尝试使用它们,您将无法获得视频输出。)
此代码将绘制并运行 ua.pohohalo.zoomabletextureview(或只是一个普通的 TextureView),但我无法将视频侦听器附加到它,默认情况下,当它初始化时,使视频垂直适应视图大小在破坏纵横比的纵向模式下。如果您将视频的大小调整为低于显示窗口大小,它也会出现严重的故障,但我可以在 polohalo 的代码中测试并修复它。我还没有想出如何做的是让原始显示遵守原始纵横比,或者附加一个 VideoListener 以在 init 上设置它——如果我使用 PlayerView,它可以正常工作,但无法扩展支持翻译。此代码块中的“VideoListener”原型应该解决纵横比问题——这就是我一直无法附加或找到一种方法来在原始视图上设置标志(这也可以完成这项工作),告诉 ExoPlayer 兑现原始纵横比并适合屏幕尺寸。
对适用于 PlayerView 的 simpleExoPlayerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIT) 的调用在 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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
以及与之配套的 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>
Run Code Online (Sandbox Code Playgroud)
更新:经过多次重击后,以下代码可以正常工作,除非您尝试在片段中使用它,在这种情况下,TextView 扩展会由于获取最小和最大比例值的方式而出现问题。显而易见的“hack”答案是检查 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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
以及与之配套的工作 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>
Run Code Online (Sandbox Code Playgroud)