Skip to content

Commit 6d10279

Browse files
[video_player] Move most Android event logic to Dart (#10128)
Rather than interpreting ExoPlayer event callbacks in Java and then sending event channel events that match the Dart platform interface, send the events directly and intepret them in Dart. This continues the process of reducing Java-side logic in the plugin. In order to make this change less error-prone, it also adopts Pigeon event channels, so that the new events are type-safe; in order to do that, this switches to the Kotlin Pigeon generator, since Pigeon event channels haven't been implemented for Java. Now that the buffer progress event synthesis is in Dart, this also fixes an existing TODO by reworking that logic to be based on an independent timer, rather than driven by playback position polling from the app-facing package. This both makes the logic clearer, and makes it work regardless of whether or not the video is paused. Part of flutter/flutter#172763 ## Pre-Review Checklist [^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
1 parent 835dccb commit 6d10279

23 files changed

+1625
-1550
lines changed

packages/video_player/video_player_android/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## 2.8.17
2+
3+
* Moves video event processing logic to Dart, and fixes an issue where buffer
4+
range would not be updated for a paused video.
5+
* Switches to Kotlin for Pigeon-generated code.
6+
* Adopts type-safe event channels for internal communication.
7+
18
## 2.8.16
29

310
* Updates Java compatibility version to 17 and minimum supported SDK version to Flutter 3.35/Dart 3.9.

packages/video_player/video_player_android/android/build.gradle

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ group = 'io.flutter.plugins.videoplayer'
22
version = '1.0-SNAPSHOT'
33

44
buildscript {
5+
ext.kotlin_version = '2.2.10'
56
repositories {
67
google()
78
mavenCentral()
89
}
910

1011
dependencies {
1112
classpath 'com.android.tools.build:gradle:8.12.1'
13+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
1214
}
1315
}
1416

@@ -20,6 +22,7 @@ rootProject.allprojects {
2022
}
2123

2224
apply plugin: 'com.android.library'
25+
apply plugin: 'kotlin-android'
2326

2427
android {
2528
namespace = "io.flutter.plugins.videoplayer"
@@ -38,6 +41,13 @@ android {
3841
sourceCompatibility = JavaVersion.VERSION_17
3942
targetCompatibility = JavaVersion.VERSION_17
4043
}
44+
kotlinOptions {
45+
jvmTarget = JavaVersion.VERSION_17.toString()
46+
}
47+
48+
sourceSets {
49+
main.java.srcDirs += 'src/main/kotlin'
50+
}
4151

4252
dependencies {
4353
def exoplayer_version = "1.5.1"

packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerEventListener.java

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import androidx.media3.exoplayer.ExoPlayer;
1111

1212
public abstract class ExoPlayerEventListener implements Player.Listener {
13-
private boolean isBuffering = false;
1413
private boolean isInitialized = false;
1514
protected final ExoPlayer exoPlayer;
1615
protected final VideoPlayerCallbacks events;
@@ -47,47 +46,34 @@ public ExoPlayerEventListener(
4746
this.events = events;
4847
}
4948

50-
private void setBuffering(boolean buffering) {
51-
if (isBuffering == buffering) {
52-
return;
53-
}
54-
isBuffering = buffering;
55-
if (buffering) {
56-
events.onBufferingStart();
57-
} else {
58-
events.onBufferingEnd();
59-
}
60-
}
61-
6249
protected abstract void sendInitialized();
6350

6451
@Override
6552
public void onPlaybackStateChanged(final int playbackState) {
53+
PlatformPlaybackState platformState = PlatformPlaybackState.UNKNOWN;
6654
switch (playbackState) {
6755
case Player.STATE_BUFFERING:
68-
setBuffering(true);
69-
events.onBufferingUpdate(exoPlayer.getBufferedPosition());
56+
platformState = PlatformPlaybackState.BUFFERING;
7057
break;
7158
case Player.STATE_READY:
59+
platformState = PlatformPlaybackState.READY;
7260
if (!isInitialized) {
7361
isInitialized = true;
7462
sendInitialized();
7563
}
7664
break;
7765
case Player.STATE_ENDED:
78-
events.onCompleted();
66+
platformState = PlatformPlaybackState.ENDED;
7967
break;
8068
case Player.STATE_IDLE:
69+
platformState = PlatformPlaybackState.IDLE;
8170
break;
8271
}
83-
if (playbackState != Player.STATE_BUFFERING) {
84-
setBuffering(false);
85-
}
72+
events.onPlaybackStateChanged(platformState);
8673
}
8774

8875
@Override
8976
public void onPlayerError(@NonNull final PlaybackException error) {
90-
setBuffering(false);
9177
if (error.errorCode == PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW) {
9278
// See
9379
// https://exoplayer.dev/live-streaming.html#behindlivewindowexception-and-error_code_behind_live_window

0 commit comments

Comments
 (0)