Skip to main content

player_switch_audio_track

Function player_switch_audio_track 

Source
pub async fn player_switch_audio_track(
    player: State<'_, PlayerStateWrapper>,
    repository_manager: State<'_, RepositoryManagerWrapper>,
    repository_handle: String,
    stream_index: i32,
    array_index: i32,
    current_position: Option<f64>,
    media_source_id: Option<String>,
) -> Result<AudioTrackSwitchResponse, String>
Expand description

Switch audio track. Note: Frontend should handle saving series preferences after this command succeeds

What decides the route is whether the stream in front of the engine carries the requested track at all — see determine_audio_track_switch_strategy:

  • A native backend playing a direct play holds the source file with every track in it, so ExoPlayer selects in place by track-group index.
  • A native backend playing a transcode does not. Jellyfin builds a transcode around one AudioStreamIndex, so the alternate tracks are not in the stream; the switch has to re-open it, which this command does itself and resumes at current_position.

That last case is a bug fix, and it was the common case on Android: any source whose default audio codec the device cannot decode is transcoded, so ExoPlayer saw Audio tracks: 1 while the menu listed every track in the file. The old code called setAudioTrack(n) regardless, which indexes ExoPlayer’s audio track groups, found nothing at n, warned Invalid audio track index and dropped the request — the default track just kept playing, with nothing in the UI saying so.

mpv selects in place the same way (mpv_tracks::select_audio, by position in the file’s audio tracks), and re-opens a transcode through the same path.

TRACES: UR-021, UR-005 | IR-019, DR-024, DR-258