mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Update demo app with image input
Adds a new option to the preset file list to show an image for 5secs at 30fps. Also adds an ImageView to show the input image PiperOrigin-RevId: 510372035
This commit is contained in:
parent
48fca7d007
commit
7614ac4778
4 changed files with 63 additions and 10 deletions
|
|
@ -132,6 +132,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
||||||
"https://storage.googleapis.com/exoplayer-test-media-0/BigBuckBunny_320x180.mp4",
|
"https://storage.googleapis.com/exoplayer-test-media-0/BigBuckBunny_320x180.mp4",
|
||||||
"https://storage.googleapis.com/exoplayer-test-media-1/mp4/portrait_avc_aac.mp4",
|
"https://storage.googleapis.com/exoplayer-test-media-1/mp4/portrait_avc_aac.mp4",
|
||||||
"https://storage.googleapis.com/exoplayer-test-media-1/mp4/portrait_rotated_avc_aac.mp4",
|
"https://storage.googleapis.com/exoplayer-test-media-1/mp4/portrait_rotated_avc_aac.mp4",
|
||||||
|
"https://storage.googleapis.com/exoplayer-test-media-1/jpg/london.jpg",
|
||||||
"https://storage.googleapis.com/exoplayer-test-media-1/mp4/slow-motion/slowMotion_stopwatch_240fps_long.mp4",
|
"https://storage.googleapis.com/exoplayer-test-media-1/mp4/slow-motion/slowMotion_stopwatch_240fps_long.mp4",
|
||||||
"https://storage.googleapis.com/exoplayer-test-media-1/gen/screens/dash-vod-single-segment/manifest-baseline.mpd",
|
"https://storage.googleapis.com/exoplayer-test-media-1/gen/screens/dash-vod-single-segment/manifest-baseline.mpd",
|
||||||
"https://storage.googleapis.com/exoplayer-test-media-1/mp4/samsung-s21-hdr-hdr10.mp4",
|
"https://storage.googleapis.com/exoplayer-test-media-1/mp4/samsung-s21-hdr-hdr10.mp4",
|
||||||
|
|
@ -149,6 +150,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
||||||
"Long 180p H264 video and AAC audio",
|
"Long 180p H264 video and AAC audio",
|
||||||
"H264 video and AAC audio (portrait, H > W, 0\u00B0)",
|
"H264 video and AAC audio (portrait, H > W, 0\u00B0)",
|
||||||
"H264 video and AAC audio (portrait, H < W, 90\u00B0)",
|
"H264 video and AAC audio (portrait, H < W, 90\u00B0)",
|
||||||
|
"JPG image (Plays for 5secs at 30fps)",
|
||||||
"SEF slow motion with 240 fps",
|
"SEF slow motion with 240 fps",
|
||||||
"480p DASH (non-square pixels)",
|
"480p DASH (non-square pixels)",
|
||||||
"HDR (HDR10) H265 limited range video (encoding may fail)",
|
"HDR (HDR10) H265 limited range video (encoding may fail)",
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
@ -41,6 +42,7 @@ import android.view.SurfaceView;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
@ -66,6 +68,7 @@ import com.google.android.exoplayer2.effect.RgbAdjustment;
|
||||||
import com.google.android.exoplayer2.effect.RgbFilter;
|
import com.google.android.exoplayer2.effect.RgbFilter;
|
||||||
import com.google.android.exoplayer2.effect.RgbMatrix;
|
import com.google.android.exoplayer2.effect.RgbMatrix;
|
||||||
import com.google.android.exoplayer2.effect.ScaleToFitTransformation;
|
import com.google.android.exoplayer2.effect.ScaleToFitTransformation;
|
||||||
|
import com.google.android.exoplayer2.effect.SimpleBitmapLoader;
|
||||||
import com.google.android.exoplayer2.effect.SingleColorLut;
|
import com.google.android.exoplayer2.effect.SingleColorLut;
|
||||||
import com.google.android.exoplayer2.effect.TextOverlay;
|
import com.google.android.exoplayer2.effect.TextOverlay;
|
||||||
import com.google.android.exoplayer2.effect.TextureOverlay;
|
import com.google.android.exoplayer2.effect.TextureOverlay;
|
||||||
|
|
@ -81,6 +84,7 @@ import com.google.android.exoplayer2.transformer.TransformationRequest;
|
||||||
import com.google.android.exoplayer2.transformer.Transformer;
|
import com.google.android.exoplayer2.transformer.Transformer;
|
||||||
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
|
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
|
||||||
import com.google.android.exoplayer2.ui.StyledPlayerView;
|
import com.google.android.exoplayer2.ui.StyledPlayerView;
|
||||||
|
import com.google.android.exoplayer2.util.BitmapLoader;
|
||||||
import com.google.android.exoplayer2.util.DebugTextViewHelper;
|
import com.google.android.exoplayer2.util.DebugTextViewHelper;
|
||||||
import com.google.android.exoplayer2.util.DebugViewProvider;
|
import com.google.android.exoplayer2.util.DebugViewProvider;
|
||||||
import com.google.android.exoplayer2.util.Effect;
|
import com.google.android.exoplayer2.util.Effect;
|
||||||
|
|
@ -91,10 +95,12 @@ import com.google.android.material.progressindicator.LinearProgressIndicator;
|
||||||
import com.google.common.base.Stopwatch;
|
import com.google.common.base.Stopwatch;
|
||||||
import com.google.common.base.Ticker;
|
import com.google.common.base.Ticker;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||||
|
|
@ -105,6 +111,8 @@ public final class TransformerActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private @MonotonicNonNull Button displayInputButton;
|
private @MonotonicNonNull Button displayInputButton;
|
||||||
private @MonotonicNonNull MaterialCardView inputCardView;
|
private @MonotonicNonNull MaterialCardView inputCardView;
|
||||||
|
private @MonotonicNonNull TextView inputTextView;
|
||||||
|
private @MonotonicNonNull ImageView inputImageView;
|
||||||
private @MonotonicNonNull StyledPlayerView inputPlayerView;
|
private @MonotonicNonNull StyledPlayerView inputPlayerView;
|
||||||
private @MonotonicNonNull StyledPlayerView outputPlayerView;
|
private @MonotonicNonNull StyledPlayerView outputPlayerView;
|
||||||
private @MonotonicNonNull TextView debugTextView;
|
private @MonotonicNonNull TextView debugTextView;
|
||||||
|
|
@ -126,6 +134,8 @@ public final class TransformerActivity extends AppCompatActivity {
|
||||||
setContentView(R.layout.transformer_activity);
|
setContentView(R.layout.transformer_activity);
|
||||||
|
|
||||||
inputCardView = findViewById(R.id.input_card_view);
|
inputCardView = findViewById(R.id.input_card_view);
|
||||||
|
inputTextView = findViewById(R.id.input_text_view);
|
||||||
|
inputImageView = findViewById(R.id.input_image_view);
|
||||||
inputPlayerView = findViewById(R.id.input_player_view);
|
inputPlayerView = findViewById(R.id.input_player_view);
|
||||||
outputPlayerView = findViewById(R.id.output_player_view);
|
outputPlayerView = findViewById(R.id.output_player_view);
|
||||||
debugTextView = findViewById(R.id.debug_text_view);
|
debugTextView = findViewById(R.id.debug_text_view);
|
||||||
|
|
@ -154,6 +164,8 @@ public final class TransformerActivity extends AppCompatActivity {
|
||||||
checkNotNull(informationTextView);
|
checkNotNull(informationTextView);
|
||||||
checkNotNull(transformationStopwatch);
|
checkNotNull(transformationStopwatch);
|
||||||
checkNotNull(inputCardView);
|
checkNotNull(inputCardView);
|
||||||
|
checkNotNull(inputTextView);
|
||||||
|
checkNotNull(inputImageView);
|
||||||
checkNotNull(inputPlayerView);
|
checkNotNull(inputPlayerView);
|
||||||
checkNotNull(outputPlayerView);
|
checkNotNull(outputPlayerView);
|
||||||
checkNotNull(debugTextView);
|
checkNotNull(debugTextView);
|
||||||
|
|
@ -187,6 +199,8 @@ public final class TransformerActivity extends AppCompatActivity {
|
||||||
|
|
||||||
@RequiresNonNull({
|
@RequiresNonNull({
|
||||||
"inputCardView",
|
"inputCardView",
|
||||||
|
"inputTextView",
|
||||||
|
"inputImageView",
|
||||||
"inputPlayerView",
|
"inputPlayerView",
|
||||||
"outputPlayerView",
|
"outputPlayerView",
|
||||||
"displayInputButton",
|
"displayInputButton",
|
||||||
|
|
@ -262,6 +276,8 @@ public final class TransformerActivity extends AppCompatActivity {
|
||||||
|
|
||||||
@RequiresNonNull({
|
@RequiresNonNull({
|
||||||
"inputCardView",
|
"inputCardView",
|
||||||
|
"inputTextView",
|
||||||
|
"inputImageView",
|
||||||
"inputPlayerView",
|
"inputPlayerView",
|
||||||
"outputPlayerView",
|
"outputPlayerView",
|
||||||
"displayInputButton",
|
"displayInputButton",
|
||||||
|
|
@ -349,6 +365,8 @@ public final class TransformerActivity extends AppCompatActivity {
|
||||||
if (bundle == null) {
|
if (bundle == null) {
|
||||||
return editedMediaItemBuilder.build();
|
return editedMediaItemBuilder.build();
|
||||||
}
|
}
|
||||||
|
// For image inputs. Automatically ignored if input is audio/video.
|
||||||
|
editedMediaItemBuilder.setDurationUs(5_000_000).setFrameRate(30);
|
||||||
ImmutableList<AudioProcessor> audioProcessors = createAudioProcessorsFromBundle(bundle);
|
ImmutableList<AudioProcessor> audioProcessors = createAudioProcessorsFromBundle(bundle);
|
||||||
ImmutableList<Effect> videoEffects = createVideoEffectsFromBundle(bundle);
|
ImmutableList<Effect> videoEffects = createVideoEffectsFromBundle(bundle);
|
||||||
return editedMediaItemBuilder
|
return editedMediaItemBuilder
|
||||||
|
|
@ -617,6 +635,8 @@ public final class TransformerActivity extends AppCompatActivity {
|
||||||
|
|
||||||
@RequiresNonNull({
|
@RequiresNonNull({
|
||||||
"inputCardView",
|
"inputCardView",
|
||||||
|
"inputTextView",
|
||||||
|
"inputImageView",
|
||||||
"inputPlayerView",
|
"inputPlayerView",
|
||||||
"outputPlayerView",
|
"outputPlayerView",
|
||||||
"displayInputButton",
|
"displayInputButton",
|
||||||
|
|
@ -642,6 +662,8 @@ public final class TransformerActivity extends AppCompatActivity {
|
||||||
|
|
||||||
@RequiresNonNull({
|
@RequiresNonNull({
|
||||||
"inputCardView",
|
"inputCardView",
|
||||||
|
"inputTextView",
|
||||||
|
"inputImageView",
|
||||||
"inputPlayerView",
|
"inputPlayerView",
|
||||||
"outputPlayerView",
|
"outputPlayerView",
|
||||||
"debugTextView",
|
"debugTextView",
|
||||||
|
|
@ -650,14 +672,7 @@ public final class TransformerActivity extends AppCompatActivity {
|
||||||
inputPlayerView.setPlayer(null);
|
inputPlayerView.setPlayer(null);
|
||||||
outputPlayerView.setPlayer(null);
|
outputPlayerView.setPlayer(null);
|
||||||
releasePlayer();
|
releasePlayer();
|
||||||
|
Uri uri = checkNotNull(inputMediaItem.localConfiguration).uri;
|
||||||
ExoPlayer inputPlayer = new ExoPlayer.Builder(/* context= */ this).build();
|
|
||||||
inputPlayerView.setPlayer(inputPlayer);
|
|
||||||
inputPlayerView.setControllerAutoShow(false);
|
|
||||||
inputPlayer.setMediaItem(inputMediaItem);
|
|
||||||
inputPlayer.prepare();
|
|
||||||
this.inputPlayer = inputPlayer;
|
|
||||||
inputPlayer.setVolume(0f);
|
|
||||||
|
|
||||||
ExoPlayer outputPlayer = new ExoPlayer.Builder(/* context= */ this).build();
|
ExoPlayer outputPlayer = new ExoPlayer.Builder(/* context= */ this).build();
|
||||||
outputPlayerView.setPlayer(outputPlayer);
|
outputPlayerView.setPlayer(outputPlayer);
|
||||||
|
|
@ -666,7 +681,34 @@ public final class TransformerActivity extends AppCompatActivity {
|
||||||
outputPlayer.prepare();
|
outputPlayer.prepare();
|
||||||
this.outputPlayer = outputPlayer;
|
this.outputPlayer = outputPlayer;
|
||||||
|
|
||||||
inputPlayer.play();
|
// Only support showing jpg images.
|
||||||
|
if (uri.toString().endsWith("jpg")) {
|
||||||
|
inputPlayerView.setVisibility(View.GONE);
|
||||||
|
inputImageView.setVisibility(View.VISIBLE);
|
||||||
|
inputTextView.setText(getString(R.string.input_image));
|
||||||
|
|
||||||
|
BitmapLoader bitmapLoader = new SimpleBitmapLoader();
|
||||||
|
ListenableFuture<Bitmap> future = bitmapLoader.loadBitmap(uri);
|
||||||
|
try {
|
||||||
|
Bitmap bitmap = future.get();
|
||||||
|
inputImageView.setImageBitmap(bitmap);
|
||||||
|
} catch (ExecutionException | InterruptedException e) {
|
||||||
|
throw new IllegalArgumentException("Failed to load bitmap.", e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
inputPlayerView.setVisibility(View.VISIBLE);
|
||||||
|
inputImageView.setVisibility(View.GONE);
|
||||||
|
inputTextView.setText(getString(R.string.input_video));
|
||||||
|
|
||||||
|
ExoPlayer inputPlayer = new ExoPlayer.Builder(/* context= */ this).build();
|
||||||
|
inputPlayerView.setPlayer(inputPlayer);
|
||||||
|
inputPlayerView.setControllerAutoShow(false);
|
||||||
|
inputPlayer.setMediaItem(inputMediaItem);
|
||||||
|
inputPlayer.prepare();
|
||||||
|
this.inputPlayer = inputPlayer;
|
||||||
|
inputPlayer.setVolume(0f);
|
||||||
|
inputPlayer.play();
|
||||||
|
}
|
||||||
outputPlayer.play();
|
outputPlayer.play();
|
||||||
|
|
||||||
debugTextViewHelper = new DebugTextViewHelper(outputPlayer, debugTextView);
|
debugTextViewHelper = new DebugTextViewHelper(outputPlayer, debugTextView);
|
||||||
|
|
@ -709,7 +751,9 @@ public final class TransformerActivity extends AppCompatActivity {
|
||||||
inputCardView.setVisibility(View.VISIBLE);
|
inputCardView.setVisibility(View.VISIBLE);
|
||||||
displayInputButton.setText(getString(R.string.hide_input_video));
|
displayInputButton.setText(getString(R.string.hide_input_video));
|
||||||
} else if (inputCardView.getVisibility() == View.VISIBLE) {
|
} else if (inputCardView.getVisibility() == View.VISIBLE) {
|
||||||
checkNotNull(inputPlayer).pause();
|
if (inputPlayer != null) {
|
||||||
|
inputPlayer.pause();
|
||||||
|
}
|
||||||
inputCardView.setVisibility(View.GONE);
|
inputCardView.setVisibility(View.GONE);
|
||||||
displayInputButton.setText(getString(R.string.show_input_video));
|
displayInputButton.setText(getString(R.string.show_input_video));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@
|
||||||
android:layout_height="wrap_content" >
|
android:layout_height="wrap_content" >
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/input_text_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
|
|
@ -79,6 +80,11 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" >
|
android:layout_height="wrap_content" >
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/input_image_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
<com.google.android.exoplayer2.ui.StyledPlayerView
|
<com.google.android.exoplayer2.ui.StyledPlayerView
|
||||||
android:id="@+id/input_player_view"
|
android:id="@+id/input_player_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@
|
||||||
<string name="hue_adjustment">Hue adjustment</string>
|
<string name="hue_adjustment">Hue adjustment</string>
|
||||||
<string name="saturation_adjustment">Saturation adjustment</string>
|
<string name="saturation_adjustment">Saturation adjustment</string>
|
||||||
<string name="lightness_adjustment">Lightness adjustment</string>
|
<string name="lightness_adjustment">Lightness adjustment</string>
|
||||||
|
<string name="input_image">Input image:</string>
|
||||||
<string name="input_video">Input video:</string>
|
<string name="input_video">Input video:</string>
|
||||||
<string name="output_video">Output video:</string>
|
<string name="output_video">Output video:</string>
|
||||||
<string name="permission_denied">Permission Denied</string>
|
<string name="permission_denied">Permission Denied</string>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue