androidx / media

Jetpack Media3 support libraries for media use cases, including ExoPlayer, an extensible media player for Android
https://developer.android.com/media/media3
Apache License 2.0
1.6k stars 377 forks source link

Android 14: Failed to set playback params: arguments out of range #1101

Open XilinJia opened 7 months ago

XilinJia commented 7 months ago

Version

Media3 1.2.1

More version details

No response

Devices that reproduce the issue

Samsung S21 running Android 14

Devices that do not reproduce the issue

Huawei Mate9 Android 9 Emulator Pixel_6a_API_34 Android 14 Emulator Pixel_7_33_OS Android 13

Reproducible in the demo app?

No

Reproduction steps

import androidx.media3.exoplayer.*
import androidx.media3.common.*

var exoPlayer: ExoPlayer =  ExoPlayer.Builder(context, DefaultRenderersFactory(context)).build()
var speed = 1.5f
Log.d(TAG, "setPlaybackParams speed=$speed pitch=${playbackParameters.pitch}")

playbackParameters = PlaybackParameters(speed, playbackParameters.pitch)
exoPlayer.playbackParameters = playbackParameters

Expected result

speed should be 1.5x

It works on Android 9

Actual result

speed is not changed

logcat output:

setPlaybackParams speed=2.45 pitch=1.0

 W  Failed to set playback params
java.lang.IllegalArgumentException: arguments out of range
    at android.media.AudioTrack.native_set_playback_params(Native Method)
    at android.media.AudioTrack.setPlaybackParams(AudioTrack.java:2809)
    at androidx.media3.exoplayer.audio.DefaultAudioSink.setAudioTrackPlaybackParametersV23(DefaultAudioSink.java:1519)
    at androidx.media3.exoplayer.audio.DefaultAudioSink.setPlaybackParameters(DefaultAudioSink.java:1273)
    at androidx.media3.exoplayer.audio.MediaCodecAudioRenderer.setPlaybackParameters(MediaCodecAudioRenderer.java:691)
    at androidx.media3.exoplayer.DefaultMediaClock.setPlaybackParameters(DefaultMediaClock.java:140)
    at androidx.media3.exoplayer.ExoPlayerImplInternal.setMediaClockPlaybackParameters(ExoPlayerImplInternal.java:1026)
    at androidx.media3.exoplayer.ExoPlayerImplInternal.setPlaybackParametersInternal(ExoPlayerImplInternal.java:1417)
    at androidx.media3.exoplayer.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:535)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loopOnce(Looper.java:230)
    at android.os.Looper.loop(Looper.java:319)
    at android.os.HandlerThread.run(HandlerThread.java:67)

Media

https://22953.mc.tritondigital.com/OMNY_STUFFYOUSHOULDKNOW1_PODCAST_P/media-session/cdfbdc63-4e2f-45cd-9d7b-155498835265/d/clips/e73c998e-6e60-432f-8610-ae210140c5b1/a91018a4-ea4f-4130-bf55-ae270180c327/1607b16b-4ee6-484b-88c8-b11501676a3b/audio/direct/t1707904871/Short_Stuff_The_Original_Snake_Oil_Salesman.mp3?t=1707904871&starship-rollup=v0_444444444444&starship-episode-id=01698d33-28e1-4a29-a5e5-1b23f0ae4a62&in_playlist=44710ecc-10bb-48d1-93c7-ae270180c33e

Bug Report

marcbaechinger commented 7 months ago

That error is coming from the framework AudioTrack saying it does not support the values that you try to set. See JavaDoc here.

I guess this does not happen if you do not set setEnableAudioTrackPlaybackParams to true. Can you confirm?

XilinJia commented 7 months ago

Before my setting, the log: Log.d(TAG, "setPlaybackParams speed=$speed pitch=${playbackParameters.pitch}") shows: pitch is always 1.0. I tried speed from 0.5 to 2.5, and it doesn't matter what number it is, always got the exception. If you look at the stacktrace, when I set say speed=1.5, somewhere in the call stack to AudioTrack the number got messed up.

As mentioned in the report, I tested my code on other Android devices, the problem didn't happen. It only happens with my S21 Android 14 device.

And in my code, setEnableAudioTrackPlaybackParams was not called.

I tried to specifically calling setEnableAudioTrackPlaybackParams with: exoPlayer = ExoPlayer.Builder(context, DefaultRenderersFactory(context).setEnableAudioTrackPlaybackParams(false)) .setTrackSelector(trackSelector) .setLoadControl(loadControl.build()) .build() And the issue is the same.

marcbaechinger commented 7 months ago

Thanks! Can you shed some more light on the configuration under which you are seeing this warning?

  1. Is setEnableAudioTrackPlaybackParams set to true?
  2. Is the player playing in offload mode when you see this warning?
  3. Have you applied some specific customization to buffer sizes when you see this warning?

The easiest way for us to help is with the ExoPlayer demo app. You are saying above it is not reproducible there. Can you explain why or how we can repro in the demo app? The question is again pointing towards whether you have some specific setup of the player that isn't applied in the demo app, else the demo app could repro this as well.

XilinJia commented 7 months ago

Ok, it has to do with offload.

I built the player with:

       val audioOffloadPreferences = AudioOffloadPreferences.Builder()
            .setAudioOffloadMode(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED)
            .setIsGaplessSupportRequired(true)
            .build()
        exoPlayer = ExoPlayer.Builder(context, DefaultRenderersFactory(context))
            .setTrackSelector(trackSelector)
            .setLoadControl(loadControl.build())
            .build()
        exoPlayer.setSeekParameters(SeekParameters.EXACT)
        exoPlayer.trackSelectionParameters = exoPlayer.trackSelectionParameters
            .buildUpon()
            .setAudioOffloadPreferences(audioOffloadPreferences)
            .build()

So that has the problem.

Now I changed it to:

        val audioOffloadPreferences = AudioOffloadPreferences.Builder()
            .setAudioOffloadMode(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED) // Add additional options as needed
            .setIsGaplessSupportRequired(true)
            .setIsSpeedChangeSupportRequired(true)
            .build()
        exoPlayer = ExoPlayer.Builder(context, DefaultRenderersFactory(context))
            .setTrackSelector(trackSelector)
            .setLoadControl(loadControl.build())
            .build()
        exoPlayer.setSeekParameters(SeekParameters.EXACT)
        exoPlayer.trackSelectionParameters = exoPlayer.trackSelectionParameters
            .buildUpon()
            .setAudioOffloadPreferences(audioOffloadPreferences)
            .build()

by adding setIsSpeedChangeSupportRequired, then the exception doesn't occur, and play speed is set correctly on the S21.

Anyhow, if anyone wants to check about the program, my project Podcini is open source at https://github.com/XilinJia/Podcini.

pawelnuzka commented 6 months ago

I've filled a similar bug report here. By setting setIsSpeedChangeSupportRequired it does not crash anymore but on some devices the playback speed doesn't work, eg Samsung Z Fold 5

XilinJia commented 6 months ago

I speculate that with my S21 case, when setIsSpeedChangeSupportRequired is specified, things work because the audio stays handled by the CPU and is not offloaded at all. Is this reasonable?