Fix track selection when same lang/id is used in 2+ audio tracks. Codec & channel configuration in track selection. debugBuild.yml #2447
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Notable improvements implemented
Summary
Successfully resolved two critical issues in the Android Cloudstream app's audio track selection system:
Issues Resolved
Issue 1: Incorrect Audio Track Selection
Problem: The audio track dialog always marked the first audio track as selected, regardless of which track was actually playing.
Root Cause: There wasn't any variable storing the current track index. So, there wasn't any way to know the current selected track. The only way was to select the pair language/id, but that doesn't work when 2 or more tracks use the same language and id.
Solution: Created getCurrentAudioTrackIndex() in CS3IPlayer.kt to query ExoPlayer's current selection when no stored index exists. This is used in CS3IPlayer's
setPreferredAudioTrack(trackLanguage: String?, trackIndex: Int?)and GeneratorPlayer'sshowTracksDialogue(). AlsosetPreferredAudioTrackno longer expects the id as it is useless. Now it uses the desired deterministic audio track index.Issue 2: Missing Audio Track Information
Problem: Audio tracks displayed only basic language information without codec or channel details.
Root Cause: The AudioTrack data class only contained id, label, and language fields - no technical specifications.
Solution: Created a public method
getAudioFormats(): List<Format>?in CS3IPlayer class to access ExoPlayer's Format objects, which contain complete technical details.Modified files
1. In CS3IPlayer.kt
getCurrentAudioTrackIndex()now automatically detects the current track from ExoPlayer when there's no stored indexgetAudioFormats()publicly exposes audio formats so other classes can access detailed informationsetPreferredAudioTrack()now receives trackIndex (Int) instead of id (String), simplifying the logic2. In GeneratorPlayer.kt
The audio dialog now displays very comprehensive information:
"[$index] $language $codec $channels"With user-friendly labels:
Channels: "mono", "stereo", "5.1", "7.1" (instead of raw numbers)
Codec: clean extracts from MIME types
Language: translated to full language name
3. In IPlayer.kt
Added
import androidx.media3.common.FormatNew interface function
getAudioFormats(): List<Format>?that CS3IPlayer must implementResult
Users can now see clear and useful information about each available audio track, such as:
And the dialog correctly marks the track that is currently playing. Excellent work solving these issues!
Cloudstream Audio Track Selection - Implementation Report
Summary
Successfully resolved two critical issues in the Android Cloudstream app's audio track selection system:
Issues Resolved
Issue #1: Incorrect Audio Track Selection
Problem:
The audio track dialog always marked the first audio track in a given language as selected, regardless of which track was actually playing.
Root Cause:
The
currentAudioTrackIndexvariable inCS3IPlayer.ktwas initialized to-1and reset during player release, but wasn't updated when ExoPlayer automatically selected a track.Solution:
Modified
getCurrentAudioTrackIndex()inCS3IPlayer.ktto query ExoPlayer's current selection when no stored index exists.Issue #2: Missing Audio Track Information
Problem:
Audio tracks displayed only basic language information without codec or channel details.
Root Cause:
The
AudioTrackdata class only containedid,label, andlanguagefields — no technical specifications.Solution:
Created a public method to access ExoPlayer's
Formatobjects, which contain complete technical details.Implementation Details
1. Changes in
CS3IPlayer.ktModified
getCurrentAudioTrackIndex()Added
getAudioFormats()MethodUpdated
setPreferredAudioTrack()SignatureChanged from:
To:
2. Changes in
GeneratorPlayer.ktEnhanced Audio Track Display
Modified the audio track adapter to show detailed information:
audioArrayAdapter.addAll(currentAudioTracks.mapIndexed { index, track -> val audioFormat = (player as? CS3IPlayer) ?.getAudioFormats() ?.getOrNull(index) val language = track.language?.let { fromTagToLanguageName(it) ?: it } ?: track.label ?: "Audio" val codec = audioFormat?.sampleMimeType?.let { mimeType -> when { mimeType.contains("mp4a") || mimeType.contains("aac") -> "aac" mimeType.contains("ac-3") || mimeType.contains("ac3") -> "ac3" mimeType.contains("eac3") -> "eac3" mimeType.contains("opus") -> "opus" mimeType.contains("vorbis") -> "vorbis" mimeType.contains("mp3") || mimeType.contains("mpeg") -> "mp3" mimeType.contains("flac") -> "flac" mimeType.contains("dts") -> "dts" else -> mimeType.substringAfterLast("/") } } ?: "codec?" val channels = when (audioFormat?.channelCount) { 1 -> "mono" 2 -> "stereo" 6 -> "5.1" 8 -> "7.1" else -> audioFormat?.channelCount?.let { "${it}Ch" } ?: "?" } "[$index] $language $codec $channels" })Updated Track Selection Call
Changed from:
To:
3. Changes in
IPlayer.ktAdded Import
Added Interface Method
Technical Improvements
Codec Detection
Implemented MIME type parsing to extract codec information:
audio/mp4a-latm→aacaudio/ac3→ac3audio/eac-3→eac3audio/opus→opusaudio/mpeg→mp3audio/flac→flacaudio/dts→dtsChannel Configuration
Converted ExoPlayer's
channelCountto user-friendly labels:1→mono2→stereo6→5.18→7.1XCh(number of channels)Language Display
Prioritized display hierarchy:
fromTagToLanguageName())."Audio".Results
Before
(First track always selected, no technical details.)
After
(Currently playing track marked, full technical specifications.)
Testing Notes
aac,ac3,opus,mp3, etc.).mono,stereo,5.1,7.1).Files Modified
getCurrentAudioTrackIndex().getAudioFormats().setPreferredAudioTrack()signature.showTracksDialogue().Formatimport.getAudioFormats()interface method.Architecture Benefits
Intfor track index instead ofStringreduces errors.Future Enhancements
Potential improvements for future iterations: