Create new class to store cues and timestamp.
We need to pass timestamp for the list of cues so we are defining a new class CueGroup which will store both cues and timestamp. PiperOrigin-RevId: 449212054
This commit is contained in:
parent
0e2bb8c8bd
commit
c728647290
@ -28,6 +28,8 @@
|
||||
* Decrease ad polling rate from every 100ms to every 200ms, to line up
|
||||
with Media Rating Council (MRC) recommendations.
|
||||
* Text:
|
||||
* Change `Player.getCurrentCues()` to return `CueGroup` instead of
|
||||
`List<Cue>`.
|
||||
* SSA: Support `OutlineColour` style setting when `BorderStyle == 3` (i.e.
|
||||
`OutlineColour` sets the background of the cue)
|
||||
([#8435](https://github.com/google/ExoPlayer/issues/8435)).
|
||||
|
@ -42,7 +42,7 @@ import androidx.media3.common.TrackGroup;
|
||||
import androidx.media3.common.TrackSelectionParameters;
|
||||
import androidx.media3.common.Tracks;
|
||||
import androidx.media3.common.VideoSize;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.common.util.Assertions;
|
||||
import androidx.media3.common.util.Clock;
|
||||
import androidx.media3.common.util.ListenerSet;
|
||||
@ -705,10 +705,10 @@ public final class CastPlayer extends BasePlayer {
|
||||
return VideoSize.UNKNOWN;
|
||||
}
|
||||
|
||||
/** This method is not supported and returns an empty list. */
|
||||
/** This method is not supported and returns an empty {@link CueGroup}. */
|
||||
@Override
|
||||
public ImmutableList<Cue> getCurrentCues() {
|
||||
return ImmutableList.of();
|
||||
public CueGroup getCurrentCues() {
|
||||
return CueGroup.EMPTY;
|
||||
}
|
||||
|
||||
/** This method is not supported and always returns {@link DeviceInfo#UNKNOWN}. */
|
||||
|
@ -22,6 +22,7 @@ import android.view.SurfaceView;
|
||||
import android.view.TextureView;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import java.util.List;
|
||||
|
||||
@ -752,7 +753,7 @@ public class ForwardingPlayer implements Player {
|
||||
|
||||
/** Calls {@link Player#getCurrentCues()} on the delegate and returns the result. */
|
||||
@Override
|
||||
public List<Cue> getCurrentCues() {
|
||||
public CueGroup getCurrentCues() {
|
||||
return player.getCurrentCues();
|
||||
}
|
||||
|
||||
@ -992,6 +993,11 @@ public class ForwardingPlayer implements Player {
|
||||
listener.onCues(cues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCues(CueGroup cueGroup) {
|
||||
listener.onCues(cueGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMetadata(Metadata metadata) {
|
||||
listener.onMetadata(metadata);
|
||||
|
@ -32,6 +32,7 @@ import androidx.annotation.IntDef;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.common.util.BundleableUtil;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.common.util.Util;
|
||||
@ -1024,16 +1025,29 @@ public interface Player {
|
||||
/**
|
||||
* Called when there is a change in the {@link Cue Cues}.
|
||||
*
|
||||
* <p>{@code cues} is in ascending order of priority. If any of the cue boxes overlap when
|
||||
* displayed, the {@link Cue} nearer the end of the list should be shown on top.
|
||||
* <p>Both {@link #onCues(List)} and {@link #onCues(CueGroup)} are called when there is a change
|
||||
* in the cues. You should only implement one or the other.
|
||||
*
|
||||
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||||
* other events that happen in the same {@link Looper} message queue iteration.
|
||||
*
|
||||
* @param cues The {@link Cue Cues}. May be empty.
|
||||
* @deprecated Use {@link #onCues(CueGroup)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@UnstableApi
|
||||
default void onCues(List<Cue> cues) {}
|
||||
|
||||
/**
|
||||
* Called when there is a change in the {@link CueGroup}.
|
||||
*
|
||||
* <p>Both {@link #onCues(List)} and {@link #onCues(CueGroup)} are called when there is a change
|
||||
* in the cues. You should only implement one or the other.
|
||||
*
|
||||
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||||
* other events that happen in the same {@link Looper} message queue iteration.
|
||||
*/
|
||||
default void onCues(CueGroup cueGroup) {}
|
||||
|
||||
/**
|
||||
* Called when there is metadata associated with the current playback time.
|
||||
*
|
||||
@ -2469,8 +2483,8 @@ public interface Player {
|
||||
*/
|
||||
VideoSize getVideoSize();
|
||||
|
||||
/** Returns the current {@link Cue Cues}. This list may be empty. */
|
||||
List<Cue> getCurrentCues();
|
||||
/** Returns the current {@link CueGroup}. */
|
||||
CueGroup getCurrentCues();
|
||||
|
||||
/** Gets the device information. */
|
||||
DeviceInfo getDeviceInfo();
|
||||
|
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package androidx.media3.common.text;
|
||||
|
||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.media3.common.Bundleable;
|
||||
import androidx.media3.common.util.BundleableUtil;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.List;
|
||||
|
||||
/** Class to represent the state of active {@link Cue Cues} at a particular time. */
|
||||
public final class CueGroup implements Bundleable {
|
||||
|
||||
/** Empty {@link CueGroup}. */
|
||||
@UnstableApi public static final CueGroup EMPTY = new CueGroup(ImmutableList.of());
|
||||
|
||||
/**
|
||||
* The cues in this group.
|
||||
*
|
||||
* <p>This list is in ascending order of priority. If any of the cue boxes overlap when displayed,
|
||||
* the {@link Cue} nearer the end of the list should be shown on top.
|
||||
*
|
||||
* <p>This list may be empty if the group represents a state with no cues.
|
||||
*/
|
||||
public final ImmutableList<Cue> cues;
|
||||
|
||||
/** Creates a CueGroup. */
|
||||
@UnstableApi
|
||||
public CueGroup(List<Cue> cues) {
|
||||
this.cues = ImmutableList.copyOf(cues);
|
||||
}
|
||||
|
||||
// Bundleable implementation.
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@Target(TYPE_USE)
|
||||
@IntDef({FIELD_CUES})
|
||||
private @interface FieldNumber {}
|
||||
|
||||
private static final int FIELD_CUES = 0;
|
||||
|
||||
@UnstableApi
|
||||
@Override
|
||||
public Bundle toBundle() {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelableArrayList(
|
||||
keyForField(FIELD_CUES), BundleableUtil.toBundleArrayList(filterOutBitmapCues(cues)));
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@UnstableApi public static final Creator<CueGroup> CREATOR = CueGroup::fromBundle;
|
||||
|
||||
private static final CueGroup fromBundle(Bundle bundle) {
|
||||
List<Cue> cues =
|
||||
BundleableUtil.fromBundleNullableList(
|
||||
Cue.CREATOR,
|
||||
bundle.getParcelableArrayList(keyForField(FIELD_CUES)),
|
||||
/* defaultValue= */ ImmutableList.of());
|
||||
return new CueGroup(cues);
|
||||
}
|
||||
|
||||
private static String keyForField(@FieldNumber int field) {
|
||||
return Integer.toString(field, Character.MAX_RADIX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out {@link Cue} objects containing {@link Bitmap}. It is used when transferring cues
|
||||
* between processes to prevent transferring too much data.
|
||||
*/
|
||||
private static ImmutableList<Cue> filterOutBitmapCues(List<Cue> cues) {
|
||||
ImmutableList.Builder<Cue> builder = ImmutableList.builder();
|
||||
for (int i = 0; i < cues.size(); i++) {
|
||||
if (cues.get(i).bitmap != null) {
|
||||
continue;
|
||||
}
|
||||
builder.add(cues.get(i));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package androidx.media3.common.text;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.text.SpannedString;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/** Tests for {@link CueGroup}. */
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class CueGroupTest {
|
||||
|
||||
@Test
|
||||
public void bundleAndUnBundleCueGroup() {
|
||||
Cue textCue = new Cue.Builder().setText(SpannedString.valueOf("text")).build();
|
||||
Cue bitmapCue =
|
||||
new Cue.Builder().setBitmap(Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)).build();
|
||||
ImmutableList<Cue> cues = ImmutableList.of(textCue, bitmapCue);
|
||||
CueGroup cueGroup = new CueGroup(cues);
|
||||
|
||||
Parcel parcel = Parcel.obtain();
|
||||
try {
|
||||
parcel.writeBundle(cueGroup.toBundle());
|
||||
parcel.setDataPosition(0);
|
||||
|
||||
Bundle bundle = parcel.readBundle();
|
||||
CueGroup filteredCueGroup = CueGroup.CREATOR.fromBundle(bundle);
|
||||
|
||||
assertThat(filteredCueGroup.cues).containsExactly(textCue);
|
||||
} finally {
|
||||
parcel.recycle();
|
||||
}
|
||||
}
|
||||
}
|
@ -40,7 +40,7 @@ import androidx.media3.common.PriorityTaskManager;
|
||||
import androidx.media3.common.Timeline;
|
||||
import androidx.media3.common.Tracks;
|
||||
import androidx.media3.common.VideoSize;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.common.util.Clock;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.common.util.Util;
|
||||
@ -358,7 +358,7 @@ public interface ExoPlayer extends Player {
|
||||
* @deprecated Use {@link Player#getCurrentCues()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
List<Cue> getCurrentCues();
|
||||
CueGroup getCurrentCues();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,6 +73,7 @@ import androidx.media3.common.TrackSelectionParameters;
|
||||
import androidx.media3.common.Tracks;
|
||||
import androidx.media3.common.VideoSize;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.common.util.Assertions;
|
||||
import androidx.media3.common.util.Clock;
|
||||
import androidx.media3.common.util.ConditionVariable;
|
||||
@ -196,7 +197,7 @@ import java.util.concurrent.TimeoutException;
|
||||
private AudioAttributes audioAttributes;
|
||||
private float volume;
|
||||
private boolean skipSilenceEnabled;
|
||||
private List<Cue> currentCues;
|
||||
private CueGroup currentCueGroup;
|
||||
@Nullable private VideoFrameMetadataListener videoFrameMetadataListener;
|
||||
@Nullable private CameraMotionListener cameraMotionListener;
|
||||
private boolean throwsWhenUsingWrongThread;
|
||||
@ -353,7 +354,7 @@ import java.util.concurrent.TimeoutException;
|
||||
} else {
|
||||
audioSessionId = Util.generateAudioSessionIdV21(applicationContext);
|
||||
}
|
||||
currentCues = ImmutableList.of();
|
||||
currentCueGroup = CueGroup.EMPTY;
|
||||
throwsWhenUsingWrongThread = true;
|
||||
|
||||
addListener(analyticsCollector);
|
||||
@ -936,7 +937,7 @@ import java.util.concurrent.TimeoutException;
|
||||
verifyApplicationThread();
|
||||
audioFocusManager.updateAudioFocus(getPlayWhenReady(), Player.STATE_IDLE);
|
||||
stopInternal(reset, /* error= */ null);
|
||||
currentCues = ImmutableList.of();
|
||||
currentCueGroup = CueGroup.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -990,7 +991,7 @@ import java.util.concurrent.TimeoutException;
|
||||
checkNotNull(priorityTaskManager).remove(C.PRIORITY_PLAYBACK);
|
||||
isPriorityTaskManagerRegistered = false;
|
||||
}
|
||||
currentCues = ImmutableList.of();
|
||||
currentCueGroup = CueGroup.EMPTY;
|
||||
playerReleased = true;
|
||||
}
|
||||
|
||||
@ -1587,9 +1588,9 @@ import java.util.concurrent.TimeoutException;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Cue> getCurrentCues() {
|
||||
public CueGroup getCurrentCues() {
|
||||
verifyApplicationThread();
|
||||
return currentCues;
|
||||
return currentCueGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -2850,13 +2851,17 @@ import java.util.concurrent.TimeoutException;
|
||||
}
|
||||
|
||||
// TextOutput implementation
|
||||
|
||||
@Override
|
||||
public void onCues(List<Cue> cues) {
|
||||
currentCues = cues;
|
||||
listeners.sendEvent(EVENT_CUES, listener -> listener.onCues(cues));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCues(CueGroup cueGroup) {
|
||||
currentCueGroup = cueGroup;
|
||||
listeners.sendEvent(EVENT_CUES, listener -> listener.onCues(cueGroup));
|
||||
}
|
||||
|
||||
// MetadataOutput implementation
|
||||
|
||||
@Override
|
||||
|
@ -38,7 +38,7 @@ import androidx.media3.common.Timeline;
|
||||
import androidx.media3.common.TrackSelectionParameters;
|
||||
import androidx.media3.common.Tracks;
|
||||
import androidx.media3.common.VideoSize;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.common.util.Clock;
|
||||
import androidx.media3.common.util.ConditionVariable;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
@ -690,7 +690,7 @@ public class SimpleExoPlayer extends BasePlayer
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Cue> getCurrentCues() {
|
||||
public CueGroup getCurrentCues() {
|
||||
blockUntilConstructorFinished();
|
||||
return player.getCurrentCues();
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ import androidx.media3.common.TrackSelectionParameters;
|
||||
import androidx.media3.common.Tracks;
|
||||
import androidx.media3.common.VideoSize;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.decoder.DecoderException;
|
||||
import androidx.media3.exoplayer.DecoderCounters;
|
||||
@ -875,15 +876,29 @@ public interface AnalyticsListener {
|
||||
/**
|
||||
* Called when there is a change in the {@link Cue Cues}.
|
||||
*
|
||||
* <p>{@code cues} is in ascending order of priority. If any of the cue boxes overlap when
|
||||
* displayed, the {@link Cue} nearer the end of the list should be shown on top.
|
||||
* <p>Both {@link #onCues(EventTime, List)} and {@link #onCues(EventTime, CueGroup)} are called
|
||||
* when there is a change in the cues. You should only implement one or the other.
|
||||
*
|
||||
* @param eventTime The event time.
|
||||
* @param cues The {@link Cue Cues}. May be empty.
|
||||
* @param cues The {@link Cue Cues}.
|
||||
* @deprecated Use {@link #onCues(EventTime, CueGroup)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@UnstableApi
|
||||
default void onCues(EventTime eventTime, List<Cue> cues) {}
|
||||
|
||||
/**
|
||||
* Called when there is a change in the {@link CueGroup}.
|
||||
*
|
||||
* <p>Both {@link #onCues(EventTime, List)} and {@link #onCues(EventTime, CueGroup)} are called
|
||||
* when there is a change in the cues. You should only implement one or the other.
|
||||
*
|
||||
* @param eventTime The event time.
|
||||
* @param cueGroup The {@link CueGroup}.
|
||||
*/
|
||||
@UnstableApi
|
||||
default void onCues(EventTime eventTime, CueGroup cueGroup) {}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #onAudioEnabled} and {@link #onVideoEnabled} instead.
|
||||
*/
|
||||
|
@ -42,6 +42,7 @@ import androidx.media3.common.TrackSelectionParameters;
|
||||
import androidx.media3.common.Tracks;
|
||||
import androidx.media3.common.VideoSize;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.common.util.Clock;
|
||||
import androidx.media3.common.util.HandlerWrapper;
|
||||
import androidx.media3.common.util.ListenerSet;
|
||||
@ -695,6 +696,7 @@ public class DefaultAnalyticsCollector implements AnalyticsCollector {
|
||||
listener -> listener.onMetadata(eventTime, metadata));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation") // Implementing and calling deprecated listener method.
|
||||
@Override
|
||||
public void onCues(List<Cue> cues) {
|
||||
EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
|
||||
@ -702,6 +704,13 @@ public class DefaultAnalyticsCollector implements AnalyticsCollector {
|
||||
eventTime, AnalyticsListener.EVENT_CUES, listener -> listener.onCues(eventTime, cues));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCues(CueGroup cueGroup) {
|
||||
EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
|
||||
sendEvent(
|
||||
eventTime, AnalyticsListener.EVENT_CUES, listener -> listener.onCues(eventTime, cueGroup));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation") // Implementing and calling deprecated listener method.
|
||||
@Override
|
||||
public final void onSeekProcessed() {
|
||||
|
@ -16,6 +16,7 @@
|
||||
package androidx.media3.exoplayer.text;
|
||||
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import java.util.List;
|
||||
|
||||
@ -26,10 +27,19 @@ public interface TextOutput {
|
||||
/**
|
||||
* Called when there is a change in the {@link Cue Cues}.
|
||||
*
|
||||
* <p>{@code cues} is in ascending order of priority. If any of the cue boxes overlap when
|
||||
* displayed, the {@link Cue} nearer the end of the list should be shown on top.
|
||||
* <p>Both {@link #onCues(List)} and {@link #onCues(CueGroup)} are called when there is a change
|
||||
* in the cues. You should only implement one or the other.
|
||||
*
|
||||
* @param cues The {@link Cue Cues}. May be empty.
|
||||
* @deprecated Use {@link #onCues(CueGroup)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
void onCues(List<Cue> cues);
|
||||
|
||||
/**
|
||||
* Called when there is a change in the {@link CueGroup}.
|
||||
*
|
||||
* <p>Both {@link #onCues(List)} and {@link #onCues(CueGroup)} are called when there is a change
|
||||
* in the cues You should only implement one or the other.
|
||||
*/
|
||||
default void onCues(CueGroup cueGroup) {}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ import androidx.media3.common.C;
|
||||
import androidx.media3.common.Format;
|
||||
import androidx.media3.common.MimeTypes;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.common.util.Log;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.common.util.Util;
|
||||
@ -395,6 +396,7 @@ public final class TextRenderer extends BaseRenderer implements Callback {
|
||||
|
||||
private void invokeUpdateOutputInternal(List<Cue> cues) {
|
||||
output.onCues(cues);
|
||||
output.onCues(new CueGroup(cues));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -52,12 +52,11 @@ import androidx.media3.common.Timeline;
|
||||
import androidx.media3.common.TrackSelectionParameters;
|
||||
import androidx.media3.common.Tracks;
|
||||
import androidx.media3.common.VideoSize;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.common.util.Consumer;
|
||||
import androidx.media3.common.util.Log;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.common.util.Util;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import java.util.List;
|
||||
@ -1583,9 +1582,9 @@ public class MediaController implements Player {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Cue> getCurrentCues() {
|
||||
public CueGroup getCurrentCues() {
|
||||
verifyApplicationThread();
|
||||
return isConnected() ? impl.getCurrentCues() : ImmutableList.of();
|
||||
return isConnected() ? impl.getCurrentCues() : CueGroup.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1981,7 +1980,7 @@ public class MediaController implements Player {
|
||||
|
||||
void clearVideoTextureView(@Nullable TextureView textureView);
|
||||
|
||||
List<Cue> getCurrentCues();
|
||||
CueGroup getCurrentCues();
|
||||
|
||||
float getVolume();
|
||||
|
||||
|
@ -134,7 +134,7 @@ import androidx.media3.common.Timeline.RemotableTimeline;
|
||||
import androidx.media3.common.Timeline.Window;
|
||||
import androidx.media3.common.TrackSelectionParameters;
|
||||
import androidx.media3.common.VideoSize;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.common.util.BundleableUtil;
|
||||
import androidx.media3.common.util.Clock;
|
||||
import androidx.media3.common.util.ListenerSet;
|
||||
@ -1490,8 +1490,8 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Cue> getCurrentCues() {
|
||||
return playerInfo.cues;
|
||||
public CueGroup getCurrentCues() {
|
||||
return playerInfo.cueGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -2356,6 +2356,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation") // Implementing and calling deprecated listener method.
|
||||
void onPlayerInfoChanged(
|
||||
PlayerInfo newPlayerInfo,
|
||||
@TimelineChangeReason int timelineChangedReason,
|
||||
@ -2427,10 +2428,12 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
/* eventFlag= */ C.INDEX_UNSET,
|
||||
listener -> listener.onAudioAttributesChanged(playerInfo.audioAttributes));
|
||||
}
|
||||
if (!Util.areEqual(oldPlayerInfo.cues, playerInfo.cues)) {
|
||||
if (!oldPlayerInfo.cueGroup.cues.equals(playerInfo.cueGroup.cues)) {
|
||||
// TODO(b/187152483): Set proper event code when available.
|
||||
listeners.queueEvent(
|
||||
/* eventFlag= */ C.INDEX_UNSET, listener -> listener.onCues(playerInfo.cues));
|
||||
/* eventFlag= */ C.INDEX_UNSET, listener -> listener.onCues(playerInfo.cueGroup.cues));
|
||||
listeners.queueEvent(
|
||||
/* eventFlag= */ C.INDEX_UNSET, listener -> listener.onCues(playerInfo.cueGroup));
|
||||
}
|
||||
if (!Util.areEqual(oldPlayerInfo.deviceInfo, playerInfo.deviceInfo)) {
|
||||
// TODO(b/187152483): Set proper event code when available.
|
||||
|
@ -91,7 +91,7 @@ import androidx.media3.common.Timeline;
|
||||
import androidx.media3.common.Timeline.Window;
|
||||
import androidx.media3.common.TrackSelectionParameters;
|
||||
import androidx.media3.common.VideoSize;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.common.util.Clock;
|
||||
import androidx.media3.common.util.ListenerSet;
|
||||
import androidx.media3.common.util.Log;
|
||||
@ -1052,9 +1052,9 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Cue> getCurrentCues() {
|
||||
public CueGroup getCurrentCues() {
|
||||
Log.w(TAG, "Session doesn't support getting Cue");
|
||||
return ImmutableList.of();
|
||||
return CueGroup.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -2042,7 +2042,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
/* playlistMetadata= */ playlistMetadata,
|
||||
/* volume= */ 1.0f,
|
||||
/* audioAttributes= */ audioAttributes,
|
||||
/* cues= */ Collections.emptyList(),
|
||||
/* cueGroup= */ CueGroup.EMPTY,
|
||||
/* deviceInfo= */ deviceInfo,
|
||||
/* deviceVolume= */ deviceVolume,
|
||||
/* deviceMuted= */ deviceMuted,
|
||||
|
@ -62,7 +62,7 @@ import androidx.media3.common.Rating;
|
||||
import androidx.media3.common.Timeline;
|
||||
import androidx.media3.common.TrackSelectionParameters;
|
||||
import androidx.media3.common.VideoSize;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.common.util.Log;
|
||||
import androidx.media3.common.util.Util;
|
||||
import androidx.media3.session.MediaSession.ControllerCb;
|
||||
@ -1016,7 +1016,7 @@ import org.checkerframework.checker.initialization.qual.Initialized;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCues(List<Cue> cues) {
|
||||
public void onCues(CueGroup cueGroup) {
|
||||
@Nullable MediaSessionImpl session = getSession();
|
||||
if (session == null) {
|
||||
return;
|
||||
@ -1026,7 +1026,7 @@ import org.checkerframework.checker.initialization.qual.Initialized;
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
session.playerInfo = new PlayerInfo.Builder(session.playerInfo).setCues(cues).build();
|
||||
session.playerInfo = new PlayerInfo.Builder(session.playerInfo).setCues(cueGroup).build();
|
||||
session.onPlayerInfoChangedHandler.sendPlayerInfoChangedMessage(/* excludeTimeline= */ true);
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,6 @@ import androidx.media3.common.ThumbRating;
|
||||
import androidx.media3.common.Timeline;
|
||||
import androidx.media3.common.Timeline.Period;
|
||||
import androidx.media3.common.Timeline.Window;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.util.Log;
|
||||
import androidx.media3.common.util.Util;
|
||||
import androidx.media3.session.MediaLibraryService.LibraryParams;
|
||||
@ -1267,21 +1266,6 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
return intersectCommandsBuilder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out {@link Cue} objects containing {@link Bitmap}. It is used when transferring cues
|
||||
* between processes to prevent transferring too large data.
|
||||
*/
|
||||
public static ImmutableList<Cue> filterOutBitmapCues(List<Cue> cues) {
|
||||
ImmutableList.Builder<Cue> builder = ImmutableList.builder();
|
||||
for (int i = 0; i < cues.size(); i++) {
|
||||
if (cues.get(i).bitmap != null) {
|
||||
continue;
|
||||
}
|
||||
builder.add(cues.get(i));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static byte[] convertToByteArray(Bitmap bitmap) throws IOException {
|
||||
try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, /* ignored */ 0, stream);
|
||||
|
@ -43,15 +43,13 @@ import androidx.media3.common.Timeline;
|
||||
import androidx.media3.common.Timeline.Window;
|
||||
import androidx.media3.common.TrackSelectionParameters;
|
||||
import androidx.media3.common.VideoSize;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.common.util.Assertions;
|
||||
import androidx.media3.common.util.BundleableUtil;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Information about the player that {@link MediaSession} uses to send its state to {@link
|
||||
@ -75,7 +73,7 @@ import java.util.List;
|
||||
private MediaMetadata playlistMetadata;
|
||||
private float volume;
|
||||
private AudioAttributes audioAttributes;
|
||||
private ImmutableList<Cue> cues;
|
||||
private CueGroup cueGroup;
|
||||
private DeviceInfo deviceInfo;
|
||||
private int deviceVolume;
|
||||
private boolean deviceMuted;
|
||||
@ -106,7 +104,7 @@ import java.util.List;
|
||||
playlistMetadata = playerInfo.playlistMetadata;
|
||||
volume = playerInfo.volume;
|
||||
audioAttributes = playerInfo.audioAttributes;
|
||||
cues = ImmutableList.copyOf(playerInfo.cues);
|
||||
cueGroup = playerInfo.cueGroup;
|
||||
deviceInfo = playerInfo.deviceInfo;
|
||||
deviceVolume = playerInfo.deviceVolume;
|
||||
deviceMuted = playerInfo.deviceMuted;
|
||||
@ -194,8 +192,8 @@ import java.util.List;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setCues(List<Cue> cues) {
|
||||
this.cues = ImmutableList.copyOf(cues);
|
||||
public Builder setCues(CueGroup cueGroup) {
|
||||
this.cueGroup = cueGroup;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -290,7 +288,7 @@ import java.util.List;
|
||||
playlistMetadata,
|
||||
volume,
|
||||
audioAttributes,
|
||||
cues,
|
||||
cueGroup,
|
||||
deviceInfo,
|
||||
deviceVolume,
|
||||
deviceMuted,
|
||||
@ -335,7 +333,7 @@ import java.util.List;
|
||||
MediaMetadata.EMPTY,
|
||||
/* volume= */ 1f,
|
||||
AudioAttributes.DEFAULT,
|
||||
/* cues = */ ImmutableList.of(),
|
||||
/* cueGroup = */ CueGroup.EMPTY,
|
||||
DeviceInfo.UNKNOWN,
|
||||
/* deviceVolume= */ 0,
|
||||
/* deviceMuted= */ false,
|
||||
@ -379,7 +377,7 @@ import java.util.List;
|
||||
|
||||
public final AudioAttributes audioAttributes;
|
||||
|
||||
public final List<Cue> cues;
|
||||
public final CueGroup cueGroup;
|
||||
|
||||
public final DeviceInfo deviceInfo;
|
||||
|
||||
@ -597,7 +595,7 @@ import java.util.List;
|
||||
MediaMetadata playlistMetadata,
|
||||
float volume,
|
||||
AudioAttributes audioAttributes,
|
||||
List<Cue> cues,
|
||||
CueGroup cueGroup,
|
||||
DeviceInfo deviceInfo,
|
||||
int deviceVolume,
|
||||
boolean deviceMuted,
|
||||
@ -626,7 +624,7 @@ import java.util.List;
|
||||
this.playlistMetadata = playlistMetadata;
|
||||
this.volume = volume;
|
||||
this.audioAttributes = audioAttributes;
|
||||
this.cues = cues;
|
||||
this.cueGroup = cueGroup;
|
||||
this.deviceInfo = deviceInfo;
|
||||
this.deviceVolume = deviceVolume;
|
||||
this.deviceMuted = deviceMuted;
|
||||
@ -689,7 +687,7 @@ import java.util.List;
|
||||
FIELD_OLD_POSITION_INFO,
|
||||
FIELD_NEW_POSITION_INFO,
|
||||
FIELD_DISCONTINUITY_REASON,
|
||||
FIELD_CUES,
|
||||
FIELD_CUE_GROUP,
|
||||
FIELD_MEDIA_METADATA,
|
||||
FIELD_SEEK_BACK_INCREMENT_MS,
|
||||
FIELD_SEEK_FORWARD_INCREMENT_MS,
|
||||
@ -721,7 +719,7 @@ import java.util.List;
|
||||
private static final int FIELD_OLD_POSITION_INFO = 21;
|
||||
private static final int FIELD_NEW_POSITION_INFO = 22;
|
||||
private static final int FIELD_DISCONTINUITY_REASON = 23;
|
||||
private static final int FIELD_CUES = 24;
|
||||
private static final int FIELD_CUE_GROUP = 24;
|
||||
private static final int FIELD_MEDIA_METADATA = 25;
|
||||
private static final int FIELD_SEEK_BACK_INCREMENT_MS = 26;
|
||||
private static final int FIELD_SEEK_FORWARD_INCREMENT_MS = 27;
|
||||
@ -759,9 +757,7 @@ import java.util.List;
|
||||
bundle.putFloat(keyForField(FIELD_VOLUME), volume);
|
||||
bundle.putBundle(keyForField(FIELD_AUDIO_ATTRIBUTES), audioAttributes.toBundle());
|
||||
if (!excludeCues) {
|
||||
bundle.putParcelableArrayList(
|
||||
keyForField(FIELD_CUES),
|
||||
BundleableUtil.toBundleArrayList(MediaUtils.filterOutBitmapCues(cues)));
|
||||
bundle.putBundle(keyForField(FIELD_CUE_GROUP), cueGroup.toBundle());
|
||||
}
|
||||
bundle.putBundle(keyForField(FIELD_DEVICE_INFO), deviceInfo.toBundle());
|
||||
bundle.putInt(keyForField(FIELD_DEVICE_VOLUME), deviceVolume);
|
||||
@ -851,11 +847,9 @@ import java.util.List;
|
||||
AudioAttributes.CREATOR,
|
||||
bundle.getBundle(keyForField(FIELD_AUDIO_ATTRIBUTES)),
|
||||
/* defaultValue= */ AudioAttributes.DEFAULT);
|
||||
List<Cue> cues =
|
||||
BundleableUtil.fromBundleNullableList(
|
||||
Cue.CREATOR,
|
||||
bundle.getParcelableArrayList(keyForField(FIELD_CUES)),
|
||||
/* defaultValue= */ ImmutableList.of());
|
||||
CueGroup cueGroup =
|
||||
BundleableUtil.fromNullableBundle(
|
||||
CueGroup.CREATOR, bundle.getBundle(keyForField(FIELD_CUE_GROUP)), CueGroup.EMPTY);
|
||||
@Nullable Bundle deviceInfoBundle = bundle.getBundle(keyForField(FIELD_DEVICE_INFO));
|
||||
DeviceInfo deviceInfo =
|
||||
BundleableUtil.fromNullableBundle(
|
||||
@ -912,7 +906,7 @@ import java.util.List;
|
||||
playlistMetadata,
|
||||
volume,
|
||||
audioAttributes,
|
||||
cues,
|
||||
cueGroup,
|
||||
deviceInfo,
|
||||
deviceVolume,
|
||||
deviceMuted,
|
||||
|
@ -42,7 +42,7 @@ import androidx.media3.common.Player;
|
||||
import androidx.media3.common.Timeline;
|
||||
import androidx.media3.common.TrackSelectionParameters;
|
||||
import androidx.media3.common.VideoSize;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.common.util.Log;
|
||||
import androidx.media3.common.util.Util;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
@ -636,7 +636,7 @@ import java.util.List;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Cue> getCurrentCues() {
|
||||
public CueGroup getCurrentCues() {
|
||||
verifyApplicationThread();
|
||||
return super.getCurrentCues();
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ interface IRemoteMediaSession {
|
||||
void notifySeekBackIncrementChanged(String sessionId, long seekBackIncrementMs);
|
||||
void notifySeekForwardIncrementChanged(String sessionId, long seekForwardIncrementMs);
|
||||
void notifyDeviceVolumeChanged(String sessionId, int volume, boolean muted);
|
||||
void notifyCuesChanged(String sessionId, in List<Bundle> cues);
|
||||
void notifyCuesChanged(String sessionId, in Bundle cueGroup);
|
||||
void notifyDeviceInfoChanged(String sessionId, in Bundle deviceInfo);
|
||||
void notifyMediaMetadataChanged(String sessionId, in Bundle mediaMetadata);
|
||||
void notifyRenderedFirstFrame(String sessionId);
|
||||
|
@ -99,7 +99,7 @@ public class CommonConstants {
|
||||
public static final String KEY_IS_PLAYING_AD = "isPlayingAd";
|
||||
public static final String KEY_CURRENT_AD_GROUP_INDEX = "currentAdGroupIndex";
|
||||
public static final String KEY_CURRENT_AD_INDEX_IN_AD_GROUP = "currentAdIndexInAdGroup";
|
||||
public static final String KEY_CURRENT_CUES = "currentCues";
|
||||
public static final String KEY_CURRENT_CUE_GROUP = "currentCueGroup";
|
||||
public static final String KEY_MEDIA_METADATA = "mediaMetadata";
|
||||
public static final String KEY_MAX_SEEK_TO_PREVIOUS_POSITION_MS = "maxSeekToPreviousPositionMs";
|
||||
public static final String KEY_TRACK_SELECTION_PARAMETERS = "trackSelectionParameters";
|
||||
|
@ -63,6 +63,7 @@ import androidx.media3.common.Timeline;
|
||||
import androidx.media3.common.TrackSelectionParameters;
|
||||
import androidx.media3.common.VideoSize;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.session.RemoteMediaSession.RemoteMockPlayer;
|
||||
import androidx.media3.test.session.common.HandlerThreadTestRule;
|
||||
import androidx.media3.test.session.common.MainLooperTestRule;
|
||||
@ -1842,12 +1843,14 @@ public class MediaControllerListenerTest {
|
||||
List<Cue> testCues = ImmutableList.of(testCue1, testCue2);
|
||||
|
||||
Bundle playerConfig =
|
||||
new RemoteMediaSession.MockPlayerConfigBuilder().setCurrentCues(testCues).build();
|
||||
new RemoteMediaSession.MockPlayerConfigBuilder()
|
||||
.setCurrentCues(new CueGroup(testCues))
|
||||
.build();
|
||||
remoteSession.setPlayer(playerConfig);
|
||||
|
||||
MediaController controller = controllerTestRule.createController(remoteSession.getToken());
|
||||
|
||||
assertThat(threadTestRule.getHandler().postAndSync(controller::getCurrentCues))
|
||||
assertThat(threadTestRule.getHandler().postAndSync(controller::getCurrentCues).cues)
|
||||
.isEqualTo(testCues);
|
||||
}
|
||||
|
||||
@ -1858,7 +1861,9 @@ public class MediaControllerListenerTest {
|
||||
List<Cue> testCues = ImmutableList.of(testCue1, testCue2);
|
||||
|
||||
Bundle playerConfig =
|
||||
new RemoteMediaSession.MockPlayerConfigBuilder().setCurrentCues(testCues).build();
|
||||
new RemoteMediaSession.MockPlayerConfigBuilder()
|
||||
.setCurrentCues(new CueGroup(testCues))
|
||||
.build();
|
||||
remoteSession.setPlayer(playerConfig);
|
||||
|
||||
MediaController controller = controllerTestRule.createController(remoteSession.getToken());
|
||||
@ -1873,7 +1878,7 @@ public class MediaControllerListenerTest {
|
||||
cuesFromParam.clear();
|
||||
cuesFromParam.addAll(cues);
|
||||
cuesFromGetter.clear();
|
||||
cuesFromGetter.addAll(controller.getCurrentCues());
|
||||
cuesFromGetter.addAll(controller.getCurrentCues().cues);
|
||||
latch.countDown();
|
||||
}
|
||||
};
|
||||
@ -1902,14 +1907,16 @@ public class MediaControllerListenerTest {
|
||||
@Override
|
||||
public void onCues(List<Cue> cues) {
|
||||
cuesFromParam.addAll(cues);
|
||||
cuesFromGetter.addAll(controller.getCurrentCues());
|
||||
cuesFromGetter.addAll(controller.getCurrentCues().cues);
|
||||
latch.countDown();
|
||||
}
|
||||
};
|
||||
controller.addListener(listener);
|
||||
|
||||
Bundle playerConfig =
|
||||
new RemoteMediaSession.MockPlayerConfigBuilder().setCurrentCues(testCues).build();
|
||||
new RemoteMediaSession.MockPlayerConfigBuilder()
|
||||
.setCurrentCues(new CueGroup(testCues))
|
||||
.build();
|
||||
remoteSession.setPlayer(playerConfig);
|
||||
|
||||
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
||||
@ -1932,13 +1939,13 @@ public class MediaControllerListenerTest {
|
||||
@Override
|
||||
public void onCues(List<Cue> cues) {
|
||||
cuesFromParam.addAll(cues);
|
||||
cuesFromGetter.addAll(controller.getCurrentCues());
|
||||
cuesFromGetter.addAll(controller.getCurrentCues().cues);
|
||||
latch.countDown();
|
||||
}
|
||||
};
|
||||
threadTestRule.getHandler().postAndSync(() -> controller.addListener(listener));
|
||||
|
||||
remoteSession.getMockPlayer().notifyCuesChanged(testCues);
|
||||
remoteSession.getMockPlayer().notifyCuesChanged(new CueGroup(testCues));
|
||||
|
||||
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
||||
assertThat(cuesFromParam).isEqualTo(testCues);
|
||||
|
@ -20,7 +20,6 @@ import static android.support.v4.media.session.MediaSessionCompat.FLAG_HANDLES_Q
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.service.media.MediaBrowserService;
|
||||
@ -31,7 +30,6 @@ import android.support.v4.media.RatingCompat;
|
||||
import android.support.v4.media.session.MediaControllerCompat;
|
||||
import android.support.v4.media.session.MediaSessionCompat;
|
||||
import android.support.v4.media.session.PlaybackStateCompat;
|
||||
import android.text.SpannedString;
|
||||
import android.text.TextUtils;
|
||||
import androidx.media.AudioAttributesCompat;
|
||||
import androidx.media3.common.AudioAttributes;
|
||||
@ -44,12 +42,10 @@ import androidx.media3.common.Player;
|
||||
import androidx.media3.common.Rating;
|
||||
import androidx.media3.common.StarRating;
|
||||
import androidx.media3.common.ThumbRating;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import androidx.test.filters.SdkSuppress;
|
||||
import androidx.test.filters.SmallTest;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -424,17 +420,6 @@ public final class MediaUtilsTest {
|
||||
assertThat(MediaUtils.convertToAudioAttributesCompat(aa)).isEqualTo(aaCompat);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterOutBitmapCues_dropsBitmap() {
|
||||
Cue textCue = new Cue.Builder().setText(SpannedString.valueOf("text")).build();
|
||||
Cue bitmapCue =
|
||||
new Cue.Builder().setBitmap(Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)).build();
|
||||
List<Cue> filteredCues = MediaUtils.filterOutBitmapCues(ImmutableList.of(textCue, bitmapCue));
|
||||
|
||||
assertThat(filteredCues).hasSize(1);
|
||||
assertThat(filteredCues.get(0)).isEqualTo(textCue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertToCurrentPosition_byDefault_returnsZero() {
|
||||
long currentPositionMs =
|
||||
|
@ -24,7 +24,7 @@ import static androidx.media3.test.session.common.CommonConstants.KEY_CONTENT_DU
|
||||
import static androidx.media3.test.session.common.CommonConstants.KEY_CONTENT_POSITION;
|
||||
import static androidx.media3.test.session.common.CommonConstants.KEY_CURRENT_AD_GROUP_INDEX;
|
||||
import static androidx.media3.test.session.common.CommonConstants.KEY_CURRENT_AD_INDEX_IN_AD_GROUP;
|
||||
import static androidx.media3.test.session.common.CommonConstants.KEY_CURRENT_CUES;
|
||||
import static androidx.media3.test.session.common.CommonConstants.KEY_CURRENT_CUE_GROUP;
|
||||
import static androidx.media3.test.session.common.CommonConstants.KEY_CURRENT_LIVE_OFFSET;
|
||||
import static androidx.media3.test.session.common.CommonConstants.KEY_CURRENT_MEDIA_ITEM_INDEX;
|
||||
import static androidx.media3.test.session.common.CommonConstants.KEY_CURRENT_PERIOD_INDEX;
|
||||
@ -78,7 +78,7 @@ import androidx.media3.common.Player.PositionInfo;
|
||||
import androidx.media3.common.Timeline;
|
||||
import androidx.media3.common.TrackSelectionParameters;
|
||||
import androidx.media3.common.VideoSize;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.common.util.BundleableUtil;
|
||||
import androidx.media3.common.util.Log;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
@ -306,10 +306,9 @@ public class MediaSessionProviderService extends Service {
|
||||
AudioAttributes.CREATOR,
|
||||
config.getBundle(KEY_AUDIO_ATTRIBUTES),
|
||||
player.audioAttributes);
|
||||
@Nullable List<Bundle> cuesBundleList = config.getParcelableArrayList(KEY_CURRENT_CUES);
|
||||
if (cuesBundleList != null) {
|
||||
player.cues = BundleableUtil.fromBundleList(Cue.CREATOR, cuesBundleList);
|
||||
}
|
||||
player.cueGroup =
|
||||
BundleableUtil.fromNullableBundle(
|
||||
CueGroup.CREATOR, config.getBundle(KEY_CURRENT_CUE_GROUP), CueGroup.EMPTY);
|
||||
player.deviceInfo =
|
||||
BundleableUtil.fromNullableBundle(
|
||||
DeviceInfo.CREATOR, config.getBundle(KEY_DEVICE_INFO), player.deviceInfo);
|
||||
@ -886,14 +885,13 @@ public class MediaSessionProviderService extends Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyCuesChanged(String sessionId, List<Bundle> cueBundleList)
|
||||
throws RemoteException {
|
||||
List<Cue> cues = BundleableUtil.fromBundleList(Cue.CREATOR, cueBundleList);
|
||||
public void notifyCuesChanged(String sessionId, Bundle cueGroupBundle) throws RemoteException {
|
||||
CueGroup cueGroup = CueGroup.CREATOR.fromBundle(cueGroupBundle);
|
||||
runOnHandler(
|
||||
() -> {
|
||||
MediaSession session = sessionMap.get(sessionId);
|
||||
MockPlayer player = (MockPlayer) session.getPlayer();
|
||||
player.cues = cues;
|
||||
player.cueGroup = cueGroup;
|
||||
player.notifyCuesChanged();
|
||||
});
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ import androidx.media3.common.Timeline;
|
||||
import androidx.media3.common.TrackSelectionParameters;
|
||||
import androidx.media3.common.Tracks;
|
||||
import androidx.media3.common.VideoSize;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.common.util.ConditionVariable;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.common.util.Util;
|
||||
@ -234,7 +234,7 @@ public class MockPlayer implements Player {
|
||||
@Nullable public SurfaceView surfaceView;
|
||||
@Nullable public TextureView textureView;
|
||||
public float volume;
|
||||
public List<Cue> cues;
|
||||
public CueGroup cueGroup;
|
||||
public DeviceInfo deviceInfo;
|
||||
public int deviceVolume;
|
||||
public boolean deviceMuted;
|
||||
@ -277,7 +277,7 @@ public class MockPlayer implements Player {
|
||||
repeatMode = Player.REPEAT_MODE_OFF;
|
||||
videoSize = VideoSize.UNKNOWN;
|
||||
volume = 1.0f;
|
||||
cues = ImmutableList.of();
|
||||
cueGroup = CueGroup.EMPTY;
|
||||
deviceInfo = DeviceInfo.UNKNOWN;
|
||||
seekPositionMs = C.TIME_UNSET;
|
||||
seekMediaItemIndex = C.INDEX_UNSET;
|
||||
@ -621,8 +621,8 @@ public class MockPlayer implements Player {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Cue> getCurrentCues() {
|
||||
return cues;
|
||||
public CueGroup getCurrentCues() {
|
||||
return cueGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1134,9 +1134,11 @@ public class MockPlayer implements Player {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation") // Implementing and calling deprecated listener method.
|
||||
public void notifyCuesChanged() {
|
||||
for (Listener listener : listeners) {
|
||||
listener.onCues(cues);
|
||||
listener.onCues(cueGroup.cues);
|
||||
listener.onCues(cueGroup);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ import static androidx.media3.test.session.common.CommonConstants.KEY_CONTENT_DU
|
||||
import static androidx.media3.test.session.common.CommonConstants.KEY_CONTENT_POSITION;
|
||||
import static androidx.media3.test.session.common.CommonConstants.KEY_CURRENT_AD_GROUP_INDEX;
|
||||
import static androidx.media3.test.session.common.CommonConstants.KEY_CURRENT_AD_INDEX_IN_AD_GROUP;
|
||||
import static androidx.media3.test.session.common.CommonConstants.KEY_CURRENT_CUES;
|
||||
import static androidx.media3.test.session.common.CommonConstants.KEY_CURRENT_CUE_GROUP;
|
||||
import static androidx.media3.test.session.common.CommonConstants.KEY_CURRENT_LIVE_OFFSET;
|
||||
import static androidx.media3.test.session.common.CommonConstants.KEY_CURRENT_MEDIA_ITEM_INDEX;
|
||||
import static androidx.media3.test.session.common.CommonConstants.KEY_CURRENT_PERIOD_INDEX;
|
||||
@ -78,7 +78,7 @@ import androidx.media3.common.Player.PositionInfo;
|
||||
import androidx.media3.common.Timeline;
|
||||
import androidx.media3.common.TrackSelectionParameters;
|
||||
import androidx.media3.common.VideoSize;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.common.util.BundleableUtil;
|
||||
import androidx.media3.common.util.Log;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
@ -389,8 +389,8 @@ public class RemoteMediaSession {
|
||||
binder.notifyDeviceVolumeChanged(sessionId, volume, muted);
|
||||
}
|
||||
|
||||
public void notifyCuesChanged(List<Cue> cues) throws RemoteException {
|
||||
binder.notifyCuesChanged(sessionId, BundleableUtil.toBundleList(cues));
|
||||
public void notifyCuesChanged(CueGroup cueGroup) throws RemoteException {
|
||||
binder.notifyCuesChanged(sessionId, cueGroup.toBundle());
|
||||
}
|
||||
|
||||
public void notifyDeviceInfoChanged(DeviceInfo deviceInfo) throws RemoteException {
|
||||
@ -595,8 +595,8 @@ public class RemoteMediaSession {
|
||||
return this;
|
||||
}
|
||||
|
||||
public MockPlayerConfigBuilder setCurrentCues(List<Cue> cues) {
|
||||
bundle.putParcelableArrayList(KEY_CURRENT_CUES, BundleableUtil.toBundleArrayList(cues));
|
||||
public MockPlayerConfigBuilder setCurrentCues(CueGroup cueGroup) {
|
||||
bundle.putBundle(KEY_CURRENT_CUE_GROUP, cueGroup.toBundle());
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ import androidx.media3.common.Timeline;
|
||||
import androidx.media3.common.TrackSelectionParameters;
|
||||
import androidx.media3.common.Tracks;
|
||||
import androidx.media3.common.VideoSize;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import java.util.List;
|
||||
|
||||
@ -346,7 +346,7 @@ public class StubPlayer extends BasePlayer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Cue> getCurrentCues() {
|
||||
public CueGroup getCurrentCues() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
@ -553,7 +553,7 @@ public class PlayerView extends FrameLayout implements AdViewProvider {
|
||||
updateAspectRatio();
|
||||
}
|
||||
if (subtitleView != null && player.isCommandAvailable(COMMAND_GET_TEXT)) {
|
||||
subtitleView.setCues(player.getCurrentCues());
|
||||
subtitleView.setCues(player.getCurrentCues().cues);
|
||||
}
|
||||
player.addListener(componentListener);
|
||||
maybeShowController(false);
|
||||
|
Loading…
x
Reference in New Issue
Block a user