Skip to content

feat(ios): add audio track selection support for AVFoundation#10313

Merged
auto-submit[bot] merged 38 commits intoflutter:mainfrom
nateshmbhat:28-oct-platform-avfoundation
Jan 21, 2026
Merged

feat(ios): add audio track selection support for AVFoundation#10313
auto-submit[bot] merged 38 commits intoflutter:mainfrom
nateshmbhat:28-oct-platform-avfoundation

Conversation

@nateshmbhat
Copy link
Contributor

  • Implemented getAudioTracks() method to retrieve available audio tracks from both HLS streams and regular video files

AVFoundation Platform PR for : #9925

Pre-Review Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] page, which explains my responsibilities.
  • I read and followed the [relevant style guides] and ran [the auto-formatter].
  • I signed the [CLA].
  • The title of the PR starts with the name of the package surrounded by square brackets, e.g. [shared_preferences]
  • I [linked to at least one issue that this PR fixes] in the description above.
  • I updated pubspec.yaml with an appropriate new version according to the [pub versioning philosophy], or I have commented below to indicate which [version change exemption] this PR falls under[^1].
  • I updated CHANGELOG.md to add a description of the change, [following repository CHANGELOG style], or I have commented below to indicate which [CHANGELOG exemption] this PR falls under[^1].
  • I updated/added any relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or I have commented below to indicate which [test exemption] this PR falls under[^1].
  • All existing and new tests are passing.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces audio track selection support for AVFoundation, enabling users to retrieve and select audio tracks from both HLS streams and regular video files. The changes include modifications to the CHANGELOG, platform-specific code (ObjC, Swift), example app, and test files. The minimum supported SDK versions have been updated, and new methods (getAudioTracks(), selectAudioTrack()) have been implemented. The code adheres to the repository's style guide, focusing on objective summaries and using code as the source of truth.

Comment on lines 498 to 500
// Skip nil options
if (!option || [option isKindOfClass:[NSNull class]]) {
continue;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Consider adding a comment explaining why nil options are skipped. This will help future developers understand the logic behind this check.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, why are we checking against NSNull or checking if the option is nil?

Comment on lines 679 to 681
}
// For asset tracks, we don't have a direct way to select them in AVFoundation
// This would require more complex track selection logic that's not commonly used

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Add a comment explaining why direct selection isn't possible and what the limitations are. This will help future developers understand the current implementation and potential areas for improvement.

assets:
- assets/flutter-mark-square-64.png
- assets/Butterfly-209.mp4
# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Per the repository style guide, the review agent should not comment about dependency_overrides sections in pubspec.yaml files that have a comment starting with: "FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE." 1

Style Guide References

Footnotes

  1. The review agent should not comment about dependency_overrides sections in pubspec.yaml files that have a comment starting with: "FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE." (link)

@stuartmorgan-g stuartmorgan-g added the triage-ios Should be looked at in iOS triage label Oct 28, 2025
- Added getAudioTracks() method supporting both HLS media selection and regular asset tracks
- Added selectAudioTrack() method with support for both track selection mechanisms
- Included comprehensive test coverage for audio track functionality with edge cases
@nateshmbhat nateshmbhat force-pushed the 28-oct-platform-avfoundation branch from 4784bd8 to 459e7f8 Compare November 7, 2025 16:32
@nateshmbhat nateshmbhat changed the title feat(video): add audio track selection support for AVFoundation feat(ios): add audio track selection support for AVFoundation Nov 7, 2025
- Update iOS minimum deployment target from 12.0 to 13.0
- Update macOS minimum deployment target from 10.14 to 10.15
- Add CocoaPods framework embedding build phases to Xcode projects
@nateshmbhat
Copy link
Contributor Author

@LongCatIsLooong @tarrinneal could you please review this PR

@nateshmbhat

This comment was marked as off-topic.

@nateshmbhat

This comment was marked as off-topic.

@nateshmbhat

This comment was marked as off-topic.

@tarrinneal
Copy link
Contributor

🥲

Sorry, I've been out as my wife is recovering from surgery. I'll try to get to this in the next couple days.

@LongCatIsLooong
Copy link
Contributor

