mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Add second player for input video
PiperOrigin-RevId: 478510687 (cherry picked from commit 48a7f6a9240cd7c0ce8016915de630d903e5c393)
This commit is contained in:
parent
186f516b65
commit
c8917b50e6
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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">
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.media3.ui.PlayerView
|
||||
android:id="@+id/player_view"
|
||||
<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="wrap_content" >
|
||||
|
||||
<androidx.media3.ui.PlayerView
|
||||
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>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/debug_text_view"
|
||||
|
||||
</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"
|
||||
android:textSize="10sp"
|
||||
tools:ignore="SmallSp"/>
|
||||
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>
|
||||
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user