Throw immediately from ExoPlayer.setVideoEffects() if dep not found

This method works by reflectively loading classes from the `lib-effect`
module, in order to avoid a hard dependency on this module for ExoPlayer
users that don't want video effect functionality. This change ensures
that a failure to load the necessary classes fails immediately, instead
of on a later thread inside `MediaCodecVideoRenderer` when the
reflection currently happens.

Also update the javadoc to make the dependency requirement clear.

#minor-release

PiperOrigin-RevId: 601387957
This commit is contained in:
ibaker 2024-01-25 02:40:55 -08:00 committed by Copybara-Service
parent f103a2dcf5
commit a6812156e6
3 changed files with 20 additions and 0 deletions

View File

@ -1573,6 +1573,10 @@ public interface ExoPlayer extends Player {
* <p>The following limitations exist for using {@linkplain Effect video effects}:
*
* <ul>
* <li>The {@code androidx.media3:media3-effect} module must be available on the runtime
* classpath. {@code androidx.media3:media3-exoplayer} does not explicitly depend on the
* effect module, so apps must make sure it's available themselves. It must be the same
* version as the rest of the {@code androidx.media3} modules being used by the app.
* <li>This feature works only with the default {@link MediaCodecVideoRenderer} and not custom
* or extension {@linkplain Renderer video renderers}.
* <li>This feature does not work with {@linkplain Effect effects} updating the timestamps.

View File

@ -81,6 +81,7 @@ import androidx.media3.common.Timeline;
import androidx.media3.common.TrackGroup;
import androidx.media3.common.TrackSelectionParameters;
import androidx.media3.common.Tracks;
import androidx.media3.common.VideoFrameProcessor;
import androidx.media3.common.VideoSize;
import androidx.media3.common.text.Cue;
import androidx.media3.common.text.CueGroup;
@ -1277,6 +1278,13 @@ import java.util.concurrent.TimeoutException;
@Override
public void setVideoEffects(List<Effect> videoEffects) {
verifyApplicationThread();
try {
// LINT.IfChange(set_video_effects)
Class.forName("androidx.media3.effect.PreviewingSingleInputVideoGraph$Factory")
.getConstructor(VideoFrameProcessor.Factory.class);
} catch (ClassNotFoundException | NoSuchMethodException e) {
throw new IllegalStateException("Could not find required lib-effect dependencies.", e);
}
sendRendererMessage(TRACK_TYPE_VIDEO, MSG_SET_VIDEO_EFFECTS, videoEffects);
}

View File

@ -14254,6 +14254,14 @@ public final class ExoPlayerTest {
assertThat(metadataAfterTransition.title).isEqualTo("title");
}
@Test
public void setVideoEffects_failsWithoutLibEffectsDep() {
ExoPlayer player = new TestExoPlayerBuilder(context).build();
IllegalStateException expected =
assertThrows(IllegalStateException.class, () -> player.setVideoEffects(ImmutableList.of()));
assertThat(expected).hasMessageThat().contains("lib-effect dependencies");
}
// Internal methods.
private void addWatchAsSystemFeature() {