google/ExoPlayer · critical · FfmpegDecoderException

Failed to load decoder native libraries.

Error message

Failed to load decoder native libraries.

What it means

FfmpegDecoderException thrown by the FfmpegAudioDecoder constructor when FfmpegLibrary.isAvailable() is false — the FFmpeg JNI native libraries were not loaded. Unlike the AAR-published extensions, the FFmpeg extension requires you to build and package libffmpeg JNI .so files yourself, so this error means the native side is missing at runtime.

Source

Thrown at extensions/ffmpeg/src/main/java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegAudioDecoder.java:69

  @Nullable private final byte[] extraData;
  private final @C.PcmEncoding int encoding;
  private final int outputBufferSize;

  private long nativeContext; // May be reassigned on resetting the codec.
  private boolean hasOutputFormat;
  private volatile int channelCount;
  private volatile int sampleRate;

  public FfmpegAudioDecoder(
      Format format,
      int numInputBuffers,
      int numOutputBuffers,
      int initialInputBufferSize,
      boolean outputFloat)
      throws FfmpegDecoderException {
    super(new DecoderInputBuffer[numInputBuffers], new SimpleDecoderOutputBuffer[numOutputBuffers]);
    if (!FfmpegLibrary.isAvailable()) {
      throw new FfmpegDecoderException("Failed to load decoder native libraries.");
    }
    Assertions.checkNotNull(format.sampleMimeType);
    codecName = Assertions.checkNotNull(FfmpegLibrary.getCodecName(format.sampleMimeType));
    extraData = getExtraData(format.sampleMimeType, format.initializationData);
    encoding = outputFloat ? C.ENCODING_PCM_FLOAT : C.ENCODING_PCM_16BIT;
    outputBufferSize = outputFloat ? OUTPUT_BUFFER_SIZE_32BIT : OUTPUT_BUFFER_SIZE_16BIT;
    nativeContext =
        ffmpegInitialize(codecName, extraData, outputFloat, format.sampleRate, format.channelCount);
    if (nativeContext == 0) {
      throw new FfmpegDecoderException("Initialization failed.");
    }
    setInitialInputBufferSize(initialInputBufferSize);
  }

  @Override
  public String getName() {
    return "ffmpeg" + FfmpegLibrary.getVersion() + "-" + codecName;
  }

View on GitHub (pinned to dd430f7053)

Solutions

  1. Build the FFmpeg extension natives (scripts in extensions/ffmpeg) and package libffmpegJNI.so for every target ABI; verify with Analyze APK
  2. Check FfmpegLibrary.isAvailable() before registering FfmpegAudioRenderer and fall back to platform MediaCodec decoding
  3. Fix abiFilters/splits so the delivered APK matches device ABIs; rebuild .so with 16KB alignment for Android 15+ targets
  4. Verify FfmpegLibrary.supportsFormat(sampleMimeType) too, since the codec list depends on how FFmpeg was configured at build time

Example fix

// before
out.add(new FfmpegAudioRenderer(...)); // crashes when natives are absent

// after
if (FfmpegLibrary.isAvailable()) {
  out.add(new FfmpegAudioRenderer(...));
} else {
  Log.w(TAG, "FFmpeg natives missing; using platform decoders");
}
super.buildAudioRenderers(context, extensionRendererMode, ...); // platform fallback
Defensive patterns

Strategy: validation

Validate before calling

if (FfmpegLibrary.isAvailable()) {
  // safe to construct FfmpegAudioDecoder / register FfmpegAudioRenderer
} else {
  // libffmpegJNI.so not packaged: use platform MediaCodec rendering only
}

Try / catch

try {
  decoder = new FfmpegAudioDecoder(format, numIn, numOut, initialSize, outputFloat);
} catch (FfmpegDecoderException e) {
  if (e.getMessage() != null && e.getMessage().contains("native libraries")) {
    // packaging problem: verify lib/<abi>/libffmpegJNI.so, then fall back
    Log.e(TAG, "FFmpeg natives missing", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Enabling FfmpegAudioRenderer in an app whose APK contains no lib/<abi>/libffmpegJNI.so; shipping the Java dependency only (compileOnly-style usage); building FFmpeg for a subset of ABIs and running on an excluded device; proguard/packaging stripping the .so.

Common situations: Adding the ffmpeg extension source without running its native build; abiFilters mismatch; using a third-party maven artifact of the extension that ships no natives; 16KB-page devices rejecting an old-style .so alignment.

Related errors


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