Add second player for input video

PiperOrigin-RevId: 478510687
(cherry picked from commit 48a7f6a9240cd7c0ce8016915de630d903e5c393)
This commit is contained in:
Googler 2022-10-03 15:27:33 +00:00 committed by microkatz
parent 186f516b65
commit c8917b50e6
3 changed files with 156 additions and 57 deletions

View File

@ -60,6 +60,7 @@ import androidx.media3.transformer.TransformationResult;
import androidx.media3.transformer.Transformer;
import androidx.media3.ui.AspectRatioFrameLayout;
import androidx.media3.ui.PlayerView;
import com.google.android.material.card.MaterialCardView;
import com.google.android.material.progressindicator.LinearProgressIndicator;
import com.google.common.base.Stopwatch;
import com.google.common.base.Ticker;
@ -76,7 +77,9 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
public final class TransformerActivity extends AppCompatActivity {
private static final String TAG = "TransformerActivity";
private @MonotonicNonNull PlayerView playerView;
private @MonotonicNonNull MaterialCardView inputCardView;
private @MonotonicNonNull PlayerView inputPlayerView;
private @MonotonicNonNull PlayerView outputPlayerView;
private @MonotonicNonNull TextView debugTextView;
private @MonotonicNonNull TextView informationTextView;
private @MonotonicNonNull ViewGroup progressViewGroup;
@ -85,7 +88,8 @@ public final class TransformerActivity extends AppCompatActivity {
private @MonotonicNonNull AspectRatioFrameLayout debugFrame;
@Nullable private DebugTextViewHelper debugTextViewHelper;
@Nullable private ExoPlayer player;
@Nullable private ExoPlayer inputPlayer;
@Nullable private ExoPlayer outputPlayer;
@Nullable private Transformer transformer;
@Nullable private File externalCacheFile;
@ -94,7 +98,9 @@ public final class TransformerActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.transformer_activity);
playerView = findViewById(R.id.player_view);
inputCardView = findViewById(R.id.input_card_view);
inputPlayerView = findViewById(R.id.input_player_view);
outputPlayerView = findViewById(R.id.output_player_view);
debugTextView = findViewById(R.id.debug_text_view);
informationTextView = findViewById(R.id.information_text_view);
progressViewGroup = findViewById(R.id.progress_view_group);
@ -104,6 +110,7 @@ public final class TransformerActivity extends AppCompatActivity {
transformationStopwatch =
Stopwatch.createUnstarted(
new Ticker() {
@Override
public long read() {
return android.os.SystemClock.elapsedRealtimeNanos();
}
@ -117,13 +124,16 @@ public final class TransformerActivity extends AppCompatActivity {
checkNotNull(progressIndicator);
checkNotNull(informationTextView);
checkNotNull(transformationStopwatch);
checkNotNull(playerView);
checkNotNull(inputCardView);
checkNotNull(inputPlayerView);
checkNotNull(outputPlayerView);
checkNotNull(debugTextView);
checkNotNull(progressViewGroup);
checkNotNull(debugFrame);
startTransformation();
playerView.onResume();
inputPlayerView.onResume();
outputPlayerView.onResume();
}
@Override
@ -137,7 +147,8 @@ public final class TransformerActivity extends AppCompatActivity {
// stop watch to be stopped in a transformer callback.
checkNotNull(transformationStopwatch).reset();
checkNotNull(playerView).onPause();
checkNotNull(inputPlayerView).onPause();
checkNotNull(outputPlayerView).onPause();
releasePlayer();
checkNotNull(externalCacheFile).delete();
@ -145,7 +156,9 @@ public final class TransformerActivity extends AppCompatActivity {
}
@RequiresNonNull({
"playerView",
"inputCardView",
"inputPlayerView",
"outputPlayerView",
"debugTextView",
"informationTextView",
"progressIndicator",
@ -171,7 +184,8 @@ public final class TransformerActivity extends AppCompatActivity {
throw new IllegalStateException(e);
}
informationTextView.setText(R.string.transformation_started);
playerView.setVisibility(View.GONE);
inputCardView.setVisibility(View.GONE);
outputPlayerView.setVisibility(View.GONE);
Handler mainHandler = new Handler(getMainLooper());
ProgressHolder progressHolder = new ProgressHolder();
mainHandler.post(
@ -210,20 +224,10 @@ public final class TransformerActivity extends AppCompatActivity {
return mediaItemBuilder.build();
}
// Create a cache file, resetting it if it already exists.
private File createExternalCacheFile(String fileName) throws IOException {
File file = new File(getExternalCacheDir(), fileName);
if (file.exists() && !file.delete()) {
throw new IllegalStateException("Could not delete the previous transformer output file");
}
if (!file.createNewFile()) {
throw new IllegalStateException("Could not create the transformer output file");
}
return file;
}
@RequiresNonNull({
"playerView",
"inputCardView",
"inputPlayerView",
"outputPlayerView",
"debugTextView",
"informationTextView",
"transformationStopwatch",
@ -284,7 +288,7 @@ public final class TransformerActivity extends AppCompatActivity {
@Override
public void onTransformationCompleted(
MediaItem mediaItem, TransformationResult transformationResult) {
TransformerActivity.this.onTransformationCompleted(filePath);
TransformerActivity.this.onTransformationCompleted(filePath, mediaItem);
}
@Override
@ -296,6 +300,18 @@ public final class TransformerActivity extends AppCompatActivity {
.build();
}
// Create a cache file, resetting it if it already exists.
private File createExternalCacheFile(String fileName) throws IOException {
File file = new File(getExternalCacheDir(), fileName);
if (file.exists() && !file.delete()) {
throw new IllegalStateException("Could not delete the previous transformer output file");
}
if (!file.createNewFile()) {
throw new IllegalStateException("Could not create the transformer output file");
}
return file;
}
private ImmutableList<Effect> createVideoEffectsListFromBundle(Bundle bundle) {
@Nullable
boolean[] selectedEffects =
@ -444,37 +460,55 @@ public final class TransformerActivity extends AppCompatActivity {
}
@RequiresNonNull({
"playerView",
"inputCardView",
"inputPlayerView",
"outputPlayerView",
"debugTextView",
"informationTextView",
"progressViewGroup",
"debugFrame",
"transformationStopwatch",
})
private void onTransformationCompleted(String filePath) {
private void onTransformationCompleted(String filePath, MediaItem inputMediaItem) {
transformationStopwatch.stop();
informationTextView.setText(
getString(
R.string.transformation_completed, transformationStopwatch.elapsed(TimeUnit.SECONDS)));
progressViewGroup.setVisibility(View.GONE);
debugFrame.removeAllViews();
playerView.setVisibility(View.VISIBLE);
playMediaItem(MediaItem.fromUri("file://" + filePath));
inputCardView.setVisibility(View.VISIBLE);
outputPlayerView.setVisibility(View.VISIBLE);
playMediaItems(inputMediaItem, MediaItem.fromUri("file://" + filePath));
Log.d(TAG, "Output file path: file://" + filePath);
}
@RequiresNonNull({"playerView", "debugTextView"})
private void playMediaItem(MediaItem mediaItem) {
playerView.setPlayer(null);
@RequiresNonNull({
"inputCardView",
"inputPlayerView",
"outputPlayerView",
"debugTextView",
})
private void playMediaItems(MediaItem inputMediaItem, MediaItem outputMediaItem) {
inputPlayerView.setPlayer(null);
outputPlayerView.setPlayer(null);
releasePlayer();
ExoPlayer player = new ExoPlayer.Builder(/* context= */ this).build();
playerView.setPlayer(player);
player.setMediaItem(mediaItem);
player.play();
player.prepare();
this.player = player;
debugTextViewHelper = new DebugTextViewHelper(player, debugTextView);
ExoPlayer inputPlayer = new ExoPlayer.Builder(/* context= */ this).build();
inputPlayerView.setPlayer(inputPlayer);
inputPlayer.setMediaItem(inputMediaItem);
inputPlayer.prepare();
this.inputPlayer = inputPlayer;
ExoPlayer outputPlayer = new ExoPlayer.Builder(/* context= */ this).build();
outputPlayerView.setPlayer(outputPlayer);
outputPlayer.setMediaItem(outputMediaItem);
outputPlayer.prepare();
this.outputPlayer = outputPlayer;
inputPlayer.play();
outputPlayer.play();
debugTextViewHelper = new DebugTextViewHelper(outputPlayer, debugTextView);
debugTextViewHelper.start();
}
@ -483,9 +517,13 @@ public final class TransformerActivity extends AppCompatActivity {
debugTextViewHelper.stop();
debugTextViewHelper = null;
}
if (player != null) {
player.release();
player = null;
if (inputPlayer != null) {
inputPlayer.release();
inputPlayer = null;
}
if (outputPlayer != null) {
outputPlayer.release();
outputPlayer = null;
}
}

View File

@ -39,32 +39,87 @@
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/input_card_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_margin="16dp"
app:cardCornerRadius="4dp"
app:cardElevation="2dp">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:padding="8dp"
android:text="@string/input_video" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="wrap_content" >
<androidx.media3.ui.PlayerView
android:id="@+id/player_view"
android:id="@+id/input_player_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.media3.ui.AspectRatioFrameLayout
android:id="@+id/input_debug_aspect_ratio_frame_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/output_card_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_margin="16dp"
app:cardCornerRadius="4dp"
app:cardElevation="2dp">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="@string/output_video" />
<TextView
android:id="@+id/debug_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:textSize="10sp"
tools:ignore="SmallSp"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_gravity="center"
android:layout_height="wrap_content">
<androidx.media3.ui.PlayerView
android:id="@+id/output_player_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@+id/progress_view_group"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_gravity="bottom"
android:padding="8dp"
android:orientation="vertical">
@ -96,5 +151,9 @@
</LinearLayout>
</FrameLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>

View File

@ -49,14 +49,16 @@
</string-array>
<string name="contrast_value" translatable="false">Contrast value</string>
<string name="rgb_adjustment_options" translatable="false">Scale RGB Channels individually</string>
<string name="rgb_adjustment_scale_red" translatable="false">Scale Red</string>
<string name="rgb_adjustment_scale_green" translatable="false">Scale Green</string>
<string name="rgb_adjustment_scale_blue" translatable="false">Scale Blue</string>
<string name="rgb_adjustment_scale_red" translatable="false">Scale red</string>
<string name="rgb_adjustment_scale_green" translatable="false">Scale green</string>
<string name="rgb_adjustment_scale_blue" translatable="false">Scale blue</string>
<string name="center_x">Center X</string>
<string name="center_y">Center Y</string>
<string name="radius_range">Radius range</string>
<string name="hsl_adjustment_options" translatable="false">HSL Adjustment Options</string>
<string name="hue_adjustment">Hue Adjustment</string>
<string name="saturation_adjustment">Saturation Adjustment</string>
<string name="lightness_adjustment">Lightness Adjustment</string>
<string name="hsl_adjustment_options" translatable="false">HSL adjustment options</string>
<string name="hue_adjustment">Hue adjustment</string>
<string name="saturation_adjustment">Saturation adjustment</string>
<string name="lightness_adjustment">Lightness adjustment</string>
<string name="input_video">Input video:</string>
<string name="output_video">Output video:</string>
</resources>