(just started reviewing this, I'll finish doing the review tomorrow, sorry for the delay I was working on a bugfix).

Copy link
Contributor

@LongCatIsLooong LongCatIsLooong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So far I've only looked at the objective-c implementation.
My biggest question: why is it required to drop down to lower-level AVAssetTrack stuff? I went to read a little about media selection group and my understanding is that it should be sufficient for most user-facing use cases. What are the use cases for the tracks information?

Additionally, track loading is lazy and asynchronous according to the documentation. I don't see logic that handles the asynchronism.

Comment on lines 498 to 500
// Skip nil options
if (!option || [option isKindOfClass:[NSNull class]]) {
continue;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, why are we checking against NSNull or checking if the option is nil?

nateshmbhat and others added 7 commits November 26, 2025 21:23
…layer_avfoundation/Sources/video_player_avfoundation/FVPVideoPlayer.m

Co-authored-by: LongCatIsLooong <31859944+LongCatIsLooong@users.noreply.github.com>
- Remove _cachedAudioSelectionOptions instance variable
- Fetch options from media selection group each time in selectAudioTrack
- Address PR review feedback from LongCatIsLooong
- Remove unnecessary nil checks for AVMediaSelectionOption
- Remove redundant equality check in isSelected comparison
- Simplify commonMetadataTitle extraction
- Remove try-catch block and type validation for format description parsing
- Remove defensive checks for Core Media format descriptions
- Streamline audio format description extraction logic
…ayer

- Return FlutterError instead of empty data when video not loaded in getAudioTracks
- Return FlutterError instead of silently failing in selectAudioTrack when no video loaded
- Remove test for nil media selection option handling (no longer needed)
- Add getAudioTracks and selectAudioTrack helper methods to _PlayerInstance
- Apply dart format to fix code style inconsistencies
…/flutter_packages into 28-oct-platform-avfoundation
@nateshmbhat
Copy link
Contributor Author

Thanks for the review! I've removed all the AVAssetTrack related code based on your comments. This also simplifies the API to only expose tracks that are actually selectable (HLS MediaSelection tracks)

Copy link
Contributor

@LongCatIsLooong LongCatIsLooong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation LGTM, but it seems the tests are not compiling.

final tracks = <VideoAudioTrack>[];

for (final track in nativeData) {
final String? label = track.commonMetadataTitle ?? track.displayName;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't displayName be preferred over metadata title, because the display name is potentially localized?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also should the fallback happen in the objective c part of this implementation so that we don't have to encode / decode both common metadata title and display name in case both are present?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our general direction in the repo is to have logic in Dart when there's not a strong reason to have it on the native side; encoding a couple of short short strings isn't something we would expect to have non-trivial perf impact.

@nateshmbhat
Copy link
Contributor Author

nateshmbhat commented Jan 9, 2026

The implementation LGTM, but it seems the tests are not compiling.

fixed the tests @LongCatIsLooong

@LouiseHsu
Copy link
Contributor

Can you resolve the conflicts and merge master?

Copy link
Contributor

@LongCatIsLooong LongCatIsLooong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CI is failing because the changes in the video_player package doesn't have associated CHANGELOG entries:

Changed packages: video_player/video_player,video_player_avfoundation
[0:00] Running for packages/video_player/video_player...
  No version change.
  Found NEXT; validating next version in the CHANGELOG.
No CHANGELOG change found.
If this PR needs an exemption from the standard policy of listing all changes in the CHANGELOG,
comment in the PR to explain why the PR is exempt, and add (or ask your reviewer to add) the
"override: no changelog needed" label.
Otherwise, please add a NEXT entry in the CHANGELOG as described in the contributing guide.

[0:00] Running for packages/video_player/video_player_avfoundation...
  2.8.9 -> 2.9.0


The following packages had errors:
  packages/video_player/video_player:
    Missing CHANGELOG change

@nateshmbhat
Copy link
Contributor Author

The CI is failing because the changes in the video_player package doesn't have associated CHANGELOG entries:

This is the main package changelog which I will update in the main PR once we merge this ios specific PR.

@tarrinneal
Copy link
Contributor

The CI is failing because the changes in the video_player package doesn't have associated CHANGELOG entries:

This is the main package changelog which I will update in the main PR once we merge this ios specific PR.

You will need to either remove the video_player/video_player changes (if that works), or add a next section to the changelog for them.

@hellohuanlin hellohuanlin removed the triage-ios Should be looked at in iOS triage label Jan 15, 2026
@nateshmbhat
Copy link
Contributor Author

nateshmbhat commented Jan 19, 2026

@tarrinneal updated the PR with a fix

@LouiseHsu LouiseHsu added the autosubmit Merge PR when tree becomes green via auto submit App label Jan 21, 2026
@auto-submit auto-submit bot merged commit 93c9395 into flutter:main Jan 21, 2026
80 checks passed
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Jan 22, 2026
github-merge-queue bot pushed a commit to flutter/flutter that referenced this pull request Jan 22, 2026
flutter/packages@d80c60e...9010299

2026-01-21 jhy03261997@gmail.com [batch-release] Step2 : Publish
packages from the release branch (flutter/packages#10459)
2026-01-21 dpxhfxywang@163.com [two_dimensional_scrollables] optimizes
tableview janks with >250k rows (flutter/packages#10738)
2026-01-21 magder@google.com [url_launcher_ios] Migrate XCTest to Swift
Testing (flutter/packages#10780)
2026-01-21 edpizzi@gmail.com [in_app_purchase] Fix an issue causing
StoreKit 2 transactions remain unfinished (flutter/packages#10656)
2026-01-21 stuartmorgan@google.com [google_maps_flutter] Restructure iOS
to prep for SwiftPM (flutter/packages#10839)
2026-01-21 jhy03261997@gmail.com [batch-release] Step3: Adds github
action to create a PR to sync changes on the go_router release branch
back to the main branch (flutter/packages#10393)
2026-01-21 nateshmbhat1@gmail.com feat(ios): add audio track selection
support for AVFoundation (flutter/packages#10313)
2026-01-21 49699333+dependabot[bot]@users.noreply.github.com
[dependabot]: Bump androidx.core:core from 1.13.1 to 1.17.0 in
/packages/image_picker/image_picker_android/android
(flutter/packages#10504)
2026-01-21 38853913+AlexDochioiu@users.noreply.github.com
[vector_graphics_compiler] Fix rgb/rgba color parsing to support modern
CSS syntax (flutter/packages#10538)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages-flutter-autoroll
Please CC flutter-ecosystem@google.com on the revert to ensure that a
human
is aware of the problem.

To file a bug in Flutter:
https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
flutter-zl pushed a commit to flutter-zl/flutter that referenced this pull request Feb 10, 2026
…r#181323)

flutter/packages@d80c60e...9010299

2026-01-21 jhy03261997@gmail.com [batch-release] Step2 : Publish
packages from the release branch (flutter/packages#10459)
2026-01-21 dpxhfxywang@163.com [two_dimensional_scrollables] optimizes
tableview janks with >250k rows (flutter/packages#10738)
2026-01-21 magder@google.com [url_launcher_ios] Migrate XCTest to Swift
Testing (flutter/packages#10780)
2026-01-21 edpizzi@gmail.com [in_app_purchase] Fix an issue causing
StoreKit 2 transactions remain unfinished (flutter/packages#10656)
2026-01-21 stuartmorgan@google.com [google_maps_flutter] Restructure iOS
to prep for SwiftPM (flutter/packages#10839)
2026-01-21 jhy03261997@gmail.com [batch-release] Step3: Adds github
action to create a PR to sync changes on the go_router release branch
back to the main branch (flutter/packages#10393)
2026-01-21 nateshmbhat1@gmail.com feat(ios): add audio track selection
support for AVFoundation (flutter/packages#10313)
2026-01-21 49699333+dependabot[bot]@users.noreply.github.com
[dependabot]: Bump androidx.core:core from 1.13.1 to 1.17.0 in
/packages/image_picker/image_picker_android/android
(flutter/packages#10504)
2026-01-21 38853913+AlexDochioiu@users.noreply.github.com
[vector_graphics_compiler] Fix rgb/rgba color parsing to support modern
CSS syntax (flutter/packages#10538)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages-flutter-autoroll
Please CC flutter-ecosystem@google.com on the revert to ensure that a
human
is aware of the problem.

To file a bug in Flutter:
https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
auto-submit bot pushed a commit that referenced this pull request Feb 17, 2026
…ection feature (#9925)

## Description

This PR adds comprehensive audio track retrieval and selection support to the video_player package, enabling developers to access detailed information about available audio tracks and switch between them during playback.

Breakout PRs: 
1. Platform interface : #10171 
2. Andrioid : #10312 
3. ios : #10313 

### Changes Made

#### Core Features
- **Added `VideoAudioTrack` model** with comprehensive metadata fields: `id`, `label`, `language`, `isSelected`, `bitrate`, `sampleRate`, `channelCount`, `codec`
- **Added [getAudioTracks()]() method** to retrieve all available audio tracks with real metadata
- **Added [selectAudioTrack()]() method** to switch between audio tracks during playback
- **Updated `VideoPlayerController`** to expose audio track functionality

#### Platform Implementations
- **Android**: 
  - Real metadata extraction using ExoPlayer's `getCurrentTracks()` API
  - Robust track selection using `TrackSelectionOverride` with proper error handling
  - Support for multiple audio formats (AAC, AC3, EAC3, MP3, etc.)
- **iOS**: 
  - Metadata extraction from AVFoundation using `AVAssetTrack` for regular videos
  - HLS stream support using `AVMediaSelectionGroup` for adaptive streams
  - Proper track selection for both asset tracks and media selection options

#### Technical Infrastructure
- **Updated Pigeon interfaces** for both Android and iOS with new data structures:
  - `AudioTrackMessage`, `ExoPlayerAudioTrackData`, `AssetAudioTrackData`, `MediaSelectionAudioTrackData`, `NativeAudioTrackData`
- **Enhanced platform interface** with new methods and data classes
- **Has native unit tests** for both Android and iOS platforms
- **Created demo screen** showcasing audio track functionality with interactive UI

### Demo Features
- Interactive video player with audio track selection
- Real-time metadata display (bitrate, sample rate, channels, codec)
- Support for multiple video sources including HLS streams
- Visual indicators for currently selected tracks

## Related Issues
Fixes flutter/flutter#59437

### Testing
- Added native unit tests for both Android and iOS
- Tested with various video formats and HLS streams
- Verified backward compatibility with existing functionality
- Demo screen widget for manual testing and validation

### Breaking Changes
None - all changes are additive and backward compatible.

## Pre-Review Checklist
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmit Merge PR when tree becomes green via auto submit App p: video_player platform-ios platform-macos

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants