recloudstream / recloudstream/cloudstream

Unable to select audio tracks when multiple tracks have the same Track Id **[Solution inside]**

Open
#2,427 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Kotlin
Stars
10.7k
Forks
1.1k
Avg merge
1d 23h
Merged PRs (30d)
15

Description

Steps to reproduce
  1. Install repo https://raw.githubusercontent.com/Sushan64/NetMirror-Extension/refs/heads/builds/Netflix.json
  2. Download Netmirror plugin
  3. Open PrimeVideo Plugin from the list of available plugins
  4. Search in the plugin for any blockbuster such as fallout
  5. Play any episode
  6. In the player tap on the change Audio Track button at the bottom
  7. Select the second Spanish (or second French) track and apply changes
  8. Tap Again in the tap on the change Audio Track button
    ERROR: Cloudstream has not selected the right track, but the first one since there is more than one track with the same ID. Having more than one track with the same ID is common in Spanish and French content.
Image
Expected behavior

Cloudstream should provide exoplayer with the right audio track and the second audio track should be selected and played.

Actual behavior

Cloudstream is not playing the selected track

Cloudstream version and commit hash

4.6.1-PRE build ee1009a

Android version

Android 14

Logcat

Other details

ROOT CAUSE ANALYSIS:
override fun setPreferredAudioTrack(trackLanguage: String?, id: String?) uses the track ID for selecting the audio track. But it is common to see several tracks with the same Id. By using the Id it is impossible to use alternate tracks sharing the same Id. Only unique value per track should be used, and the Track Index seems to be the only value capable of ensure success.

PROPOSED SOLUTION:
The function above in file CS3IPlayer.kt should receive the desired audio track index which is unique per track in a stream and not the Id.

This is the proposed function:

override fun setPreferredAudioTrack(trackLanguage: String?, trackNum: Int?) {
    preferredAudioTrackLanguage = trackLanguage

    val player = exoPlayer ?: return
    val tracks = player.currentTracks

    // Find the audio group
    val audioGroup = tracks.groups
        .firstOrNull { it.type == TRACK_TYPE_AUDIO }

    // If a track number is provided, try to override by index
    if (audioGroup != null && trackNum != null) {
        if (trackNum in 0 until audioGroup.length) {

            val override = TrackSelectionOverride(
                audioGroup.mediaTrackGroup,
                listOf(trackNum)   // <-- select by track number
            )

            player.trackSelectionParameters =
                player.trackSelectionParameters
                    .buildUpon()
                    .clearOverridesOfType(TRACK_TYPE_AUDIO)
                    .addOverride(override)
                    .build()

            return
        }
    }

    // Fallback: use preferred language
    player.trackSelectionParameters =
        player.trackSelectionParameters
            .buildUpon()
            .setPreferredAudioLanguage(trackLanguage)
            .build()
}

The function is called only once, when a new audio track is selected. That is performed in function override fun showTracksDialogue() in file 'GeneratorPlayer.kt'

On click, the block of code should be:

binding.applyBtt.setOnClickListener {
    // Line not needed: val currentTrack = currentAudioTracks.getOrNull(audioIndexStart)
    player.setPreferredAudioTrack(
        currentTrack?.language, audioIndexStart // not currentTrack?.id
    )

    val currentVideo = currentVideoTracks.getOrNull(videoIndex)
    val width = currentVideo?.width ?: NO_VALUE
    val height = currentVideo?.height ?: NO_VALUE
    if (width != NO_VALUE && height != NO_VALUE) {
        player.setMaxVideoSize(width, height, currentVideo?.id)
    }

    trackDialog.dismissSafe(activity)
}

This way the track selection will work as intended, even when there are more than one audio track with the same Id, something common for Spanish and French audio tracks.

Acknowledgements
  • I am sure my issue is related to the app and NOT some extension.
  • I have searched the existing issues and this is a new ticket, NOT a duplicate or related to another open issue.
  • I have written a short but informative title.
  • I have updated the app to pre-release version Latest.
  • I will fill out all of the requested information in this form.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in CS3IPlayer.kt at setPreferredAudioTrack and in GeneratorPlayer.kt at showTracksDialogue, then trace how the selected audio track is passed to ExoPlayer. Verify that selection uses the track index rather than a non-unique track ID. Done means selecting the second Spanish or French track remains selected and plays when multiple tracks share an ID.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, kotlin
Domain
audio-video-rtc, mobile-dev
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.