google/ExoPlayer · error · AudioProcessor.UnhandledAudioFormatException

Unhandled input format: {inputAudioFormat}

Error message

Unhandled input format: {inputAudioFormat}

What it means

TrimmingAudioProcessor removes a fixed number of frames from the start and end of each audio stream (used for gapless playback trim metadata from containers like MP4/M4A). It only operates on its fixed OUTPUT_ENCODING (16-bit PCM); onConfigure throws UnhandledAudioFormatException for anything else, because sample-accurate trimming is implemented on 16-bit samples only.

Source

Thrown at library/core/src/main/java/com/google/android/exoplayer2/audio/TrimmingAudioProcessor.java:84

  /** Sets the trimmed frame count returned by {@link #getTrimmedFrameCount()} to zero. */
  public void resetTrimmedFrameCount() {
    trimmedFrameCount = 0;
  }

  /**
   * Returns the number of audio frames trimmed since the last call to {@link
   * #resetTrimmedFrameCount()}.
   */
  public long getTrimmedFrameCount() {
    return trimmedFrameCount;
  }

  @Override
  public AudioFormat onConfigure(AudioFormat inputAudioFormat)
      throws UnhandledAudioFormatException {
    if (inputAudioFormat.encoding != OUTPUT_ENCODING) {
      throw new UnhandledAudioFormatException(inputAudioFormat);
    }
    reconfigurationPending = true;
    return trimStartFrames != 0 || trimEndFrames != 0 ? inputAudioFormat : AudioFormat.NOT_SET;
  }

  @Override
  public void queueInput(ByteBuffer inputBuffer) {
    int position = inputBuffer.position();
    int limit = inputBuffer.limit();
    int remaining = limit - position;

    if (remaining == 0) {
      return;
    }

    // Trim any pending start bytes from the input buffer.
    int trimBytes = min(remaining, pendingTrimStartBytes);
    trimmedFrameCount += trimBytes / inputAudioFormat.bytesPerFrame;

View on GitHub (pinned to dd430f7053)

Solutions

  1. Clear trim metadata before playback for high-res content (e.g. use MediaItem.Builder with a cloned Format or a custom MediaSource that strips gapless info).
  2. Force the decode chain to 16-bit PCM so trimming can operate (accept the quality downgrade).
  3. Catch the configuration failure and retry without gapless trimming.
  4. If authoring content, encode gapless high-res files without trim tags or as 16-bit.

Example fix

// before — trim metadata from a 24-bit FLAC triggers the processor
MediaItem item = MediaItem.fromUri(flacWithGaplessTags);

// after — strip gapless/trim metadata so the processor stays inactive
MediaMetadata stripped = mediaMetadata.buildUpon()
    .setExtras(null)
    .build();
// or bypass via ExtractorsFactory that ignores gapless info for high-res PCM
Defensive patterns

Strategy: validation

Validate before calling

static boolean trimSafe(Format format) {
  // trimming operates on 16-bit PCM only
  return format.pcmEncoding == C.ENCODING_PCM_16BIT
      || (MimeTypes.AUDIO_RAW.equals(format.sampleMimeType)
          && format pcmEncoding unset for 16-bit);
}
// strip gapless/trim metadata before playback when !trimSafe(format)

Try / catch

try {
  player.setMediaItem(gaplessItem);
} catch (Exception e) { // surfaces as ConfigurationException on configure
  player.setMediaItem(stripTrimMetadata(gaplessItem));
}

Prevention

When it happens

Trigger: Media carries trim metadata (e.g. gapless info in ID3/MP4) so the player configures trimming, but the decoded audio is 24/32-bit PCM or float, not 16-bit.

Common situations: Playing gapless-annotated FLAC/ALAC files whose decoder outputs high-res PCM; custom decoders emitting float; version changes in which trim metadata parsing became enabled by default for more containers.

Related errors


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