Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
15a0d09
Add platform interface changes
FirentisTFW Jan 21, 2025
25520fc
Add platform view support for Android
FirentisTFW Jan 21, 2025
28d38c5
Rearrange native unit tests after merge
FirentisTFW Jan 21, 2025
0d3a753
Remove a todo in web implementation
FirentisTFW Jan 21, 2025
ea16d63
Set initial value of nextNonTexturePlayerId to Long.MAX_VALUE
FirentisTFW Jan 21, 2025
25425ca
Use player provider instead of modifiable list
FirentisTFW Jan 21, 2025
ce2aa51
Remove empty line
FirentisTFW Jan 21, 2025
8aeca10
Check player view states in Dart unit tests
FirentisTFW Jan 21, 2025
209f34f
Restore previous formatting for comments
FirentisTFW Jan 21, 2025
42cb659
Add missing licenses
FirentisTFW Jan 21, 2025
690ec54
Format files
FirentisTFW Jan 21, 2025
6db9e6d
Fix linting issues
FirentisTFW Jan 21, 2025
277bff7
Rename textureId to playerId in platform interace methods
FirentisTFW Jan 21, 2025
5aca5db
Rename textureId to playerId in Android Dart files
FirentisTFW Jan 21, 2025
751d529
Rename textureId to playerId in Android native code
FirentisTFW Jan 21, 2025
e6f856b
Add an ignore to UI test (it times out on Firebase Test Lab)
FirentisTFW Jan 21, 2025
b752b4c
Merge branch 'main' into feature/video-player-android-platform-view-s…
FirentisTFW Jan 28, 2025
8fc1fa0
Bump platform interface dependency to 6.3.0
FirentisTFW Jan 28, 2025
b745dcc
Remove resolved todo and fix dartdocs
FirentisTFW Jan 28, 2025
773cfc1
Add missing import
FirentisTFW Jan 28, 2025
89dfcea
Format test file
FirentisTFW Jan 28, 2025
f59463a
Add more context to class names for native views
FirentisTFW Jan 28, 2025
650cc21
Add missing docs for Android
FirentisTFW Jan 28, 2025
18463e7
Format file
FirentisTFW Jan 28, 2025
11647d0
Remove redundant async keyword
FirentisTFW Jan 29, 2025
8f9ccd8
Depend on platform interface 6.3.0
FirentisTFW Feb 10, 2025
0c2e19b
Add more details to javadocs for players
FirentisTFW Feb 10, 2025
17d5c6c
Rename method for clarity
FirentisTFW Feb 10, 2025
10640da
Remove "///" from a javadoc
FirentisTFW Feb 11, 2025
7917c0c
Add unit tests for NativeVideoView and NativeVideoViewFactory
FirentisTFW Feb 19, 2025
06b20a1
Add unit tests for VideoPlayerPlugin.create method
FirentisTFW Feb 19, 2025
1e51f8c
Add empty line to separate concepts
FirentisTFW Feb 19, 2025
e2a5afa
Clean up newly added tests
FirentisTFW Feb 19, 2025
2692564
Sort imports
FirentisTFW Feb 19, 2025
f5258df
Add missing licenses
FirentisTFW Feb 19, 2025
1bbe2c2
Split ExoPlayerEventListener into two classes, for platform view and …
FirentisTFW Feb 24, 2025
f43e9ba
Make class final
FirentisTFW Feb 24, 2025
22c9241
Use "PlatformView" instead of "NativeView" everywhere
FirentisTFW Feb 24, 2025
df3959d
Rename TextureBased to Texture, move texture player to a separate pac…
FirentisTFW Feb 24, 2025
4575c4c
Make VideoPlayer abstract
FirentisTFW Feb 24, 2025
eae1eb5
Clean up analysis
FirentisTFW Feb 24, 2025
c39b14c
Rename nextNonTexturePlayerId to nextPlatformViewPlayerId
FirentisTFW Feb 24, 2025
8d3279d
Split tests for exo player event listeners
FirentisTFW Feb 24, 2025
2862323
Update implementation comment
FirentisTFW Feb 24, 2025
314bf82
Use widget instead of a method
FirentisTFW Feb 24, 2025
feca35d
Move VideoPlayerProvider to PlatformVideoViewFactory
FirentisTFW Feb 24, 2025
7956b19
Comment on swapping width and height
FirentisTFW Feb 25, 2025
70ed428
Remove redundant abstract class method
FirentisTFW Feb 25, 2025
ce63f14
Handle SurfaceView on Android 9 correctly, document workarounds
FirentisTFW Feb 25, 2025
81a71a3
Test output, not internal state
FirentisTFW Feb 25, 2025
41891d2
Remove overriden == operator as it's not needed anymore
FirentisTFW Feb 25, 2025
6bf34e7
Clean up code
FirentisTFW Feb 25, 2025
dc08e2d
Format code
FirentisTFW Feb 25, 2025
0681400
Use custom test class in VideoPlayerTest
FirentisTFW Feb 25, 2025
b0f282d
Add missing licenses
FirentisTFW Feb 25, 2025
6c17ebc
Add a todo to decouple identifiers in the future
FirentisTFW Feb 26, 2025
9895676
Format file
FirentisTFW Feb 26, 2025
da1b78d
Resolve lint issues
FirentisTFW Feb 26, 2025
ae4bfae
Inline method
FirentisTFW Feb 26, 2025
371c462
Format file
FirentisTFW Feb 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Rename TextureBased to Texture, move texture player to a separate pac…
…kage
  • Loading branch information
