google/ExoPlayer · error · AudioSink.InitializationException

AudioTrack.STATE_UNINITIALIZED

AudioTrack.STATE_UNINITIALIZED

Error message

AudioTrack init failed {audioTrackState} Config({sampleRate}, {channelConfig}, {bufferSize}) {format}{isRecoverable? \ (recoverable\)}

What it means

While building the platform AudioTrack, DefaultAudioSink first calls createAudioTrack(...); if the framework itself rejects construction (throwing UnsupportedOperationException or IllegalArgumentException — e.g. an unsupported combination of encoding/sample rate/channel config or invalid attributes), it wraps the failure in AudioSink.InitializationException with AudioTrack.STATE_UNINITIALIZED, the negotiated sample rate, channel config, buffer size, input format, and isRecoverable=true only when in offload mode. Recovery semantics matter: recoverable errors let ExoPlayer offload-disable and retry, non-recoverable ones disable that renderer.

Source

Thrown at library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java:2096

          && newConfiguration.enableAudioTrackPlaybackParams == enableAudioTrackPlaybackParams;
    }

    public long inputFramesToDurationUs(long frameCount) {
      return Util.sampleCountToDurationUs(frameCount, inputFormat.sampleRate);
    }

    public long framesToDurationUs(long frameCount) {
      return Util.sampleCountToDurationUs(frameCount, outputSampleRate);
    }

    public AudioTrack buildAudioTrack(
        boolean tunneling, AudioAttributes audioAttributes, int audioSessionId)
        throws InitializationException {
      AudioTrack audioTrack;
      try {
        audioTrack = createAudioTrack(tunneling, audioAttributes, audioSessionId);
      } catch (UnsupportedOperationException | IllegalArgumentException e) {
        throw new InitializationException(
            AudioTrack.STATE_UNINITIALIZED,
            outputSampleRate,
            outputChannelConfig,
            bufferSize,
            inputFormat,
            /* isRecoverable= */ outputModeIsOffload(),
            e);
      }

      int state = audioTrack.getState();
      if (state != AudioTrack.STATE_INITIALIZED) {
        try {
          audioTrack.release();
        } catch (Exception e) {
          // The track has already failed to initialize, so it wouldn't be that surprising if
          // release were to fail too. Swallow the exception.
        }
        throw new InitializationException(

View on GitHub (pinned to dd430f7053)

Solutions

  1. Read InitializationException fields (audioTrackState, isRecoverable, format) to decide fallback: if isRecoverable, retry with offload disabled.
  2. Gate offload on AudioManager.isOffloadedPlaybackSupported(...) before enabling it.
  3. Fall back to PCM playback: disable passthrough/offload for that item and let track selection pick a decodable variant.
  4. Test on physical devices — emulators frequently cannot create compressed-output AudioTracks.

Example fix

// before
sinkBuilder.setOffloadMode(DefaultAudioSink.OFFLOAD_MODE_ENABLED_ALWAYS);

// after — verify platform offload support first, fall back otherwise
boolean offloadOk = audioManager.isOffloadedPlaybackSupported(audioAttributes, audioFormat);
sinkBuilder.setOffloadMode(offloadOk
    ? DefaultAudioSink.OFFLOAD_MODE_ENABLED_ALWAYS
    : DefaultAudioSink.OFFLOAD_MODE_DISABLED);
Defensive patterns

Strategy: fallback

Validate before calling

boolean canInit = false;
try {
  AudioTrack probe = new AudioTrack.Builder()
      .setAudioAttributes(new AudioAttributes.Builder()
          .setUsage(AudioAttributes.USAGE_MEDIA).build())
      .setAudioFormat(new AudioFormat.Builder()
          .setEncoding(targetEncoding)
          .setSampleRate(sampleRate)
          .setChannelMask(channelConfig).build())
      .setBufferSizeInBytes(minBuffer).build();
  canInit = probe.getState() == AudioTrack.STATE_INITIALIZED;
  probe.release();
} catch (RuntimeException ignored) {
}

Try / catch

player.addListener(new Player.Listener() {
  @Override public void onPlayerError(PlaybackException e) {
    if (e.getErrorCode()
        == PlaybackException.ERROR_CODE_AUDIO_TRACK_INIT_FAILED) {
      Throwable cause = e.getCause();
      if (cause instanceof AudioSink.InitializationException
          && ((AudioSink.InitializationException) cause).isRecoverable) {
        restartWithoutOffload(); // recoverable: retry PCM
      }
    }
  }
});

Prevention

When it happens

Trigger: new AudioTrack(...) throwing IllegalArgumentException/UnsupportedOperationException during AudioSink.configure — offload or passthrough encoding unsupported at the framework level for that track configuration, invalid audio session id, or channel config the platform AudioTrack builder rejects.

Common situations: Forcing offload for a codec Android cannot offload on that device/model; passthrough encodings rejected by the attached output; emulators lacking compressed audio output; OEM-specific AudioTrack argument validation quirks.

Related errors


AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14). Data as JSON: /api/errors/05ab389338064f37. Report an issue: GitHub.