mirror of
https://github.com/androidx/media.git
synced 2025-05-08 08:00:49 +08:00
Merge branch 'dev-v2' of https://github.com/google/ExoPlayer into dev-v2
This commit is contained in:
commit
e77fa14eb0
@ -178,7 +178,10 @@ MediaItem preRollAd = MediaItem.fromUri(preRollAdUri);
|
|||||||
MediaItem contentStart =
|
MediaItem contentStart =
|
||||||
new MediaItem.Builder()
|
new MediaItem.Builder()
|
||||||
.setUri(contentUri)
|
.setUri(contentUri)
|
||||||
.setClipEndPositionMs(120_000)
|
.setClippingConfiguration(
|
||||||
|
new ClippingConfiguration.Builder()
|
||||||
|
.setEndPositionMs(120_000)
|
||||||
|
.build())
|
||||||
.build();
|
.build();
|
||||||
// A mid-roll ad.
|
// A mid-roll ad.
|
||||||
MediaItem midRollAd = MediaItem.fromUri(midRollAdUri);
|
MediaItem midRollAd = MediaItem.fromUri(midRollAdUri);
|
||||||
@ -186,7 +189,10 @@ MediaItem midRollAd = MediaItem.fromUri(midRollAdUri);
|
|||||||
MediaItem contentEnd =
|
MediaItem contentEnd =
|
||||||
new MediaItem.Builder()
|
new MediaItem.Builder()
|
||||||
.setUri(contentUri)
|
.setUri(contentUri)
|
||||||
.setClipStartPositionMs(120_000)
|
.setClippingConfiguration(
|
||||||
|
new ClippingConfiguration.Builder()
|
||||||
|
.setStartPositionMs(120_000)
|
||||||
|
.build())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// Build the playlist.
|
// Build the playlist.
|
||||||
|
19
docs/drm.md
19
docs/drm.md
@ -24,7 +24,8 @@ outlined in the sections below.
|
|||||||
### Key rotation ###
|
### Key rotation ###
|
||||||
|
|
||||||
To play streams with rotating keys, pass `true` to
|
To play streams with rotating keys, pass `true` to
|
||||||
`MediaItem.Builder.setDrmMultiSession` when building the media item.
|
`MediaItem.DrmConfiguration.Builder.setMultiSession` when building the media
|
||||||
|
item.
|
||||||
|
|
||||||
### Multi-key content ###
|
### Multi-key content ###
|
||||||
|
|
||||||
@ -49,8 +50,9 @@ to access the different streams.
|
|||||||
|
|
||||||
In this case, the license server is configured to respond with only the key
|
In this case, the license server is configured to respond with only the key
|
||||||
specified in the request. Multi-key content can be played with this license
|
specified in the request. Multi-key content can be played with this license
|
||||||
server configuration by passing `true` to `MediaItem.Builder.setDrmMultiSession`
|
server configuration by passing `true` to
|
||||||
when building the media item.
|
`MediaItem.DrmConfiguration.Builder.setMultiSession` when building the media
|
||||||
|
item.
|
||||||
|
|
||||||
We do not recommend configuring your license server to behave in this way. It
|
We do not recommend configuring your license server to behave in this way. It
|
||||||
requires extra license requests to play multi-key content, which is less
|
requires extra license requests to play multi-key content, which is less
|
||||||
@ -59,9 +61,9 @@ efficient and robust than the alternative described above.
|
|||||||
### Offline keys ###
|
### Offline keys ###
|
||||||
|
|
||||||
An offline key set can be loaded by passing the key set ID to
|
An offline key set can be loaded by passing the key set ID to
|
||||||
`MediaItem.Builder.setDrmKeySetId` when building the media item. This
|
`MediaItem.DrmConfiguration.Builder.setKeySetId` when building the media item.
|
||||||
allows playback using the keys stored in the offline key set with the specified
|
This allows playback using the keys stored in the offline key set with the
|
||||||
ID.
|
specified ID.
|
||||||
|
|
||||||
{% include known-issue-box.html issue-id="3872" description="Only one offline
|
{% include known-issue-box.html issue-id="3872" description="Only one offline
|
||||||
key set can be specified per playback. As a result, offline playback of
|
key set can be specified per playback. As a result, offline playback of
|
||||||
@ -75,8 +77,9 @@ clear content as are used when playing encrypted content. When media contains
|
|||||||
both clear and encrypted sections, you may want to use placeholder `DrmSessions`
|
both clear and encrypted sections, you may want to use placeholder `DrmSessions`
|
||||||
to avoid re-creation of decoders when transitions between clear and encrypted
|
to avoid re-creation of decoders when transitions between clear and encrypted
|
||||||
sections occur. Use of placeholder `DrmSessions` for audio and video tracks can
|
sections occur. Use of placeholder `DrmSessions` for audio and video tracks can
|
||||||
be enabled by passing `true` to `MediaItem.Builder.setDrmSessionForClearPeriods`
|
be enabled by passing `true` to
|
||||||
when building the media item.
|
`MediaItem.DrmConfiguration.Builder.forceSessionsForAudioAndVideoTracks` when
|
||||||
|
building the media item.
|
||||||
|
|
||||||
### Using a custom DrmSessionManager ###
|
### Using a custom DrmSessionManager ###
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ components to support additional modes when playing live streams.
|
|||||||
|
|
||||||
By default, ExoPlayer uses live playback parameters defined by the media. If you
|
By default, ExoPlayer uses live playback parameters defined by the media. If you
|
||||||
want to configure the live playback parameters yourself, you can set them on a
|
want to configure the live playback parameters yourself, you can set them on a
|
||||||
per `MediaItem` basis by calling `MediaItem.Builder.setLiveXXX` methods. If
|
per `MediaItem` basis by calling `MediaItem.Builder.setLiveConfiguration`. If
|
||||||
you'd like to set these values globally for all items, you can set them on the
|
you'd like to set these values globally for all items, you can set them on the
|
||||||
`DefaultMediaSourceFactory` provided to the player. In both cases, the provided
|
`DefaultMediaSourceFactory` provided to the player. In both cases, the provided
|
||||||
values will override parameters defined by the media.
|
values will override parameters defined by the media.
|
||||||
|
@ -86,17 +86,17 @@ To sideload subtitle tracks, `MediaItem.Subtitle` instances can be added when
|
|||||||
when building a media item:
|
when building a media item:
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
MediaItem.Subtitle subtitle =
|
MediaItem.SubtitleConfiguration subtitle =
|
||||||
new MediaItem.Subtitle(
|
new MediaItem.SubtitleConfiguration.Builder(subtitleUri)
|
||||||
subtitleUri,
|
.setMimeType(MimeTypes.APPLICATION_SUBRIP) // The correct MIME type (required).
|
||||||
MimeTypes.APPLICATION_SUBRIP, // The correct MIME type.
|
.setLanguage(language) // The subtitle language (optional).
|
||||||
language, // The subtitle language. May be null.
|
.setSelectionFlags(selectionFlags) // Selection flags for the track (optional).
|
||||||
selectionFlags); // Selection flags for the track.
|
.build();
|
||||||
|
MediaItem mediaItem =
|
||||||
MediaItem mediaItem = new MediaItem.Builder()
|
new MediaItem.Builder()
|
||||||
.setUri(videoUri)
|
.setUri(videoUri)
|
||||||
.setSubtitles(Lists.newArrayList(subtitle))
|
.setSubtitleConfigurations(ImmutableList.of(subtitle))
|
||||||
.build();
|
.build();
|
||||||
~~~
|
~~~
|
||||||
{: .language-java}
|
{: .language-java}
|
||||||
|
|
||||||
@ -110,11 +110,15 @@ It's possible to clip the content referred to by a media item by setting custom
|
|||||||
start and end positions:
|
start and end positions:
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
MediaItem mediaItem = new MediaItem.Builder()
|
MediaItem mediaItem =
|
||||||
.setUri(videoUri)
|
new MediaItem.Builder()
|
||||||
.setClipStartPositionMs(startPositionMs)
|
.setUri(videoUri)
|
||||||
.setClipEndPositionMs(endPositionMs)
|
.setClippingConfiguration(
|
||||||
.build();
|
new ClippingConfiguration.Builder()
|
||||||
|
.setStartPositionMs(startPositionMs)
|
||||||
|
.setEndPositionMs(endPositionMs)
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
~~~
|
~~~
|
||||||
{: .language-java}
|
{: .language-java}
|
||||||
|
|
||||||
|
@ -15,9 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.ext.ima;
|
package com.google.android.exoplayer2.ext.ima;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
|
import com.google.android.exoplayer2.ExoPlayer;
|
||||||
import com.google.android.exoplayer2.MediaItem;
|
import com.google.android.exoplayer2.MediaItem;
|
||||||
import com.google.android.exoplayer2.Player;
|
import com.google.android.exoplayer2.Player;
|
||||||
import com.google.android.exoplayer2.Timeline;
|
import com.google.android.exoplayer2.Timeline;
|
||||||
@ -29,8 +29,8 @@ import com.google.android.exoplayer2.util.Clock;
|
|||||||
import com.google.android.exoplayer2.util.ListenerSet;
|
import com.google.android.exoplayer2.util.ListenerSet;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
|
|
||||||
/** A fake player for testing content/ad playback. */
|
/** A fake {@link ExoPlayer} for testing content/ad playback. */
|
||||||
/* package */ final class FakePlayer extends StubExoPlayer {
|
/* package */ final class FakeExoPlayer extends StubExoPlayer {
|
||||||
|
|
||||||
private final ListenerSet<Listener> listeners;
|
private final ListenerSet<Listener> listeners;
|
||||||
private final Timeline.Period period;
|
private final Timeline.Period period;
|
||||||
@ -48,8 +48,7 @@ import com.google.android.exoplayer2.util.Util;
|
|||||||
private int adGroupIndex;
|
private int adGroupIndex;
|
||||||
private int adIndexInAdGroup;
|
private int adIndexInAdGroup;
|
||||||
|
|
||||||
public FakePlayer(Context context) {
|
public FakeExoPlayer() {
|
||||||
super(context);
|
|
||||||
listeners =
|
listeners =
|
||||||
new ListenerSet<>(
|
new ListenerSet<>(
|
||||||
Looper.getMainLooper(),
|
Looper.getMainLooper(),
|
@ -139,13 +139,13 @@ public final class ImaAdsLoaderTest {
|
|||||||
private ContentProgressProvider contentProgressProvider;
|
private ContentProgressProvider contentProgressProvider;
|
||||||
private VideoAdPlayer videoAdPlayer;
|
private VideoAdPlayer videoAdPlayer;
|
||||||
private TestAdsLoaderListener adsLoaderListener;
|
private TestAdsLoaderListener adsLoaderListener;
|
||||||
private FakePlayer fakePlayer;
|
private FakeExoPlayer fakePlayer;
|
||||||
private ImaAdsLoader imaAdsLoader;
|
private ImaAdsLoader imaAdsLoader;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
setupMocks();
|
setupMocks();
|
||||||
fakePlayer = new FakePlayer(getApplicationContext());
|
fakePlayer = new FakeExoPlayer();
|
||||||
adViewGroup = new FrameLayout(getApplicationContext());
|
adViewGroup = new FrameLayout(getApplicationContext());
|
||||||
View adOverlayView = new View(getApplicationContext());
|
View adOverlayView = new View(getApplicationContext());
|
||||||
adViewProvider =
|
adViewProvider =
|
||||||
|
@ -49,7 +49,6 @@ dependencies {
|
|||||||
testImplementation 'junit:junit:' + junitVersion
|
testImplementation 'junit:junit:' + junitVersion
|
||||||
testImplementation 'com.google.truth:truth:' + truthVersion
|
testImplementation 'com.google.truth:truth:' + truthVersion
|
||||||
testImplementation 'org.robolectric:robolectric:' + robolectricVersion
|
testImplementation 'org.robolectric:robolectric:' + robolectricVersion
|
||||||
testImplementation project(modulePrefix + 'library-core')
|
|
||||||
testImplementation project(modulePrefix + 'testutils')
|
testImplementation project(modulePrefix + 'testutils')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ import static com.google.common.truth.Truth.assertThat;
|
|||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import com.google.android.exoplayer2.drm.DrmInitData;
|
import com.google.android.exoplayer2.drm.DrmInitData;
|
||||||
import com.google.android.exoplayer2.metadata.Metadata;
|
import com.google.android.exoplayer2.metadata.Metadata;
|
||||||
import com.google.android.exoplayer2.metadata.id3.TextInformationFrame;
|
import com.google.android.exoplayer2.testutil.FakeMetadataEntry;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
import com.google.android.exoplayer2.video.ColorInfo;
|
import com.google.android.exoplayer2.video.ColorInfo;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -65,10 +65,7 @@ public final class FormatTest {
|
|||||||
|
|
||||||
byte[] projectionData = new byte[] {1, 2, 3};
|
byte[] projectionData = new byte[] {1, 2, 3};
|
||||||
|
|
||||||
Metadata metadata =
|
Metadata metadata = new Metadata(new FakeMetadataEntry("id1"), new FakeMetadataEntry("id2"));
|
||||||
new Metadata(
|
|
||||||
new TextInformationFrame("id1", "description1", "value1"),
|
|
||||||
new TextInformationFrame("id2", "description2", "value2"));
|
|
||||||
|
|
||||||
ColorInfo colorInfo =
|
ColorInfo colorInfo =
|
||||||
new ColorInfo(
|
new ColorInfo(
|
||||||
|
@ -24,10 +24,8 @@ import static org.mockito.ArgumentMatchers.same;
|
|||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import com.google.android.exoplayer2.testutil.StubExoPlayer;
|
import com.google.android.exoplayer2.testutil.StubPlayer;
|
||||||
import com.google.android.exoplayer2.util.FlagSet;
|
import com.google.android.exoplayer2.util.FlagSet;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
@ -48,7 +46,7 @@ public class ForwardingPlayerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addListener_addsForwardingListener() {
|
public void addListener_addsForwardingListener() {
|
||||||
FakePlayer player = new FakePlayer(ApplicationProvider.getApplicationContext());
|
FakePlayer player = new FakePlayer();
|
||||||
Player.Listener listener1 = mock(Player.Listener.class);
|
Player.Listener listener1 = mock(Player.Listener.class);
|
||||||
Player.Listener listener2 = mock(Player.Listener.class);
|
Player.Listener listener2 = mock(Player.Listener.class);
|
||||||
|
|
||||||
@ -63,7 +61,7 @@ public class ForwardingPlayerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void removeListener_removesForwardingListener() {
|
public void removeListener_removesForwardingListener() {
|
||||||
FakePlayer player = new FakePlayer(ApplicationProvider.getApplicationContext());
|
FakePlayer player = new FakePlayer();
|
||||||
Player.Listener listener1 = mock(Player.Listener.class);
|
Player.Listener listener1 = mock(Player.Listener.class);
|
||||||
Player.Listener listener2 = mock(Player.Listener.class);
|
Player.Listener listener2 = mock(Player.Listener.class);
|
||||||
ForwardingPlayer forwardingPlayer = new ForwardingPlayer(player);
|
ForwardingPlayer forwardingPlayer = new ForwardingPlayer(player);
|
||||||
@ -81,7 +79,7 @@ public class ForwardingPlayerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onEvents_passesForwardingPlayerAsArgument() {
|
public void onEvents_passesForwardingPlayerAsArgument() {
|
||||||
FakePlayer player = new FakePlayer(ApplicationProvider.getApplicationContext());
|
FakePlayer player = new FakePlayer();
|
||||||
Player.Listener listener = mock(Player.Listener.class);
|
Player.Listener listener = mock(Player.Listener.class);
|
||||||
ForwardingPlayer forwardingPlayer = new ForwardingPlayer(player);
|
ForwardingPlayer forwardingPlayer = new ForwardingPlayer(player);
|
||||||
forwardingPlayer.addListener(listener);
|
forwardingPlayer.addListener(listener);
|
||||||
@ -180,14 +178,10 @@ public class ForwardingPlayerTest {
|
|||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class FakePlayer extends StubExoPlayer {
|
private static class FakePlayer extends StubPlayer {
|
||||||
|
|
||||||
private final Set<Listener> listeners = new HashSet<>();
|
private final Set<Listener> listeners = new HashSet<>();
|
||||||
|
|
||||||
public FakePlayer(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addListener(Listener listener) {
|
public void addListener(Listener listener) {
|
||||||
listeners.add(listener);
|
listeners.add(listener);
|
||||||
|
@ -19,7 +19,7 @@ import static com.google.common.truth.Truth.assertThat;
|
|||||||
|
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import com.google.android.exoplayer2.metadata.id3.BinaryFrame;
|
import com.google.android.exoplayer2.testutil.FakeMetadataEntry;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
@ -30,8 +30,7 @@ public class MetadataTest {
|
|||||||
@Test
|
@Test
|
||||||
public void parcelable() {
|
public void parcelable() {
|
||||||
Metadata metadataToParcel =
|
Metadata metadataToParcel =
|
||||||
new Metadata(
|
new Metadata(new FakeMetadataEntry("id1"), new FakeMetadataEntry("id2"));
|
||||||
new BinaryFrame("id1", new byte[] {1}), new BinaryFrame("id2", new byte[] {2}));
|
|
||||||
|
|
||||||
Parcel parcel = Parcel.obtain();
|
Parcel parcel = Parcel.obtain();
|
||||||
metadataToParcel.writeToParcel(parcel, 0);
|
metadataToParcel.writeToParcel(parcel, 0);
|
||||||
|
@ -19,10 +19,8 @@ import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
|
|||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import com.google.android.exoplayer2.Bundleable;
|
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.Format;
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride;
|
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelectionOverrides.TrackSelectionOverride;
|
import com.google.android.exoplayer2.trackselection.TrackSelectionOverrides.TrackSelectionOverride;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
@ -183,17 +181,4 @@ public final class TrackSelectionParametersTest {
|
|||||||
assertThat(parameters.viewportHeight).isEqualTo(Integer.MAX_VALUE);
|
assertThat(parameters.viewportHeight).isEqualTo(Integer.MAX_VALUE);
|
||||||
assertThat(parameters.viewportOrientationMayChange).isTrue();
|
assertThat(parameters.viewportOrientationMayChange).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Tests {@link SelectionOverride}'s {@link Bundleable} implementation. */
|
|
||||||
@Test
|
|
||||||
public void roundTripViaBundle_ofSelectionOverride_yieldsEqualInstance() {
|
|
||||||
SelectionOverride selectionOverrideToBundle =
|
|
||||||
new SelectionOverride(/* groupIndex= */ 1, /* tracks...= */ 2, 3);
|
|
||||||
|
|
||||||
SelectionOverride selectionOverrideFromBundle =
|
|
||||||
DefaultTrackSelector.SelectionOverride.CREATOR.fromBundle(
|
|
||||||
selectionOverrideToBundle.toBundle());
|
|
||||||
|
|
||||||
assertThat(selectionOverrideFromBundle).isEqualTo(selectionOverrideToBundle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ public final class AtomicFileTest {
|
|||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
tempFolder =
|
tempFolder =
|
||||||
Util.createTempDirectory(ApplicationProvider.getApplicationContext(), "ExoPlayerTest");
|
Util.createTempDirectory(ApplicationProvider.getApplicationContext(), "AtomicFileTest");
|
||||||
file = new File(tempFolder, "atomicFile");
|
file = new File(tempFolder, "atomicFile");
|
||||||
atomicFile = new AtomicFile(file);
|
atomicFile = new AtomicFile(file);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ import org.junit.runner.RunWith;
|
|||||||
public class MediaFormatUtilTest {
|
public class MediaFormatUtilTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createMediaFormatFromEmptyExoPlayerFormat_generatesExpectedEntries() {
|
public void createMediaFormatFromFormat_withEmptyFormat_generatesExpectedEntries() {
|
||||||
MediaFormat mediaFormat =
|
MediaFormat mediaFormat =
|
||||||
MediaFormatUtil.createMediaFormatFromFormat(new Format.Builder().build());
|
MediaFormatUtil.createMediaFormatFromFormat(new Format.Builder().build());
|
||||||
// Assert that no invalid keys are accidentally being populated.
|
// Assert that no invalid keys are accidentally being populated.
|
||||||
@ -59,7 +59,7 @@ public class MediaFormatUtilTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createMediaFormatFromPopulatedExoPlayerFormat_generatesExpectedMediaFormatEntries() {
|
public void createMediaFormatFromFormat_withPopulatedFormat_generatesExpectedEntries() {
|
||||||
Format format =
|
Format format =
|
||||||
new Format.Builder()
|
new Format.Builder()
|
||||||
.setAverageBitrate(1)
|
.setAverageBitrate(1)
|
||||||
@ -145,7 +145,7 @@ public class MediaFormatUtilTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createMediaFormatWithExoPlayerPcmEncoding_containsExoPlayerSpecificEncoding() {
|
public void createMediaFormatFromFormat_withPcmEncoding_setsCustomPcmEncodingEntry() {
|
||||||
Format format = new Format.Builder().setPcmEncoding(C.ENCODING_PCM_32BIT).build();
|
Format format = new Format.Builder().setPcmEncoding(C.ENCODING_PCM_32BIT).build();
|
||||||
MediaFormat mediaFormat = MediaFormatUtil.createMediaFormatFromFormat(format);
|
MediaFormat mediaFormat = MediaFormatUtil.createMediaFormatFromFormat(format);
|
||||||
assertThat(mediaFormat.getInteger(MediaFormatUtil.KEY_EXO_PCM_ENCODING))
|
assertThat(mediaFormat.getInteger(MediaFormatUtil.KEY_EXO_PCM_ENCODING))
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
package com.google.android.exoplayer2;
|
package com.google.android.exoplayer2;
|
||||||
|
|
||||||
import static com.google.android.exoplayer2.util.Assertions.checkArgument;
|
import static com.google.android.exoplayer2.util.Assertions.checkArgument;
|
||||||
|
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
|
||||||
import static com.google.android.exoplayer2.util.Assertions.checkState;
|
import static com.google.android.exoplayer2.util.Assertions.checkState;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@ -59,6 +60,7 @@ import com.google.android.exoplayer2.video.MediaCodecVideoRenderer;
|
|||||||
import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
|
import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
|
||||||
import com.google.android.exoplayer2.video.VideoSize;
|
import com.google.android.exoplayer2.video.VideoSize;
|
||||||
import com.google.android.exoplayer2.video.spherical.CameraMotionListener;
|
import com.google.android.exoplayer2.video.spherical.CameraMotionListener;
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -366,12 +368,12 @@ public interface ExoPlayer extends Player {
|
|||||||
|
|
||||||
/* package */ Clock clock;
|
/* package */ Clock clock;
|
||||||
/* package */ long foregroundModeTimeoutMs;
|
/* package */ long foregroundModeTimeoutMs;
|
||||||
/* package */ RenderersFactory renderersFactory;
|
/* package */ Supplier<RenderersFactory> renderersFactorySupplier;
|
||||||
/* package */ MediaSourceFactory mediaSourceFactory;
|
/* package */ Supplier<MediaSourceFactory> mediaSourceFactorySupplier;
|
||||||
/* package */ TrackSelector trackSelector;
|
/* package */ Supplier<TrackSelector> trackSelectorSupplier;
|
||||||
/* package */ LoadControl loadControl;
|
/* package */ Supplier<LoadControl> loadControlSupplier;
|
||||||
/* package */ BandwidthMeter bandwidthMeter;
|
/* package */ Supplier<BandwidthMeter> bandwidthMeterSupplier;
|
||||||
/* package */ AnalyticsCollector analyticsCollector;
|
/* package */ Supplier<AnalyticsCollector> analyticsCollectorSupplier;
|
||||||
/* package */ Looper looper;
|
/* package */ Looper looper;
|
||||||
@Nullable /* package */ PriorityTaskManager priorityTaskManager;
|
@Nullable /* package */ PriorityTaskManager priorityTaskManager;
|
||||||
/* package */ AudioAttributes audioAttributes;
|
/* package */ AudioAttributes audioAttributes;
|
||||||
@ -437,8 +439,8 @@ public interface ExoPlayer extends Player {
|
|||||||
public Builder(Context context) {
|
public Builder(Context context) {
|
||||||
this(
|
this(
|
||||||
context,
|
context,
|
||||||
new DefaultRenderersFactory(context),
|
() -> new DefaultRenderersFactory(context),
|
||||||
new DefaultMediaSourceFactory(context, new DefaultExtractorsFactory()));
|
() -> new DefaultMediaSourceFactory(context, new DefaultExtractorsFactory()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -456,8 +458,8 @@ public interface ExoPlayer extends Player {
|
|||||||
public Builder(Context context, RenderersFactory renderersFactory) {
|
public Builder(Context context, RenderersFactory renderersFactory) {
|
||||||
this(
|
this(
|
||||||
context,
|
context,
|
||||||
renderersFactory,
|
() -> renderersFactory,
|
||||||
new DefaultMediaSourceFactory(context, new DefaultExtractorsFactory()));
|
() -> new DefaultMediaSourceFactory(context, new DefaultExtractorsFactory()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -474,7 +476,7 @@ public interface ExoPlayer extends Player {
|
|||||||
* MediaItem}.
|
* MediaItem}.
|
||||||
*/
|
*/
|
||||||
public Builder(Context context, MediaSourceFactory mediaSourceFactory) {
|
public Builder(Context context, MediaSourceFactory mediaSourceFactory) {
|
||||||
this(context, new DefaultRenderersFactory(context), mediaSourceFactory);
|
this(context, () -> new DefaultRenderersFactory(context), () -> mediaSourceFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -494,14 +496,7 @@ public interface ExoPlayer extends Player {
|
|||||||
*/
|
*/
|
||||||
public Builder(
|
public Builder(
|
||||||
Context context, RenderersFactory renderersFactory, MediaSourceFactory mediaSourceFactory) {
|
Context context, RenderersFactory renderersFactory, MediaSourceFactory mediaSourceFactory) {
|
||||||
this(
|
this(context, () -> renderersFactory, () -> mediaSourceFactory);
|
||||||
context,
|
|
||||||
renderersFactory,
|
|
||||||
mediaSourceFactory,
|
|
||||||
new DefaultTrackSelector(context),
|
|
||||||
new DefaultLoadControl(),
|
|
||||||
DefaultBandwidthMeter.getSingletonInstance(context),
|
|
||||||
new AnalyticsCollector(Clock.DEFAULT));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -527,13 +522,48 @@ public interface ExoPlayer extends Player {
|
|||||||
LoadControl loadControl,
|
LoadControl loadControl,
|
||||||
BandwidthMeter bandwidthMeter,
|
BandwidthMeter bandwidthMeter,
|
||||||
AnalyticsCollector analyticsCollector) {
|
AnalyticsCollector analyticsCollector) {
|
||||||
|
this(
|
||||||
|
context,
|
||||||
|
() -> renderersFactory,
|
||||||
|
() -> mediaSourceFactory,
|
||||||
|
() -> trackSelector,
|
||||||
|
() -> loadControl,
|
||||||
|
() -> bandwidthMeter,
|
||||||
|
() -> analyticsCollector);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Builder(
|
||||||
|
Context context,
|
||||||
|
Supplier<RenderersFactory> renderersFactorySupplier,
|
||||||
|
Supplier<MediaSourceFactory> mediaSourceFactorySupplier) {
|
||||||
|
this(
|
||||||
|
context,
|
||||||
|
renderersFactorySupplier,
|
||||||
|
mediaSourceFactorySupplier,
|
||||||
|
() -> new DefaultTrackSelector(context),
|
||||||
|
DefaultLoadControl::new,
|
||||||
|
() -> DefaultBandwidthMeter.getSingletonInstance(context),
|
||||||
|
/* analyticsCollectorSupplier= */ null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Builder(
|
||||||
|
Context context,
|
||||||
|
Supplier<RenderersFactory> renderersFactorySupplier,
|
||||||
|
Supplier<MediaSourceFactory> mediaSourceFactorySupplier,
|
||||||
|
Supplier<TrackSelector> trackSelectorSupplier,
|
||||||
|
Supplier<LoadControl> loadControlSupplier,
|
||||||
|
Supplier<BandwidthMeter> bandwidthMeterSupplier,
|
||||||
|
@Nullable Supplier<AnalyticsCollector> analyticsCollectorSupplier) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.renderersFactory = renderersFactory;
|
this.renderersFactorySupplier = renderersFactorySupplier;
|
||||||
this.mediaSourceFactory = mediaSourceFactory;
|
this.mediaSourceFactorySupplier = mediaSourceFactorySupplier;
|
||||||
this.trackSelector = trackSelector;
|
this.trackSelectorSupplier = trackSelectorSupplier;
|
||||||
this.loadControl = loadControl;
|
this.loadControlSupplier = loadControlSupplier;
|
||||||
this.bandwidthMeter = bandwidthMeter;
|
this.bandwidthMeterSupplier = bandwidthMeterSupplier;
|
||||||
this.analyticsCollector = analyticsCollector;
|
this.analyticsCollectorSupplier =
|
||||||
|
analyticsCollectorSupplier != null
|
||||||
|
? analyticsCollectorSupplier
|
||||||
|
: () -> new AnalyticsCollector(checkNotNull(clock));
|
||||||
looper = Util.getCurrentOrMainLooper();
|
looper = Util.getCurrentOrMainLooper();
|
||||||
audioAttributes = AudioAttributes.DEFAULT;
|
audioAttributes = AudioAttributes.DEFAULT;
|
||||||
wakeMode = C.WAKE_MODE_NONE;
|
wakeMode = C.WAKE_MODE_NONE;
|
||||||
@ -573,7 +603,7 @@ public interface ExoPlayer extends Player {
|
|||||||
*/
|
*/
|
||||||
public Builder setRenderersFactory(RenderersFactory renderersFactory) {
|
public Builder setRenderersFactory(RenderersFactory renderersFactory) {
|
||||||
checkState(!buildCalled);
|
checkState(!buildCalled);
|
||||||
this.renderersFactory = renderersFactory;
|
this.renderersFactorySupplier = () -> renderersFactory;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -586,7 +616,7 @@ public interface ExoPlayer extends Player {
|
|||||||
*/
|
*/
|
||||||
public Builder setMediaSourceFactory(MediaSourceFactory mediaSourceFactory) {
|
public Builder setMediaSourceFactory(MediaSourceFactory mediaSourceFactory) {
|
||||||
checkState(!buildCalled);
|
checkState(!buildCalled);
|
||||||
this.mediaSourceFactory = mediaSourceFactory;
|
this.mediaSourceFactorySupplier = () -> mediaSourceFactory;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -599,7 +629,7 @@ public interface ExoPlayer extends Player {
|
|||||||
*/
|
*/
|
||||||
public Builder setTrackSelector(TrackSelector trackSelector) {
|
public Builder setTrackSelector(TrackSelector trackSelector) {
|
||||||
checkState(!buildCalled);
|
checkState(!buildCalled);
|
||||||
this.trackSelector = trackSelector;
|
this.trackSelectorSupplier = () -> trackSelector;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -612,7 +642,7 @@ public interface ExoPlayer extends Player {
|
|||||||
*/
|
*/
|
||||||
public Builder setLoadControl(LoadControl loadControl) {
|
public Builder setLoadControl(LoadControl loadControl) {
|
||||||
checkState(!buildCalled);
|
checkState(!buildCalled);
|
||||||
this.loadControl = loadControl;
|
this.loadControlSupplier = () -> loadControl;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -625,7 +655,7 @@ public interface ExoPlayer extends Player {
|
|||||||
*/
|
*/
|
||||||
public Builder setBandwidthMeter(BandwidthMeter bandwidthMeter) {
|
public Builder setBandwidthMeter(BandwidthMeter bandwidthMeter) {
|
||||||
checkState(!buildCalled);
|
checkState(!buildCalled);
|
||||||
this.bandwidthMeter = bandwidthMeter;
|
this.bandwidthMeterSupplier = () -> bandwidthMeter;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -652,7 +682,7 @@ public interface ExoPlayer extends Player {
|
|||||||
*/
|
*/
|
||||||
public Builder setAnalyticsCollector(AnalyticsCollector analyticsCollector) {
|
public Builder setAnalyticsCollector(AnalyticsCollector analyticsCollector) {
|
||||||
checkState(!buildCalled);
|
checkState(!buildCalled);
|
||||||
this.analyticsCollector = analyticsCollector;
|
this.analyticsCollectorSupplier = () -> analyticsCollector;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ import static com.google.android.exoplayer2.Renderer.MSG_SET_SKIP_SILENCE_ENABLE
|
|||||||
import static com.google.android.exoplayer2.Renderer.MSG_SET_VIDEO_FRAME_METADATA_LISTENER;
|
import static com.google.android.exoplayer2.Renderer.MSG_SET_VIDEO_FRAME_METADATA_LISTENER;
|
||||||
import static com.google.android.exoplayer2.Renderer.MSG_SET_VIDEO_OUTPUT;
|
import static com.google.android.exoplayer2.Renderer.MSG_SET_VIDEO_OUTPUT;
|
||||||
import static com.google.android.exoplayer2.Renderer.MSG_SET_VOLUME;
|
import static com.google.android.exoplayer2.Renderer.MSG_SET_VOLUME;
|
||||||
|
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
@ -66,7 +67,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
|||||||
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters;
|
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters;
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
||||||
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
|
||||||
import com.google.android.exoplayer2.util.Clock;
|
import com.google.android.exoplayer2.util.Clock;
|
||||||
import com.google.android.exoplayer2.util.ConditionVariable;
|
import com.google.android.exoplayer2.util.ConditionVariable;
|
||||||
import com.google.android.exoplayer2.util.Log;
|
import com.google.android.exoplayer2.util.Log;
|
||||||
@ -409,12 +409,14 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
Clock clock,
|
Clock clock,
|
||||||
Looper applicationLooper) {
|
Looper applicationLooper) {
|
||||||
this(
|
this(
|
||||||
new ExoPlayer.Builder(context, renderersFactory)
|
new ExoPlayer.Builder(
|
||||||
.setTrackSelector(trackSelector)
|
context,
|
||||||
.setMediaSourceFactory(mediaSourceFactory)
|
renderersFactory,
|
||||||
.setLoadControl(loadControl)
|
mediaSourceFactory,
|
||||||
.setBandwidthMeter(bandwidthMeter)
|
trackSelector,
|
||||||
.setAnalyticsCollector(analyticsCollector)
|
loadControl,
|
||||||
|
bandwidthMeter,
|
||||||
|
analyticsCollector)
|
||||||
.setUseLazyPreparation(useLazyPreparation)
|
.setUseLazyPreparation(useLazyPreparation)
|
||||||
.setClock(clock)
|
.setClock(clock)
|
||||||
.setLooper(applicationLooper));
|
.setLooper(applicationLooper));
|
||||||
@ -431,7 +433,7 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
constructorFinished = new ConditionVariable();
|
constructorFinished = new ConditionVariable();
|
||||||
try {
|
try {
|
||||||
applicationContext = builder.context.getApplicationContext();
|
applicationContext = builder.context.getApplicationContext();
|
||||||
analyticsCollector = builder.analyticsCollector;
|
analyticsCollector = builder.analyticsCollectorSupplier.get();
|
||||||
priorityTaskManager = builder.priorityTaskManager;
|
priorityTaskManager = builder.priorityTaskManager;
|
||||||
audioAttributes = builder.audioAttributes;
|
audioAttributes = builder.audioAttributes;
|
||||||
videoScalingMode = builder.videoScalingMode;
|
videoScalingMode = builder.videoScalingMode;
|
||||||
@ -443,12 +445,15 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
listeners = new CopyOnWriteArraySet<>();
|
listeners = new CopyOnWriteArraySet<>();
|
||||||
Handler eventHandler = new Handler(builder.looper);
|
Handler eventHandler = new Handler(builder.looper);
|
||||||
renderers =
|
renderers =
|
||||||
builder.renderersFactory.createRenderers(
|
builder
|
||||||
eventHandler,
|
.renderersFactorySupplier
|
||||||
componentListener,
|
.get()
|
||||||
componentListener,
|
.createRenderers(
|
||||||
componentListener,
|
eventHandler,
|
||||||
componentListener);
|
componentListener,
|
||||||
|
componentListener,
|
||||||
|
componentListener,
|
||||||
|
componentListener);
|
||||||
|
|
||||||
// Set initial values.
|
// Set initial values.
|
||||||
volume = 1;
|
volume = 1;
|
||||||
@ -476,10 +481,10 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
player =
|
player =
|
||||||
new ExoPlayerImpl(
|
new ExoPlayerImpl(
|
||||||
renderers,
|
renderers,
|
||||||
builder.trackSelector,
|
builder.trackSelectorSupplier.get(),
|
||||||
builder.mediaSourceFactory,
|
builder.mediaSourceFactorySupplier.get(),
|
||||||
builder.loadControl,
|
builder.loadControlSupplier.get(),
|
||||||
builder.bandwidthMeter,
|
builder.bandwidthMeterSupplier.get(),
|
||||||
analyticsCollector,
|
analyticsCollector,
|
||||||
builder.useLazyPreparation,
|
builder.useLazyPreparation,
|
||||||
builder.seekParameters,
|
builder.seekParameters,
|
||||||
@ -848,7 +853,7 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
@Override
|
@Override
|
||||||
public void addAnalyticsListener(AnalyticsListener listener) {
|
public void addAnalyticsListener(AnalyticsListener listener) {
|
||||||
// Don't verify application thread. We allow calls to this method from any thread.
|
// Don't verify application thread. We allow calls to this method from any thread.
|
||||||
Assertions.checkNotNull(listener);
|
checkNotNull(listener);
|
||||||
analyticsCollector.addListener(listener);
|
analyticsCollector.addListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -874,7 +879,7 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isPriorityTaskManagerRegistered) {
|
if (isPriorityTaskManagerRegistered) {
|
||||||
Assertions.checkNotNull(this.priorityTaskManager).remove(C.PRIORITY_PLAYBACK);
|
checkNotNull(this.priorityTaskManager).remove(C.PRIORITY_PLAYBACK);
|
||||||
}
|
}
|
||||||
if (priorityTaskManager != null && isLoading()) {
|
if (priorityTaskManager != null && isLoading()) {
|
||||||
priorityTaskManager.add(C.PRIORITY_PLAYBACK);
|
priorityTaskManager.add(C.PRIORITY_PLAYBACK);
|
||||||
@ -982,7 +987,7 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addListener(Listener listener) {
|
public void addListener(Listener listener) {
|
||||||
Assertions.checkNotNull(listener);
|
checkNotNull(listener);
|
||||||
listeners.add(listener);
|
listeners.add(listener);
|
||||||
EventListener eventListener = listener;
|
EventListener eventListener = listener;
|
||||||
addListener(eventListener);
|
addListener(eventListener);
|
||||||
@ -992,13 +997,13 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
@Override
|
@Override
|
||||||
public void addListener(Player.EventListener listener) {
|
public void addListener(Player.EventListener listener) {
|
||||||
// Don't verify application thread. We allow calls to this method from any thread.
|
// Don't verify application thread. We allow calls to this method from any thread.
|
||||||
Assertions.checkNotNull(listener);
|
checkNotNull(listener);
|
||||||
player.addEventListener(listener);
|
player.addEventListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeListener(Listener listener) {
|
public void removeListener(Listener listener) {
|
||||||
Assertions.checkNotNull(listener);
|
checkNotNull(listener);
|
||||||
listeners.remove(listener);
|
listeners.remove(listener);
|
||||||
EventListener eventListener = listener;
|
EventListener eventListener = listener;
|
||||||
removeListener(eventListener);
|
removeListener(eventListener);
|
||||||
@ -1322,7 +1327,7 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
ownedSurface = null;
|
ownedSurface = null;
|
||||||
}
|
}
|
||||||
if (isPriorityTaskManagerRegistered) {
|
if (isPriorityTaskManagerRegistered) {
|
||||||
Assertions.checkNotNull(priorityTaskManager).remove(C.PRIORITY_PLAYBACK);
|
checkNotNull(priorityTaskManager).remove(C.PRIORITY_PLAYBACK);
|
||||||
isPriorityTaskManagerRegistered = false;
|
isPriorityTaskManagerRegistered = false;
|
||||||
}
|
}
|
||||||
currentCues = Collections.emptyList();
|
currentCues = Collections.emptyList();
|
||||||
|
@ -24,6 +24,7 @@ import androidx.annotation.Nullable;
|
|||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.util.GlUtil;
|
import com.google.android.exoplayer2.util.GlUtil;
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class to render spherical meshes for video or images. Call {@link #init()} on the GL
|
* Utility class to render spherical meshes for video or images. Call {@link #init()} on the GL
|
||||||
@ -93,9 +94,9 @@ import java.nio.FloatBuffer;
|
|||||||
private int stereoMode;
|
private int stereoMode;
|
||||||
@Nullable private MeshData leftMeshData;
|
@Nullable private MeshData leftMeshData;
|
||||||
@Nullable private MeshData rightMeshData;
|
@Nullable private MeshData rightMeshData;
|
||||||
@Nullable private GlUtil.Program program;
|
private GlUtil.@MonotonicNonNull Program program;
|
||||||
|
|
||||||
// Program related GL items. These are only valid if program is non-null.
|
// Program related GL items. These are only valid if Program is valid.
|
||||||
private int mvpMatrixHandle;
|
private int mvpMatrixHandle;
|
||||||
private int uTexMatrixHandle;
|
private int uTexMatrixHandle;
|
||||||
private int positionHandle;
|
private int positionHandle;
|
||||||
@ -195,11 +196,10 @@ import java.nio.FloatBuffer;
|
|||||||
GLES20.glDisableVertexAttribArray(texCoordsHandle);
|
GLES20.glDisableVertexAttribArray(texCoordsHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Cleans up the GL resources. */
|
/** Cleans up GL resources. */
|
||||||
/* package */ void shutdown() {
|
/* package */ void shutdown() {
|
||||||
if (program != null) {
|
if (program != null) {
|
||||||
program.delete();
|
program.delete();
|
||||||
program = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
projectionRenderer.draw(textureId, tempMatrix, rightEye);
|
projectionRenderer.draw(textureId, tempMatrix, rightEye);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Cleans up the GL resources. */
|
/** Cleans up GL resources. */
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
projectionRenderer.shutdown();
|
projectionRenderer.shutdown();
|
||||||
}
|
}
|
||||||
|
@ -1750,6 +1750,19 @@ public final class DefaultTrackSelectorTest {
|
|||||||
assertThat(trackGroupInfos.get(0).getTrackSupport(0)).isEqualTo(FORMAT_HANDLED);
|
assertThat(trackGroupInfos.get(0).getTrackSupport(0)).isEqualTo(FORMAT_HANDLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Tests {@link SelectionOverride}'s {@link Bundleable} implementation. */
|
||||||
|
@Test
|
||||||
|
public void roundTripViaBundle_ofSelectionOverride_yieldsEqualInstance() {
|
||||||
|
SelectionOverride selectionOverrideToBundle =
|
||||||
|
new SelectionOverride(/* groupIndex= */ 1, /* tracks...= */ 2, 3);
|
||||||
|
|
||||||
|
SelectionOverride selectionOverrideFromBundle =
|
||||||
|
DefaultTrackSelector.SelectionOverride.CREATOR.fromBundle(
|
||||||
|
selectionOverrideToBundle.toBundle());
|
||||||
|
|
||||||
|
assertThat(selectionOverrideFromBundle).isEqualTo(selectionOverrideToBundle);
|
||||||
|
}
|
||||||
|
|
||||||
private static void assertSelections(TrackSelectorResult result, TrackSelection[] expected) {
|
private static void assertSelections(TrackSelectorResult result, TrackSelection[] expected) {
|
||||||
assertThat(result.length).isEqualTo(expected.length);
|
assertThat(result.length).isEqualTo(expected.length);
|
||||||
for (int i = 0; i < expected.length; i++) {
|
for (int i = 0; i < expected.length; i++) {
|
||||||
|
@ -19,6 +19,7 @@ import static java.lang.Math.max;
|
|||||||
import static java.lang.Math.min;
|
import static java.lang.Math.min;
|
||||||
|
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
import androidx.annotation.IntDef;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.Format;
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.ParserException;
|
import com.google.android.exoplayer2.ParserException;
|
||||||
@ -34,8 +35,14 @@ import com.google.android.exoplayer2.util.MimeTypes;
|
|||||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
|
import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
|
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||||
|
|
||||||
/** Extracts data from WAV byte streams. */
|
/** Extracts data from WAV byte streams. */
|
||||||
public final class WavExtractor implements Extractor {
|
public final class WavExtractor implements Extractor {
|
||||||
@ -50,13 +57,26 @@ public final class WavExtractor implements Extractor {
|
|||||||
/** Factory for {@link WavExtractor} instances. */
|
/** Factory for {@link WavExtractor} instances. */
|
||||||
public static final ExtractorsFactory FACTORY = () -> new Extractor[] {new WavExtractor()};
|
public static final ExtractorsFactory FACTORY = () -> new Extractor[] {new WavExtractor()};
|
||||||
|
|
||||||
|
/** Parser state. */
|
||||||
|
@Documented
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@Target({ElementType.TYPE_USE})
|
||||||
|
@IntDef({STATE_READING_HEADER, STATE_SKIPPING_TO_SAMPLE_DATA, STATE_READING_SAMPLE_DATA})
|
||||||
|
private @interface State {}
|
||||||
|
|
||||||
|
private static final int STATE_READING_HEADER = 0;
|
||||||
|
private static final int STATE_SKIPPING_TO_SAMPLE_DATA = 1;
|
||||||
|
private static final int STATE_READING_SAMPLE_DATA = 2;
|
||||||
|
|
||||||
private @MonotonicNonNull ExtractorOutput extractorOutput;
|
private @MonotonicNonNull ExtractorOutput extractorOutput;
|
||||||
private @MonotonicNonNull TrackOutput trackOutput;
|
private @MonotonicNonNull TrackOutput trackOutput;
|
||||||
|
private @State int state;
|
||||||
private @MonotonicNonNull OutputWriter outputWriter;
|
private @MonotonicNonNull OutputWriter outputWriter;
|
||||||
private int dataStartPosition;
|
private int dataStartPosition;
|
||||||
private long dataEndPosition;
|
private long dataEndPosition;
|
||||||
|
|
||||||
public WavExtractor() {
|
public WavExtractor() {
|
||||||
|
state = STATE_READING_HEADER;
|
||||||
dataStartPosition = C.POSITION_UNSET;
|
dataStartPosition = C.POSITION_UNSET;
|
||||||
dataEndPosition = C.POSITION_UNSET;
|
dataEndPosition = C.POSITION_UNSET;
|
||||||
}
|
}
|
||||||
@ -75,6 +95,7 @@ public final class WavExtractor implements Extractor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void seek(long position, long timeUs) {
|
public void seek(long position, long timeUs) {
|
||||||
|
state = position == 0 ? STATE_READING_HEADER : STATE_READING_SAMPLE_DATA;
|
||||||
if (outputWriter != null) {
|
if (outputWriter != null) {
|
||||||
outputWriter.reset(timeUs);
|
outputWriter.reset(timeUs);
|
||||||
}
|
}
|
||||||
@ -86,59 +107,21 @@ public final class WavExtractor implements Extractor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ReadResult
|
||||||
public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException {
|
public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException {
|
||||||
assertInitialized();
|
assertInitialized();
|
||||||
if (outputWriter == null) {
|
switch (state) {
|
||||||
WavHeader header = WavHeaderReader.peek(input);
|
case STATE_READING_HEADER:
|
||||||
if (header == null) {
|
readHeader(input);
|
||||||
// Should only happen if the media wasn't sniffed.
|
return Extractor.RESULT_CONTINUE;
|
||||||
throw ParserException.createForMalformedContainer(
|
case STATE_SKIPPING_TO_SAMPLE_DATA:
|
||||||
"Unsupported or unrecognized wav header.", /* cause= */ null);
|
skipToSampleData(input);
|
||||||
}
|
return Extractor.RESULT_CONTINUE;
|
||||||
|
case STATE_READING_SAMPLE_DATA:
|
||||||
if (header.formatType == WavUtil.TYPE_IMA_ADPCM) {
|
return readSampleData(input);
|
||||||
outputWriter = new ImaAdPcmOutputWriter(extractorOutput, trackOutput, header);
|
default:
|
||||||
} else if (header.formatType == WavUtil.TYPE_ALAW) {
|
throw new IllegalStateException();
|
||||||
outputWriter =
|
|
||||||
new PassthroughOutputWriter(
|
|
||||||
extractorOutput,
|
|
||||||
trackOutput,
|
|
||||||
header,
|
|
||||||
MimeTypes.AUDIO_ALAW,
|
|
||||||
/* pcmEncoding= */ Format.NO_VALUE);
|
|
||||||
} else if (header.formatType == WavUtil.TYPE_MLAW) {
|
|
||||||
outputWriter =
|
|
||||||
new PassthroughOutputWriter(
|
|
||||||
extractorOutput,
|
|
||||||
trackOutput,
|
|
||||||
header,
|
|
||||||
MimeTypes.AUDIO_MLAW,
|
|
||||||
/* pcmEncoding= */ Format.NO_VALUE);
|
|
||||||
} else {
|
|
||||||
@C.PcmEncoding
|
|
||||||
int pcmEncoding = WavUtil.getPcmEncodingForType(header.formatType, header.bitsPerSample);
|
|
||||||
if (pcmEncoding == C.ENCODING_INVALID) {
|
|
||||||
throw ParserException.createForUnsupportedContainerFeature(
|
|
||||||
"Unsupported WAV format type: " + header.formatType);
|
|
||||||
}
|
|
||||||
outputWriter =
|
|
||||||
new PassthroughOutputWriter(
|
|
||||||
extractorOutput, trackOutput, header, MimeTypes.AUDIO_RAW, pcmEncoding);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataStartPosition == C.POSITION_UNSET) {
|
|
||||||
Pair<Long, Long> dataBounds = WavHeaderReader.skipToData(input);
|
|
||||||
dataStartPosition = dataBounds.first.intValue();
|
|
||||||
dataEndPosition = dataBounds.second;
|
|
||||||
outputWriter.init(dataStartPosition, dataEndPosition);
|
|
||||||
} else if (input.getPosition() == 0) {
|
|
||||||
input.skipFully(dataStartPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
Assertions.checkState(dataEndPosition != C.POSITION_UNSET);
|
|
||||||
long bytesLeft = dataEndPosition - input.getPosition();
|
|
||||||
return outputWriter.sampleData(input, bytesLeft) ? RESULT_END_OF_INPUT : RESULT_CONTINUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnsuresNonNull({"extractorOutput", "trackOutput"})
|
@EnsuresNonNull({"extractorOutput", "trackOutput"})
|
||||||
@ -147,6 +130,71 @@ public final class WavExtractor implements Extractor {
|
|||||||
Util.castNonNull(extractorOutput);
|
Util.castNonNull(extractorOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresNonNull({"extractorOutput", "trackOutput"})
|
||||||
|
private void readHeader(ExtractorInput input) throws IOException {
|
||||||
|
Assertions.checkState(input.getPosition() == 0);
|
||||||
|
if (dataStartPosition != C.POSITION_UNSET) {
|
||||||
|
input.skipFully(dataStartPosition);
|
||||||
|
state = STATE_READING_SAMPLE_DATA;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
WavHeader header = WavHeaderReader.peek(input);
|
||||||
|
if (header == null) {
|
||||||
|
// Should only happen if the media wasn't sniffed.
|
||||||
|
throw ParserException.createForMalformedContainer(
|
||||||
|
"Unsupported or unrecognized wav header.", /* cause= */ null);
|
||||||
|
}
|
||||||
|
input.skipFully((int) (input.getPeekPosition() - input.getPosition()));
|
||||||
|
|
||||||
|
if (header.formatType == WavUtil.TYPE_IMA_ADPCM) {
|
||||||
|
outputWriter = new ImaAdPcmOutputWriter(extractorOutput, trackOutput, header);
|
||||||
|
} else if (header.formatType == WavUtil.TYPE_ALAW) {
|
||||||
|
outputWriter =
|
||||||
|
new PassthroughOutputWriter(
|
||||||
|
extractorOutput,
|
||||||
|
trackOutput,
|
||||||
|
header,
|
||||||
|
MimeTypes.AUDIO_ALAW,
|
||||||
|
/* pcmEncoding= */ Format.NO_VALUE);
|
||||||
|
} else if (header.formatType == WavUtil.TYPE_MLAW) {
|
||||||
|
outputWriter =
|
||||||
|
new PassthroughOutputWriter(
|
||||||
|
extractorOutput,
|
||||||
|
trackOutput,
|
||||||
|
header,
|
||||||
|
MimeTypes.AUDIO_MLAW,
|
||||||
|
/* pcmEncoding= */ Format.NO_VALUE);
|
||||||
|
} else {
|
||||||
|
@C.PcmEncoding
|
||||||
|
int pcmEncoding = WavUtil.getPcmEncodingForType(header.formatType, header.bitsPerSample);
|
||||||
|
if (pcmEncoding == C.ENCODING_INVALID) {
|
||||||
|
throw ParserException.createForUnsupportedContainerFeature(
|
||||||
|
"Unsupported WAV format type: " + header.formatType);
|
||||||
|
}
|
||||||
|
outputWriter =
|
||||||
|
new PassthroughOutputWriter(
|
||||||
|
extractorOutput, trackOutput, header, MimeTypes.AUDIO_RAW, pcmEncoding);
|
||||||
|
}
|
||||||
|
state = STATE_SKIPPING_TO_SAMPLE_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void skipToSampleData(ExtractorInput input) throws IOException {
|
||||||
|
Pair<Long, Long> dataBounds = WavHeaderReader.skipToSampleData(input);
|
||||||
|
dataStartPosition = dataBounds.first.intValue();
|
||||||
|
dataEndPosition = dataBounds.second;
|
||||||
|
Assertions.checkNotNull(outputWriter).init(dataStartPosition, dataEndPosition);
|
||||||
|
state = STATE_READING_SAMPLE_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReadResult
|
||||||
|
private int readSampleData(ExtractorInput input) throws IOException {
|
||||||
|
Assertions.checkState(dataEndPosition != C.POSITION_UNSET);
|
||||||
|
long bytesLeft = dataEndPosition - input.getPosition();
|
||||||
|
return Assertions.checkNotNull(outputWriter).sampleData(input, bytesLeft)
|
||||||
|
? RESULT_END_OF_INPUT
|
||||||
|
: RESULT_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
/** Writes to the extractor's output. */
|
/** Writes to the extractor's output. */
|
||||||
private interface OutputWriter {
|
private interface OutputWriter {
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ import java.io.IOException;
|
|||||||
* @throws ParserException If an error occurs parsing chunks.
|
* @throws ParserException If an error occurs parsing chunks.
|
||||||
* @throws IOException If reading from the input fails.
|
* @throws IOException If reading from the input fails.
|
||||||
*/
|
*/
|
||||||
public static Pair<Long, Long> skipToData(ExtractorInput input) throws IOException {
|
public static Pair<Long, Long> skipToSampleData(ExtractorInput input) throws IOException {
|
||||||
Assertions.checkNotNull(input);
|
Assertions.checkNotNull(input);
|
||||||
|
|
||||||
// Make sure the peek position is set to the read position before we peek the first header.
|
// Make sure the peek position is set to the read position before we peek the first header.
|
||||||
@ -118,14 +118,8 @@ import java.io.IOException;
|
|||||||
// Skip all chunks until we find the data header.
|
// Skip all chunks until we find the data header.
|
||||||
ChunkHeader chunkHeader = ChunkHeader.peek(input, scratch);
|
ChunkHeader chunkHeader = ChunkHeader.peek(input, scratch);
|
||||||
while (chunkHeader.id != WavUtil.DATA_FOURCC) {
|
while (chunkHeader.id != WavUtil.DATA_FOURCC) {
|
||||||
if (chunkHeader.id != WavUtil.RIFF_FOURCC && chunkHeader.id != WavUtil.FMT_FOURCC) {
|
Log.w(TAG, "Ignoring unknown WAV chunk: " + chunkHeader.id);
|
||||||
Log.w(TAG, "Ignoring unknown WAV chunk: " + chunkHeader.id);
|
|
||||||
}
|
|
||||||
long bytesToSkip = ChunkHeader.SIZE_IN_BYTES + chunkHeader.size;
|
long bytesToSkip = ChunkHeader.SIZE_IN_BYTES + chunkHeader.size;
|
||||||
// Override size of RIFF chunk, since it describes its size as the entire file.
|
|
||||||
if (chunkHeader.id == WavUtil.RIFF_FOURCC) {
|
|
||||||
bytesToSkip = ChunkHeader.SIZE_IN_BYTES + 4;
|
|
||||||
}
|
|
||||||
if (bytesToSkip > Integer.MAX_VALUE) {
|
if (bytesToSkip > Integer.MAX_VALUE) {
|
||||||
throw ParserException.createForUnsupportedContainerFeature(
|
throw ParserException.createForUnsupportedContainerFeature(
|
||||||
"Chunk is too large (~2GB+) to skip; id: " + chunkHeader.id);
|
"Chunk is too large (~2GB+) to skip; id: " + chunkHeader.id);
|
||||||
|
@ -45,7 +45,6 @@ import com.google.android.exoplayer2.Renderer;
|
|||||||
import com.google.android.exoplayer2.RenderersFactory;
|
import com.google.android.exoplayer2.RenderersFactory;
|
||||||
import com.google.android.exoplayer2.Timeline;
|
import com.google.android.exoplayer2.Timeline;
|
||||||
import com.google.android.exoplayer2.TracksInfo;
|
import com.google.android.exoplayer2.TracksInfo;
|
||||||
import com.google.android.exoplayer2.analytics.AnalyticsListener;
|
|
||||||
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
|
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
|
||||||
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
|
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
|
||||||
import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor;
|
import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor;
|
||||||
@ -56,6 +55,7 @@ import com.google.android.exoplayer2.source.MediaSourceFactory;
|
|||||||
import com.google.android.exoplayer2.text.TextOutput;
|
import com.google.android.exoplayer2.text.TextOutput;
|
||||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||||
import com.google.android.exoplayer2.util.Clock;
|
import com.google.android.exoplayer2.util.Clock;
|
||||||
|
import com.google.android.exoplayer2.util.Log;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import com.google.android.exoplayer2.video.VideoRendererEventListener;
|
import com.google.android.exoplayer2.video.VideoRendererEventListener;
|
||||||
@ -92,12 +92,16 @@ public final class TranscodingTransformer {
|
|||||||
/** A builder for {@link TranscodingTransformer} instances. */
|
/** A builder for {@link TranscodingTransformer} instances. */
|
||||||
public static final class Builder {
|
public static final class Builder {
|
||||||
|
|
||||||
|
// Mandatory field.
|
||||||
private @MonotonicNonNull Context context;
|
private @MonotonicNonNull Context context;
|
||||||
|
|
||||||
|
// Optional fields.
|
||||||
private @MonotonicNonNull MediaSourceFactory mediaSourceFactory;
|
private @MonotonicNonNull MediaSourceFactory mediaSourceFactory;
|
||||||
private Muxer.Factory muxerFactory;
|
private Muxer.Factory muxerFactory;
|
||||||
private boolean removeAudio;
|
private boolean removeAudio;
|
||||||
private boolean removeVideo;
|
private boolean removeVideo;
|
||||||
private boolean flattenForSlowMotion;
|
private boolean flattenForSlowMotion;
|
||||||
|
private int outputHeight;
|
||||||
private String outputMimeType;
|
private String outputMimeType;
|
||||||
@Nullable private String audioMimeType;
|
@Nullable private String audioMimeType;
|
||||||
@Nullable private String videoMimeType;
|
@Nullable private String videoMimeType;
|
||||||
@ -122,6 +126,7 @@ public final class TranscodingTransformer {
|
|||||||
this.removeAudio = transcodingTransformer.transformation.removeAudio;
|
this.removeAudio = transcodingTransformer.transformation.removeAudio;
|
||||||
this.removeVideo = transcodingTransformer.transformation.removeVideo;
|
this.removeVideo = transcodingTransformer.transformation.removeVideo;
|
||||||
this.flattenForSlowMotion = transcodingTransformer.transformation.flattenForSlowMotion;
|
this.flattenForSlowMotion = transcodingTransformer.transformation.flattenForSlowMotion;
|
||||||
|
this.outputHeight = transcodingTransformer.transformation.outputHeight;
|
||||||
this.outputMimeType = transcodingTransformer.transformation.outputMimeType;
|
this.outputMimeType = transcodingTransformer.transformation.outputMimeType;
|
||||||
this.audioMimeType = transcodingTransformer.transformation.audioMimeType;
|
this.audioMimeType = transcodingTransformer.transformation.audioMimeType;
|
||||||
this.videoMimeType = transcodingTransformer.transformation.videoMimeType;
|
this.videoMimeType = transcodingTransformer.transformation.videoMimeType;
|
||||||
@ -214,6 +219,21 @@ public final class TranscodingTransformer {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the output resolution for the video, using the output height. The default value is to
|
||||||
|
* use the same height as the input. Output width will scale to preserve the input video's
|
||||||
|
* aspect ratio.
|
||||||
|
*
|
||||||
|
* <p>For example, a 1920x1440 video can be scaled to 640x480 by calling setResolution(480).
|
||||||
|
*
|
||||||
|
* @param outputHeight The output height for the video, in pixels.
|
||||||
|
* @return This builder.
|
||||||
|
*/
|
||||||
|
public Builder setResolution(int outputHeight) {
|
||||||
|
this.outputHeight = outputHeight;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the MIME type of the output. The default value is {@link MimeTypes#VIDEO_MP4}. Supported
|
* Sets the MIME type of the output. The default value is {@link MimeTypes#VIDEO_MP4}. Supported
|
||||||
* values are:
|
* values are:
|
||||||
@ -357,6 +377,12 @@ public final class TranscodingTransformer {
|
|||||||
checkState(
|
checkState(
|
||||||
muxerFactory.supportsOutputMimeType(outputMimeType),
|
muxerFactory.supportsOutputMimeType(outputMimeType),
|
||||||
"Unsupported output MIME type: " + outputMimeType);
|
"Unsupported output MIME type: " + outputMimeType);
|
||||||
|
// TODO(ME): Test with values of 10, 100, 1000).
|
||||||
|
Log.e("TranscodingTransformer", "outputHeight = " + outputHeight);
|
||||||
|
if (outputHeight == 0) {
|
||||||
|
// TODO(ME): get output height from input video.
|
||||||
|
outputHeight = 480;
|
||||||
|
}
|
||||||
if (audioMimeType != null) {
|
if (audioMimeType != null) {
|
||||||
checkSampleMimeType(audioMimeType);
|
checkSampleMimeType(audioMimeType);
|
||||||
}
|
}
|
||||||
@ -368,6 +394,7 @@ public final class TranscodingTransformer {
|
|||||||
removeAudio,
|
removeAudio,
|
||||||
removeVideo,
|
removeVideo,
|
||||||
flattenForSlowMotion,
|
flattenForSlowMotion,
|
||||||
|
outputHeight,
|
||||||
outputMimeType,
|
outputMimeType,
|
||||||
audioMimeType,
|
audioMimeType,
|
||||||
videoMimeType);
|
videoMimeType);
|
||||||
@ -454,6 +481,7 @@ public final class TranscodingTransformer {
|
|||||||
checkState(
|
checkState(
|
||||||
!transformation.removeAudio || !transformation.removeVideo,
|
!transformation.removeAudio || !transformation.removeVideo,
|
||||||
"Audio and video cannot both be removed.");
|
"Audio and video cannot both be removed.");
|
||||||
|
checkState(!(transformation.removeVideo));
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.mediaSourceFactory = mediaSourceFactory;
|
this.mediaSourceFactory = mediaSourceFactory;
|
||||||
this.muxerFactory = muxerFactory;
|
this.muxerFactory = muxerFactory;
|
||||||
@ -573,8 +601,7 @@ public final class TranscodingTransformer {
|
|||||||
.setClock(clock)
|
.setClock(clock)
|
||||||
.build();
|
.build();
|
||||||
player.setMediaItem(mediaItem);
|
player.setMediaItem(mediaItem);
|
||||||
player.addAnalyticsListener(
|
player.addListener(new TranscodingTransformerPlayerListener(mediaItem, muxerWrapper));
|
||||||
new TranscodingTransformerAnalyticsListener(mediaItem, muxerWrapper));
|
|
||||||
player.prepare();
|
player.prepare();
|
||||||
|
|
||||||
progressState = PROGRESS_STATE_WAITING_FOR_AVAILABILITY;
|
progressState = PROGRESS_STATE_WAITING_FOR_AVAILABILITY;
|
||||||
@ -688,30 +715,30 @@ public final class TranscodingTransformer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class TranscodingTransformerAnalyticsListener implements AnalyticsListener {
|
private final class TranscodingTransformerPlayerListener implements Player.Listener {
|
||||||
|
|
||||||
private final MediaItem mediaItem;
|
private final MediaItem mediaItem;
|
||||||
private final MuxerWrapper muxerWrapper;
|
private final MuxerWrapper muxerWrapper;
|
||||||
|
|
||||||
public TranscodingTransformerAnalyticsListener(MediaItem mediaItem, MuxerWrapper muxerWrapper) {
|
public TranscodingTransformerPlayerListener(MediaItem mediaItem, MuxerWrapper muxerWrapper) {
|
||||||
this.mediaItem = mediaItem;
|
this.mediaItem = mediaItem;
|
||||||
this.muxerWrapper = muxerWrapper;
|
this.muxerWrapper = muxerWrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlaybackStateChanged(EventTime eventTime, int state) {
|
public void onPlaybackStateChanged(int state) {
|
||||||
if (state == Player.STATE_ENDED) {
|
if (state == Player.STATE_ENDED) {
|
||||||
handleTransformationEnded(/* exception= */ null);
|
handleTransformationEnded(/* exception= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTimelineChanged(EventTime eventTime, int reason) {
|
public void onTimelineChanged(Timeline timeline, int reason) {
|
||||||
if (progressState != PROGRESS_STATE_WAITING_FOR_AVAILABILITY) {
|
if (progressState != PROGRESS_STATE_WAITING_FOR_AVAILABILITY) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Timeline.Window window = new Timeline.Window();
|
Timeline.Window window = new Timeline.Window();
|
||||||
eventTime.timeline.getWindow(/* windowIndex= */ 0, window);
|
timeline.getWindow(/* windowIndex= */ 0, window);
|
||||||
if (!window.isPlaceholder) {
|
if (!window.isPlaceholder) {
|
||||||
long durationUs = window.durationUs;
|
long durationUs = window.durationUs;
|
||||||
// Make progress permanently unavailable if the duration is unknown, so that it doesn't jump
|
// Make progress permanently unavailable if the duration is unknown, so that it doesn't jump
|
||||||
@ -726,7 +753,7 @@ public final class TranscodingTransformer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTracksInfoChanged(EventTime eventTime, TracksInfo tracksInfo) {
|
public void onTracksInfoChanged(TracksInfo tracksInfo) {
|
||||||
if (muxerWrapper.getTrackCount() == 0) {
|
if (muxerWrapper.getTrackCount() == 0) {
|
||||||
handleTransformationEnded(
|
handleTransformationEnded(
|
||||||
new IllegalStateException(
|
new IllegalStateException(
|
||||||
@ -736,7 +763,7 @@ public final class TranscodingTransformer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerError(EventTime eventTime, PlaybackException error) {
|
public void onPlayerError(PlaybackException error) {
|
||||||
handleTransformationEnded(error);
|
handleTransformationEnded(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ import androidx.annotation.Nullable;
|
|||||||
public final boolean removeAudio;
|
public final boolean removeAudio;
|
||||||
public final boolean removeVideo;
|
public final boolean removeVideo;
|
||||||
public final boolean flattenForSlowMotion;
|
public final boolean flattenForSlowMotion;
|
||||||
|
public final int outputHeight;
|
||||||
public final String outputMimeType;
|
public final String outputMimeType;
|
||||||
@Nullable public final String audioMimeType;
|
@Nullable public final String audioMimeType;
|
||||||
@Nullable public final String videoMimeType;
|
@Nullable public final String videoMimeType;
|
||||||
@ -32,12 +33,14 @@ import androidx.annotation.Nullable;
|
|||||||
boolean removeAudio,
|
boolean removeAudio,
|
||||||
boolean removeVideo,
|
boolean removeVideo,
|
||||||
boolean flattenForSlowMotion,
|
boolean flattenForSlowMotion,
|
||||||
|
int outputHeight,
|
||||||
String outputMimeType,
|
String outputMimeType,
|
||||||
@Nullable String audioMimeType,
|
@Nullable String audioMimeType,
|
||||||
@Nullable String videoMimeType) {
|
@Nullable String videoMimeType) {
|
||||||
this.removeAudio = removeAudio;
|
this.removeAudio = removeAudio;
|
||||||
this.removeVideo = removeVideo;
|
this.removeVideo = removeVideo;
|
||||||
this.flattenForSlowMotion = flattenForSlowMotion;
|
this.flattenForSlowMotion = flattenForSlowMotion;
|
||||||
|
this.outputHeight = outputHeight;
|
||||||
this.outputMimeType = outputMimeType;
|
this.outputMimeType = outputMimeType;
|
||||||
this.audioMimeType = audioMimeType;
|
this.audioMimeType = audioMimeType;
|
||||||
this.videoMimeType = videoMimeType;
|
this.videoMimeType = videoMimeType;
|
||||||
|
@ -46,7 +46,6 @@ import com.google.android.exoplayer2.Renderer;
|
|||||||
import com.google.android.exoplayer2.RenderersFactory;
|
import com.google.android.exoplayer2.RenderersFactory;
|
||||||
import com.google.android.exoplayer2.Timeline;
|
import com.google.android.exoplayer2.Timeline;
|
||||||
import com.google.android.exoplayer2.TracksInfo;
|
import com.google.android.exoplayer2.TracksInfo;
|
||||||
import com.google.android.exoplayer2.analytics.AnalyticsListener;
|
|
||||||
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
|
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
|
||||||
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
|
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
|
||||||
import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor;
|
import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor;
|
||||||
@ -298,11 +297,13 @@ public final class Transformer {
|
|||||||
checkState(
|
checkState(
|
||||||
muxerFactory.supportsOutputMimeType(outputMimeType),
|
muxerFactory.supportsOutputMimeType(outputMimeType),
|
||||||
"Unsupported output MIME type: " + outputMimeType);
|
"Unsupported output MIME type: " + outputMimeType);
|
||||||
|
int outputHeight = 0; // TODO(ME): How do we get the input height here?
|
||||||
Transformation transformation =
|
Transformation transformation =
|
||||||
new Transformation(
|
new Transformation(
|
||||||
removeAudio,
|
removeAudio,
|
||||||
removeVideo,
|
removeVideo,
|
||||||
flattenForSlowMotion,
|
flattenForSlowMotion,
|
||||||
|
outputHeight,
|
||||||
outputMimeType,
|
outputMimeType,
|
||||||
/* audioMimeType= */ null,
|
/* audioMimeType= */ null,
|
||||||
/* videoMimeType= */ null);
|
/* videoMimeType= */ null);
|
||||||
@ -496,7 +497,7 @@ public final class Transformer {
|
|||||||
.setClock(clock)
|
.setClock(clock)
|
||||||
.build();
|
.build();
|
||||||
player.setMediaItem(mediaItem);
|
player.setMediaItem(mediaItem);
|
||||||
player.addAnalyticsListener(new TransformerAnalyticsListener(mediaItem, muxerWrapper));
|
player.addListener(new TransformerPlayerListener(mediaItem, muxerWrapper));
|
||||||
player.prepare();
|
player.prepare();
|
||||||
|
|
||||||
progressState = PROGRESS_STATE_WAITING_FOR_AVAILABILITY;
|
progressState = PROGRESS_STATE_WAITING_FOR_AVAILABILITY;
|
||||||
@ -606,30 +607,30 @@ public final class Transformer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class TransformerAnalyticsListener implements AnalyticsListener {
|
private final class TransformerPlayerListener implements Player.Listener {
|
||||||
|
|
||||||
private final MediaItem mediaItem;
|
private final MediaItem mediaItem;
|
||||||
private final MuxerWrapper muxerWrapper;
|
private final MuxerWrapper muxerWrapper;
|
||||||
|
|
||||||
public TransformerAnalyticsListener(MediaItem mediaItem, MuxerWrapper muxerWrapper) {
|
public TransformerPlayerListener(MediaItem mediaItem, MuxerWrapper muxerWrapper) {
|
||||||
this.mediaItem = mediaItem;
|
this.mediaItem = mediaItem;
|
||||||
this.muxerWrapper = muxerWrapper;
|
this.muxerWrapper = muxerWrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlaybackStateChanged(EventTime eventTime, int state) {
|
public void onPlaybackStateChanged(int state) {
|
||||||
if (state == Player.STATE_ENDED) {
|
if (state == Player.STATE_ENDED) {
|
||||||
handleTransformationEnded(/* exception= */ null);
|
handleTransformationEnded(/* exception= */ null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTimelineChanged(EventTime eventTime, int reason) {
|
public void onTimelineChanged(Timeline timeline, int reason) {
|
||||||
if (progressState != PROGRESS_STATE_WAITING_FOR_AVAILABILITY) {
|
if (progressState != PROGRESS_STATE_WAITING_FOR_AVAILABILITY) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Timeline.Window window = new Timeline.Window();
|
Timeline.Window window = new Timeline.Window();
|
||||||
eventTime.timeline.getWindow(/* windowIndex= */ 0, window);
|
timeline.getWindow(/* windowIndex= */ 0, window);
|
||||||
if (!window.isPlaceholder) {
|
if (!window.isPlaceholder) {
|
||||||
long durationUs = window.durationUs;
|
long durationUs = window.durationUs;
|
||||||
// Make progress permanently unavailable if the duration is unknown, so that it doesn't jump
|
// Make progress permanently unavailable if the duration is unknown, so that it doesn't jump
|
||||||
@ -644,7 +645,7 @@ public final class Transformer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTracksInfoChanged(EventTime eventTime, TracksInfo tracksInfo) {
|
public void onTracksInfoChanged(TracksInfo tracksInfo) {
|
||||||
if (muxerWrapper.getTrackCount() == 0) {
|
if (muxerWrapper.getTrackCount() == 0) {
|
||||||
handleTransformationEnded(
|
handleTransformationEnded(
|
||||||
new IllegalStateException(
|
new IllegalStateException(
|
||||||
@ -654,7 +655,7 @@ public final class Transformer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerError(EventTime eventTime, PlaybackException error) {
|
public void onPlayerError(PlaybackException error) {
|
||||||
handleTransformationEnded(error);
|
handleTransformationEnded(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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 com.google.android.exoplayer2.testutil;
|
||||||
|
|
||||||
|
import static com.google.android.exoplayer2.util.Util.castNonNull;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import com.google.android.exoplayer2.metadata.Metadata;
|
||||||
|
|
||||||
|
/** A fake {@link Metadata.Entry}. */
|
||||||
|
public final class FakeMetadataEntry implements Metadata.Entry {
|
||||||
|
|
||||||
|
public final String data;
|
||||||
|
|
||||||
|
public FakeMetadataEntry(String data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* package */ FakeMetadataEntry(Parcel in) {
|
||||||
|
data = castNonNull(in.readString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(@Nullable Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null || getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
FakeMetadataEntry other = (FakeMetadataEntry) obj;
|
||||||
|
return data.equals(other.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return data.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeString(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Parcelable.Creator<FakeMetadataEntry> CREATOR =
|
||||||
|
new Parcelable.Creator<FakeMetadataEntry>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FakeMetadataEntry createFromParcel(Parcel in) {
|
||||||
|
return new FakeMetadataEntry(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FakeMetadataEntry[] newArray(int size) {
|
||||||
|
return new FakeMetadataEntry[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -15,26 +15,14 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.testutil;
|
package com.google.android.exoplayer2.testutil;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.view.Surface;
|
|
||||||
import android.view.SurfaceHolder;
|
|
||||||
import android.view.SurfaceView;
|
|
||||||
import android.view.TextureView;
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.BasePlayer;
|
|
||||||
import com.google.android.exoplayer2.DeviceInfo;
|
|
||||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||||
import com.google.android.exoplayer2.ExoPlayer;
|
import com.google.android.exoplayer2.ExoPlayer;
|
||||||
import com.google.android.exoplayer2.Format;
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.MediaItem;
|
|
||||||
import com.google.android.exoplayer2.MediaMetadata;
|
|
||||||
import com.google.android.exoplayer2.PlaybackParameters;
|
|
||||||
import com.google.android.exoplayer2.Player;
|
import com.google.android.exoplayer2.Player;
|
||||||
import com.google.android.exoplayer2.PlayerMessage;
|
import com.google.android.exoplayer2.PlayerMessage;
|
||||||
import com.google.android.exoplayer2.SeekParameters;
|
import com.google.android.exoplayer2.SeekParameters;
|
||||||
import com.google.android.exoplayer2.Timeline;
|
|
||||||
import com.google.android.exoplayer2.TracksInfo;
|
|
||||||
import com.google.android.exoplayer2.analytics.AnalyticsCollector;
|
import com.google.android.exoplayer2.analytics.AnalyticsCollector;
|
||||||
import com.google.android.exoplayer2.analytics.AnalyticsListener;
|
import com.google.android.exoplayer2.analytics.AnalyticsListener;
|
||||||
import com.google.android.exoplayer2.audio.AudioAttributes;
|
import com.google.android.exoplayer2.audio.AudioAttributes;
|
||||||
@ -42,15 +30,10 @@ import com.google.android.exoplayer2.audio.AuxEffectInfo;
|
|||||||
import com.google.android.exoplayer2.decoder.DecoderCounters;
|
import com.google.android.exoplayer2.decoder.DecoderCounters;
|
||||||
import com.google.android.exoplayer2.source.MediaSource;
|
import com.google.android.exoplayer2.source.MediaSource;
|
||||||
import com.google.android.exoplayer2.source.ShuffleOrder;
|
import com.google.android.exoplayer2.source.ShuffleOrder;
|
||||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
|
||||||
import com.google.android.exoplayer2.text.Cue;
|
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters;
|
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
||||||
import com.google.android.exoplayer2.util.Clock;
|
import com.google.android.exoplayer2.util.Clock;
|
||||||
import com.google.android.exoplayer2.util.PriorityTaskManager;
|
import com.google.android.exoplayer2.util.PriorityTaskManager;
|
||||||
import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
|
import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
|
||||||
import com.google.android.exoplayer2.video.VideoSize;
|
|
||||||
import com.google.android.exoplayer2.video.spherical.CameraMotionListener;
|
import com.google.android.exoplayer2.video.spherical.CameraMotionListener;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -58,11 +41,7 @@ import java.util.List;
|
|||||||
* An abstract {@link ExoPlayer} implementation that throws {@link UnsupportedOperationException}
|
* An abstract {@link ExoPlayer} implementation that throws {@link UnsupportedOperationException}
|
||||||
* from every method.
|
* from every method.
|
||||||
*/
|
*/
|
||||||
public class StubExoPlayer extends BasePlayer implements ExoPlayer {
|
public class StubExoPlayer extends StubPlayer implements ExoPlayer {
|
||||||
|
|
||||||
public StubExoPlayer(Context context) {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ -93,31 +72,16 @@ public class StubExoPlayer extends BasePlayer implements ExoPlayer {
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Looper getApplicationLooper() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Clock getClock() {
|
public Clock getClock() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addListener(Listener listener) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addListener(Player.EventListener listener) {
|
public void addListener(Player.EventListener listener) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeListener(Listener listener) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeListener(Player.EventListener listener) {
|
public void removeListener(Player.EventListener listener) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
@ -148,68 +112,29 @@ public class StubExoPlayer extends BasePlayer implements ExoPlayer {
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@State
|
|
||||||
public int getPlaybackState() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@PlaybackSuppressionReason
|
|
||||||
public int getPlaybackSuppressionReason() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExoPlaybackException getPlayerError() {
|
public ExoPlaybackException getPlayerError() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @deprecated Use {@link #prepare()} instead. */
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@Override
|
@Override
|
||||||
public void retry() {
|
public void retry() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Use {@link #setMediaSource(MediaSource)} and {@link ExoPlayer#prepare()} instead.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
@Override
|
|
||||||
public void prepare() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Use {@link #setMediaSource(MediaSource)} and {@link ExoPlayer#prepare()} instead.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@Override
|
@Override
|
||||||
public void prepare(MediaSource mediaSource) {
|
public void prepare(MediaSource mediaSource) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Use {@link #setMediaSource(MediaSource, boolean)} and {@link ExoPlayer#prepare()}
|
|
||||||
* instead.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@Override
|
@Override
|
||||||
public void prepare(MediaSource mediaSource, boolean resetPosition, boolean resetState) {
|
public void prepare(MediaSource mediaSource, boolean resetPosition, boolean resetState) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setMediaItems(List<MediaItem> mediaItems, boolean resetPosition) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setMediaItems(List<MediaItem> mediaItems, int startIndex, long startPositionMs) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMediaSource(MediaSource mediaSource) {
|
public void setMediaSource(MediaSource mediaSource) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
@ -241,11 +166,6 @@ public class StubExoPlayer extends BasePlayer implements ExoPlayer {
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addMediaItems(int index, List<MediaItem> mediaItems) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addMediaSource(MediaSource mediaSource) {
|
public void addMediaSource(MediaSource mediaSource) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
@ -266,41 +186,6 @@ public class StubExoPlayer extends BasePlayer implements ExoPlayer {
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void moveMediaItems(int fromIndex, int toIndex, int newIndex) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeMediaItems(int fromIndex, int toIndex) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Commands getAvailableCommands() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPlayWhenReady(boolean playWhenReady) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean getPlayWhenReady() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setRepeatMode(@RepeatMode int repeatMode) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getRepeatMode() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setShuffleOrder(ShuffleOrder shuffleOrder) {
|
public void setShuffleOrder(ShuffleOrder shuffleOrder) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
@ -381,51 +266,6 @@ public class StubExoPlayer extends BasePlayer implements ExoPlayer {
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setShuffleModeEnabled(boolean shuffleModeEnabled) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean getShuffleModeEnabled() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isLoading() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void seekTo(int mediaItemIndex, long positionMs) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getSeekBackIncrement() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getSeekForwardIncrement() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getMaxSeekToPreviousPosition() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPlaybackParameters(PlaybackParameters playbackParameters) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PlaybackParameters getPlaybackParameters() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setSeekParameters(@Nullable SeekParameters seekParameters) {
|
public void setSeekParameters(@Nullable SeekParameters seekParameters) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
@ -436,22 +276,6 @@ public class StubExoPlayer extends BasePlayer implements ExoPlayer {
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stop() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
@Override
|
|
||||||
public void stop(boolean reset) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void release() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlayerMessage createMessage(PlayerMessage.Target target) {
|
public PlayerMessage createMessage(PlayerMessage.Target target) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
@ -473,211 +297,6 @@ public class StubExoPlayer extends BasePlayer implements ExoPlayer {
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public TrackGroupArray getCurrentTrackGroups() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TrackSelectionArray getCurrentTrackSelections() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TracksInfo getCurrentTracksInfo() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TrackSelectionParameters getTrackSelectionParameters() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setTrackSelectionParameters(TrackSelectionParameters parameters) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MediaMetadata getMediaMetadata() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MediaMetadata getPlaylistMetadata() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPlaylistMetadata(MediaMetadata mediaMetadata) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Timeline getCurrentTimeline() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCurrentPeriodIndex() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCurrentMediaItemIndex() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getDuration() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getCurrentPosition() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getBufferedPosition() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getTotalBufferedDuration() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isPlayingAd() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCurrentAdGroupIndex() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCurrentAdIndexInAdGroup() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getContentPosition() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getContentBufferedPosition() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AudioAttributes getAudioAttributes() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setVolume(float volume) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getVolume() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clearVideoSurface() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clearVideoSurface(@Nullable Surface surface) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setVideoSurface(@Nullable Surface surface) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setVideoSurfaceHolder(@Nullable SurfaceHolder surfaceHolder) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clearVideoSurfaceHolder(@Nullable SurfaceHolder surfaceHolder) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setVideoSurfaceView(@Nullable SurfaceView surfaceView) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clearVideoSurfaceView(@Nullable SurfaceView surfaceView) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setVideoTextureView(@Nullable TextureView textureView) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clearVideoTextureView(@Nullable TextureView textureView) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VideoSize getVideoSize() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Cue> getCurrentCues() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DeviceInfo getDeviceInfo() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getDeviceVolume() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDeviceMuted() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDeviceVolume(int volume) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void increaseDeviceVolume() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void decreaseDeviceVolume() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDeviceMuted(boolean muted) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setForegroundMode(boolean foregroundMode) {
|
public void setForegroundMode(boolean foregroundMode) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
@ -0,0 +1,399 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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 com.google.android.exoplayer2.testutil;
|
||||||
|
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.view.Surface;
|
||||||
|
import android.view.SurfaceHolder;
|
||||||
|
import android.view.SurfaceView;
|
||||||
|
import android.view.TextureView;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import com.google.android.exoplayer2.BasePlayer;
|
||||||
|
import com.google.android.exoplayer2.DeviceInfo;
|
||||||
|
import com.google.android.exoplayer2.MediaItem;
|
||||||
|
import com.google.android.exoplayer2.MediaMetadata;
|
||||||
|
import com.google.android.exoplayer2.PlaybackException;
|
||||||
|
import com.google.android.exoplayer2.PlaybackParameters;
|
||||||
|
import com.google.android.exoplayer2.Player;
|
||||||
|
import com.google.android.exoplayer2.Timeline;
|
||||||
|
import com.google.android.exoplayer2.TracksInfo;
|
||||||
|
import com.google.android.exoplayer2.audio.AudioAttributes;
|
||||||
|
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||||
|
import com.google.android.exoplayer2.text.Cue;
|
||||||
|
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||||
|
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters;
|
||||||
|
import com.google.android.exoplayer2.video.VideoSize;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An abstract {@link Player} implementation that throws {@link UnsupportedOperationException} from
|
||||||
|
* every method.
|
||||||
|
*/
|
||||||
|
public class StubPlayer extends BasePlayer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Looper getApplicationLooper() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addListener(Listener listener) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeListener(Listener listener) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@State
|
||||||
|
public int getPlaybackState() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@PlaybackSuppressionReason
|
||||||
|
public int getPlaybackSuppressionReason() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlaybackException getPlayerError() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void prepare() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMediaItems(List<MediaItem> mediaItems, boolean resetPosition) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMediaItems(List<MediaItem> mediaItems, int startIndex, long startPositionMs) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addMediaItems(int index, List<MediaItem> mediaItems) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void moveMediaItems(int fromIndex, int toIndex, int newIndex) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeMediaItems(int fromIndex, int toIndex) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Commands getAvailableCommands() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPlayWhenReady(boolean playWhenReady) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getPlayWhenReady() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRepeatMode(@RepeatMode int repeatMode) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRepeatMode() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setShuffleModeEnabled(boolean shuffleModeEnabled) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getShuffleModeEnabled() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLoading() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void seekTo(int mediaItemIndex, long positionMs) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getSeekBackIncrement() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getSeekForwardIncrement() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getMaxSeekToPreviousPosition() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPlaybackParameters(PlaybackParameters playbackParameters) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlaybackParameters getPlaybackParameters() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public void stop(boolean reset) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void release() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TrackGroupArray getCurrentTrackGroups() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TrackSelectionArray getCurrentTrackSelections() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TracksInfo getCurrentTracksInfo() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TrackSelectionParameters getTrackSelectionParameters() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTrackSelectionParameters(TrackSelectionParameters parameters) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MediaMetadata getMediaMetadata() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MediaMetadata getPlaylistMetadata() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPlaylistMetadata(MediaMetadata mediaMetadata) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Timeline getCurrentTimeline() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCurrentPeriodIndex() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCurrentMediaItemIndex() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getDuration() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getCurrentPosition() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getBufferedPosition() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getTotalBufferedDuration() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPlayingAd() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCurrentAdGroupIndex() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCurrentAdIndexInAdGroup() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getContentPosition() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getContentBufferedPosition() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AudioAttributes getAudioAttributes() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setVolume(float volume) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getVolume() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearVideoSurface() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearVideoSurface(@Nullable Surface surface) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setVideoSurface(@Nullable Surface surface) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setVideoSurfaceHolder(@Nullable SurfaceHolder surfaceHolder) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearVideoSurfaceHolder(@Nullable SurfaceHolder surfaceHolder) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setVideoSurfaceView(@Nullable SurfaceView surfaceView) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearVideoSurfaceView(@Nullable SurfaceView surfaceView) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setVideoTextureView(@Nullable TextureView textureView) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearVideoTextureView(@Nullable TextureView textureView) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VideoSize getVideoSize() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Cue> getCurrentCues() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DeviceInfo getDeviceInfo() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDeviceVolume() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDeviceMuted() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDeviceVolume(int volume) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void increaseDeviceVolume() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decreaseDeviceVolume() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDeviceMuted(boolean muted) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user