FirentisTFW committed Feb 24, 2025
commit df3959d99f67fa233ef2f5b49e1ae5f64700df48
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* is reclaimed. Upon <em>resume</em>, the player will need to be recreated, but start again at the
* previous point (and settings).
*/
final class ExoPlayerState {
public final class ExoPlayerState {
/**
* Saves a representation of the current state of the player at the current point in time.
*
Expand All @@ -24,7 +24,7 @@ final class ExoPlayerState {
* @param exoPlayer the active player instance.
* @return an opaque object representing the state.
*/
static ExoPlayerState save(ExoPlayer exoPlayer) {
public static ExoPlayerState save(ExoPlayer exoPlayer) {
return new ExoPlayerState(
/*position=*/ exoPlayer.getCurrentPosition(),
/*repeatMode=*/ exoPlayer.getRepeatMode(),
Expand Down Expand Up @@ -60,7 +60,7 @@ private ExoPlayerState(
*
* @param exoPlayer the new player instance to reflect the state back to.
*/
void restore(ExoPlayer exoPlayer) {
public void restore(ExoPlayer exoPlayer) {
exoPlayer.seekTo(position);
exoPlayer.setRepeatMode(repeatMode);
exoPlayer.setVolume(volume);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ final class HttpVideoAsset extends VideoAsset {

@NonNull
@Override
MediaItem getMediaItem() {
public MediaItem getMediaItem() {
MediaItem.Builder builder = new MediaItem.Builder().setUri(assetUrl);
String mimeType = null;
switch (streamingFormat) {
Expand All @@ -58,7 +58,7 @@ MediaItem getMediaItem() {
}

@Override
MediaSource.Factory getMediaSourceFactory(Context context) {
public MediaSource.Factory getMediaSourceFactory(Context context) {
return getMediaSourceFactory(context, new DefaultHttpDataSource.Factory());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ final class LocalVideoAsset extends VideoAsset {

@NonNull
@Override
MediaItem getMediaItem() {
public MediaItem getMediaItem() {
return new MediaItem.Builder().setUri(assetUrl).build();
}

@Override
MediaSource.Factory getMediaSourceFactory(Context context) {
public MediaSource.Factory getMediaSourceFactory(Context context) {
return new DefaultMediaSourceFactory(context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ final class RtspVideoAsset extends VideoAsset {

@NonNull
@Override
MediaItem getMediaItem() {
public MediaItem getMediaItem() {
return new MediaItem.Builder().setUri(assetUrl).build();
}

// TODO: Migrate to stable API, see https://github.com/flutter/flutter/issues/147039.
@OptIn(markerClass = UnstableApi.class)
@Override
MediaSource.Factory getMediaSourceFactory(Context context) {
public MediaSource.Factory getMediaSourceFactory(Context context) {
return new RtspMediaSource.Factory();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import java.util.Map;

/** A video to be played by {@link VideoPlayer}. */
abstract class VideoAsset {
public abstract class VideoAsset {
/**
* Returns an asset from a local {@code asset:///} URL, i.e. an on-device asset.
*
Expand Down Expand Up @@ -70,15 +70,15 @@ protected VideoAsset(@Nullable String assetUrl) {
* @return media item.
*/
@NonNull
abstract MediaItem getMediaItem();
public abstract MediaItem getMediaItem();

/**
* Returns the configured media source factory, if needed for this asset type.
*
* @param context application context.
* @return configured factory, or {@code null} if not needed for this asset type.
*/
abstract MediaSource.Factory getMediaSourceFactory(Context context);
public abstract MediaSource.Factory getMediaSourceFactory(Context context);

/** Streaming formats that can be provided to the video player as a hint. */
enum StreamingFormat {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@
import androidx.media3.exoplayer.ExoPlayer;
import io.flutter.plugins.videoplayer.platformview.PlatformVideoViewFactory;
import io.flutter.plugins.videoplayer.platformview.PlatformViewExoPlayerEventListener;
import io.flutter.plugins.videoplayer.texture.TextureVideoPlayer;

/**
* A class responsible for managing video playback using {@link ExoPlayer}. It provides methods to
* control playback, adjust volume, and handle seeking. This class contains all functionalities
* needed to manage video playback in platform views and is typically used alongside {@link
* PlatformVideoViewFactory}. If you need to display a video using a texture, use {@link
* TextureBasedVideoPlayer} instead.
* TextureVideoPlayer} instead.
*/
public class VideoPlayer {
@NonNull private final ExoPlayerProvider exoPlayerProvider;
Expand Down Expand Up @@ -60,7 +61,7 @@ static VideoPlayer create(
}

/** A closure-compatible signature since {@link java.util.function.Supplier} is API level 24. */
interface ExoPlayerProvider {
public interface ExoPlayerProvider {
/**
* Returns a new {@link ExoPlayer}.
*
Expand All @@ -70,7 +71,7 @@ interface ExoPlayerProvider {
}

@VisibleForTesting
VideoPlayer(
public VideoPlayer(
@NonNull ExoPlayerProvider exoPlayerProvider,
@NonNull VideoPlayerCallbacks events,
@NonNull MediaItem mediaItem,
Expand Down Expand Up @@ -155,7 +156,7 @@ public ExoPlayer getExoPlayer() {
return exoPlayer;
}

void dispose() {
public void dispose() {
exoPlayer.release();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

package io.flutter.plugins.videoplayer;

class VideoPlayerOptions {
public class VideoPlayerOptions {
public boolean mixWithOthers;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import io.flutter.plugins.videoplayer.Messages.AndroidVideoPlayerApi;
import io.flutter.plugins.videoplayer.Messages.CreateMessage;
import io.flutter.plugins.videoplayer.platformview.PlatformVideoViewFactory;
import io.flutter.plugins.videoplayer.texture.TextureVideoPlayer;
import io.flutter.view.TextureRegistry;

/** Android platform implementation of the VideoPlayerPlugin. */
Expand Down Expand Up @@ -130,7 +131,7 @@ public void initialize() {
TextureRegistry.SurfaceProducer handle = flutterState.textureRegistry.createSurfaceProducer();
id = handle.id();
videoPlayer =
TextureBasedVideoPlayer.create(
TextureVideoPlayer.create(
flutterState.applicationContext,
VideoPlayerEventCallbacks.bindTo(createEventChannel(id)),
handle,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugins.videoplayer;
package io.flutter.plugins.videoplayer.texture;

import android.content.Context;
import androidx.annotation.NonNull;
Expand All @@ -11,7 +11,13 @@
import androidx.annotation.VisibleForTesting;
import androidx.media3.common.MediaItem;
import androidx.media3.exoplayer.ExoPlayer;
import io.flutter.plugins.videoplayer.texture.TextureExoPlayerEventListener;
import io.flutter.plugins.videoplayer.ExoPlayerEventListener;
import io.flutter.plugins.videoplayer.ExoPlayerState;
import io.flutter.plugins.videoplayer.Messages;
import io.flutter.plugins.videoplayer.VideoAsset;
import io.flutter.plugins.videoplayer.VideoPlayer;
import io.flutter.plugins.videoplayer.VideoPlayerCallbacks;
import io.flutter.plugins.videoplayer.VideoPlayerOptions;
import io.flutter.view.TextureRegistry;

/**
Expand All @@ -20,7 +26,7 @@
* video is properly displayed on the texture. If you need to display a video using platform view,
* use {@link VideoPlayer} instead.
*/
final class TextureBasedVideoPlayer extends VideoPlayer
public final class TextureVideoPlayer extends VideoPlayer
implements TextureRegistry.SurfaceProducer.Callback {
@NonNull private final TextureRegistry.SurfaceProducer surfaceProducer;
@Nullable private ExoPlayerState savedStateDuring;
Expand All @@ -36,13 +42,13 @@ final class TextureBasedVideoPlayer extends VideoPlayer
* @return a video player instance.
*/
@NonNull
static TextureBasedVideoPlayer create(
public static TextureVideoPlayer create(
@NonNull Context context,
@NonNull VideoPlayerCallbacks events,
@NonNull TextureRegistry.SurfaceProducer surfaceProducer,
@NonNull VideoAsset asset,
@NonNull VideoPlayerOptions options) {
return new TextureBasedVideoPlayer(
return new TextureVideoPlayer(
() -> {
ExoPlayer.Builder builder =
new ExoPlayer.Builder(context)
Expand All @@ -56,7 +62,7 @@ static TextureBasedVideoPlayer create(
}

@VisibleForTesting
TextureBasedVideoPlayer(
public TextureVideoPlayer(
@NonNull ExoPlayerProvider exoPlayerProvider,
@NonNull VideoPlayerCallbacks events,
@NonNull TextureRegistry.SurfaceProducer surfaceProducer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import androidx.media3.common.Player;
import androidx.media3.common.VideoSize;
import androidx.media3.exoplayer.ExoPlayer;

import io.flutter.plugins.videoplayer.texture.TextureVideoPlayer;
import io.flutter.view.TextureRegistry;
import org.junit.Before;
import org.junit.Rule;
Expand All @@ -29,9 +31,9 @@
import org.robolectric.RobolectricTestRunner;

/**
* Unit tests for {@link TextureBasedVideoPlayer}.
* Unit tests for {@link TextureVideoPlayer}.
*
* <p>This test suite <em>narrowly verifies</em> that {@link TextureBasedVideoPlayer} interfaces
* <p>This test suite <em>narrowly verifies</em> that {@link TextureVideoPlayer} interfaces
* with the {@link ExoPlayer} interface <em>exactly</em> as it did when the test suite was created.
* That is, if the behavior changes, this test will need to change. However, this suite should catch
* bugs related to <em>"this is a safe refactor with no behavior changes"</em>.
Expand All @@ -41,7 +43,7 @@
* in order to figure out how to set everything up so the player "works".
*/
@RunWith(RobolectricTestRunner.class)
public final class TextureBasedVideoPlayerTest {
public final class TextureVideoPlayerTest {
private static final String FAKE_ASSET_URL = "https://flutter.dev/movie.mp4";
private FakeVideoAsset fakeVideoAsset;

Expand All @@ -64,8 +66,8 @@ private VideoPlayer createVideoPlayer() {
return createVideoPlayer(new VideoPlayerOptions());
}

private TextureBasedVideoPlayer createVideoPlayer(VideoPlayerOptions options) {
return new TextureBasedVideoPlayer(
private TextureVideoPlayer createVideoPlayer(VideoPlayerOptions options) {
return new TextureVideoPlayer(
() -> mockExoPlayer, mockEvents, mockProducer, fakeVideoAsset.getMediaItem(), options);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import io.flutter.plugins.videoplayer.Messages.CreateMessage;
import io.flutter.plugins.videoplayer.Messages.PlatformVideoViewType;
import io.flutter.plugins.videoplayer.platformview.PlatformVideoViewFactory;
import io.flutter.plugins.videoplayer.texture.TextureVideoPlayer;
import io.flutter.view.TextureRegistry;
import java.lang.reflect.Field;
import java.util.HashMap;
Expand Down Expand Up @@ -62,7 +63,7 @@ public void initPluginDoesNotThrow() {
}

@Test
public void registersPlatformVideoViewFactory() throws Exception {
public void registersPlatformVideoViewFactory() {
verify(mockPlatformViewRegistry)
.registerViewFactory(
eq("plugins.flutter.dev/video_player_android"), any(PlatformVideoViewFactory.class));
Expand Down Expand Up @@ -91,11 +92,11 @@ public void createsVideoPlayerWithPlatformViewType() throws Exception {

@Test
public void createsVideoPlayerWithTextureViewType() throws Exception {
try (MockedStatic<TextureBasedVideoPlayer> mockedTextureBasedVideoPlayerStatic =
mockStatic(TextureBasedVideoPlayer.class)) {
try (MockedStatic<TextureVideoPlayer> mockedTextureBasedVideoPlayerStatic =
mockStatic(TextureVideoPlayer.class)) {
mockedTextureBasedVideoPlayerStatic
.when(() -> TextureBasedVideoPlayer.create(any(), any(), any(), any(), any()))
.thenReturn(mock(TextureBasedVideoPlayer.class));
.when(() -> TextureVideoPlayer.create(any(), any(), any(), any(), any()))
.thenReturn(mock(TextureVideoPlayer.class));

final CreateMessage createMessage =
new CreateMessage.Builder()
Expand All @@ -107,7 +108,7 @@ public void createsVideoPlayerWithTextureViewType() throws Exception {
final long playerId = plugin.create(createMessage);

final LongSparseArray<VideoPlayer> videoPlayers = getVideoPlayers();
assertTrue(videoPlayers.get(playerId) instanceof TextureBasedVideoPlayer);
assertTrue(videoPlayers.get(playerId) instanceof TextureVideoPlayer);
}
}
}