Skip to content

Commit e3df547

Browse files
committed
refactor(video_player): change audio track selection from string ID to separate indices
- Replaced concatenated string trackId with separate groupIndex and trackIndex parameters in Android implementation - Updated iOS/macOS to use trackType and numeric trackId instead of prefixed string format - Modified Pigeon message definitions and generated code to support new parameter structure
1 parent c63b050 commit e3df547

File tree

12 files changed

+132
-85
lines changed

12 files changed

+132
-85
lines changed

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

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ public ExoPlayer getExoPlayer() {
160160
// Create audio track data with metadata
161161
ExoPlayerAudioTrackData audioTrack =
162162
new ExoPlayerAudioTrackData(
163-
groupIndex + "_" + trackIndex,
163+
(long) groupIndex,
164+
(long) trackIndex,
164165
format.label,
165166
format.language,
166167
isSelected,
@@ -178,26 +179,13 @@ public ExoPlayer getExoPlayer() {
178179

179180
@UnstableApi
180181
@Override
181-
public void selectAudioTrack(@NonNull String trackId) {
182+
public void selectAudioTrack(long groupIndex, long trackIndex) {
182183
if (trackSelector == null) {
183184
Log.w("VideoPlayer", "Cannot select audio track: track selector is null");
184185
return;
185186
}
186187

187188
try {
188-
// Parse the trackId (format: "groupIndex_trackIndex")
189-
String[] parts = trackId.split("_");
190-
if (parts.length != 2) {
191-
Log.w(
192-
"VideoPlayer",
193-
"Cannot select audio track: invalid trackId format '"
194-
+ trackId
195-
+ "'. Expected format: 'groupIndex_trackIndex'");
196-
return;
197-
}
198-
199-
int groupIndex = Integer.parseInt(parts[0]);
200-
int trackIndex = Integer.parseInt(parts[1]);
201189

202190
// Get current tracks
203191
Tracks tracks = exoPlayer.getCurrentTracks();
@@ -213,10 +201,10 @@ public void selectAudioTrack(@NonNull String trackId) {
213201
return;
214202
}
215203

216-
Tracks.Group group = tracks.getGroups().get(groupIndex);
204+
Tracks.Group group = tracks.getGroups().get((int) groupIndex);
217205

218206
// Verify it's an audio track and the track index is valid
219-
if (group.getType() != C.TRACK_TYPE_AUDIO || trackIndex >= group.length) {
207+
if (group.getType() != C.TRACK_TYPE_AUDIO || (int) trackIndex >= group.length) {
220208
if (group.getType() != C.TRACK_TYPE_AUDIO) {
221209
Log.w(
222210
"VideoPlayer",
@@ -239,16 +227,21 @@ public void selectAudioTrack(@NonNull String trackId) {
239227

240228
// Get the track group and create a selection override
241229
TrackGroup trackGroup = group.getMediaTrackGroup();
242-
TrackSelectionOverride override = new TrackSelectionOverride(trackGroup, trackIndex);
230+
TrackSelectionOverride override = new TrackSelectionOverride(trackGroup, (int) trackIndex);
243231

244232
// Apply the track selection override
245233
trackSelector.setParameters(
246234
trackSelector.buildUponParameters().setOverrideForType(override).build());
247235

248-
} catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
236+
} catch (ArrayIndexOutOfBoundsException e) {
249237
Log.w(
250238
"VideoPlayer",
251-
"Cannot select audio track: invalid trackId format '" + trackId + "'. " + e.getMessage());
239+
"Cannot select audio track: invalid indices (groupIndex: "
240+
+ groupIndex
241+
+ ", trackIndex: "
242+
+ trackIndex
243+
+ "). "
244+
+ e.getMessage());
252245
}
253246
}
254247

packages/video_player/video_player_android/android/src/main/kotlin/io/flutter/plugins/videoplayer/Messages.kt

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,8 @@ data class AudioTrackMessage(
461461
* Generated class from Pigeon that represents data sent in messages.
462462
*/
463463
data class ExoPlayerAudioTrackData(
464-
val trackId: String,
464+
val groupIndex: Long,
465+
val trackIndex: Long,
465466
val label: String? = null,
466467
val language: String? = null,
467468
val isSelected: Boolean,
@@ -472,22 +473,32 @@ data class ExoPlayerAudioTrackData(
472473
) {
473474
companion object {
474475
fun fromList(pigeonVar_list: List<Any?>): ExoPlayerAudioTrackData {
475-
val trackId = pigeonVar_list[0] as String
476-
val label = pigeonVar_list[1] as String?
477-
val language = pigeonVar_list[2] as String?
478-
val isSelected = pigeonVar_list[3] as Boolean
479-
val bitrate = pigeonVar_list[4] as Long?
480-
val sampleRate = pigeonVar_list[5] as Long?
481-
val channelCount = pigeonVar_list[6] as Long?
482-
val codec = pigeonVar_list[7] as String?
476+
val groupIndex = pigeonVar_list[0] as Long
477+
val trackIndex = pigeonVar_list[1] as Long
478+
val label = pigeonVar_list[2] as String?
479+
val language = pigeonVar_list[3] as String?
480+
val isSelected = pigeonVar_list[4] as Boolean
481+
val bitrate = pigeonVar_list[5] as Long?
482+
val sampleRate = pigeonVar_list[6] as Long?
483+
val channelCount = pigeonVar_list[7] as Long?
484+
val codec = pigeonVar_list[8] as String?
483485
return ExoPlayerAudioTrackData(
484-
trackId, label, language, isSelected, bitrate, sampleRate, channelCount, codec)
486+
groupIndex,
487+
trackIndex,
488+
label,
489+
language,
490+
isSelected,
491+
bitrate,
492+
sampleRate,
493+
channelCount,
494+
codec)
485495
}
486496
}
487497

488498
fun toList(): List<Any?> {
489499
return listOf(
490-
trackId,
500+
groupIndex,
501+
trackIndex,
491502
label,
492503
language,
493504
isSelected,
@@ -841,8 +852,8 @@ interface VideoPlayerInstanceApi {
841852
fun getBufferedPosition(): Long
842853
/** Gets the available audio tracks for the video. */
843854
fun getAudioTracks(): NativeAudioTrackData
844-
/** Selects which audio track is chosen for playback from its [trackId] */
845-
fun selectAudioTrack(trackId: String)
855+
/** Selects which audio track is chosen for playback from its [groupIndex] and [trackIndex] */
856+
fun selectAudioTrack(groupIndex: Long, trackIndex: Long)
846857

847858
companion object {
848859
/** The codec used by VideoPlayerInstanceApi. */
@@ -1062,10 +1073,11 @@ interface VideoPlayerInstanceApi {
10621073
if (api != null) {
10631074
channel.setMessageHandler { message, reply ->
10641075
val args = message as List<Any?>
1065-
val trackIdArg = args[0] as String
1076+
val groupIndexArg = args[0] as Long
1077+
val trackIndexArg = args[1] as Long
10661078
val wrapped: List<Any?> =
10671079
try {
1068-
api.selectAudioTrack(trackIdArg)
1080+
api.selectAudioTrack(groupIndexArg, trackIndexArg)
10691081
listOf(null)
10701082
} catch (exception: Throwable) {
10711083
MessagesPigeonUtils.wrapError(exception)

packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/AudioTracksTest.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ public void testGetAudioTracks_withMultipleAudioTracks() {
125125

126126
// Verify first track
127127
ExoPlayerAudioTrackData track1 = result.get(0);
128-
assertEquals("0_0", track1.getTrackId());
128+
assertEquals(0L, track1.getGroupIndex());
129+
assertEquals(0L, track1.getTrackIndex());
129130
assertEquals("English", track1.getLabel());
130131
assertEquals("en", track1.getLanguage());
131132
assertTrue(track1.isSelected());
@@ -136,7 +137,8 @@ public void testGetAudioTracks_withMultipleAudioTracks() {
136137

137138
// Verify second track
138139
ExoPlayerAudioTrackData track2 = result.get(1);
139-
assertEquals("1_0", track2.getTrackId());
140+
assertEquals(1L, track2.getGroupIndex());
141+
assertEquals(0L, track2.getTrackIndex());
140142
assertEquals("Español", track2.getLabel());
141143
assertEquals("es", track2.getLanguage());
142144
assertFalse(track2.isSelected());
@@ -197,7 +199,8 @@ public void testGetAudioTracks_withNullValues() {
197199
assertEquals(1, result.size());
198200

199201
ExoPlayerAudioTrackData track = result.get(0);
200-
assertEquals("0_0", track.getTrackId());
202+
assertEquals(0L, track.getGroupIndex());
203+
assertEquals(0L, track.getTrackIndex());
201204
assertNull(track.getLabel()); // Null values should be preserved
202205
assertNull(track.getLanguage()); // Null values should be preserved
203206
assertFalse(track.isSelected());
@@ -246,12 +249,16 @@ public void testGetAudioTracks_withMultipleTracksInSameGroup() {
246249
assertNotNull(result);
247250
assertEquals(2, result.size());
248251

249-
// Verify track IDs are unique
252+
// Verify track indices are correct
250253
ExoPlayerAudioTrackData track1 = result.get(0);
251254
ExoPlayerAudioTrackData track2 = result.get(1);
252-
assertEquals("0_0", track1.getTrackId());
253-
assertEquals("0_1", track2.getTrackId());
254-
assertNotEquals(track1.getTrackId(), track2.getTrackId());
255+
assertEquals(0L, track1.getGroupIndex());
256+
assertEquals(0L, track1.getTrackIndex());
257+
assertEquals(0L, track2.getGroupIndex());
258+
assertEquals(1L, track2.getTrackIndex());
259+
// Tracks have same group but different track indices
260+
assertEquals(track1.getGroupIndex(), track2.getGroupIndex());
261+
assertNotEquals(track1.getTrackIndex(), track2.getTrackIndex());
255262
}
256263

257264
@Test

packages/video_player/video_player_android/lib/src/android_video_player.dart

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,11 @@ class AndroidVideoPlayer extends VideoPlayerPlatform {
235235
// Convert ExoPlayer tracks to VideoAudioTrack
236236
if (nativeData.exoPlayerTracks != null) {
237237
for (final ExoPlayerAudioTrackData track in nativeData.exoPlayerTracks!) {
238+
// Construct a string ID from groupIndex and trackIndex for compatibility
239+
final String trackId = '${track.groupIndex}_${track.trackIndex}';
238240
tracks.add(
239241
VideoAudioTrack(
240-
id: track.trackId,
242+
id: trackId,
241243
label: track.label,
242244
language: track.language,
243245
isSelected: track.isSelected,
@@ -352,11 +354,22 @@ class _PlayerInstance {
352354
}
353355

354356
Future<void> selectAudioTrack(String trackId) async {
357+
// Parse the trackId to get groupIndex and trackIndex
358+
final List<String> parts = trackId.split('_');
359+
if (parts.length != 2) {
360+
throw ArgumentError(
361+
'Invalid trackId format: "$trackId". Expected format: "groupIndex_trackIndex"',
362+
);
363+
}
364+
365+
final int groupIndex = int.parse(parts[0]);
366+
final int trackIndex = int.parse(parts[1]);
367+
355368
// Create a completer to wait for the track selection to complete
356369
_audioTrackSelectionCompleter = Completer<void>();
357370

358371
try {
359-
await _api.selectAudioTrack(trackId);
372+
await _api.selectAudioTrack(groupIndex, trackIndex);
360373

361374
// Wait for the onTracksChanged event from ExoPlayer with a timeout
362375
await _audioTrackSelectionCompleter!.future.timeout(

packages/video_player/video_player_android/lib/src/messages.g.dart

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,8 @@ class AudioTrackMessage {
469469
/// Raw audio track data from ExoPlayer Format objects.
470470
class ExoPlayerAudioTrackData {
471471
ExoPlayerAudioTrackData({
472-
required this.trackId,
472+
required this.groupIndex,
473+
required this.trackIndex,
473474
this.label,
474475
this.language,
475476
required this.isSelected,
@@ -479,7 +480,9 @@ class ExoPlayerAudioTrackData {
479480
this.codec,
480481
});
481482

482-
String trackId;
483+
int groupIndex;
484+
485+
int trackIndex;
483486

484487
String? label;
485488

@@ -497,7 +500,8 @@ class ExoPlayerAudioTrackData {
497500

498501
List<Object?> _toList() {
499502
return <Object?>[
500-
trackId,
503+
groupIndex,
504+
trackIndex,
501505
label,
502506
language,
503507
isSelected,
@@ -515,14 +519,15 @@ class ExoPlayerAudioTrackData {
515519
static ExoPlayerAudioTrackData decode(Object result) {
516520
result as List<Object?>;
517521
return ExoPlayerAudioTrackData(
518-
trackId: result[0]! as String,
519-
label: result[1] as String?,
520-
language: result[2] as String?,
521-
isSelected: result[3]! as bool,
522-
bitrate: result[4] as int?,
523-
sampleRate: result[5] as int?,
524-
channelCount: result[6] as int?,
525-
codec: result[7] as String?,
522+
groupIndex: result[0]! as int,
523+
trackIndex: result[1]! as int,
524+
label: result[2] as String?,
525+
language: result[3] as String?,
526+
isSelected: result[4]! as bool,
527+
bitrate: result[5] as int?,
528+
sampleRate: result[6] as int?,
529+
channelCount: result[7] as int?,
530+
codec: result[8] as String?,
526531
);
527532
}
528533

@@ -1142,8 +1147,8 @@ class VideoPlayerInstanceApi {
11421147
}
11431148
}
11441149

1145-
/// Selects which audio track is chosen for playback from its [trackId]
1146-
Future<void> selectAudioTrack(String trackId) async {
1150+
/// Selects which audio track is chosen for playback from its [groupIndex] and [trackIndex]
1151+
Future<void> selectAudioTrack(int groupIndex, int trackIndex) async {
11471152
final String pigeonVar_channelName =
11481153
'dev.flutter.pigeon.video_player_android.VideoPlayerInstanceApi.selectAudioTrack$pigeonVar_messageChannelSuffix';
11491154
final BasicMessageChannel<Object?> pigeonVar_channel =
@@ -1153,7 +1158,7 @@ class VideoPlayerInstanceApi {
11531158
binaryMessenger: pigeonVar_binaryMessenger,
11541159
);
11551160
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(
1156-
<Object?>[trackId],
1161+
<Object?>[groupIndex, trackIndex],
11571162
);
11581163
final List<Object?>? pigeonVar_replyList =
11591164
await pigeonVar_sendFuture as List<Object?>?;

packages/video_player/video_player_android/pigeons/messages.dart

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ class AudioTrackMessage {
118118
/// Raw audio track data from ExoPlayer Format objects.
119119
class ExoPlayerAudioTrackData {
120120
ExoPlayerAudioTrackData({
121-
required this.trackId,
121+
required this.groupIndex,
122+
required this.trackIndex,
122123
this.label,
123124
this.language,
124125
required this.isSelected,
@@ -128,7 +129,8 @@ class ExoPlayerAudioTrackData {
128129
this.codec,
129130
});
130131

131-
String trackId;
132+
int groupIndex;
133+
int trackIndex;
132134
String? label;
133135
String? language;
134136
bool isSelected;
@@ -188,8 +190,8 @@ abstract class VideoPlayerInstanceApi {
188190
/// Gets the available audio tracks for the video.
189191
NativeAudioTrackData getAudioTracks();
190192

191-
/// Selects which audio track is chosen for playback from its [trackId]
192-
void selectAudioTrack(String trackId);
193+
/// Selects which audio track is chosen for playback from its [groupIndex] and [trackIndex]
194+
void selectAudioTrack(int groupIndex, int trackIndex);
193195
}
194196

195197
@EventChannelApi()

0 commit comments

Comments
 (0)