google/ExoPlayer · critical · RuntimeException
Error instantiating AV1 extension
Error message
Error instantiating AV1 extension
What it means
DefaultRenderersFactory reflectively instantiates the optional AV1 decoder renderer (com.google.android.exoplayer2.ext.av1.Libgav1VideoRenderer) when extension renderers are enabled. ClassNotFoundException (extension not built) is expected and ignored, but any other exception while resolving the constructor or creating the instance proves the extension is present yet unusable, so the factory throws a RuntimeException with the original cause. This prevents a corrupted extension build from silently degrading playback.
Source
Thrown at library/core/src/main/java/com/google/android/exoplayer2/DefaultRenderersFactory.java:432
clazz.getConstructor(
long.class,
android.os.Handler.class,
com.google.android.exoplayer2.video.VideoRendererEventListener.class,
int.class);
Renderer renderer =
(Renderer)
constructor.newInstance(
allowedVideoJoiningTimeMs,
eventHandler,
eventListener,
MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY);
out.add(extensionRendererIndex++, renderer);
Log.i(TAG, "Loaded Libgav1VideoRenderer.");
} 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 AV1 extension", e);
}
}
/**
* Builds audio renderers for use by the player.
*
* @param context The {@link Context} associated with the player.
* @param extensionRendererMode The extension renderer mode.
* @param mediaCodecSelector A decoder selector.
* @param enableDecoderFallback Whether to enable fallback to lower-priority decoders if decoder
* initialization fails. This may result in using a decoder that is slower/less efficient than
* the primary decoder.
* @param audioSink A sink to which the renderers will output.
* @param eventHandler A handler to use when invoking event listeners and outputs.
* @param eventListener An event listener.
* @param out An array to which the built renderers should be appended.
*/
protected void buildAudioRenderers(View on GitHub (pinned to dd430f7053)
Solutions
- Inspect the wrapped cause exception to identify whether it is a signature mismatch (NoSuchMethodException) or a native load failure (UnsatisfiedLinkError).
- Pin core, exoplayer-av1 (libgav1) and any UI/extension modules to the same release version.
- Add ProGuard keep rules so com.google.android.exoplayer2.ext.av1.Libgav1VideoRenderer and its constructor survive shrinking.
- Ship the extension native library for every ABI you support, or disable the extension renderer mode.
Example fix
// before
new DefaultRenderersFactory(context)
.setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER);
// after
try {
player = new ExoPlayer.Builder(new DefaultRenderersFactory(context)
.setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER))
.build(context);
} catch (RuntimeException e) {
// Extension present but broken — fall back to core-only renderers.
player = new ExoPlayer.Builder(
new DefaultRenderersFactory(context)
.setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF))
.build(context);
} Defensive patterns
Strategy: try-catch
Validate before calling
boolean av1Usable = false;
try {
Class.forName("com.google.android.exoplayer2.ext.av1.Libgav1VideoRenderer")
.getConstructor(long.class, android.os.Handler.class,
com.google.android.exoplayer2.video.VideoRendererEventListener.class, int.class);
av1Usable = true;
} catch (ReflectiveOperationException ignored) {
} Try / catch
try {
renderersFactory = withAv1Extension(context);
} catch (RuntimeException e) {
if (e.getCause() instanceof UnsatisfiedLinkError) {
renderersFactory = coreOnlyFactory(context); // no AV1 extension
} else { throw e; }
} Prevention
- Align extension and core versions in one Gradle version catalog entry
- Keep extension classes out of R8 shrinking scope
- Prefer platform AV1 decoders (Android 10+) unless software decode is required
- CI: assert class-path contains exactly one version of each extension
When it happens
Trigger: EXTENSION_RENDERER_MODE_ON/PREFER with the ext.av1 module on the classpath whose (long, Handler, VideoRendererEventListener, int) constructor is missing (version drift), not accessible, or whose construction throws (native libgav1 .so fails to load).
Common situations: Core and extension artifacts from different ExoPlayer releases; obfuscated/shrunk release builds that altered the constructor signature; device ABI without the bundled libgav1 native library; multiple conflicting extension versions on the dependency graph.
Related errors
- Error instantiating VP9 extension
- Error instantiating MIDI 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/77e1311cc817778a.
Report an issue: GitHub.