{"record":{"id":"05ab389338064f37","repo":"google/ExoPlayer","slug":"audiotrack-state-uninitialized","errorCode":"AudioTrack.STATE_UNINITIALIZED","errorMessage":"AudioTrack init failed {audioTrackState} Config({sampleRate}, {channelConfig}, {bufferSize}) {format}{isRecoverable? \\ (recoverable\\)}","messagePattern":"AudioTrack init failed (.+?) Config\\((.+?), (.+?), (.+?)\\) (.+?)(.+?)","errorType":"exception","errorClass":"AudioSink.InitializationException","httpStatus":null,"severity":"error","filePath":"library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java","lineNumber":2096,"sourceCode":"          && newConfiguration.enableAudioTrackPlaybackParams == enableAudioTrackPlaybackParams;\n    }\n\n    public long inputFramesToDurationUs(long frameCount) {\n      return Util.sampleCountToDurationUs(frameCount, inputFormat.sampleRate);\n    }\n\n    public long framesToDurationUs(long frameCount) {\n      return Util.sampleCountToDurationUs(frameCount, outputSampleRate);\n    }\n\n    public AudioTrack buildAudioTrack(\n        boolean tunneling, AudioAttributes audioAttributes, int audioSessionId)\n        throws InitializationException {\n      AudioTrack audioTrack;\n      try {\n        audioTrack = createAudioTrack(tunneling, audioAttributes, audioSessionId);\n      } catch (UnsupportedOperationException | IllegalArgumentException e) {\n        throw new InitializationException(\n            AudioTrack.STATE_UNINITIALIZED,\n            outputSampleRate,\n            outputChannelConfig,\n            bufferSize,\n            inputFormat,\n            /* isRecoverable= */ outputModeIsOffload(),\n            e);\n      }\n\n      int state = audioTrack.getState();\n      if (state != AudioTrack.STATE_INITIALIZED) {\n        try {\n          audioTrack.release();\n        } catch (Exception e) {\n          // The track has already failed to initialize, so it wouldn't be that surprising if\n          // release were to fail too. Swallow the exception.\n        }\n        throw new InitializationException(","sourceCodeStart":2078,"sourceCodeEnd":2114,"githubUrl":"https://github.com/google/ExoPlayer/blob/dd430f7053a1a3958deea3ead6a0565150c06bfc/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java#L2078-L2114","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read InitializationException fields (audioTrackState, isRecoverable, format) to decide fallback: if isRecoverable, retry with offload disabled.","Gate offload on AudioManager.isOffloadedPlaybackSupported(...) before enabling it.","Fall back to PCM playback: disable passthrough/offload for that item and let track selection pick a decodable variant.","Test on physical devices — emulators frequently cannot create compressed-output AudioTracks."],"exampleFix":"// before\nsinkBuilder.setOffloadMode(DefaultAudioSink.OFFLOAD_MODE_ENABLED_ALWAYS);\n\n// after — verify platform offload support first, fall back otherwise\nboolean offloadOk = audioManager.isOffloadedPlaybackSupported(audioAttributes, audioFormat);\nsinkBuilder.setOffloadMode(offloadOk\n    ? DefaultAudioSink.OFFLOAD_MODE_ENABLED_ALWAYS\n    : DefaultAudioSink.OFFLOAD_MODE_DISABLED);","handlingStrategy":"fallback","validationCode":"boolean canInit = false;\ntry {\n  AudioTrack probe = new AudioTrack.Builder()\n      .setAudioAttributes(new AudioAttributes.Builder()\n          .setUsage(AudioAttributes.USAGE_MEDIA).build())\n      .setAudioFormat(new AudioFormat.Builder()\n          .setEncoding(targetEncoding)\n          .setSampleRate(sampleRate)\n          .setChannelMask(channelConfig).build())\n      .setBufferSizeInBytes(minBuffer).build();\n  canInit = probe.getState() == AudioTrack.STATE_INITIALIZED;\n  probe.release();\n} catch (RuntimeException ignored) {\n}","typeGuard":null,"tryCatchPattern":"player.addListener(new Player.Listener() {\n  @Override public void onPlayerError(PlaybackException e) {\n    if (e.getErrorCode()\n        == PlaybackException.ERROR_CODE_AUDIO_TRACK_INIT_FAILED) {\n      Throwable cause = e.getCause();\n      if (cause instanceof AudioSink.InitializationException\n          && ((AudioSink.InitializationException) cause).isRecoverable) {\n        restartWithoutOffload(); // recoverable: retry PCM\n      }\n    }\n  }\n});","preventionTips":["Probe AudioTrack construction for exotic configs before playback","Gate offload/passthrough on platform capability APIs","Test compressed audio paths on physical devices"],"tags":["exoplayer","audio","audiotrack","initialization","offload","configuration"],"backgroundTag":null,"analyzedSha":"dd430f7053a1a3958deea3ead6a0565150c06bfc","analyzedAt":"2026-08-14T12:22:02.982Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}