google/ExoPlayer · critical · RuntimeException
Error instantiating MIDI extension
Error message
Error instantiating MIDI extension
What it means
DefaultRenderersFactory reflectively loads the built-in MIDI renderer (com.google.android.exoplayer2.decoder.midi.MidiRenderer, a no-arg constructor) as part of building audio renderers when extension renderer mode is enabled. If the class is present but cannot be constructed (any exception other than ClassNotFoundException), the factory throws a RuntimeException with the cause. Since MidiRenderer ships in the core artifact, hitting this almost always indicates a corrupted or mismatched build rather than a missing optional dependency.
Source
Thrown at library/core/src/main/java/com/google/android/exoplayer2/DefaultRenderersFactory.java:488
if (extensionRendererMode == EXTENSION_RENDERER_MODE_OFF) {
return;
}
int extensionRendererIndex = out.size();
if (extensionRendererMode == EXTENSION_RENDERER_MODE_PREFER) {
extensionRendererIndex--;
}
try {
Class<?> clazz = Class.forName("com.google.android.exoplayer2.decoder.midi.MidiRenderer");
Constructor<?> constructor = clazz.getConstructor();
Renderer renderer = (Renderer) constructor.newInstance();
out.add(extensionRendererIndex++, renderer);
Log.i(TAG, "Loaded MidiRenderer.");
} catch (ClassNotFoundException e) {
// Expected if the app was built without the extension.
} catch (Exception e) {
// The extension is present, but instantiation failed.
throw new RuntimeException("Error instantiating MIDI extension", e);
}
try {
// Full class names used for constructor args so the LINT rule triggers if any of them move.
Class<?> clazz = Class.forName("com.google.android.exoplayer2.ext.opus.LibopusAudioRenderer");
Constructor<?> constructor =
clazz.getConstructor(
android.os.Handler.class,
com.google.android.exoplayer2.audio.AudioRendererEventListener.class,
com.google.android.exoplayer2.audio.AudioSink.class);
Renderer renderer =
(Renderer) constructor.newInstance(eventHandler, eventListener, audioSink);
out.add(extensionRendererIndex++, renderer);
Log.i(TAG, "Loaded LibopusAudioRenderer.");
} catch (ClassNotFoundException e) {
// Expected if the app was built without the extension.
} catch (Exception e) {
// The extension is present, but instantiation failed.View on GitHub (pinned to dd430f7053)
Solutions
- Read the cause exception — it pinpoints whether the constructor was missing, inaccessible, or threw.
- Verify a single consistent com.google.android.exoplayer:exoplayer-core version across all modules (./gradlew dependencies).
- Keep the class and its constructor unobfuscated: -keep class com.google.android.exoplayer2.decoder.** { *; }.
- If MIDI playback is not needed, use EXTENSION_RENDERER_MODE_OFF, which skips this reflective block.
Example fix
// before
setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON)
// after — proguard-rules.pro
//-keep class com.google.android.exoplayer2.decoder.midi.MidiRenderer { <init>(); } Defensive patterns
Strategy: try-catch
Validate before calling
try {
Class.forName("com.google.android.exoplayer2.decoder.midi.MidiRenderer").getConstructor();
} catch (ReflectiveOperationException e) {
// do not enable extension renderer modes until fixed
} Try / catch
try {
player = new ExoPlayer.Builder(factoryWithExtensions).build(context);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("MIDI extension")) {
player = new ExoPlayer.Builder(new DefaultRenderersFactory(context)).build(context);
} else { throw e; }
} Prevention
- Run ./gradlew dependencies and confirm a single exoplayer-core version
- Keep com.google.android.exoplayer2.decoder.** intact under R8
- Smoke-test player construction in CI on a minSdk emulator
When it happens
Trigger: Building renderers with an extension renderer mode while the MidiRenderer class exists but its no-arg constructor is missing (obfuscated or different version) or its static/instance initializers throw.
Common situations: R8 full-mode rewriting or removing the no-arg constructor; a dependency resolution conflict pulling an older/newer core variant where part of the class is multidexed away; reflective instantiation blocked on newer runtimes.
Related errors
- Error instantiating VP9 extension
- Error instantiating AV1 extension
- Error instantiating Opus extension
- Error instantiating FLAC extension
- Error instantiating FFmpeg extension
AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14).
Data as JSON: /api/errors/66e9eb6d00bde22a.
Report an issue: GitHub.