Add support to render video onto a TextureView with SimpleExoPlayer.
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=132306954
This commit is contained in:
parent
12b7bbf803
commit
7c48028fe7
@ -281,7 +281,7 @@ public class PlayerActivity extends Activity implements OnKeyListener, OnTouchLi
|
||||
player.setId3Output(eventLogger);
|
||||
player.setTextOutput(subtitleView);
|
||||
player.setVideoListener(this);
|
||||
player.setVideoSurfaceHolder(surfaceView.getHolder());
|
||||
player.setVideoSurfaceView(surfaceView);
|
||||
if (shouldRestorePosition) {
|
||||
if (playerPosition == C.TIME_UNSET) {
|
||||
player.seekToDefaultPosition(playerWindow);
|
||||
|
@ -17,6 +17,7 @@ package com.google.android.exoplayer2;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaCodec;
|
||||
import android.media.PlaybackParams;
|
||||
@ -24,6 +25,8 @@ import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.TextureView;
|
||||
import com.google.android.exoplayer2.audio.AudioCapabilities;
|
||||
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
|
||||
import com.google.android.exoplayer2.audio.AudioTrack;
|
||||
@ -99,6 +102,7 @@ public final class SimpleExoPlayer implements ExoPlayer {
|
||||
private Format audioFormat;
|
||||
|
||||
private SurfaceHolder surfaceHolder;
|
||||
private TextureView textureView;
|
||||
private TextRenderer.Output textOutput;
|
||||
private MetadataRenderer.Output<List<Id3Frame>> id3Output;
|
||||
private VideoListener videoListener;
|
||||
@ -176,17 +180,16 @@ public final class SimpleExoPlayer implements ExoPlayer {
|
||||
* tracking the lifecycle of the surface, and must clear the surface by calling
|
||||
* {@code setVideoSurface(null)} if the surface is destroyed.
|
||||
* <p>
|
||||
* If the surface is held by a {@link SurfaceHolder} then it's recommended to use
|
||||
* {@link #setVideoSurfaceHolder(SurfaceHolder)} rather than this method, since passing the
|
||||
* holder allows the player to track the lifecycle of the surface automatically.
|
||||
* If the surface is held by a {@link SurfaceView}, {@link TextureView} or {@link SurfaceHolder}
|
||||
* then it's recommended to use {@link #setVideoSurfaceView(SurfaceView)},
|
||||
* {@link #setVideoTextureView(TextureView)} or {@link #setVideoSurfaceHolder(SurfaceHolder)}
|
||||
* rather than this method, since passing the holder allows the player to track the lifecycle of
|
||||
* the surface automatically.
|
||||
*
|
||||
* @param surface The {@link Surface}.
|
||||
*/
|
||||
public void setVideoSurface(Surface surface) {
|
||||
if (surfaceHolder != null) {
|
||||
surfaceHolder.removeCallback(componentListener);
|
||||
surfaceHolder = null;
|
||||
}
|
||||
removeSurfaceCallbacks();
|
||||
setVideoSurfaceInternal(surface);
|
||||
}
|
||||
|
||||
@ -197,9 +200,7 @@ public final class SimpleExoPlayer implements ExoPlayer {
|
||||
* @param surfaceHolder The surface holder.
|
||||
*/
|
||||
public void setVideoSurfaceHolder(SurfaceHolder surfaceHolder) {
|
||||
if (this.surfaceHolder != null) {
|
||||
this.surfaceHolder.removeCallback(componentListener);
|
||||
}
|
||||
removeSurfaceCallbacks();
|
||||
this.surfaceHolder = surfaceHolder;
|
||||
if (surfaceHolder == null) {
|
||||
setVideoSurfaceInternal(null);
|
||||
@ -209,6 +210,34 @@ public final class SimpleExoPlayer implements ExoPlayer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link SurfaceView} onto which video will be rendered. The player will track the
|
||||
* lifecycle of the surface automatically.
|
||||
*
|
||||
* @param surfaceView The surface view.
|
||||
*/
|
||||
public void setVideoSurfaceView(SurfaceView surfaceView) {
|
||||
setVideoSurfaceHolder(surfaceView.getHolder());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link TextureView} onto which video will be rendered. The player will track the
|
||||
* lifecycle of the surface automatically.
|
||||
*
|
||||
* @param textureView The texture view.
|
||||
*/
|
||||
public void setVideoTextureView(TextureView textureView) {
|
||||
removeSurfaceCallbacks();
|
||||
this.textureView = textureView;
|
||||
if (textureView == null) {
|
||||
setVideoSurfaceInternal(null);
|
||||
} else {
|
||||
SurfaceTexture surfaceTexture = textureView.getSurfaceTexture();
|
||||
setVideoSurfaceInternal(surfaceTexture == null ? null : new Surface(surfaceTexture));
|
||||
textureView.setSurfaceTextureListener(componentListener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the audio volume, with 0 being silence and 1 being unity gain.
|
||||
*
|
||||
@ -548,6 +577,17 @@ public final class SimpleExoPlayer implements ExoPlayer {
|
||||
}
|
||||
}
|
||||
|
||||
private void removeSurfaceCallbacks() {
|
||||
if (this.textureView != null) {
|
||||
this.textureView.setSurfaceTextureListener(null);
|
||||
this.textureView = null;
|
||||
}
|
||||
if (this.surfaceHolder != null) {
|
||||
this.surfaceHolder.removeCallback(componentListener);
|
||||
this.surfaceHolder = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void setVideoSurfaceInternal(Surface surface) {
|
||||
ExoPlayerMessage[] messages = new ExoPlayerMessage[videoRendererCount];
|
||||
int count = 0;
|
||||
@ -566,7 +606,7 @@ public final class SimpleExoPlayer implements ExoPlayer {
|
||||
|
||||
private final class ComponentListener implements VideoRendererEventListener,
|
||||
AudioRendererEventListener, TextRenderer.Output, MetadataRenderer.Output<List<Id3Frame>>,
|
||||
SurfaceHolder.Callback {
|
||||
SurfaceHolder.Callback, TextureView.SurfaceTextureListener {
|
||||
|
||||
// VideoRendererEventListener implementation
|
||||
|
||||
@ -709,9 +749,7 @@ public final class SimpleExoPlayer implements ExoPlayer {
|
||||
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
if (player != null) {
|
||||
setVideoSurfaceInternal(holder.getSurface());
|
||||
}
|
||||
setVideoSurfaceInternal(holder.getSurface());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -721,9 +759,30 @@ public final class SimpleExoPlayer implements ExoPlayer {
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
if (player != null) {
|
||||
setVideoSurfaceInternal(null);
|
||||
}
|
||||
setVideoSurfaceInternal(null);
|
||||
}
|
||||
|
||||
// TextureView.SurfaceTextureListener implementation
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
|
||||
setVideoSurfaceInternal(new Surface(surfaceTexture));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
|
||||
setVideoSurface(null);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user