google/ExoPlayer · error · RuntimeException
Failed to load MediaPipeShaderProgram
Error message
Failed to load MediaPipeShaderProgram
What it means
RuntimeException thrown by the MediaPipe effects factory lambda in TransformerActivity when Constructor.newInstance fails, i.e. the MediaPipeShaderProgram class could not be constructed. The reflection-based construction fails when the MediaPipe artifacts are absent from the runtime classpath or the constructor signature does not match. The demo already shows a toast and the outer try/catch downgrades selection, so this crash only escapes if the factory is invoked later during composition building.
Source
Thrown at demos/transformer/src/main/java/com/google/android/exoplayer2/transformerdemo/TransformerActivity.java:467
String.class,
boolean.class,
String.class,
String.class);
effects.add(
(GlEffect)
(Context context, boolean useHdr) -> {
try {
return (GlShaderProgram)
constructor.newInstance(
context,
useHdr,
/* graphName= */ "edge_detector_mediapipe_graph.binarypb",
/* isSingleFrameGraph= */ true,
/* inputStreamName= */ "input_video",
/* outputStreamName= */ "output_video");
} catch (Exception e) {
runOnUiThread(() -> showToast(R.string.no_media_pipe_error));
throw new RuntimeException("Failed to load MediaPipeShaderProgram", e);
}
});
} catch (Exception e) {
showToast(R.string.no_media_pipe_error);
}
}
if (selectedEffects[ConfigurationActivity.COLOR_FILTERS_INDEX]) {
switch (bundle.getInt(ConfigurationActivity.COLOR_FILTER_SELECTION)) {
case ConfigurationActivity.COLOR_FILTER_GRAYSCALE:
effects.add(RgbFilter.createGrayscaleFilter());
break;
case ConfigurationActivity.COLOR_FILTER_INVERTED:
effects.add(RgbFilter.createInvertedFilter());
break;
case ConfigurationActivity.COLOR_FILTER_SEPIA:
// W3C Sepia RGBA matrix with sRGB as a target color space:
// https://www.w3.org/TR/filter-effects-1/#sepiaEquivalent
// The matrix is defined for the sRGB color space and the Transformer libraryView on GitHub (pinned to dd430f7053)
Solutions
- Add the required MediaPipe dependencies (com.google.mediapipe:mediapipe-* and the extension artifacts) to the demo's gradle config
- Verify the MediaPipeShaderProgram constructor signature matches the invoked (context, useHdr, graphName, isSingleFrameGraph, inputStreamName, outputStreamName) parameter list for your version
- Bundle the 'edge_detector_mediapipe_graph.binarypb' asset (and any .task/.binarypb files) with the APK
- Add proguard keep rules for com.google.android.exoplayer2.effect and com.google.mediapipe classes when minifying
Example fix
// before
} catch (Exception e) {
runOnUiThread(() -> showToast(R.string.no_media_pipe_error));
throw new RuntimeException("Failed to load MediaPipeShaderProgram", e);
}
// after: resolve the constructor once, before adding the effect, and skip the effect gracefully
try {
constructor = mediaPipeShaderProgramClass.getConstructor(
Context.class, boolean.class, String.class, boolean.class, String.class, String.class);
} catch (NoSuchMethodException e) {
showToast(R.string.no_media_pipe_error); // effect unavailable; do not add it
} Defensive patterns
Strategy: validation
Validate before calling
private boolean mediaPipeEffectAvailable() {
try {
Class<?> clazz = Class.forName("com.google.mediapipe.framework.MediaPipeShaderProgram");
clazz.getConstructor(Context.class, boolean.class,
String.class, boolean.class, String.class, String.class);
return true; // constructor resolvable -> deps present and signature matches
} catch (ReflectiveOperationException e) {
return false;
}
} Try / catch
if (!mediaPipeEffectAvailable()) {
showToast(R.string.no_media_pipe_error); // skip the effect, keep export usable
} else {
effects.add((GlEffect) (context, useHdr) -> {
try {
return (GlShaderProgram) constructor.newInstance(context, useHdr,
"edge_detector_mediapipe_graph.binarypb", true, "input_video", "output_video");
} catch (Exception e) {
throw new RuntimeException("Failed to load MediaPipeShaderProgram", e);
}
});
} Prevention
- Resolve reflected classes and constructors eagerly at config time, not inside per-frame factories
- Pin MediaPipe and Media3 versions you have tested together; constructor signatures do change
- Add proguard keep rules for classes loaded via reflection in release builds
When it happens
Trigger: Selecting the MediaPipe effect in the Transformer demo without the MediaPipe shader/dependencies on the classpath; version mismatch where MediaPipeShaderProgram's constructor args (graphName, isSingleFrameGraph, inputStreamName, outputStreamName) differ from those passed; graph asset 'edge_detector_mediapipe_graph.binarypb' missing from assets.
Common situations: Building the demo from source without the optional MediaPipe AARs; upgrading Media3/MediaPipe versions that changed the constructor; proguard stripping the reflected class in release builds.
Related errors
- Could not delete the previous export output file
- Could not create the export output file
- Unexpected color filter ${colorFilterSelection}
- Failed to load bitmap.
- Failed to load decoder native library.
AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14).
Data as JSON: /api/errors/70dce6fcdcf8ccb0.
Report an issue: GitHub.