Skip to content

Commit

Permalink
Revert "Migrate video_player/android from SurfaceTexture->`Surfac…
Browse files Browse the repository at this point in the history
…eProducer`." (flutter#6882)

Reverts flutter#6456
  • Loading branch information
jonahwilliams authored Jun 6, 2024
1 parent fb1eeff commit 8a2c4e4
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 132 deletions.
4 changes: 4 additions & 0 deletions packages/video_player/video_player_android/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.4.17

* Revert Impeller support.

## 2.4.16

* [Supports Impeller](https://docs.flutter.dev/release/breaking-changes/android-surface-plugins).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import android.content.Context;
import android.net.Uri;
import android.view.Surface;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import com.google.android.exoplayer2.C;
Expand Down Expand Up @@ -47,37 +48,32 @@ final class VideoPlayer {

private ExoPlayer exoPlayer;

private TextureRegistry.SurfaceProducer surfaceProducer;
private Surface surface;

private final TextureRegistry.SurfaceTextureEntry textureEntry;

private QueuingEventSink eventSink;

private final EventChannel eventChannel;

private static final String USER_AGENT = "User-Agent";

private MediaSource mediaSource;

@VisibleForTesting boolean isInitialized = false;

// State that must be reset when the surface is re-created.
private final VideoPlayerOptions options;
private long restoreVideoLocation = 0;
private int restoreRepeatMode = 0;
private float restoreVolume = 0;
private PlaybackParameters restorePlaybackParameters;

private DefaultHttpDataSource.Factory httpDataSourceFactory = new DefaultHttpDataSource.Factory();

VideoPlayer(
Context context,
EventChannel eventChannel,
TextureRegistry.SurfaceProducer surfaceProducer,
TextureRegistry.SurfaceTextureEntry textureEntry,
String dataSource,
String formatHint,
@NonNull Map<String, String> httpHeaders,
VideoPlayerOptions options) {
this.eventChannel = eventChannel;
this.surfaceProducer = surfaceProducer;
this.textureEntry = textureEntry;
this.options = options;

ExoPlayer exoPlayer = new ExoPlayer.Builder(context).build();
Expand All @@ -87,7 +83,7 @@ final class VideoPlayer {
DataSource.Factory dataSourceFactory =
new DefaultDataSource.Factory(context, httpDataSourceFactory);

mediaSource = buildMediaSource(uri, dataSourceFactory, formatHint);
MediaSource mediaSource = buildMediaSource(uri, dataSourceFactory, formatHint);

exoPlayer.setMediaSource(mediaSource);
exoPlayer.prepare();
Expand All @@ -100,12 +96,12 @@ final class VideoPlayer {
VideoPlayer(
ExoPlayer exoPlayer,
EventChannel eventChannel,
TextureRegistry.SurfaceProducer surfaceProducer,
TextureRegistry.SurfaceTextureEntry textureEntry,
VideoPlayerOptions options,
QueuingEventSink eventSink,
DefaultHttpDataSource.Factory httpDataSourceFactory) {
this.eventChannel = eventChannel;
this.surfaceProducer = surfaceProducer;
this.textureEntry = textureEntry;
this.options = options;
this.httpDataSourceFactory = httpDataSourceFactory;

Expand Down Expand Up @@ -173,40 +169,6 @@ private MediaSource buildMediaSource(
}
}

public void recreateSurface(Context context) {
ExoPlayer exoPlayer = new ExoPlayer.Builder(context).build();

exoPlayer.setMediaSource(mediaSource);
exoPlayer.prepare();

setUpVideoPlayer(exoPlayer, new QueuingEventSink());
exoPlayer.setVideoSurface(surfaceProducer.getSurface());
exoPlayer.seekTo(restoreVideoLocation);
exoPlayer.setRepeatMode(restoreRepeatMode);
exoPlayer.setVolume(restoreVolume);
if (restorePlaybackParameters != null) {
exoPlayer.setPlaybackParameters(restorePlaybackParameters);
}
}

public void pauseSurface() {
if (!isInitialized) {
return;
}
restoreVideoLocation = exoPlayer.getCurrentPosition();
restoreRepeatMode = exoPlayer.getRepeatMode();
restoreVolume = exoPlayer.getVolume();
restorePlaybackParameters = exoPlayer.getPlaybackParameters();
eventChannel.setStreamHandler(null);
if (isInitialized) {
exoPlayer.stop();
}
if (exoPlayer != null) {
exoPlayer.release();
}
isInitialized = false;
}

private void setUpVideoPlayer(ExoPlayer exoPlayer, QueuingEventSink eventSink) {
this.exoPlayer = exoPlayer;
this.eventSink = eventSink;
Expand All @@ -224,7 +186,8 @@ public void onCancel(Object o) {
}
});

exoPlayer.setVideoSurface(surfaceProducer.getSurface());
surface = new Surface(textureEntry.surfaceTexture());
exoPlayer.setVideoSurface(surface);
setAudioAttributes(exoPlayer, options.mixWithOthers);

exoPlayer.addListener(
Expand Down Expand Up @@ -371,8 +334,11 @@ void dispose() {
if (isInitialized) {
exoPlayer.stop();
}
surfaceProducer.release();
textureEntry.release();
eventChannel.setStreamHandler(null);
if (surface != null) {
surface.release();
}
if (exoPlayer != null) {
exoPlayer.release();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,9 @@
import android.os.Build;
import android.util.LongSparseArray;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import io.flutter.FlutterInjector;
import io.flutter.Log;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.embedding.engine.plugins.lifecycle.FlutterLifecycleAdapter;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugins.videoplayer.Messages.AndroidVideoPlayerApi;
Expand All @@ -36,13 +29,11 @@
import javax.net.ssl.HttpsURLConnection;

/** Android platform implementation of the VideoPlayerPlugin. */
public class VideoPlayerPlugin
implements FlutterPlugin, AndroidVideoPlayerApi, DefaultLifecycleObserver, ActivityAware {
public class VideoPlayerPlugin implements FlutterPlugin, AndroidVideoPlayerApi {
private static final String TAG = "VideoPlayerPlugin";
private final LongSparseArray<VideoPlayer> videoPlayers = new LongSparseArray<>();
private FlutterState flutterState;
private final VideoPlayerOptions options = new VideoPlayerOptions();
@Nullable Lifecycle lifecycle;

/** Register this with the v2 embedding for the plugin to respond to lifecycle callbacks. */
public VideoPlayerPlugin() {}
Expand Down Expand Up @@ -92,7 +83,7 @@ public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
}
flutterState.stopListening(binding.getBinaryMessenger());
flutterState = null;
performDestroy();
onDestroy();
}

private void disposeAllPlayers() {
Expand All @@ -102,7 +93,7 @@ private void disposeAllPlayers() {
videoPlayers.clear();
}

public void performDestroy() {
public void onDestroy() {
// The whole FlutterView is being destroyed. Here we release resources acquired for all
// instances
// of VideoPlayer. Once https://github.com/flutter/flutter/issues/19358 is resolved this may
Expand All @@ -116,7 +107,8 @@ public void initialize() {
}

public @NonNull TextureMessage create(@NonNull CreateMessage arg) {
TextureRegistry.SurfaceProducer handle = flutterState.textureRegistry.createSurfaceProducer();
TextureRegistry.SurfaceTextureEntry handle =
flutterState.textureRegistry.createSurfaceTexture();
EventChannel eventChannel =
new EventChannel(
flutterState.binaryMessenger, "flutter.io/videoPlayer/videoEvents" + handle.id());
Expand Down Expand Up @@ -152,6 +144,7 @@ public void initialize() {
options);
}
videoPlayers.put(handle.id(), player);

return new TextureMessage.Builder().setTextureId(handle.id()).build();
}

Expand Down Expand Up @@ -207,62 +200,6 @@ public void setMixWithOthers(@NonNull MixWithOthersMessage arg) {
options.mixWithOthers = arg.getMixWithOthers();
}

// Activity Aware

@Override
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
lifecycle = FlutterLifecycleAdapter.getActivityLifecycle(binding);
lifecycle.addObserver(this);
}

@Override
public void onDetachedFromActivity() {}

@Override
public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
onAttachedToActivity(binding);
}

@Override
public void onDetachedFromActivityForConfigChanges() {
onDetachedFromActivity();
}

// DefaultLifecycleObserver
@Override
public void onResume(@NonNull LifecycleOwner owner) {
recreateAllSurfaces();
}

@Override
public void onPause(@NonNull LifecycleOwner owner) {
destroyAllSurfaces();
}

@Override
public void onStop(@NonNull LifecycleOwner owner) {
destroyAllSurfaces();
}

@Override
public void onDestroy(@NonNull LifecycleOwner owner) {
if (lifecycle != null) {
lifecycle.removeObserver(this);
}
}

private void destroyAllSurfaces() {
for (int i = 0; i < videoPlayers.size(); i++) {
videoPlayers.valueAt(i).pauseSurface();
}
}

private void recreateAllSurfaces() {
for (int i = 0; i < videoPlayers.size(); i++) {
videoPlayers.valueAt(i).recreateSurface(flutterState.applicationContext);
}
}

private interface KeyForAssetFn {
String get(String asset);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;

import android.graphics.SurfaceTexture;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.PlaybackException;
Expand All @@ -37,7 +38,8 @@
public class VideoPlayerTest {
private ExoPlayer fakeExoPlayer;
private EventChannel fakeEventChannel;
private TextureRegistry.SurfaceProducer fakeSurfaceProducer;
private TextureRegistry.SurfaceTextureEntry fakeSurfaceTextureEntry;
private SurfaceTexture fakeSurfaceTexture;
private VideoPlayerOptions fakeVideoPlayerOptions;
private QueuingEventSink fakeEventSink;
private DefaultHttpDataSource.Factory httpDataSourceFactorySpy;
Expand All @@ -50,7 +52,9 @@ public void before() {

fakeExoPlayer = mock(ExoPlayer.class);
fakeEventChannel = mock(EventChannel.class);
fakeSurfaceProducer = mock(TextureRegistry.SurfaceProducer.class);
fakeSurfaceTextureEntry = mock(TextureRegistry.SurfaceTextureEntry.class);
fakeSurfaceTexture = mock(SurfaceTexture.class);
when(fakeSurfaceTextureEntry.surfaceTexture()).thenReturn(fakeSurfaceTexture);
fakeVideoPlayerOptions = mock(VideoPlayerOptions.class);
fakeEventSink = mock(QueuingEventSink.class);
httpDataSourceFactorySpy = spy(new DefaultHttpDataSource.Factory());
Expand All @@ -62,7 +66,7 @@ public void videoPlayer_buildsHttpDataSourceFactoryProperlyWhenHttpHeadersNull()
new VideoPlayer(
fakeExoPlayer,
fakeEventChannel,
fakeSurfaceProducer,
fakeSurfaceTextureEntry,
fakeVideoPlayerOptions,
fakeEventSink,
httpDataSourceFactorySpy);
Expand All @@ -81,7 +85,7 @@ public void videoPlayer_buildsHttpDataSourceFactoryProperlyWhenHttpHeadersNull()
new VideoPlayer(
fakeExoPlayer,
fakeEventChannel,
fakeSurfaceProducer,
fakeSurfaceTextureEntry,
fakeVideoPlayerOptions,
fakeEventSink,
httpDataSourceFactorySpy);
Expand All @@ -107,7 +111,7 @@ public void videoPlayer_buildsHttpDataSourceFactoryProperlyWhenHttpHeadersNull()
new VideoPlayer(
fakeExoPlayer,
fakeEventChannel,
fakeSurfaceProducer,
fakeSurfaceTextureEntry,
fakeVideoPlayerOptions,
fakeEventSink,
httpDataSourceFactorySpy);
Expand All @@ -131,7 +135,7 @@ public void sendInitializedSendsExpectedEvent_90RotationDegrees() {
new VideoPlayer(
fakeExoPlayer,
fakeEventChannel,
fakeSurfaceProducer,
fakeSurfaceTextureEntry,
fakeVideoPlayerOptions,
fakeEventSink,
httpDataSourceFactorySpy);
Expand Down Expand Up @@ -160,7 +164,7 @@ public void sendInitializedSendsExpectedEvent_270RotationDegrees() {
new VideoPlayer(
fakeExoPlayer,
fakeEventChannel,
fakeSurfaceProducer,
fakeSurfaceTextureEntry,
fakeVideoPlayerOptions,
fakeEventSink,
httpDataSourceFactorySpy);
Expand Down Expand Up @@ -189,7 +193,7 @@ public void sendInitializedSendsExpectedEvent_0RotationDegrees() {
new VideoPlayer(
fakeExoPlayer,
fakeEventChannel,
fakeSurfaceProducer,
fakeSurfaceTextureEntry,
fakeVideoPlayerOptions,
fakeEventSink,
httpDataSourceFactorySpy);
Expand Down Expand Up @@ -218,7 +222,7 @@ public void sendInitializedSendsExpectedEvent_180RotationDegrees() {
new VideoPlayer(
fakeExoPlayer,
fakeEventChannel,
fakeSurfaceProducer,
fakeSurfaceTextureEntry,
fakeVideoPlayerOptions,
fakeEventSink,
httpDataSourceFactorySpy);
Expand Down Expand Up @@ -247,7 +251,7 @@ public void onIsPlayingChangedSendsExpectedEvent() {
new VideoPlayer(
fakeExoPlayer,
fakeEventChannel,
fakeSurfaceProducer,
fakeSurfaceTextureEntry,
fakeVideoPlayerOptions,
fakeEventSink,
httpDataSourceFactorySpy);
Expand Down Expand Up @@ -292,7 +296,7 @@ public void behindLiveWindowErrorResetsPlayerToDefaultPosition() {
new VideoPlayer(
fakeExoPlayer,
fakeEventChannel,
fakeSurfaceProducer,
fakeSurfaceTextureEntry,
fakeVideoPlayerOptions,
fakeEventSink,
httpDataSourceFactorySpy);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,6 @@ public void disposeAllPlayers() {

engine.destroy();
verify(videoPlayerPlugin, times(1)).onDetachedFromEngine(pluginBindingCaptor.capture());
verify(videoPlayerPlugin, times(1)).performDestroy();
verify(videoPlayerPlugin, times(1)).onDestroy();
}
}
Loading

0 comments on commit 8a2c4e4

Please sign in to comment.