Commit 03569f9e by Ian Baker Committed by GitHub

Merge pull request #10349 from google/dev-v2-r2.18.0

r2.18.0
parents a308c691 85d8682b
Showing with 1604 additions and 416 deletions
......@@ -18,6 +18,7 @@ body:
label: ExoPlayer Version
description: What version of ExoPlayer are you using?
options:
- 2.18.0
- 2.17.1
- 2.17.0
- 2.16.1
......
......@@ -17,7 +17,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.0.3'
classpath 'com.android.tools.build:gradle:7.2.1'
classpath 'com.google.android.gms:strict-version-matcher-plugin:1.2.2'
}
}
......
......@@ -29,5 +29,10 @@ android {
targetCompatibility JavaVersion.VERSION_1_8
}
testOptions.unitTests.includeAndroidResources = true
testOptions {
unitTests.all {
jvmArgs "-Xmx2g"
}
unitTests.includeAndroidResources true
}
}
......@@ -13,21 +13,21 @@
// limitations under the License.
project.ext {
// ExoPlayer version and version code.
releaseVersion = '2.17.1'
releaseVersionCode = 2_017_001
releaseVersion = '2.18.0'
releaseVersionCode = 2_018_000
minSdkVersion = 16
appTargetSdkVersion = 29
// Upgrading this requires [Internal ref: b/193254928] to be fixed, or some
// additional robolectric config.
targetSdkVersion = 30
compileSdkVersion = 31
compileSdkVersion = 32
dexmakerVersion = '2.28.1'
junitVersion = '4.13.2'
// Use the same Guava version as the Android repo:
// https://cs.android.com/android/platform/superproject/+/master:external/guava/METADATA
guavaVersion = '31.0.1-android'
mockitoVersion = '3.12.4'
robolectricVersion = '4.6.1'
robolectricVersion = '4.8.1'
// Keep this in sync with Google's internal Checker Framework version.
checkerframeworkVersion = '3.13.0'
checkerframeworkCompatVersion = '2.5.5'
......
......@@ -230,8 +230,8 @@ public class MainActivity extends AppCompatActivity
@Override
public boolean onMove(
RecyclerView list, RecyclerView.ViewHolder origin, RecyclerView.ViewHolder target) {
int fromPosition = origin.getAdapterPosition();
int toPosition = target.getAdapterPosition();
int fromPosition = origin.getBindingAdapterPosition();
int toPosition = target.getBindingAdapterPosition();
if (draggingFromPosition == C.INDEX_UNSET) {
// A drag has started, but changes to the media queue will be reflected in clearView().
draggingFromPosition = fromPosition;
......@@ -243,7 +243,7 @@ public class MainActivity extends AppCompatActivity
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
int position = viewHolder.getAdapterPosition();
int position = viewHolder.getBindingAdapterPosition();
QueueItemViewHolder queueItemHolder = (QueueItemViewHolder) viewHolder;
if (playerManager.removeItem(queueItemHolder.item)) {
mediaQueueListAdapter.notifyItemRemoved(position);
......@@ -282,7 +282,7 @@ public class MainActivity extends AppCompatActivity
@Override
public void onClick(View v) {
playerManager.selectQueueItem(getAdapterPosition());
playerManager.selectQueueItem(getBindingAdapterPosition());
}
}
......
......@@ -25,7 +25,7 @@ import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Player.DiscontinuityReason;
import com.google.android.exoplayer2.Player.TimelineChangeReason;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.TracksInfo;
import com.google.android.exoplayer2.Tracks;
import com.google.android.exoplayer2.ext.cast.CastPlayer;
import com.google.android.exoplayer2.ext.cast.SessionAvailabilityListener;
import com.google.android.exoplayer2.ui.StyledPlayerControlView;
......@@ -57,7 +57,7 @@ import java.util.ArrayList;
private final ArrayList<MediaItem> mediaQueue;
private final Listener listener;
private TracksInfo lastSeenTrackGroupInfo;
private Tracks lastSeenTracks;
private int currentItemIndex;
private Player currentPlayer;
......@@ -219,19 +219,19 @@ import java.util.ArrayList;
}
@Override
public void onTracksInfoChanged(TracksInfo tracksInfo) {
if (currentPlayer != localPlayer || tracksInfo == lastSeenTrackGroupInfo) {
public void onTracksChanged(Tracks tracks) {
if (currentPlayer != localPlayer || tracks == lastSeenTracks) {
return;
}
if (!tracksInfo.isTypeSupportedOrEmpty(
C.TRACK_TYPE_VIDEO, /* allowExceedsCapabilities= */ true)) {
if (tracks.containsType(C.TRACK_TYPE_VIDEO)
&& !tracks.isTypeSupported(C.TRACK_TYPE_VIDEO, /* allowExceedsCapabilities= */ true)) {
listener.onUnsupportedTrack(C.TRACK_TYPE_VIDEO);
}
if (!tracksInfo.isTypeSupportedOrEmpty(
C.TRACK_TYPE_AUDIO, /* allowExceedsCapabilities= */ true)) {
if (tracks.containsType(C.TRACK_TYPE_AUDIO)
&& !tracks.isTypeSupported(C.TRACK_TYPE_AUDIO, /* allowExceedsCapabilities= */ true)) {
listener.onUnsupportedTrack(C.TRACK_TYPE_AUDIO);
}
lastSeenTrackGroupInfo = tracksInfo;
lastSeenTracks = tracks;
}
// CastPlayer.SessionAvailabilityListener implementation.
......
......@@ -27,6 +27,7 @@ import android.graphics.drawable.BitmapDrawable;
import android.opengl.GLES20;
import android.opengl.GLUtils;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.GlProgram;
import com.google.android.exoplayer2.util.GlUtil;
import java.io.IOException;
import java.util.Locale;
......@@ -50,7 +51,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private final Bitmap logoBitmap;
private final Canvas overlayCanvas;
private GlUtil.@MonotonicNonNull Program program;
private @MonotonicNonNull GlProgram program;
private float bitmapScaleX;
private float bitmapScaleY;
......@@ -78,7 +79,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
public void initialize() {
try {
program =
new GlUtil.Program(
new GlProgram(
context,
/* vertexShaderFilePath= */ "bitmap_overlay_video_processor_vertex.glsl",
/* fragmentShaderFilePath= */ "bitmap_overlay_video_processor_fragment.glsl");
......@@ -86,9 +87,13 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
throw new IllegalStateException(e);
}
program.setBufferAttribute(
"aFramePosition", GlUtil.getNormalizedCoordinateBounds(), GlUtil.RECTANGLE_VERTICES_COUNT);
"aFramePosition",
GlUtil.getNormalizedCoordinateBounds(),
GlUtil.HOMOGENEOUS_COORDINATE_VECTOR_SIZE);
program.setBufferAttribute(
"aTexCoords", GlUtil.getTextureCoordinateBounds(), GlUtil.RECTANGLE_VERTICES_COUNT);
"aTexCoords",
GlUtil.getTextureCoordinateBounds(),
GlUtil.HOMOGENEOUS_COORDINATE_VECTOR_SIZE);
GLES20.glGenTextures(1, textures, 0);
GLES20.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
GLES20.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
......@@ -117,9 +122,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
GlUtil.checkGlError();
// Run the shader program.
GlUtil.Program program = checkNotNull(this.program);
program.setSamplerTexIdUniform("uTexSampler0", frameTexture, /* unit= */ 0);
program.setSamplerTexIdUniform("uTexSampler1", textures[0], /* unit= */ 1);
GlProgram program = checkNotNull(this.program);
program.setSamplerTexIdUniform("uTexSampler0", frameTexture, /* texUnitIndex= */ 0);
program.setSamplerTexIdUniform("uTexSampler1", textures[0], /* texUnitIndex= */ 1);
program.setFloatUniform("uScaleX", bitmapScaleX);
program.setFloatUniform("uScaleY", bitmapScaleY);
program.setFloatsUniform("uTexTransform", transformMatrix);
......
......@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.widget.FrameLayout;
import android.widget.Toast;
import androidx.annotation.Nullable;
......@@ -38,7 +39,6 @@ import com.google.android.exoplayer2.ui.StyledPlayerView;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultDataSource;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.EventLogger;
import com.google.android.exoplayer2.util.GlUtil;
......@@ -144,7 +144,7 @@ public final class MainActivity extends Activity {
String drmScheme = Assertions.checkNotNull(intent.getStringExtra(DRM_SCHEME_EXTRA));
String drmLicenseUrl = Assertions.checkNotNull(intent.getStringExtra(DRM_LICENSE_URL_EXTRA));
UUID drmSchemeUuid = Assertions.checkNotNull(Util.getDrmUuid(drmScheme));
HttpDataSource.Factory licenseDataSourceFactory = new DefaultHttpDataSource.Factory();
DataSource.Factory licenseDataSourceFactory = new DefaultHttpDataSource.Factory();
HttpMediaDrmCallback drmCallback =
new HttpMediaDrmCallback(drmLicenseUrl, licenseDataSourceFactory);
drmSessionManager =
......@@ -157,13 +157,18 @@ public final class MainActivity extends Activity {
DataSource.Factory dataSourceFactory = new DefaultDataSource.Factory(this);
MediaSource mediaSource;
@C.ContentType int type = Util.inferContentType(uri, intent.getStringExtra(EXTENSION_EXTRA));
if (type == C.TYPE_DASH) {
@Nullable String fileExtension = intent.getStringExtra(EXTENSION_EXTRA);
@C.ContentType
int type =
TextUtils.isEmpty(fileExtension)
? Util.inferContentType(uri)
: Util.inferContentTypeForExtension(fileExtension);
if (type == C.CONTENT_TYPE_DASH) {
mediaSource =
new DashMediaSource.Factory(dataSourceFactory)
.setDrmSessionManagerProvider(unusedMediaItem -> drmSessionManager)
.createMediaSource(MediaItem.fromUri(uri));
} else if (type == C.TYPE_OTHER) {
} else if (type == C.CONTENT_TYPE_OTHER) {
mediaSource =
new ProgressiveMediaSource.Factory(dataSourceFactory)
.setDrmSessionManagerProvider(unusedMediaItem -> drmSessionManager)
......@@ -181,7 +186,7 @@ public final class MainActivity extends Activity {
Assertions.checkNotNull(this.videoProcessingGLSurfaceView);
videoProcessingGLSurfaceView.setPlayer(player);
Assertions.checkNotNull(playerView).setPlayer(player);
player.addAnalyticsListener(new EventLogger(/* trackSelector= */ null));
player.addAnalyticsListener(new EventLogger());
this.player = player;
}
......
......@@ -27,7 +27,6 @@ import com.google.android.exoplayer2.ui.DownloadNotificationHelper;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultDataSource;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.upstream.cache.Cache;
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor;
......@@ -59,7 +58,7 @@ public final class DemoUtil {
private static final String DOWNLOAD_CONTENT_DIRECTORY = "downloads";
private static DataSource.@MonotonicNonNull Factory dataSourceFactory;
private static HttpDataSource.@MonotonicNonNull Factory httpDataSourceFactory;
private static DataSource.@MonotonicNonNull Factory httpDataSourceFactory;
private static @MonotonicNonNull DatabaseProvider databaseProvider;
private static @MonotonicNonNull File downloadDirectory;
private static @MonotonicNonNull Cache downloadCache;
......@@ -85,7 +84,7 @@ public final class DemoUtil {
.setExtensionRendererMode(extensionRendererMode);
}
public static synchronized HttpDataSource.Factory getHttpDataSourceFactory(Context context) {
public static synchronized DataSource.Factory getHttpDataSourceFactory(Context context) {
if (httpDataSourceFactory == null) {
if (USE_CRONET_FOR_NETWORKING) {
context = context.getApplicationContext();
......
......@@ -15,8 +15,7 @@
*/
package com.google.android.exoplayer2.demo;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull;
import static com.google.common.base.Preconditions.checkNotNull;
import android.content.Context;
import android.content.DialogInterface;
......@@ -29,6 +28,7 @@ import androidx.fragment.app.FragmentManager;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.RenderersFactory;
import com.google.android.exoplayer2.Tracks;
import com.google.android.exoplayer2.drm.DrmInitData;
import com.google.android.exoplayer2.drm.DrmSession;
import com.google.android.exoplayer2.drm.DrmSessionEventListener;
......@@ -43,9 +43,9 @@ import com.google.android.exoplayer2.offline.DownloadRequest;
import com.google.android.exoplayer2.offline.DownloadService;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;
......@@ -65,31 +65,26 @@ public class DownloadTracker {
private static final String TAG = "DownloadTracker";
private final Context context;
private final HttpDataSource.Factory httpDataSourceFactory;
private final DataSource.Factory dataSourceFactory;
private final CopyOnWriteArraySet<Listener> listeners;
private final HashMap<Uri, Download> downloads;
private final DownloadIndex downloadIndex;
private final DefaultTrackSelector.Parameters trackSelectorParameters;
@Nullable private StartDownloadDialogHelper startDownloadDialogHelper;
public DownloadTracker(
Context context,
HttpDataSource.Factory httpDataSourceFactory,
DownloadManager downloadManager) {
Context context, DataSource.Factory dataSourceFactory, DownloadManager downloadManager) {
this.context = context.getApplicationContext();
this.httpDataSourceFactory = httpDataSourceFactory;
this.dataSourceFactory = dataSourceFactory;
listeners = new CopyOnWriteArraySet<>();
downloads = new HashMap<>();
downloadIndex = downloadManager.getDownloadIndex();
trackSelectorParameters = DownloadHelper.getDefaultTrackSelectorParameters(context);
downloadManager.addListener(new DownloadManagerListener());
loadDownloads();
}
public void addListener(Listener listener) {
checkNotNull(listener);
listeners.add(listener);
listeners.add(checkNotNull(listener));
}
public void removeListener(Listener listener) {
......@@ -120,8 +115,7 @@ public class DownloadTracker {
startDownloadDialogHelper =
new StartDownloadDialogHelper(
fragmentManager,
DownloadHelper.forMediaItem(
context, mediaItem, renderersFactory, httpDataSourceFactory),
DownloadHelper.forMediaItem(context, mediaItem, renderersFactory, dataSourceFactory),
mediaItem);
}
}
......@@ -159,7 +153,7 @@ public class DownloadTracker {
private final class StartDownloadDialogHelper
implements DownloadHelper.Callback,
DialogInterface.OnClickListener,
TrackSelectionDialog.TrackSelectionListener,
DialogInterface.OnDismissListener {
private final FragmentManager fragmentManager;
......@@ -167,7 +161,6 @@ public class DownloadTracker {
private final MediaItem mediaItem;
private TrackSelectionDialog trackSelectionDialog;
private MappedTrackInfo mappedTrackInfo;
private WidevineOfflineLicenseFetchTask widevineOfflineLicenseFetchTask;
@Nullable private byte[] keySetId;
......@@ -220,7 +213,7 @@ public class DownloadTracker {
new WidevineOfflineLicenseFetchTask(
format,
mediaItem.localConfiguration.drmConfiguration,
httpDataSourceFactory,
dataSourceFactory,
/* dialogHelper= */ this,
helper);
widevineOfflineLicenseFetchTask.execute();
......@@ -237,21 +230,13 @@ public class DownloadTracker {
Log.e(TAG, logMessage, e);
}
// DialogInterface.OnClickListener implementation.
// TrackSelectionListener implementation.
@Override
public void onClick(DialogInterface dialog, int which) {
public void onTracksSelected(TrackSelectionParameters trackSelectionParameters) {
for (int periodIndex = 0; periodIndex < downloadHelper.getPeriodCount(); periodIndex++) {
downloadHelper.clearTrackSelections(periodIndex);
for (int i = 0; i < mappedTrackInfo.getRendererCount(); i++) {
if (!trackSelectionDialog.getIsDisabled(/* rendererIndex= */ i)) {
downloadHelper.addTrackSelectionForSingleRenderer(
periodIndex,
/* rendererIndex= */ i,
trackSelectorParameters,
trackSelectionDialog.getOverrides(/* rendererIndex= */ i));
}
}
downloadHelper.addTrackSelection(periodIndex, trackSelectionParameters);
}
DownloadRequest downloadRequest = buildDownloadRequest();
if (downloadRequest.streamKeys.isEmpty()) {
......@@ -316,21 +301,21 @@ public class DownloadTracker {
return;
}
mappedTrackInfo = downloadHelper.getMappedTrackInfo(/* periodIndex= */ 0);
if (!TrackSelectionDialog.willHaveContent(mappedTrackInfo)) {
Tracks tracks = downloadHelper.getTracks(/* periodIndex= */ 0);
if (!TrackSelectionDialog.willHaveContent(tracks)) {
Log.d(TAG, "No dialog content. Downloading entire stream.");
startDownload();
downloadHelper.release();
return;
}
trackSelectionDialog =
TrackSelectionDialog.createForMappedTrackInfoAndParameters(
TrackSelectionDialog.createForTracksAndParameters(
/* titleId= */ R.string.exo_download_description,
mappedTrackInfo,
trackSelectorParameters,
tracks,
DownloadHelper.getDefaultTrackSelectorParameters(context),
/* allowAdaptiveSelections= */ false,
/* allowMultipleOverrides= */ true,
/* onClickListener= */ this,
/* onTracksSelectedListener= */ this,
/* onDismissListener= */ this);
trackSelectionDialog.show(fragmentManager, /* tag= */ null);
}
......@@ -371,7 +356,7 @@ public class DownloadTracker {
private final Format format;
private final MediaItem.DrmConfiguration drmConfiguration;
private final HttpDataSource.Factory httpDataSourceFactory;
private final DataSource.Factory dataSourceFactory;
private final StartDownloadDialogHelper dialogHelper;
private final DownloadHelper downloadHelper;
......@@ -381,12 +366,12 @@ public class DownloadTracker {
public WidevineOfflineLicenseFetchTask(
Format format,
MediaItem.DrmConfiguration drmConfiguration,
HttpDataSource.Factory httpDataSourceFactory,
DataSource.Factory dataSourceFactory,
StartDownloadDialogHelper dialogHelper,
DownloadHelper downloadHelper) {
this.format = format;
this.drmConfiguration = drmConfiguration;
this.httpDataSourceFactory = httpDataSourceFactory;
this.dataSourceFactory = dataSourceFactory;
this.dialogHelper = dialogHelper;
this.downloadHelper = downloadHelper;
}
......@@ -397,7 +382,7 @@ public class DownloadTracker {
OfflineLicenseHelper.newWidevineInstance(
drmConfiguration.licenseUri.toString(),
drmConfiguration.forceDefaultLicenseUri,
httpDataSourceFactory,
dataSourceFactory,
drmConfiguration.licenseRequestHeaders,
new DrmSessionEventListener.EventDispatcher());
try {
......@@ -415,7 +400,7 @@ public class DownloadTracker {
if (drmSessionException != null) {
dialogHelper.onOfflineLicenseFetchedError(drmSessionException);
} else {
dialogHelper.onOfflineLicenseFetched(downloadHelper, checkStateNotNull(keySetId));
dialogHelper.onOfflineLicenseFetched(downloadHelper, checkNotNull(keySetId));
}
}
}
......
......@@ -15,8 +15,9 @@
*/
package com.google.android.exoplayer2.demo;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import android.content.Intent;
import android.net.Uri;
......@@ -26,7 +27,6 @@ import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.MediaItem.ClippingConfiguration;
import com.google.android.exoplayer2.MediaItem.SubtitleConfiguration;
import com.google.android.exoplayer2.MediaMetadata;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
......@@ -87,7 +87,7 @@ public class IntentUtil {
/** Populates the intent with the given list of {@link MediaItem media items}. */
public static void addToIntent(List<MediaItem> mediaItems, Intent intent) {
Assertions.checkArgument(!mediaItems.isEmpty());
checkArgument(!mediaItems.isEmpty());
if (mediaItems.size() == 1) {
MediaItem mediaItem = mediaItems.get(0);
MediaItem.LocalConfiguration localConfiguration = checkNotNull(mediaItem.localConfiguration);
......@@ -178,7 +178,7 @@ public class IntentUtil {
headers.put(keyRequestPropertiesArray[i], keyRequestPropertiesArray[i + 1]);
}
}
@Nullable UUID drmUuid = Util.getDrmUuid(Util.castNonNull(drmSchemeExtra));
@Nullable UUID drmUuid = Util.getDrmUuid(drmSchemeExtra);
if (drmUuid != null) {
builder.setDrmConfiguration(
new MediaItem.DrmConfiguration.Builder(drmUuid)
......@@ -189,7 +189,7 @@ public class IntentUtil {
intent.getBooleanExtra(
DRM_FORCE_DEFAULT_LICENSE_URI_EXTRA + extrasKeySuffix, false))
.setLicenseRequestHeaders(headers)
.forceSessionsForAudioAndVideoTracks(
.setForceSessionsForAudioAndVideoTracks(
intent.getBooleanExtra(DRM_SESSION_FOR_CLEAR_CONTENT + extrasKeySuffix, false))
.build());
}
......@@ -242,7 +242,7 @@ public class IntentUtil {
drmConfiguration.forcedSessionTrackTypes;
if (!forcedDrmSessionTrackTypes.isEmpty()) {
// Only video and audio together are supported.
Assertions.checkState(
checkState(
forcedDrmSessionTrackTypes.size() == 2
&& forcedDrmSessionTrackTypes.contains(C.TRACK_TYPE_VIDEO)
&& forcedDrmSessionTrackTypes.contains(C.TRACK_TYPE_AUDIO));
......
......@@ -15,9 +15,9 @@
*/
package com.google.android.exoplayer2.demo;
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.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import android.content.Context;
import android.content.Intent;
......@@ -27,6 +27,7 @@ import android.content.res.AssetManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.JsonReader;
import android.view.Menu;
import android.view.MenuInflater;
......@@ -53,6 +54,7 @@ import com.google.android.exoplayer2.upstream.DataSourceUtil;
import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.Util;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.io.IOException;
......@@ -116,8 +118,11 @@ public class SampleChooserActivity extends AppCompatActivity
useExtensionRenderers = DemoUtil.useExtensionRenderers();
downloadTracker = DemoUtil.getDownloadTracker(/* context= */ this);
loadSample();
startDownloadService();
}
// Start the download service if it should be running but it's not currently.
/** Start the download service if it should be running but it's not currently. */
private void startDownloadService() {
// Starting the service in the foreground causes notification flicker if there is no scheduled
// action. Starting it in the background throws an exception if the app is in the background too
// (e.g. if device screen is locked).
......@@ -436,7 +441,10 @@ public class SampleChooserActivity extends AppCompatActivity
} else {
@Nullable
String adaptiveMimeType =
Util.getAdaptiveMimeTypeForContentType(Util.inferContentType(uri, extension));
Util.getAdaptiveMimeTypeForContentType(
TextUtils.isEmpty(extension)
? Util.inferContentType(uri)
: Util.inferContentTypeForExtension(extension));
mediaItem
.setUri(uri)
.setMediaMetadata(new MediaMetadata.Builder().setTitle(title).build())
......@@ -447,7 +455,7 @@ public class SampleChooserActivity extends AppCompatActivity
new MediaItem.DrmConfiguration.Builder(drmUuid)
.setLicenseUri(drmLicenseUri)
.setLicenseRequestHeaders(drmLicenseRequestHeaders)
.forceSessionsForAudioAndVideoTracks(drmSessionForClearContent)
.setForceSessionsForAudioAndVideoTracks(drmSessionForClearContent)
.setMultiSession(drmMultiSession)
.setForceDefaultLicenseUri(drmForceDefaultLicenseUri)
.build());
......@@ -481,7 +489,7 @@ public class SampleChooserActivity extends AppCompatActivity
private PlaylistGroup getGroup(String groupName, List<PlaylistGroup> groups) {
for (int i = 0; i < groups.size(); i++) {
if (Util.areEqual(groupName, groups.get(i).title)) {
if (Objects.equal(groupName, groups.get(i).title)) {
return groups.get(i);
}
}
......
......@@ -19,6 +19,7 @@ import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceHolder;
......@@ -42,7 +43,6 @@ import com.google.android.exoplayer2.ui.PlayerControlView;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultDataSource;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util;
import java.util.UUID;
......@@ -189,7 +189,7 @@ public final class MainActivity extends Activity {
String drmScheme = Assertions.checkNotNull(intent.getStringExtra(DRM_SCHEME_EXTRA));
String drmLicenseUrl = Assertions.checkNotNull(intent.getStringExtra(DRM_LICENSE_URL_EXTRA));
UUID drmSchemeUuid = Assertions.checkNotNull(Util.getDrmUuid(drmScheme));
HttpDataSource.Factory licenseDataSourceFactory = new DefaultHttpDataSource.Factory();
DataSource.Factory licenseDataSourceFactory = new DefaultHttpDataSource.Factory();
HttpMediaDrmCallback drmCallback =
new HttpMediaDrmCallback(drmLicenseUrl, licenseDataSourceFactory);
drmSessionManager =
......@@ -202,13 +202,18 @@ public final class MainActivity extends Activity {
DataSource.Factory dataSourceFactory = new DefaultDataSource.Factory(this);
MediaSource mediaSource;
@C.ContentType int type = Util.inferContentType(uri, intent.getStringExtra(EXTENSION_EXTRA));
if (type == C.TYPE_DASH) {
@Nullable String fileExtension = intent.getStringExtra(EXTENSION_EXTRA);
@C.ContentType
int type =
TextUtils.isEmpty(fileExtension)
? Util.inferContentType(uri)
: Util.inferContentTypeForExtension(fileExtension);
if (type == C.CONTENT_TYPE_DASH) {
mediaSource =
new DashMediaSource.Factory(dataSourceFactory)
.setDrmSessionManagerProvider(unusedMediaItem -> drmSessionManager)
.createMediaSource(MediaItem.fromUri(uri));
} else if (type == C.TYPE_OTHER) {
} else if (type == C.CONTENT_TYPE_OTHER) {
mediaSource =
new ProgressiveMediaSource.Factory(dataSourceFactory)
.setDrmSessionManagerProvider(unusedMediaItem -> drmSessionManager)
......
# Build targets for a demo MediaPipe graph.
# See README.md for instructions on using MediaPipe in the demo.
load("//mediapipe/java/com/google/mediapipe:mediapipe_aar.bzl", "mediapipe_aar")
load(
"//mediapipe/framework/tool:mediapipe_graph.bzl",
"mediapipe_binary_graph",
)
mediapipe_aar(
name = "edge_detector_mediapipe_aar",
calculators = [
"//mediapipe/calculators/image:luminance_calculator",
"//mediapipe/calculators/image:sobel_edges_calculator",
],
)
mediapipe_binary_graph(
name = "edge_detector_binary_graph",
graph = "edge_detector_mediapipe_graph.pbtxt",
output_name = "edge_detector_mediapipe_graph.binarypb",
)
......@@ -6,4 +6,61 @@ example by removing audio or video.
See the [demos README](../README.md) for instructions on how to build and run
this demo.
## MediaPipe frame processing demo
Building the demo app with [MediaPipe][] integration enabled requires some extra
manual steps.
1. Follow the
[instructions](https://google.github.io/mediapipe/getting_started/install.html)
to install MediaPipe.
1. Copy the Transformer demo's build configuration and MediaPipe graph text
protocol buffer under the MediaPipe source tree. This makes it easy to
[build an AAR][] with bazel by reusing MediaPipe's workspace.
```sh
cd "<path to MediaPipe checkout>"
MEDIAPIPE_ROOT="$(pwd)"
MEDIAPIPE_TRANSFORMER_ROOT="${MEDIAPIPE_ROOT}/mediapipe/java/com/google/mediapipe/transformer"
cd "<path to the transformer demo (containing this readme)>"
TRANSFORMER_DEMO_ROOT="$(pwd)"
mkdir -p "${MEDIAPIPE_TRANSFORMER_ROOT}"
mkdir -p "${TRANSFORMER_DEMO_ROOT}/libs"
cp ${TRANSFORMER_DEMO_ROOT}/BUILD.bazel ${MEDIAPIPE_TRANSFORMER_ROOT}/BUILD
cp ${TRANSFORMER_DEMO_ROOT}/src/withMediaPipe/assets/edge_detector_mediapipe_graph.pbtxt \
${MEDIAPIPE_TRANSFORMER_ROOT}
```
1. Build the AAR and the binary proto for the demo's MediaPipe graph, then copy
them to Transformer.
```sh
cd ${MEDIAPIPE_ROOT}
bazel build -c opt --strip=ALWAYS \
--host_crosstool_top=@bazel_tools//tools/cpp:toolchain \
--fat_apk_cpu=arm64-v8a,armeabi-v7a \
--legacy_whole_archive=0 \
--features=-legacy_whole_archive \
--copt=-fvisibility=hidden \
--copt=-ffunction-sections \
--copt=-fdata-sections \
--copt=-fstack-protector \
--copt=-Oz \
--copt=-fomit-frame-pointer \
--copt=-DABSL_MIN_LOG_LEVEL=2 \
--linkopt=-Wl,--gc-sections,--strip-all \
mediapipe/java/com/google/mediapipe/transformer:edge_detector_mediapipe_aar.aar
cp bazel-bin/mediapipe/java/com/google/mediapipe/transformer/edge_detector_mediapipe_aar.aar \
${TRANSFORMER_DEMO_ROOT}/libs
bazel build mediapipe/java/com/google/mediapipe/transformer:edge_detector_binary_graph
cp bazel-bin/mediapipe/java/com/google/mediapipe/transformer/edge_detector_mediapipe_graph.binarypb \
${TRANSFORMER_DEMO_ROOT}/src/withMediaPipe/assets
```
1. In Android Studio, gradle sync and select the `withMediaPipe` build variant
(this will only appear if the AAR is present), then build and run the demo
app and select a MediaPipe-based effect.
[Transformer]: https://exoplayer.dev/transforming-media.html
[MediaPipe]: https://google.github.io/mediapipe/
[build an AAR]: https://google.github.io/mediapipe/getting_started/android_archive_library.html
......@@ -45,6 +45,27 @@ android {
// This demo app isn't indexed and doesn't have translations.
disable 'GoogleAppIndexingWarning','MissingTranslation'
}
flavorDimensions "mediaPipe"
productFlavors {
noMediaPipe {
dimension "mediaPipe"
}
withMediaPipe {
dimension "mediaPipe"
}
}
// Ignore the withMediaPipe variant if the MediaPipe AAR is not present.
if (!project.file("libs/edge_detector_mediapipe_aar.aar").exists()) {
variantFilter { variant ->
def names = variant.flavors*.name
if (names.contains("withMediaPipe")) {
setIgnore(true)
}
}
}
}
dependencies {
......@@ -56,6 +77,14 @@ dependencies {
implementation 'androidx.multidex:multidex:' + androidxMultidexVersion
implementation 'com.google.android.material:material:' + androidxMaterialVersion
implementation project(modulePrefix + 'library-core')
implementation project(modulePrefix + 'library-dash')
implementation project(modulePrefix + 'library-transformer')
implementation project(modulePrefix + 'library-ui')
// For MediaPipe and its dependencies:
withMediaPipeImplementation fileTree(dir: 'libs', include: ['*.aar'])
withMediaPipeImplementation 'com.google.flogger:flogger:latest.release'
withMediaPipeImplementation 'com.google.flogger:flogger-system-backend:latest.release'
withMediaPipeImplementation 'com.google.code.findbugs:jsr305:latest.release'
withMediaPipeImplementation 'com.google.protobuf:protobuf-javalite:3.19.1'
}
#version 100
// Copyright 2022 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ES 2 fragment shader that overlays the bitmap from uTexSampler1 over a video
// frame from uTexSampler0.
precision mediump float;
// Texture containing an input video frame.
uniform sampler2D uTexSampler0;
// Texture containing the overlap bitmap.
uniform sampler2D uTexSampler1;
// Horizontal scaling factor for the overlap bitmap.
uniform float uScaleX;
// Vertical scaling factory for the overlap bitmap.
uniform float uScaleY;
varying vec2 vTexSamplingCoord;
void main() {
vec4 videoColor = texture2D(uTexSampler0, vTexSamplingCoord);
vec4 overlayColor = texture2D(uTexSampler1,
vec2(vTexSamplingCoord.x * uScaleX,
vTexSamplingCoord.y * uScaleY));
// Blend the video decoder output and the overlay bitmap.
gl_FragColor = videoColor * (1.0 - overlayColor.a)
+ overlayColor * overlayColor.a;
}
#version 100
// Copyright 2022 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ES 2 fragment shader that samples from a (non-external) texture with uTexSampler,
// copying from this texture to the current output while applying a vignette effect
// by linearly darkening the pixels between uInnerRadius and uOuterRadius.
precision mediump float;
uniform sampler2D uTexSampler;
uniform vec2 uCenter;
uniform float uInnerRadius;
uniform float uOuterRadius;
varying vec2 vTexSamplingCoord;
void main() {
vec3 src = texture2D(uTexSampler, vTexSamplingCoord).xyz;
float dist = distance(vTexSamplingCoord, uCenter);
float scale = clamp(1.0 - (dist - uInnerRadius) / (uOuterRadius - uInnerRadius), 0.0, 1.0);
gl_FragColor = vec4(src.r * scale, src.g * scale, src.b * scale, 1.0);
}
#version 100
// Copyright 2022 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ES 2 vertex shader that leaves the coordinates unchanged.
attribute vec4 aFramePosition;
varying vec2 vTexSamplingCoord;
void main() {
gl_Position = aFramePosition;
vTexSamplingCoord = vec2(aFramePosition.x * 0.5 + 0.5, aFramePosition.y * 0.5 + 0.5);
}
/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.transformerdemo;
import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.opengl.GLES20;
import android.opengl.GLUtils;
import android.util.Size;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.transformer.FrameProcessingException;
import com.google.android.exoplayer2.transformer.SingleFrameGlTextureProcessor;
import com.google.android.exoplayer2.util.GlProgram;
import com.google.android.exoplayer2.util.GlUtil;
import java.io.IOException;
import java.util.Locale;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/**
* A {@link SingleFrameGlTextureProcessor} that overlays a bitmap with a logo and timer on each
* frame.
*
* <p>The bitmap is drawn using an Android {@link Canvas}.
*/
// TODO(b/227625365): Delete this class and use a texture processor from the Transformer library,
// once overlaying a bitmap and text is supported in Transformer.
/* package */ final class BitmapOverlayProcessor implements SingleFrameGlTextureProcessor {
static {
GlUtil.glAssertionsEnabled = true;
}
private static final String VERTEX_SHADER_PATH = "vertex_shader_copy_es2.glsl";
private static final String FRAGMENT_SHADER_PATH = "fragment_shader_bitmap_overlay_es2.glsl";
private static final int BITMAP_WIDTH_HEIGHT = 512;
private final Paint paint;
private final Bitmap overlayBitmap;
private final Canvas overlayCanvas;
private float bitmapScaleX;
private float bitmapScaleY;
private int bitmapTexId;
private @MonotonicNonNull Size outputSize;
private @MonotonicNonNull Bitmap logoBitmap;
private @MonotonicNonNull GlProgram glProgram;
public BitmapOverlayProcessor() {
paint = new Paint();
paint.setTextSize(64);
paint.setAntiAlias(true);
paint.setARGB(0xFF, 0xFF, 0xFF, 0xFF);
paint.setColor(Color.GRAY);
overlayBitmap =
Bitmap.createBitmap(BITMAP_WIDTH_HEIGHT, BITMAP_WIDTH_HEIGHT, Bitmap.Config.ARGB_8888);
overlayCanvas = new Canvas(overlayBitmap);
}
@Override
public void initialize(Context context, int inputTexId, int inputWidth, int inputHeight)
throws IOException {
if (inputWidth > inputHeight) {
bitmapScaleX = inputWidth / (float) inputHeight;
bitmapScaleY = 1f;
} else {
bitmapScaleX = 1f;
bitmapScaleY = inputHeight / (float) inputWidth;
}
outputSize = new Size(inputWidth, inputHeight);
try {
logoBitmap =
((BitmapDrawable)
context.getPackageManager().getApplicationIcon(context.getPackageName()))
.getBitmap();
} catch (PackageManager.NameNotFoundException e) {
throw new IllegalStateException(e);
}
bitmapTexId = GlUtil.createTexture(BITMAP_WIDTH_HEIGHT, BITMAP_WIDTH_HEIGHT);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, /* level= */ 0, overlayBitmap, /* border= */ 0);
glProgram = new GlProgram(context, VERTEX_SHADER_PATH, FRAGMENT_SHADER_PATH);
// Draw the frame on the entire normalized device coordinate space, from -1 to 1, for x and y.
glProgram.setBufferAttribute(
"aFramePosition",
GlUtil.getNormalizedCoordinateBounds(),
GlUtil.HOMOGENEOUS_COORDINATE_VECTOR_SIZE);
glProgram.setSamplerTexIdUniform("uTexSampler0", inputTexId, /* texUnitIndex= */ 0);
glProgram.setSamplerTexIdUniform("uTexSampler1", bitmapTexId, /* texUnitIndex= */ 1);
glProgram.setFloatUniform("uScaleX", bitmapScaleX);
glProgram.setFloatUniform("uScaleY", bitmapScaleY);
}
@Override
public Size getOutputSize() {
return checkStateNotNull(outputSize);
}
@Override
public void drawFrame(long presentationTimeUs) throws FrameProcessingException {
try {
checkStateNotNull(glProgram).use();
// Draw to the canvas and store it in a texture.
String text =
String.format(Locale.US, "%.02f", presentationTimeUs / (float) C.MICROS_PER_SECOND);
overlayBitmap.eraseColor(Color.TRANSPARENT);
overlayCanvas.drawBitmap(checkStateNotNull(logoBitmap), /* left= */ 3, /* top= */ 378, paint);
overlayCanvas.drawText(text, /* x= */ 160, /* y= */ 466, paint);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, bitmapTexId);
GLUtils.texSubImage2D(
GLES20.GL_TEXTURE_2D,
/* level= */ 0,
/* xoffset= */ 0,
/* yoffset= */ 0,
flipBitmapVertically(overlayBitmap));
GlUtil.checkGlError();
glProgram.bindAttributesAndUniforms();
// The four-vertex triangle strip forms a quad.
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, /* first= */ 0, /* count= */ 4);
GlUtil.checkGlError();
} catch (GlUtil.GlException e) {
throw new FrameProcessingException(e);
}
}
@Override
public void release() {
if (glProgram != null) {
glProgram.delete();
}
}
private static Bitmap flipBitmapVertically(Bitmap bitmap) {
Matrix flip = new Matrix();
flip.postScale(1f, -1f);
return Bitmap.createBitmap(
bitmap,
/* x= */ 0,
/* y= */ 0,
bitmap.getWidth(),
bitmap.getHeight(),
flip,
/* filter= */ true);
}
}
/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.transformerdemo;
import android.graphics.Matrix;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.transformer.GlMatrixTransformation;
import com.google.android.exoplayer2.transformer.MatrixTransformation;
import com.google.android.exoplayer2.util.Util;
/**
* Factory for {@link GlMatrixTransformation GlMatrixTransformations} and {@link
* MatrixTransformation MatrixTransformations} that create video effects by applying transformation
* matrices to the individual video frames.
*/
/* package */ final class MatrixTransformationFactory {
/**
* Returns a {@link MatrixTransformation} that rescales the frames over the first {@value
* #ZOOM_DURATION_SECONDS} seconds, such that the rectangle filled with the input frame increases
* linearly in size from a single point to filling the full output frame.
*/
public static MatrixTransformation createZoomInTransition() {
return MatrixTransformationFactory::calculateZoomInTransitionMatrix;
}
/**
* Returns a {@link MatrixTransformation} that crops frames to a rectangle that moves on an
* ellipse.
*/
public static MatrixTransformation createDizzyCropEffect() {
return MatrixTransformationFactory::calculateDizzyCropMatrix;
}
/**
* Returns a {@link GlMatrixTransformation} that rotates a frame in 3D around the y-axis and
* applies perspective projection to 2D.
*/
public static GlMatrixTransformation createSpin3dEffect() {
return MatrixTransformationFactory::calculate3dSpinMatrix;
}
private static final float ZOOM_DURATION_SECONDS = 2f;
private static final float DIZZY_CROP_ROTATION_PERIOD_US = 1_500_000f;
private static Matrix calculateZoomInTransitionMatrix(long presentationTimeUs) {
Matrix transformationMatrix = new Matrix();
float scale = Math.min(1, presentationTimeUs / (C.MICROS_PER_SECOND * ZOOM_DURATION_SECONDS));
transformationMatrix.postScale(/* sx= */ scale, /* sy= */ scale);
return transformationMatrix;
}
private static android.graphics.Matrix calculateDizzyCropMatrix(long presentationTimeUs) {
double theta = presentationTimeUs * 2 * Math.PI / DIZZY_CROP_ROTATION_PERIOD_US;
float centerX = 0.5f * (float) Math.cos(theta);
float centerY = 0.5f * (float) Math.sin(theta);
android.graphics.Matrix transformationMatrix = new android.graphics.Matrix();
transformationMatrix.postTranslate(/* dx= */ centerX, /* dy= */ centerY);
transformationMatrix.postScale(/* sx= */ 2f, /* sy= */ 2f);
return transformationMatrix;
}
private static float[] calculate3dSpinMatrix(long presentationTimeUs) {
float[] transformationMatrix = new float[16];
android.opengl.Matrix.frustumM(
transformationMatrix,
/* offset= */ 0,
/* left= */ -1f,
/* right= */ 1f,
/* bottom= */ -1f,
/* top= */ 1f,
/* near= */ 3f,
/* far= */ 5f);
android.opengl.Matrix.translateM(
transformationMatrix, /* mOffset= */ 0, /* x= */ 0f, /* y= */ 0f, /* z= */ -4f);
float theta = Util.usToMs(presentationTimeUs) / 10f;
android.opengl.Matrix.rotateM(
transformationMatrix, /* mOffset= */ 0, theta, /* x= */ 0f, /* y= */ 1f, /* z= */ 0f);
return transformationMatrix;
}
}
/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.transformerdemo;
import static com.google.android.exoplayer2.util.Assertions.checkArgument;
import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull;
import android.content.Context;
import android.opengl.GLES20;
import android.util.Size;
import com.google.android.exoplayer2.transformer.FrameProcessingException;
import com.google.android.exoplayer2.transformer.SingleFrameGlTextureProcessor;
import com.google.android.exoplayer2.util.GlProgram;
import com.google.android.exoplayer2.util.GlUtil;
import java.io.IOException;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/**
* A {@link SingleFrameGlTextureProcessor} that periodically dims the frames such that pixels are
* darker the further they are away from the frame center.
*/
/* package */ final class PeriodicVignetteProcessor implements SingleFrameGlTextureProcessor {
static {
GlUtil.glAssertionsEnabled = true;
}
private static final String VERTEX_SHADER_PATH = "vertex_shader_copy_es2.glsl";
private static final String FRAGMENT_SHADER_PATH = "fragment_shader_vignette_es2.glsl";
private static final float DIMMING_PERIOD_US = 5_600_000f;
private float centerX;
private float centerY;
private float minInnerRadius;
private float deltaInnerRadius;
private float outerRadius;
private @MonotonicNonNull Size outputSize;
private @MonotonicNonNull GlProgram glProgram;
/**
* Creates a new instance.
*
* <p>The inner radius of the vignette effect oscillates smoothly between {@code minInnerRadius}
* and {@code maxInnerRadius}.
*
* <p>The pixels between the inner radius and the {@code outerRadius} are darkened linearly based
* on their distance from {@code innerRadius}. All pixels outside {@code outerRadius} are black.
*
* <p>The parameters are given in normalized texture coordinates from 0 to 1.
*
* @param centerX The x-coordinate of the center of the effect.
* @param centerY The y-coordinate of the center of the effect.
* @param minInnerRadius The lower bound of the radius that is unaffected by the effect.
* @param maxInnerRadius The upper bound of the radius that is unaffected by the effect.
* @param outerRadius The radius after which all pixels are black.
*/
public PeriodicVignetteProcessor(
float centerX, float centerY, float minInnerRadius, float maxInnerRadius, float outerRadius) {
checkArgument(minInnerRadius <= maxInnerRadius);
checkArgument(maxInnerRadius <= outerRadius);
this.centerX = centerX;
this.centerY = centerY;
this.minInnerRadius = minInnerRadius;
this.deltaInnerRadius = maxInnerRadius - minInnerRadius;
this.outerRadius = outerRadius;
}
@Override
public void initialize(Context context, int inputTexId, int inputWidth, int inputHeight)
throws IOException {
outputSize = new Size(inputWidth, inputHeight);
glProgram = new GlProgram(context, VERTEX_SHADER_PATH, FRAGMENT_SHADER_PATH);
glProgram.setSamplerTexIdUniform("uTexSampler", inputTexId, /* texUnitIndex= */ 0);
glProgram.setFloatsUniform("uCenter", new float[] {centerX, centerY});
glProgram.setFloatsUniform("uOuterRadius", new float[] {outerRadius});
// Draw the frame on the entire normalized device coordinate space, from -1 to 1, for x and y.
glProgram.setBufferAttribute(
"aFramePosition",
GlUtil.getNormalizedCoordinateBounds(),
GlUtil.HOMOGENEOUS_COORDINATE_VECTOR_SIZE);
}
@Override
public Size getOutputSize() {
return checkStateNotNull(outputSize);
}
@Override
public void drawFrame(long presentationTimeUs) throws FrameProcessingException {
try {
checkStateNotNull(glProgram).use();
double theta = presentationTimeUs * 2 * Math.PI / DIMMING_PERIOD_US;
float innerRadius =
minInnerRadius + deltaInnerRadius * (0.5f - 0.5f * (float) Math.cos(theta));
glProgram.setFloatsUniform("uInnerRadius", new float[] {innerRadius});
glProgram.bindAttributesAndUniforms();
// The four-vertex triangle strip forms a quad.
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, /* first= */ 0, /* count= */ 4);
} catch (GlUtil.GlException e) {
throw new FrameProcessingException(e);
}
}
@Override
public void release() {
if (glProgram != null) {
glProgram.delete();
}
}
}
......@@ -21,7 +21,6 @@ import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
......@@ -32,13 +31,19 @@ import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.transformer.DefaultEncoderFactory;
import com.google.android.exoplayer2.transformer.EncoderSelector;
import com.google.android.exoplayer2.transformer.GlEffect;
import com.google.android.exoplayer2.transformer.ProgressHolder;
import com.google.android.exoplayer2.transformer.SingleFrameGlTextureProcessor;
import com.google.android.exoplayer2.transformer.TransformationException;
import com.google.android.exoplayer2.transformer.TransformationRequest;
import com.google.android.exoplayer2.transformer.TransformationResult;
import com.google.android.exoplayer2.transformer.Transformer;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
import com.google.android.exoplayer2.ui.StyledPlayerView;
......@@ -48,8 +53,10 @@ import com.google.android.exoplayer2.util.Util;
import com.google.android.material.progressindicator.LinearProgressIndicator;
import com.google.common.base.Stopwatch;
import com.google.common.base.Ticker;
import com.google.common.collect.ImmutableList;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
......@@ -145,9 +152,10 @@ public final class TransformerActivity extends AppCompatActivity {
externalCacheFile = createExternalCacheFile("transformer-output.mp4");
String filePath = externalCacheFile.getAbsolutePath();
@Nullable Bundle bundle = intent.getExtras();
MediaItem mediaItem = createMediaItem(bundle, uri);
Transformer transformer = createTransformer(bundle, filePath);
transformationStopwatch.start();
transformer.startTransformation(MediaItem.fromUri(uri), filePath);
transformer.startTransformation(mediaItem, filePath);
this.transformer = transformer;
} catch (IOException e) {
throw new IllegalStateException(e);
......@@ -174,6 +182,24 @@ public final class TransformerActivity extends AppCompatActivity {
});
}
private MediaItem createMediaItem(@Nullable Bundle bundle, Uri uri) {
MediaItem.Builder mediaItemBuilder = new MediaItem.Builder().setUri(uri);
if (bundle != null) {
long trimStartMs =
bundle.getLong(ConfigurationActivity.TRIM_START_MS, /* defaultValue= */ C.TIME_UNSET);
long trimEndMs =
bundle.getLong(ConfigurationActivity.TRIM_END_MS, /* defaultValue= */ C.TIME_UNSET);
if (trimStartMs != C.TIME_UNSET && trimEndMs != C.TIME_UNSET) {
mediaItemBuilder.setClippingConfiguration(
new MediaItem.ClippingConfiguration.Builder()
.setStartPositionMs(trimStartMs)
.setEndPositionMs(trimEndMs)
.build());
}
}
return mediaItemBuilder.build();
}
// Create a cache file, resetting it if it already exists.
private File createExternalCacheFile(String fileName) throws IOException {
File file = new File(getExternalCacheDir(), fileName);
......@@ -214,22 +240,89 @@ public final class TransformerActivity extends AppCompatActivity {
if (resolutionHeight != C.LENGTH_UNSET) {
requestBuilder.setResolution(resolutionHeight);
}
Matrix transformationMatrix = getTransformationMatrix(bundle);
if (!transformationMatrix.isIdentity()) {
requestBuilder.setTransformationMatrix(transformationMatrix);
}
float scaleX = bundle.getFloat(ConfigurationActivity.SCALE_X, /* defaultValue= */ 1);
float scaleY = bundle.getFloat(ConfigurationActivity.SCALE_Y, /* defaultValue= */ 1);
requestBuilder.setScale(scaleX, scaleY);
float rotateDegrees =
bundle.getFloat(ConfigurationActivity.ROTATE_DEGREES, /* defaultValue= */ 0);
requestBuilder.setRotationDegrees(rotateDegrees);
requestBuilder.setEnableRequestSdrToneMapping(
bundle.getBoolean(ConfigurationActivity.ENABLE_REQUEST_SDR_TONE_MAPPING));
requestBuilder.experimental_setEnableHdrEditing(
bundle.getBoolean(ConfigurationActivity.ENABLE_HDR_EDITING));
transformerBuilder
.setTransformationRequest(requestBuilder.build())
.setRemoveAudio(bundle.getBoolean(ConfigurationActivity.SHOULD_REMOVE_AUDIO))
.setRemoveVideo(bundle.getBoolean(ConfigurationActivity.SHOULD_REMOVE_VIDEO));
.setRemoveVideo(bundle.getBoolean(ConfigurationActivity.SHOULD_REMOVE_VIDEO))
.setEncoderFactory(
new DefaultEncoderFactory(
EncoderSelector.DEFAULT,
/* enableFallback= */ bundle.getBoolean(ConfigurationActivity.ENABLE_FALLBACK)));
ImmutableList.Builder<GlEffect> effects = new ImmutableList.Builder<>();
@Nullable
boolean[] selectedEffects =
bundle.getBooleanArray(ConfigurationActivity.DEMO_EFFECTS_SELECTIONS);
if (selectedEffects != null) {
if (selectedEffects[0]) {
effects.add(MatrixTransformationFactory.createDizzyCropEffect());
}
if (selectedEffects[1]) {
try {
Class<?> clazz =
Class.forName("com.google.android.exoplayer2.transformerdemo.MediaPipeProcessor");
Constructor<?> constructor =
clazz.getConstructor(String.class, String.class, String.class);
effects.add(
() -> {
try {
return (SingleFrameGlTextureProcessor)
constructor.newInstance(
/* graphName= */ "edge_detector_mediapipe_graph.binarypb",
/* inputStreamName= */ "input_video",
/* outputStreamName= */ "output_video");
} catch (Exception e) {
runOnUiThread(() -> showToast(R.string.no_media_pipe_error));
throw new RuntimeException("Failed to load MediaPipe processor", e);
}
});
} catch (Exception e) {
showToast(R.string.no_media_pipe_error);
}
}
if (selectedEffects[2]) {
effects.add(
() ->
new PeriodicVignetteProcessor(
bundle.getFloat(ConfigurationActivity.PERIODIC_VIGNETTE_CENTER_X),
bundle.getFloat(ConfigurationActivity.PERIODIC_VIGNETTE_CENTER_Y),
/* minInnerRadius= */ bundle.getFloat(
ConfigurationActivity.PERIODIC_VIGNETTE_INNER_RADIUS),
/* maxInnerRadius= */ bundle.getFloat(
ConfigurationActivity.PERIODIC_VIGNETTE_OUTER_RADIUS),
bundle.getFloat(ConfigurationActivity.PERIODIC_VIGNETTE_OUTER_RADIUS)));
}
if (selectedEffects[3]) {
effects.add(MatrixTransformationFactory.createSpin3dEffect());
}
if (selectedEffects[4]) {
effects.add(BitmapOverlayProcessor::new);
}
if (selectedEffects[5]) {
effects.add(MatrixTransformationFactory.createZoomInTransition());
}
transformerBuilder.setVideoFrameEffects(effects.build());
}
}
return transformerBuilder
.addListener(
new Transformer.Listener() {
@Override
public void onTransformationCompleted(MediaItem mediaItem) {
public void onTransformationCompleted(
MediaItem mediaItem, TransformationResult transformationResult) {
TransformerActivity.this.onTransformationCompleted(filePath);
}
......@@ -243,26 +336,6 @@ public final class TransformerActivity extends AppCompatActivity {
.build();
}
private static Matrix getTransformationMatrix(Bundle bundle) {
Matrix transformationMatrix = new Matrix();
float translateX = bundle.getFloat(ConfigurationActivity.TRANSLATE_X, /* defaultValue= */ 0);
float translateY = bundle.getFloat(ConfigurationActivity.TRANSLATE_Y, /* defaultValue= */ 0);
// TODO(b/213198690): Get resolution for aspect ratio and scale all translations' translateX
// by this aspect ratio.
transformationMatrix.postTranslate(translateX, translateY);
float scaleX = bundle.getFloat(ConfigurationActivity.SCALE_X, /* defaultValue= */ 1);
float scaleY = bundle.getFloat(ConfigurationActivity.SCALE_Y, /* defaultValue= */ 1);
transformationMatrix.postScale(scaleX, scaleY);
float rotateDegrees =
bundle.getFloat(ConfigurationActivity.ROTATE_DEGREES, /* defaultValue= */ 0);
transformationMatrix.postRotate(rotateDegrees);
return transformationMatrix;
}
@RequiresNonNull({
"informationTextView",
"progressViewGroup",
......@@ -335,6 +408,10 @@ public final class TransformerActivity extends AppCompatActivity {
}
}
private void showToast(@StringRes int messageResource) {
Toast.makeText(getApplicationContext(), getString(messageResource), Toast.LENGTH_LONG).show();
}
private final class DemoDebugViewProvider implements Transformer.DebugViewProvider {
@Nullable
......
......@@ -34,18 +34,18 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/choose_file_button"
android:id="@+id/select_file_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
android:text="@string/choose_file_title"
android:text="@string/select_file_title"
app:layout_constraintTop_toBottomOf="@+id/configuration_text_view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/chosen_file_text_view"
android:id="@+id/selected_file_text_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
......@@ -57,14 +57,14 @@
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/choose_file_button" />
app:layout_constraintTop_toBottomOf="@+id/select_file_button" />
<androidx.core.widget.NestedScrollView
android:layout_width="fill_parent"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/chosen_file_text_view"
app:layout_constraintBottom_toTopOf="@+id/transform_button">
app:layout_constraintTop_toBottomOf="@+id/selected_file_text_view"
app:layout_constraintBottom_toTopOf="@+id/select_demo_effects_button">
<TableLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
......@@ -141,17 +141,6 @@
android:layout_weight="1"
android:gravity="center_vertical" >
<TextView
android:id="@+id/translate"
android:text="@string/translate"/>
<Spinner
android:id="@+id/translate_spinner"
android:layout_gravity="right|center_vertical"
android:gravity="right" />
</TableRow>
<TableRow
android:layout_weight="1"
android:gravity="center_vertical" >
<TextView
android:id="@+id/scale"
android:text="@string/scale"/>
<Spinner
......@@ -174,6 +163,36 @@
android:layout_weight="1"
android:gravity="center_vertical" >
<TextView
android:id="@+id/trim"
android:text="@string/trim" />
<CheckBox
android:id="@+id/trim_checkbox"
android:layout_gravity="right" />
</TableRow>
<TableRow
android:layout_weight="1"
android:gravity="center_vertical" >
<TextView
android:text="@string/enable_fallback" />
<CheckBox
android:id="@+id/enable_fallback_checkbox"
android:layout_gravity="right"
android:checked="true"/>
</TableRow>
<TableRow
android:layout_weight="1"
android:gravity="center_vertical" >
<TextView
android:id="@+id/request_sdr_tone_mapping"
android:text="@string/request_sdr_tone_mapping" />
<CheckBox
android:id="@+id/request_sdr_tone_mapping_checkbox"
android:layout_gravity="right" />
</TableRow>
<TableRow
android:layout_weight="1"
android:gravity="center_vertical" >
<TextView
android:id="@+id/hdr_editing"
android:text="@string/hdr_editing" />
<CheckBox
......@@ -183,6 +202,17 @@
</TableLayout>
</androidx.core.widget.NestedScrollView>
<Button
android:id="@+id/select_demo_effects_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
android:text="@string/select_demo_effects"
app:layout_constraintBottom_toTopOf="@+id/transform_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/transform_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
......
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2022 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context=".ConfigurationActivity">
<TableLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stretchColumns="1"
android:layout_marginTop="32dp"
android:measureWithLargestChild="true"
android:paddingLeft="24dp"
android:paddingRight="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<TableRow
android:layout_weight="1"
android:gravity="center_vertical" >
<TextView
android:text="@string/center_x" />
<com.google.android.material.slider.Slider
android:id="@+id/periodic_vignette_center_x_slider"
android:valueFrom="0.0"
android:value="0.5"
android:valueTo="1.0"
android:layout_gravity="right"/>
</TableRow>
<TableRow
android:layout_weight="1"
android:gravity="center_vertical" >
<TextView
android:text="@string/center_y" />
<com.google.android.material.slider.Slider
android:id="@+id/periodic_vignette_center_y_slider"
android:valueFrom="0.0"
android:value="0.5"
android:valueTo="1.0"
android:layout_gravity="right"/>
</TableRow>
<TableRow
android:layout_weight="1"
android:gravity="center_vertical" >
<TextView
android:text="@string/radius_range" />
<com.google.android.material.slider.RangeSlider
android:id="@+id/periodic_vignette_radius_range_slider"
android:valueFrom="0.0"
android:valueTo="1.414"
android:layout_gravity="right"/>
</TableRow>
</TableLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2022 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context=".ConfigurationActivity">
<TableLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stretchColumns="1"
android:layout_marginTop="32dp"
android:measureWithLargestChild="true"
android:paddingLeft="24dp"
android:paddingRight="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<TableRow
android:layout_weight="1"
android:gravity="center_vertical" >
<TextView
android:text="@string/trim_range" />
<com.google.android.material.slider.RangeSlider
android:id="@+id/trim_bounds_range_slider"
android:valueFrom="0.0"
android:valueTo="60.0"
android:layout_gravity="right"/>
</TableRow>
</TableLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
......@@ -17,22 +17,31 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" translatable="false">Transformer Demo</string>
<string name="configuration" translatable="false">Configuration</string>
<string name="choose_file_title" translatable="false">Choose file</string>
<string name="select_file_title" translatable="false">Choose file</string>
<string name="remove_audio" translatable="false">Remove audio</string>
<string name="remove_video" translatable="false">Remove video</string>
<string name="flatten_for_slow_motion" translatable="false">Flatten for slow motion</string>
<string name="audio_mime" translatable="false">Output audio MIME type</string>
<string name="video_mime" translatable="false">Output video MIME type</string>
<string name="resolution_height" translatable="false">Output video resolution</string>
<string name="translate" translatable="false">Translate video</string>
<string name="scale" translatable="false">Scale video</string>
<string name="rotate" translatable="false">Rotate video (degrees)</string>
<string name="transform" translatable="false">Transform</string>
<string name="enable_fallback" translatable="false">Enable fallback</string>
<string name="trim" translatable="false">Trim</string>
<string name="request_sdr_tone_mapping" translatable="false">Request SDR tone-mapping (API 31+)</string>
<string name="hdr_editing" translatable="false">[Experimental] HDR editing</string>
<string name="select_demo_effects" translatable="false">Add demo effects</string>
<string name="periodic_vignette_options" translatable="false">Periodic vignette options</string>
<string name="no_media_pipe_error" translatable="false">Failed to load MediaPipe processor. Check the README for instructions.</string>
<string name="transform" translatable="false">Transform</string>
<string name="debug_preview" translatable="false">Debug preview:</string>
<string name="debug_preview_not_available" translatable="false">No debug preview available.</string>
<string name="transformation_started" translatable="false">Transformation started</string>
<string name="transformation_timer" translatable="false">Transformation started %d seconds ago.</string>
<string name="transformation_completed" translatable="false">Transformation completed in %d seconds.</string>
<string name="transformation_error" translatable="false">Transformation error</string>
<string name="center_x">Center X</string>
<string name="center_y">Center Y</string>
<string name="radius_range">Radius range</string>
<string name="trim_range">Bounds in seconds</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2022 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<manifest package="com.google.android.exoplayer2.transformerdemo">
<uses-sdk />
</manifest>
# Demo MediaPipe graph that shows edges using a SobelEdgesCalculator.
input_stream: "input_video"
output_stream: "output_video"
node: {
calculator: "LuminanceCalculator"
input_stream: "input_video"
output_stream: "luma_video"
}
node: {
calculator: "SobelEdgesCalculator"
input_stream: "luma_video"
output_stream: "output_video"
}
/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.transformerdemo;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull;
import android.content.Context;
import android.opengl.EGL14;
import android.opengl.GLES20;
import android.util.Size;
import com.google.android.exoplayer2.transformer.FrameProcessingException;
import com.google.android.exoplayer2.transformer.SingleFrameGlTextureProcessor;
import com.google.android.exoplayer2.util.ConditionVariable;
import com.google.android.exoplayer2.util.GlProgram;
import com.google.android.exoplayer2.util.GlUtil;
import com.google.android.exoplayer2.util.LibraryLoader;
import com.google.mediapipe.components.FrameProcessor;
import com.google.mediapipe.framework.AndroidAssetUtil;
import com.google.mediapipe.framework.AppTextureFrame;
import com.google.mediapipe.framework.TextureFrame;
import com.google.mediapipe.glutil.EglManager;
import java.io.IOException;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/**
* Runs a MediaPipe graph on input frames. The implementation is currently limited to graphs that
* can immediately produce one output frame per input frame.
*/
/* package */ final class MediaPipeProcessor implements SingleFrameGlTextureProcessor {
private static final LibraryLoader LOADER =
new LibraryLoader("mediapipe_jni") {
@Override
protected void loadLibrary(String name) {
System.loadLibrary(name);
}
};
static {
// Not all build configurations require OpenCV to be loaded separately, so attempt to load the
// library but ignore the error if it's not present.
try {
System.loadLibrary("opencv_java3");
} catch (UnsatisfiedLinkError e) {
// Do nothing.
}
}
private static final String COPY_VERTEX_SHADER_NAME = "vertex_shader_copy_es2.glsl";
private static final String COPY_FRAGMENT_SHADER_NAME = "shaders/fragment_shader_copy_es2.glsl";
private final String graphName;
private final String inputStreamName;
private final String outputStreamName;
private final ConditionVariable frameProcessorConditionVariable;
private @MonotonicNonNull FrameProcessor frameProcessor;
private int inputWidth;
private int inputHeight;
private int inputTexId;
private @MonotonicNonNull GlProgram glProgram;
private @MonotonicNonNull TextureFrame outputFrame;
private @MonotonicNonNull RuntimeException frameProcessorPendingError;
/**
* Creates a new texture processor that wraps a MediaPipe graph.
*
* @param graphName Name of a MediaPipe graph asset to load.
* @param inputStreamName Name of the input video stream in the graph.
* @param outputStreamName Name of the input video stream in the graph.
*/
public MediaPipeProcessor(String graphName, String inputStreamName, String outputStreamName) {
checkState(LOADER.isAvailable());
this.graphName = graphName;
this.inputStreamName = inputStreamName;
this.outputStreamName = outputStreamName;
frameProcessorConditionVariable = new ConditionVariable();
}
@Override
public void initialize(Context context, int inputTexId, int inputWidth, int inputHeight)
throws IOException {
this.inputTexId = inputTexId;
this.inputWidth = inputWidth;
this.inputHeight = inputHeight;
glProgram = new GlProgram(context, COPY_VERTEX_SHADER_NAME, COPY_FRAGMENT_SHADER_NAME);
AndroidAssetUtil.initializeNativeAssetManager(context);
EglManager eglManager = new EglManager(EGL14.eglGetCurrentContext());
frameProcessor =
new FrameProcessor(
context, eglManager.getNativeContext(), graphName, inputStreamName, outputStreamName);
// Unblock drawFrame when there is an output frame or an error.
frameProcessor.setConsumer(
frame -> {
outputFrame = frame;
frameProcessorConditionVariable.open();
});
frameProcessor.setAsynchronousErrorListener(
error -> {
frameProcessorPendingError = error;
frameProcessorConditionVariable.open();
});
}
@Override
public Size getOutputSize() {
return new Size(inputWidth, inputHeight);
}
@Override
public void drawFrame(long presentationTimeUs) throws FrameProcessingException {
frameProcessorConditionVariable.close();
// Pass the input frame to MediaPipe.
AppTextureFrame appTextureFrame = new AppTextureFrame(inputTexId, inputWidth, inputHeight);
appTextureFrame.setTimestamp(presentationTimeUs);
checkStateNotNull(frameProcessor).onNewFrame(appTextureFrame);
// Wait for output to be passed to the consumer.
try {
frameProcessorConditionVariable.block();
} catch (InterruptedException e) {
// Propagate the interrupted flag so the next blocking operation will throw.
// TODO(b/230469581): The next processor that runs will not have valid input due to returning
// early here. This could be fixed by checking for interruption in the outer loop that runs
// through the texture processors.
Thread.currentThread().interrupt();
return;
}
if (frameProcessorPendingError != null) {
throw new FrameProcessingException(frameProcessorPendingError);
}
// Copy from MediaPipe's output texture to the current output.
try {
checkStateNotNull(glProgram).use();
glProgram.setSamplerTexIdUniform(
"uTexSampler", checkStateNotNull(outputFrame).getTextureName(), /* texUnitIndex= */ 0);
glProgram.setBufferAttribute(
"aFramePosition",
GlUtil.getNormalizedCoordinateBounds(),
GlUtil.HOMOGENEOUS_COORDINATE_VECTOR_SIZE);
glProgram.bindAttributesAndUniforms();
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, /* first= */ 0, /* count= */ 4);
GlUtil.checkGlError();
} catch (GlUtil.GlException e) {
throw new FrameProcessingException(e);
} finally {
checkStateNotNull(outputFrame).release();
}
}
@Override
public void release() {
checkStateNotNull(frameProcessor).close();
}
}
......@@ -51,8 +51,8 @@ build and inject a `DefaultMediaSourceFactory` configured with an
~~~
MediaSource.Factory mediaSourceFactory =
new DefaultMediaSourceFactory(context)
.setAdsLoaderProvider(adsLoaderProvider)
.setAdViewProvider(playerView);
.setLocalAdInsertionComponents(
adsLoaderProvider, /* adViewProvider= */ playerView);
ExoPlayer player = new ExoPlayer.Builder(context)
.setMediaSourceFactory(mediaSourceFactory)
.build();
......@@ -220,7 +220,7 @@ server-side ad insertion `MediaSource` for URIs using the `ssai://` scheme:
Player player =
new ExoPlayer.Builder(context)
.setMediaSourceFactory(
new DefaultMediaSourceFactory(dataSourceFactory)
new DefaultMediaSourceFactory(context)
.setServerSideAdInsertionMediaSourceFactory(ssaiFactory))
.build();
```
......@@ -241,7 +241,7 @@ In order to use this class, you need to set up the
```
// MediaSource.Factory to load the actual media stream.
DefaultMediaSourceFactory defaultMediaSourceFactory =
new DefaultMediaSourceFactory(dataSourceFactory);
new DefaultMediaSourceFactory(context);
// AdsLoader that can be reused for multiple playbacks.
ImaServerSideAdInsertionMediaSource.AdsLoader adsLoader =
new ImaServerSideAdInsertionMediaSource.AdsLoader.Builder(context, adViewProvider)
......@@ -267,7 +267,10 @@ with `ImaServerSideAdInsertionUriBuilder`:
```
Uri ssaiUri =
new ImaServerSideAdInsertionUriBuilder().setAssetKey(assetKey).build();
new ImaServerSideAdInsertionUriBuilder()
.setAssetKey(assetKey)
.setFormat(C.TYPE_HLS)
.build();
player.setMediaItem(MediaItem.fromUri(ssaiUri));
```
......
......@@ -43,32 +43,7 @@ described below.
### Configuring the network stack ###
ExoPlayer supports Android's default network stack, as well as Cronet and
OkHttp. In each case it's possible to customize the network stack for your use
case. The following example shows how to customize the player to use Android's
default network stack with cross-protocol redirects enabled:
~~~
// Build a HttpDataSource.Factory with cross-protocol redirects enabled.
HttpDataSource.Factory httpDataSourceFactory =
new DefaultHttpDataSource.Factory().setAllowCrossProtocolRedirects(true);
// Wrap the HttpDataSource.Factory in a DefaultDataSource.Factory, which adds in
// support for requesting data from other sources (e.g., files, resources, etc).
DefaultDataSource.Factory dataSourceFactory =
new DefaultDataSource.Factory(context, httpDataSourceFactory);
// Inject the DefaultDataSourceFactory when creating the player.
ExoPlayer player =
new ExoPlayer.Builder(context)
.setMediaSourceFactory(new DefaultMediaSourceFactory(dataSourceFactory))
.build();
~~~
{: .language-java}
The same approach can be used to configure and inject `HttpDataSource.Factory`
implementations provided by the [Cronet extension] and the [OkHttp extension],
depending on your preferred choice of network stack.
We have a page about [customizing the network stack used by ExoPlayer].
### Caching data loaded from the network ###
......@@ -84,7 +59,8 @@ DataSource.Factory cacheDataSourceFactory =
ExoPlayer player = new ExoPlayer.Builder(context)
.setMediaSourceFactory(
new DefaultMediaSourceFactory(cacheDataSourceFactory))
new DefaultMediaSourceFactory(context)
.setDataSourceFactory(cacheDataSourceFactory))
.build();
~~~
{: .language-java}
......@@ -108,7 +84,9 @@ DataSource.Factory dataSourceFactory = () -> {
};
ExoPlayer player = new ExoPlayer.Builder(context)
.setMediaSourceFactory(new DefaultMediaSourceFactory(dataSourceFactory))
.setMediaSourceFactory(
new DefaultMediaSourceFactory(context)
.setDataSourceFactory(dataSourceFactory))
.build();
~~~
{: .language-java}
......@@ -206,6 +184,56 @@ DefaultExtractorsFactory extractorsFactory =
The `ExtractorsFactory` can then be injected via `DefaultMediaSourceFactory` as
described for customizing extractor flags above.
### Enabling asynchronous buffer queueing ###
Asynchronous buffer queueing is an enhancement in ExoPlayer's rendering
pipeline, which operates `MediaCodec` instances in [asynchronous mode][] and
uses additional threads to schedule decoding and rendering of data. Enabling it
can reduce dropped frames and audio underruns.
Asynchronous buffer queueing is enabled by default on devices running Android 12
and above, and can be enabled manually from Android 6. Consider enabling the
feature for specific devices on which you observe dropped frames or audio
underruns, particularly when playing DRM protected or high frame rate content.
In the simplest case, you need to inject a `DefaultRenderersFactory` to the
player as follows:
~~~
DefaultRenderersFactory renderersFactory =
new DefaultRenderersFactory(context)
.forceEnableMediaCodecAsynchronousQueueing();
ExoPlayer exoPlayer = new ExoPlayer.Builder(context, renderersFactory).build();
~~~
{: .language-java}
If you're instantiating renderers directly, pass a
`AsynchronousMediaCodecAdapter.Factory` to the `MediaCodecVideoRenderer` and
`MediaCodecAudioRenderer` constructors.
### Intercepting method calls with `ForwardingPlayer` ###
You can customize some of the behavior of a `Player` instance by wrapping it in
a subclass of `ForwardingPlayer` and overriding methods in order to do any of
the following:
* Access parameters before passing them to the delegate `Player`.
* Access the return value from the delegate `Player` before returning it.
* Re-implement the method completely.
When overriding `ForwardingPlayer` methods it's important to ensure the
implementation remains self-consistent and compliant with the `Player`
interface, especially when dealing with methods that are intended to have
identical or related behavior. For example, if you want to override every 'play'
operation, you need to override both `ForwardingPlayer.play` and
`ForwardingPlayer.setPlayWhenReady`, because a caller will expect the behavior
of these methdods to be identical when `playWhenReady = true`. Similarly, if you
want to change the seek-forward increment you need to override both
`ForwardingPlayer.seekForward` to perform a seek with your customized increment,
and `ForwardingPlayer.getSeekForwardIncrement` in order to report the correct
customized increment back to the caller.
## MediaSource customization ##
The examples above inject customized components for use during playback of all
......@@ -270,8 +298,8 @@ When building custom components, we recommend the following:
ensures that they are executed in order with any other operations being
performed on the player.
[Cronet extension]: https://github.com/google/ExoPlayer/tree/release-v2/extensions/cronet
[OkHttp extension]: https://github.com/google/ExoPlayer/tree/release-v2/extensions/okhttp
[customizing the network stack used by ExoPlayer]: {{ site.baseurl }}/network-stacks.html
[LoadErrorHandlingPolicy]: {{ site.exo_sdk }}/upstream/LoadErrorHandlingPolicy.html
[media source based playlist API]: {{ site.baseurl }}/media-sources.html#media-source-based-playlist-api
[asynchronous mode]: https://developer.android.com/reference/android/media/MediaCodec#asynchronous-processing-using-buffers
......@@ -9,13 +9,10 @@ issues. `EventLogger` implements `AnalyticsListener`, so registering an instance
with an `ExoPlayer` is easy:
```
player.addAnalyticsListener(new EventLogger(trackSelector));
player.addAnalyticsListener(new EventLogger());
```
{: .language-java}
Passing the `trackSelector` enables additional logging, but is optional and so
`null` can be passed instead.
The easiest way to observe the log is using Android Studio's [logcat tab][]. You
can select your app as debuggable process by the package name (
`com.google.android.exoplayer2.demo` if using the demo app) and tell the logcat
......@@ -80,20 +77,16 @@ logging for an adaptive stream:
```
EventLogger: tracks [eventTime=0.30, mediaPos=0.00, window=0, period=0,
EventLogger: MediaCodecVideoRenderer [
EventLogger: Group:0, adaptive_supported=YES [
EventLogger: [X] Track:0, id=133, mimeType=video/avc, bitrate=261112, codecs=avc1.4d4015, res=426x240, fps=30.0, supported=YES
EventLogger: [X] Track:1, id=134, mimeType=video/avc, bitrate=671331, codecs=avc1.4d401e, res=640x360, fps=30.0, supported=YES
EventLogger: [X] Track:2, id=135, mimeType=video/avc, bitrate=1204535, codecs=avc1.4d401f, res=854x480, fps=30.0, supported=YES
EventLogger: [X] Track:3, id=160, mimeType=video/avc, bitrate=112329, codecs=avc1.4d400c, res=256x144, fps=30.0, supported=YES
EventLogger: [ ] Track:4, id=136, mimeType=video/avc, bitrate=2400538, codecs=avc1.4d401f, res=1280x720, fps=30.0, supported=NO_EXCEEDS_CAPABILITIES
EventLogger: ]
EventLogger: group [
EventLogger: [X] Track:0, id=133, mimeType=video/avc, bitrate=261112, codecs=avc1.4d4015, res=426x240, fps=30.0, supported=YES
EventLogger: [X] Track:1, id=134, mimeType=video/avc, bitrate=671331, codecs=avc1.4d401e, res=640x360, fps=30.0, supported=YES
EventLogger: [X] Track:2, id=135, mimeType=video/avc, bitrate=1204535, codecs=avc1.4d401f, res=854x480, fps=30.0, supported=YES
EventLogger: [X] Track:3, id=160, mimeType=video/avc, bitrate=112329, codecs=avc1.4d400c, res=256x144, fps=30.0, supported=YES
EventLogger: [ ] Track:4, id=136, mimeType=video/avc, bitrate=2400538, codecs=avc1.4d401f, res=1280x720, fps=30.0, supported=NO_EXCEEDS_CAPABILITIES
EventLogger: ]
EventLogger: MediaCodecAudioRenderer [
EventLogger: Group:0, adaptive_supported=YES_NOT_SEAMLESS [
EventLogger: [ ] Track:0, id=139, mimeType=audio/mp4a-latm, bitrate=48582, codecs=mp4a.40.5, channels=2, sample_rate=22050, supported=YES
EventLogger: [X] Track:1, id=140, mimeType=audio/mp4a-latm, bitrate=127868, codecs=mp4a.40.2, channels=2, sample_rate=44100, supported=YES
EventLogger: ]
EventLogger: group [
EventLogger: [ ] Track:0, id=139, mimeType=audio/mp4a-latm, bitrate=48582, codecs=mp4a.40.5, channels=2, sample_rate=22050, supported=YES
EventLogger: [X] Track:1, id=140, mimeType=audio/mp4a-latm, bitrate=127868, codecs=mp4a.40.2, channels=2, sample_rate=44100, supported=YES
EventLogger: ]
EventLogger: ]
```
......
This diff could not be displayed because it is too large.
......@@ -192,35 +192,35 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<td class="colLast">&nbsp;</td>
</tr>
<tr class="altColor">
<th class="colFirst" scope="row"><a href="com/google/android/exoplayer2/extractor/flac/package-summary.html">com.google.android.exoplayer2.extractor.flac</a></th>
<th class="colFirst" scope="row"><a href="com/google/android/exoplayer2/extractor/avi/package-summary.html">com.google.android.exoplayer2.extractor.avi</a></th>
<td class="colLast">&nbsp;</td>
</tr>
<tr class="rowColor">
<th class="colFirst" scope="row"><a href="com/google/android/exoplayer2/extractor/flv/package-summary.html">com.google.android.exoplayer2.extractor.flv</a></th>
<th class="colFirst" scope="row"><a href="com/google/android/exoplayer2/extractor/flac/package-summary.html">com.google.android.exoplayer2.extractor.flac</a></th>
<td class="colLast">&nbsp;</td>
</tr>
<tr class="altColor">
<th class="colFirst" scope="row"><a href="com/google/android/exoplayer2/extractor/jpeg/package-summary.html">com.google.android.exoplayer2.extractor.jpeg</a></th>
<th class="colFirst" scope="row"><a href="com/google/android/exoplayer2/extractor/flv/package-summary.html">com.google.android.exoplayer2.extractor.flv</a></th>
<td class="colLast">&nbsp;</td>
</tr>
<tr class="rowColor">
<th class="colFirst" scope="row"><a href="com/google/android/exoplayer2/extractor/mkv/package-summary.html">com.google.android.exoplayer2.extractor.mkv</a></th>
<th class="colFirst" scope="row"><a href="com/google/android/exoplayer2/extractor/jpeg/package-summary.html">com.google.android.exoplayer2.extractor.jpeg</a></th>
<td class="colLast">&nbsp;</td>
</tr>
<tr class="altColor">
<th class="colFirst" scope="row"><a href="com/google/android/exoplayer2/extractor/mp3/package-summary.html">com.google.android.exoplayer2.extractor.mp3</a></th>
<th class="colFirst" scope="row"><a href="com/google/android/exoplayer2/extractor/mkv/package-summary.html">com.google.android.exoplayer2.extractor.mkv</a></th>
<td class="colLast">&nbsp;</td>
</tr>
<tr class="rowColor">
<th class="colFirst" scope="row"><a href="com/google/android/exoplayer2/extractor/mp4/package-summary.html">com.google.android.exoplayer2.extractor.mp4</a></th>
<th class="colFirst" scope="row"><a href="com/google/android/exoplayer2/extractor/mp3/package-summary.html">com.google.android.exoplayer2.extractor.mp3</a></th>
<td class="colLast">&nbsp;</td>
</tr>
<tr class="altColor">
<th class="colFirst" scope="row"><a href="com/google/android/exoplayer2/extractor/ogg/package-summary.html">com.google.android.exoplayer2.extractor.ogg</a></th>
<th class="colFirst" scope="row"><a href="com/google/android/exoplayer2/extractor/mp4/package-summary.html">com.google.android.exoplayer2.extractor.mp4</a></th>
<td class="colLast">&nbsp;</td>
</tr>
<tr class="rowColor">
<th class="colFirst" scope="row"><a href="com/google/android/exoplayer2/extractor/rawcc/package-summary.html">com.google.android.exoplayer2.extractor.rawcc</a></th>
<th class="colFirst" scope="row"><a href="com/google/android/exoplayer2/extractor/ogg/package-summary.html">com.google.android.exoplayer2.extractor.ogg</a></th>
<td class="colLast">&nbsp;</td>
</tr>
<tr class="altColor">
......
......@@ -117,8 +117,15 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<a href="https://developer.android.com/reference/java/lang/annotation/Retention.html" title="class or interface in java.lang.annotation" class="externalLink">@Retention</a>(<a href="https://developer.android.com/reference/java/lang/annotation/RetentionPolicy.html?is-external=true#SOURCE" title="class or interface in java.lang.annotation" class="externalLink" target="_top">SOURCE</a>)
<a href="https://developer.android.com/reference/java/lang/annotation/Target.html" title="class or interface in java.lang.annotation" class="externalLink">@Target</a>({<a href="https://developer.android.com/reference/java/lang/annotation/ElementType.html?is-external=true#FIELD" title="class or interface in java.lang.annotation" class="externalLink">FIELD</a>,<a href="https://developer.android.com/reference/java/lang/annotation/ElementType.html?is-external=true#METHOD" title="class or interface in java.lang.annotation" class="externalLink">METHOD</a>,<a href="https://developer.android.com/reference/java/lang/annotation/ElementType.html?is-external=true#PARAMETER" title="class or interface in java.lang.annotation" class="externalLink">PARAMETER</a>,<a href="https://developer.android.com/reference/java/lang/annotation/ElementType.html?is-external=true#LOCAL_VARIABLE" title="class or interface in java.lang.annotation" class="externalLink">LOCAL_VARIABLE</a>,<a href="https://developer.android.com/reference/java/lang/annotation/ElementType.html?is-external=true#TYPE_USE" title="class or interface in java.lang.annotation" class="externalLink" target="_top">TYPE_USE</a>})
public static @interface <span class="memberNameLabel">C.AudioContentType</span></pre>
<div class="block">Content types for audio attributes. One of <a href="C.html#CONTENT_TYPE_MOVIE"><code>C.CONTENT_TYPE_MOVIE</code></a>, <a href="C.html#CONTENT_TYPE_MUSIC"><code>C.CONTENT_TYPE_MUSIC</code></a>, <a href="C.html#CONTENT_TYPE_SONIFICATION"><code>C.CONTENT_TYPE_SONIFICATION</code></a>, <a href="C.html#CONTENT_TYPE_SPEECH"><code>C.CONTENT_TYPE_SPEECH</code></a> or
<a href="C.html#CONTENT_TYPE_UNKNOWN"><code>C.CONTENT_TYPE_UNKNOWN</code></a>.</div>
<div class="block">Content types for audio attributes. One of:
<ul>
<li><a href="C.html#AUDIO_CONTENT_TYPE_MOVIE"><code>C.AUDIO_CONTENT_TYPE_MOVIE</code></a>
<li><a href="C.html#AUDIO_CONTENT_TYPE_MUSIC"><code>C.AUDIO_CONTENT_TYPE_MUSIC</code></a>
<li><a href="C.html#AUDIO_CONTENT_TYPE_SONIFICATION"><code>C.AUDIO_CONTENT_TYPE_SONIFICATION</code></a>
<li><a href="C.html#AUDIO_CONTENT_TYPE_SPEECH"><code>C.AUDIO_CONTENT_TYPE_SPEECH</code></a>
<li><a href="C.html#AUDIO_CONTENT_TYPE_UNKNOWN"><code>C.AUDIO_CONTENT_TYPE_UNKNOWN</code></a>
</ul></div>
</li>
</ul>
</div>
......
......@@ -117,8 +117,8 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<a href="https://developer.android.com/reference/java/lang/annotation/Retention.html" title="class or interface in java.lang.annotation" class="externalLink">@Retention</a>(<a href="https://developer.android.com/reference/java/lang/annotation/RetentionPolicy.html?is-external=true#SOURCE" title="class or interface in java.lang.annotation" class="externalLink" target="_top">SOURCE</a>)
<a href="https://developer.android.com/reference/java/lang/annotation/Target.html" title="class or interface in java.lang.annotation" class="externalLink">@Target</a>(<a href="https://developer.android.com/reference/java/lang/annotation/ElementType.html?is-external=true#TYPE_USE" title="class or interface in java.lang.annotation" class="externalLink" target="_top">TYPE_USE</a>)
public static @interface <span class="memberNameLabel">C.BufferFlags</span></pre>
<div class="block">Flags which can apply to a buffer containing a media sample. Possible flag values are <a href="C.html#BUFFER_FLAG_KEY_FRAME"><code>C.BUFFER_FLAG_KEY_FRAME</code></a>, <a href="C.html#BUFFER_FLAG_END_OF_STREAM"><code>C.BUFFER_FLAG_END_OF_STREAM</code></a>, <a href="C.html#BUFFER_FLAG_LAST_SAMPLE"><code>C.BUFFER_FLAG_LAST_SAMPLE</code></a>,
<a href="C.html#BUFFER_FLAG_ENCRYPTED"><code>C.BUFFER_FLAG_ENCRYPTED</code></a> and <a href="C.html#BUFFER_FLAG_DECODE_ONLY"><code>C.BUFFER_FLAG_DECODE_ONLY</code></a>.</div>
<div class="block">Flags which can apply to a buffer containing a media sample. Possible flag values are <a href="C.html#BUFFER_FLAG_KEY_FRAME"><code>C.BUFFER_FLAG_KEY_FRAME</code></a>, <a href="C.html#BUFFER_FLAG_END_OF_STREAM"><code>C.BUFFER_FLAG_END_OF_STREAM</code></a>, <a href="C.html#BUFFER_FLAG_FIRST_SAMPLE"><code>C.BUFFER_FLAG_FIRST_SAMPLE</code></a>,
<a href="C.html#BUFFER_FLAG_LAST_SAMPLE"><code>C.BUFFER_FLAG_LAST_SAMPLE</code></a>, <a href="C.html#BUFFER_FLAG_ENCRYPTED"><code>C.BUFFER_FLAG_ENCRYPTED</code></a> and <a href="C.html#BUFFER_FLAG_DECODE_ONLY"><code>C.BUFFER_FLAG_DECODE_ONLY</code></a>.</div>
</li>
</ul>
</div>
......
......@@ -117,7 +117,15 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<a href="https://developer.android.com/reference/java/lang/annotation/Retention.html" title="class or interface in java.lang.annotation" class="externalLink">@Retention</a>(<a href="https://developer.android.com/reference/java/lang/annotation/RetentionPolicy.html?is-external=true#SOURCE" title="class or interface in java.lang.annotation" class="externalLink" target="_top">SOURCE</a>)
<a href="https://developer.android.com/reference/java/lang/annotation/Target.html" title="class or interface in java.lang.annotation" class="externalLink">@Target</a>({<a href="https://developer.android.com/reference/java/lang/annotation/ElementType.html?is-external=true#FIELD" title="class or interface in java.lang.annotation" class="externalLink">FIELD</a>,<a href="https://developer.android.com/reference/java/lang/annotation/ElementType.html?is-external=true#METHOD" title="class or interface in java.lang.annotation" class="externalLink">METHOD</a>,<a href="https://developer.android.com/reference/java/lang/annotation/ElementType.html?is-external=true#PARAMETER" title="class or interface in java.lang.annotation" class="externalLink">PARAMETER</a>,<a href="https://developer.android.com/reference/java/lang/annotation/ElementType.html?is-external=true#LOCAL_VARIABLE" title="class or interface in java.lang.annotation" class="externalLink">LOCAL_VARIABLE</a>,<a href="https://developer.android.com/reference/java/lang/annotation/ElementType.html?is-external=true#TYPE_USE" title="class or interface in java.lang.annotation" class="externalLink" target="_top">TYPE_USE</a>})
public static @interface <span class="memberNameLabel">C.ContentType</span></pre>
<div class="block">Represents a streaming or other media type. One of <a href="C.html#TYPE_DASH"><code>C.TYPE_DASH</code></a>, <a href="C.html#TYPE_SS"><code>C.TYPE_SS</code></a>, <a href="C.html#TYPE_HLS"><code>C.TYPE_HLS</code></a>, <a href="C.html#TYPE_RTSP"><code>C.TYPE_RTSP</code></a> or <a href="C.html#TYPE_OTHER"><code>C.TYPE_OTHER</code></a>.</div>
<div class="block">Represents a streaming or other media type. One of:
<ul>
<li><a href="C.html#CONTENT_TYPE_DASH"><code>C.CONTENT_TYPE_DASH</code></a>
<li><a href="C.html#CONTENT_TYPE_SS"><code>C.CONTENT_TYPE_SS</code></a>
<li><a href="C.html#CONTENT_TYPE_HLS"><code>C.CONTENT_TYPE_HLS</code></a>
<li><a href="C.html#CONTENT_TYPE_RTSP"><code>C.CONTENT_TYPE_RTSP</code></a>
<li><a href="C.html#CONTENT_TYPE_OTHER"><code>C.CONTENT_TYPE_OTHER</code></a>
</ul></div>
</li>
</ul>
</div>
......
......@@ -188,7 +188,7 @@ extends <a href="PlaybackException.html" title="class in com.google.android.exop
<!-- -->
</a>
<h3>Nested classes/interfaces inherited from class&nbsp;com.google.android.exoplayer2.<a href="PlaybackException.html" title="class in com.google.android.exoplayer2">PlaybackException</a></h3>
<code><a href="PlaybackException.ErrorCode.html" title="annotation in com.google.android.exoplayer2">PlaybackException.ErrorCode</a>, <a href="PlaybackException.FieldNumber.html" title="annotation in com.google.android.exoplayer2">PlaybackException.FieldNumber</a></code></li>
<code><a href="PlaybackException.ErrorCode.html" title="annotation in com.google.android.exoplayer2">PlaybackException.ErrorCode</a></code></li>
</ul>
<ul class="blockList">
<li class="blockList"><a id="nested.classes.inherited.from.class.com.google.android.exoplayer2.Bundleable">
......@@ -405,7 +405,7 @@ extends <a href="PlaybackException.html" title="class in com.google.android.exop
<!-- -->
</a>
<h3>Methods inherited from class&nbsp;com.google.android.exoplayer2.<a href="PlaybackException.html" title="class in com.google.android.exoplayer2">PlaybackException</a></h3>
<code><a href="PlaybackException.html#getErrorCodeName()">getErrorCodeName</a>, <a href="PlaybackException.html#getErrorCodeName(@com.google.android.exoplayer2.PlaybackException.ErrorCodeint)">getErrorCodeName</a>, <a href="PlaybackException.html#keyForField(@com.google.android.exoplayer2.PlaybackException.FieldNumberint)">keyForField</a></code></li>
<code><a href="PlaybackException.html#getErrorCodeName()">getErrorCodeName</a>, <a href="PlaybackException.html#getErrorCodeName(@com.google.android.exoplayer2.PlaybackException.ErrorCodeint)">getErrorCodeName</a>, <a href="PlaybackException.html#keyForField(int)">keyForField</a></code></li>
</ul>
<ul class="blockList">
<li class="blockList"><a id="methods.inherited.from.class.java.lang.Throwable">
......
......@@ -25,7 +25,7 @@
catch(err) {
}
//-->
var data = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10,"i7":10,"i8":10,"i9":10,"i10":10,"i11":10,"i12":10,"i13":10,"i14":10,"i15":10,"i16":10,"i17":10,"i18":10,"i19":10,"i20":10,"i21":10,"i22":10,"i23":10,"i24":10};
var data = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10,"i7":10,"i8":10,"i9":10,"i10":10,"i11":10,"i12":10,"i13":10,"i14":10,"i15":10,"i16":10,"i17":10,"i18":10,"i19":10,"i20":10,"i21":10,"i22":10,"i23":10,"i24":10,"i25":10};
var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]};
var altColor = "altColor";
var rowColor = "rowColor";
......@@ -376,20 +376,27 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
</tr>
<tr id="i22" class="altColor">
<td class="colFirst"><code><a href="ExoPlayer.Builder.html" title="class in com.google.android.exoplayer2">ExoPlayer.Builder</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setUsePlatformDiagnostics(boolean)">setUsePlatformDiagnostics</a></span>&#8203;(boolean&nbsp;usePlatformDiagnostics)</code></th>
<td class="colLast">
<div class="block">Sets whether the player reports diagnostics data to the Android platform.</div>
</td>
</tr>
<tr id="i23" class="rowColor">
<td class="colFirst"><code><a href="ExoPlayer.Builder.html" title="class in com.google.android.exoplayer2">ExoPlayer.Builder</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setVideoChangeFrameRateStrategy(@com.google.android.exoplayer2.C.VideoChangeFrameRateStrategyint)">setVideoChangeFrameRateStrategy</a></span>&#8203;(@com.google.android.exoplayer2.C.VideoChangeFrameRateStrategy int&nbsp;videoChangeFrameRateStrategy)</code></th>
<td class="colLast">
<div class="block">Sets a <a href="C.VideoChangeFrameRateStrategy.html" title="annotation in com.google.android.exoplayer2"><code>C.VideoChangeFrameRateStrategy</code></a> that will be used by the player when provided
with a video output <a href="https://developer.android.com/reference/android/view/Surface.html" title="class or interface in android.view" class="externalLink" target="_top"><code>Surface</code></a>.</div>
</td>
</tr>
<tr id="i23" class="rowColor">
<tr id="i24" class="altColor">
<td class="colFirst"><code><a href="ExoPlayer.Builder.html" title="class in com.google.android.exoplayer2">ExoPlayer.Builder</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setVideoScalingMode(@com.google.android.exoplayer2.C.VideoScalingModeint)">setVideoScalingMode</a></span>&#8203;(@com.google.android.exoplayer2.C.VideoScalingMode int&nbsp;videoScalingMode)</code></th>
<td class="colLast">
<div class="block">Sets the <a href="C.VideoScalingMode.html" title="annotation in com.google.android.exoplayer2"><code>C.VideoScalingMode</code></a> that will be used by the player.</div>
</td>
</tr>
<tr id="i24" class="altColor">
<tr id="i25" class="rowColor">
<td class="colFirst"><code><a href="ExoPlayer.Builder.html" title="class in com.google.android.exoplayer2">ExoPlayer.Builder</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setWakeMode(@com.google.android.exoplayer2.C.WakeModeint)">setWakeMode</a></span>&#8203;(@com.google.android.exoplayer2.C.WakeMode int&nbsp;wakeMode)</code></th>
<td class="colLast">
......@@ -460,6 +467,7 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<li><code>releaseTimeoutMs</code>: <a href="ExoPlayer.html#DEFAULT_RELEASE_TIMEOUT_MS"><code>ExoPlayer.DEFAULT_RELEASE_TIMEOUT_MS</code></a>
<li><code>detachSurfaceTimeoutMs</code>: <a href="ExoPlayer.html#DEFAULT_DETACH_SURFACE_TIMEOUT_MS"><code>ExoPlayer.DEFAULT_DETACH_SURFACE_TIMEOUT_MS</code></a>
<li><code>pauseAtEndOfMediaItems</code>: <code>false</code>
<li><code>usePlatformDiagnostics</code>: <code>true</code>
<li><a href="util/Clock.html" title="interface in com.google.android.exoplayer2.util"><code>Clock</code></a>: <a href="util/Clock.html#DEFAULT"><code>Clock.DEFAULT</code></a>
</ul></div>
<dl>
......@@ -1035,6 +1043,31 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
</dl>
</li>
</ul>
<a id="setUsePlatformDiagnostics(boolean)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>setUsePlatformDiagnostics</h4>
<pre class="methodSignature">public&nbsp;<a href="ExoPlayer.Builder.html" title="class in com.google.android.exoplayer2">ExoPlayer.Builder</a>&nbsp;setUsePlatformDiagnostics&#8203;(boolean&nbsp;usePlatformDiagnostics)</pre>
<div class="block">Sets whether the player reports diagnostics data to the Android platform.
<p>If enabled, the player will use the <a href="https://developer.android.com/reference/android/media/metrics/MediaMetricsManager.html" title="class or interface in android.media.metrics" class="externalLink" target="_top"><code>MediaMetricsManager</code></a> to
create a <a href="https://developer.android.com/reference/android/media/metrics/PlaybackSession.html" title="class or interface in android.media.metrics" class="externalLink" target="_top"><code>PlaybackSession</code></a> and forward playback events and
performance data to this session. This helps to provide system performance and debugging
information for media playback on the device. This data may also be collected by Google <a href="https://support.google.com/accounts/answer/6078260">if sharing usage and diagnostics
data is enabled</a> by the user of the device.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>usePlatformDiagnostics</code> - Whether the player reports diagnostics data to the Android
platform.</dd>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>This builder.</dd>
<dt><span class="throwsLabel">Throws:</span></dt>
<dd><code><a href="https://developer.android.com/reference/java/lang/IllegalStateException.html" title="class or interface in java.lang" class="externalLink">IllegalStateException</a></code> - If <a href="#build()" target="_top"><code>build()</code></a> has already been called.</dd>
</dl>
</li>
</ul>
<a id="setClock(com.google.android.exoplayer2.util.Clock)">
<!-- -->
</a>
......
......@@ -156,7 +156,7 @@ public static interface <span class="typeNameLabel">ExoPlayer.TextComponent</spa
<th class="colLast" scope="col">Description</th>
</tr>
<tr id="i0" class="altColor">
<td class="colFirst"><code><a href="https://developer.android.com/reference/java/util/List.html" title="class or interface in java.util" class="externalLink">List</a>&lt;<a href="text/Cue.html" title="class in com.google.android.exoplayer2.text" target="_top">Cue</a>&gt;</code></td>
<td class="colFirst"><code><a href="text/CueGroup.html" title="class in com.google.android.exoplayer2.text">CueGroup</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#getCurrentCues()">getCurrentCues</a></span>()</code></th>
<td class="colLast">
<div class="block"><span class="deprecatedLabel">Deprecated.</span>
......@@ -188,7 +188,7 @@ public static interface <span class="typeNameLabel">ExoPlayer.TextComponent</spa
<li class="blockList">
<h4>getCurrentCues</h4>
<pre class="methodSignature"><a href="https://developer.android.com/reference/java/lang/Deprecated.html" title="class or interface in java.lang" class="externalLink" target="_top">@Deprecated</a>
<a href="https://developer.android.com/reference/java/util/List.html" title="class or interface in java.util" class="externalLink">List</a>&lt;<a href="text/Cue.html" title="class in com.google.android.exoplayer2.text" target="_top">Cue</a>&gt;&nbsp;getCurrentCues()</pre>
<a href="text/CueGroup.html" title="class in com.google.android.exoplayer2.text">CueGroup</a>&nbsp;getCurrentCues()</pre>
<div class="deprecationBlock"><span class="deprecatedLabel">Deprecated.</span>
<div class="deprecationComment">Use <a href="Player.html#getCurrentCues()"><code>Player.getCurrentCues()</code></a> instead.</div>
</div>
......
......@@ -187,13 +187,6 @@ extends <a href="Rating.html" title="class in com.google.android.exoplayer2">Rat
</td>
</tr>
</table>
<ul class="blockList">
<li class="blockList"><a id="fields.inherited.from.class.com.google.android.exoplayer2.Rating">
<!-- -->
</a>
<h3>Fields inherited from class&nbsp;com.google.android.exoplayer2.<a href="Rating.html" title="class in com.google.android.exoplayer2">Rating</a></h3>
<code><a href="Rating.html#RATING_UNSET">RATING_UNSET</a></code></li>
</ul>
</li>
</ul>
</section>
......
......@@ -25,7 +25,7 @@
catch(err) {
}
//-->
var data = {"i0":10,"i1":10,"i2":42,"i3":42,"i4":42,"i5":42,"i6":10,"i7":42,"i8":42,"i9":42,"i10":42,"i11":10,"i12":10,"i13":42,"i14":42,"i15":42,"i16":42,"i17":42,"i18":42,"i19":42,"i20":42,"i21":42,"i22":42,"i23":10,"i24":42,"i25":42,"i26":42,"i27":42,"i28":42,"i29":10,"i30":10,"i31":10,"i32":10,"i33":10,"i34":42,"i35":10,"i36":10,"i37":10};
var data = {"i0":10,"i1":10,"i2":42,"i3":42,"i4":42,"i5":42,"i6":10,"i7":42,"i8":42,"i9":42,"i10":42,"i11":10,"i12":10,"i13":42,"i14":42,"i15":42,"i16":42,"i17":42,"i18":42,"i19":42,"i20":42,"i21":42,"i22":42,"i23":10,"i24":42,"i25":42,"i26":42,"i27":42,"i28":42,"i29":10,"i30":10,"i31":10,"i32":10,"i33":10,"i34":10,"i35":42,"i36":10,"i37":10,"i38":10};
var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"],32:["t6","Deprecated Methods"]};
var altColor = "altColor";
var rowColor = "rowColor";
......@@ -358,7 +358,7 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setDrmSessionForClearPeriods(boolean)">setDrmSessionForClearPeriods</a></span>&#8203;(boolean&nbsp;sessionForClearPeriods)</code></th>
<td class="colLast">
<div class="block"><span class="deprecatedLabel">Deprecated.</span>
<div class="deprecationComment">Use <a href="#setDrmConfiguration(com.google.android.exoplayer2.MediaItem.DrmConfiguration)"><code>setDrmConfiguration(DrmConfiguration)</code></a> and <a href="MediaItem.DrmConfiguration.Builder.html#forceSessionsForAudioAndVideoTracks(boolean)"><code>MediaItem.DrmConfiguration.Builder.forceSessionsForAudioAndVideoTracks(boolean)</code></a> instead.</div>
<div class="deprecationComment">Use <a href="#setDrmConfiguration(com.google.android.exoplayer2.MediaItem.DrmConfiguration)"><code>setDrmConfiguration(DrmConfiguration)</code></a> and <a href="MediaItem.DrmConfiguration.Builder.html#setForceSessionsForAudioAndVideoTracks(boolean)"><code>MediaItem.DrmConfiguration.Builder.setForceSessionsForAudioAndVideoTracks(boolean)</code></a> instead.</div>
</div>
</td>
</tr>
......@@ -456,20 +456,27 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
</tr>
<tr id="i32" class="altColor">
<td class="colFirst"><code><a href="MediaItem.Builder.html" title="class in com.google.android.exoplayer2">MediaItem.Builder</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setRequestMetadata(com.google.android.exoplayer2.MediaItem.RequestMetadata)">setRequestMetadata</a></span>&#8203;(<a href="MediaItem.RequestMetadata.html" title="class in com.google.android.exoplayer2">MediaItem.RequestMetadata</a>&nbsp;requestMetadata)</code></th>
<td class="colLast">
<div class="block">Sets the request metadata.</div>
</td>
</tr>
<tr id="i33" class="rowColor">
<td class="colFirst"><code><a href="MediaItem.Builder.html" title="class in com.google.android.exoplayer2">MediaItem.Builder</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setStreamKeys(java.util.List)">setStreamKeys</a></span>&#8203;(<a href="https://developer.android.com/reference/java/util/List.html" title="class or interface in java.util" class="externalLink">List</a>&lt;<a href="offline/StreamKey.html" title="class in com.google.android.exoplayer2.offline" target="_top">StreamKey</a>&gt;&nbsp;streamKeys)</code></th>
<td class="colLast">
<div class="block">Sets the optional stream keys by which the manifest is filtered (only used for adaptive
streams).</div>
</td>
</tr>
<tr id="i33" class="rowColor">
<tr id="i34" class="altColor">
<td class="colFirst"><code><a href="MediaItem.Builder.html" title="class in com.google.android.exoplayer2">MediaItem.Builder</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setSubtitleConfigurations(java.util.List)">setSubtitleConfigurations</a></span>&#8203;(<a href="https://developer.android.com/reference/java/util/List.html" title="class or interface in java.util" class="externalLink">List</a>&lt;<a href="MediaItem.SubtitleConfiguration.html" title="class in com.google.android.exoplayer2" target="_top">MediaItem.SubtitleConfiguration</a>&gt;&nbsp;subtitleConfigurations)</code></th>
<td class="colLast">
<div class="block">Sets the optional subtitles.</div>
</td>
</tr>
<tr id="i34" class="altColor">
<tr id="i35" class="rowColor">
<td class="colFirst"><code><a href="MediaItem.Builder.html" title="class in com.google.android.exoplayer2">MediaItem.Builder</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setSubtitles(java.util.List)">setSubtitles</a></span>&#8203;(<a href="https://developer.android.com/reference/java/util/List.html" title="class or interface in java.util" class="externalLink">List</a>&lt;<a href="MediaItem.Subtitle.html" title="class in com.google.android.exoplayer2" target="_top">MediaItem.Subtitle</a>&gt;&nbsp;subtitles)</code></th>
<td class="colLast">
......@@ -478,21 +485,21 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
</div>
</td>
</tr>
<tr id="i35" class="rowColor">
<tr id="i36" class="altColor">
<td class="colFirst"><code><a href="MediaItem.Builder.html" title="class in com.google.android.exoplayer2">MediaItem.Builder</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setTag(java.lang.Object)">setTag</a></span>&#8203;(<a href="https://developer.android.com/reference/java/lang/Object.html" title="class or interface in java.lang" class="externalLink" target="_top">Object</a>&nbsp;tag)</code></th>
<td class="colLast">
<div class="block">Sets the optional tag for custom attributes.</div>
</td>
</tr>
<tr id="i36" class="altColor">
<tr id="i37" class="rowColor">
<td class="colFirst"><code><a href="MediaItem.Builder.html" title="class in com.google.android.exoplayer2">MediaItem.Builder</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setUri(android.net.Uri)">setUri</a></span>&#8203;(<a href="https://developer.android.com/reference/android/net/Uri.html" title="class or interface in android.net" class="externalLink" target="_top">Uri</a>&nbsp;uri)</code></th>
<td class="colLast">
<div class="block">Sets the optional URI.</div>
</td>
</tr>
<tr id="i37" class="rowColor">
<tr id="i38" class="altColor">
<td class="colFirst"><code><a href="MediaItem.Builder.html" title="class in com.google.android.exoplayer2">MediaItem.Builder</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setUri(java.lang.String)">setUri</a></span>&#8203;(<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&nbsp;uri)</code></th>
<td class="colLast">
......@@ -795,7 +802,7 @@ public&nbsp;<a href="MediaItem.Builder.html" title="class in com.google.android.
<pre class="methodSignature"><a href="https://developer.android.com/reference/java/lang/Deprecated.html" title="class or interface in java.lang" class="externalLink" target="_top">@Deprecated</a>
public&nbsp;<a href="MediaItem.Builder.html" title="class in com.google.android.exoplayer2">MediaItem.Builder</a>&nbsp;setDrmSessionForClearPeriods&#8203;(boolean&nbsp;sessionForClearPeriods)</pre>
<div class="deprecationBlock"><span class="deprecatedLabel">Deprecated.</span>
<div class="deprecationComment">Use <a href="#setDrmConfiguration(com.google.android.exoplayer2.MediaItem.DrmConfiguration)"><code>setDrmConfiguration(DrmConfiguration)</code></a> and <a href="MediaItem.DrmConfiguration.Builder.html#forceSessionsForAudioAndVideoTracks(boolean)"><code>MediaItem.DrmConfiguration.Builder.forceSessionsForAudioAndVideoTracks(boolean)</code></a> instead.</div>
<div class="deprecationComment">Use <a href="#setDrmConfiguration(com.google.android.exoplayer2.MediaItem.DrmConfiguration)"><code>setDrmConfiguration(DrmConfiguration)</code></a> and <a href="MediaItem.DrmConfiguration.Builder.html#setForceSessionsForAudioAndVideoTracks(boolean)"><code>MediaItem.DrmConfiguration.Builder.setForceSessionsForAudioAndVideoTracks(boolean)</code></a> instead.</div>
</div>
</li>
</ul>
......@@ -1045,6 +1052,16 @@ public&nbsp;<a href="MediaItem.Builder.html" title="class in com.google.android.
<div class="block">Sets the media metadata.</div>
</li>
</ul>
<a id="setRequestMetadata(com.google.android.exoplayer2.MediaItem.RequestMetadata)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>setRequestMetadata</h4>
<pre class="methodSignature">public&nbsp;<a href="MediaItem.Builder.html" title="class in com.google.android.exoplayer2">MediaItem.Builder</a>&nbsp;setRequestMetadata&#8203;(<a href="MediaItem.RequestMetadata.html" title="class in com.google.android.exoplayer2">MediaItem.RequestMetadata</a>&nbsp;requestMetadata)</pre>
<div class="block">Sets the request metadata.</div>
</li>
</ul>
<a id="build()">
<!-- -->
</a>
......
......@@ -299,7 +299,8 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<ul class="blockList">
<li class="blockList">
<h4>setMimeType</h4>
<pre class="methodSignature">public&nbsp;<a href="MediaItem.SubtitleConfiguration.Builder.html" title="class in com.google.android.exoplayer2">MediaItem.SubtitleConfiguration.Builder</a>&nbsp;setMimeType&#8203;(<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&nbsp;mimeType)</pre>
<pre class="methodSignature">public&nbsp;<a href="MediaItem.SubtitleConfiguration.Builder.html" title="class in com.google.android.exoplayer2">MediaItem.SubtitleConfiguration.Builder</a>&nbsp;setMimeType&#8203;(@Nullable
<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&nbsp;mimeType)</pre>
<div class="block">Sets the MIME type.</div>
</li>
</ul>
......
......@@ -219,6 +219,13 @@ implements <a href="Bundleable.html" title="interface in com.google.android.exop
</tr>
<tr class="altColor">
<td class="colFirst"><code>static class&nbsp;</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="MediaItem.RequestMetadata.html" title="class in com.google.android.exoplayer2">MediaItem.RequestMetadata</a></span></code></th>
<td class="colLast">
<div class="block">Metadata that helps the player to understand a playback request represented by a <a href="MediaItem.html" title="class in com.google.android.exoplayer2"><code>MediaItem</code></a>.</div>
</td>
</tr>
<tr class="rowColor">
<td class="colFirst"><code>static class&nbsp;</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="MediaItem.Subtitle.html" title="class in com.google.android.exoplayer2">MediaItem.Subtitle</a></span></code></th>
<td class="colLast">
<div class="block"><span class="deprecatedLabel">Deprecated.</span>
......@@ -226,7 +233,7 @@ implements <a href="Bundleable.html" title="interface in com.google.android.exop
</div>
</td>
</tr>
<tr class="rowColor">
<tr class="altColor">
<td class="colFirst"><code>static class&nbsp;</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="MediaItem.SubtitleConfiguration.html" title="class in com.google.android.exoplayer2">MediaItem.SubtitleConfiguration</a></span></code></th>
<td class="colLast">
......@@ -332,6 +339,13 @@ implements <a href="Bundleable.html" title="interface in com.google.android.exop
</div>
</td>
</tr>
<tr class="altColor">
<td class="colFirst"><code><a href="MediaItem.RequestMetadata.html" title="class in com.google.android.exoplayer2">MediaItem.RequestMetadata</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#requestMetadata">requestMetadata</a></span></code></th>
<td class="colLast">
<div class="block">The media <a href="MediaItem.RequestMetadata.html" title="class in com.google.android.exoplayer2"><code>MediaItem.RequestMetadata</code></a>.</div>
</td>
</tr>
</table>
</li>
</ul>
......@@ -515,6 +529,16 @@ public final&nbsp;<a href="MediaItem.ClippingProperties.html" title="class in co
</div>
</li>
</ul>
<a id="requestMetadata">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>requestMetadata</h4>
<pre>public final&nbsp;<a href="MediaItem.RequestMetadata.html" title="class in com.google.android.exoplayer2">MediaItem.RequestMetadata</a> requestMetadata</pre>
<div class="block">The media <a href="MediaItem.RequestMetadata.html" title="class in com.google.android.exoplayer2"><code>MediaItem.RequestMetadata</code></a>.</div>
</li>
</ul>
<a id="CREATOR">
<!-- -->
</a>
......
......@@ -186,13 +186,6 @@ extends <a href="Rating.html" title="class in com.google.android.exoplayer2">Rat
</td>
</tr>
</table>
<ul class="blockList">
<li class="blockList"><a id="fields.inherited.from.class.com.google.android.exoplayer2.Rating">
<!-- -->
</a>
<h3>Fields inherited from class&nbsp;com.google.android.exoplayer2.<a href="Rating.html" title="class in com.google.android.exoplayer2">Rating</a></h3>
<code><a href="Rating.html#RATING_UNSET">RATING_UNSET</a></code></li>
</ul>
</li>
</ul>
</section>
......
......@@ -182,13 +182,6 @@ implements <a href="Bundleable.html" title="interface in com.google.android.exop
<div class="block">Codes that identify causes of player errors.</div>
</td>
</tr>
<tr class="rowColor">
<td class="colFirst"><code>protected static interface&nbsp;</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="PlaybackException.FieldNumber.html" title="annotation in com.google.android.exoplayer2">PlaybackException.FieldNumber</a></span></code></th>
<td class="colLast">
<div class="block">Identifiers for fields in a <a href="https://developer.android.com/reference/android/os/Bundle.html" title="class or interface in android.os" class="externalLink" target="_top"><code>Bundle</code></a> which represents a playback exception.</div>
</td>
</tr>
</table>
<ul class="blockList">
<li class="blockList"><a id="nested.classes.inherited.from.class.com.google.android.exoplayer2.Bundleable">
......@@ -481,7 +474,7 @@ implements <a href="Bundleable.html" title="interface in com.google.android.exop
<td class="colFirst"><code>protected static int</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#FIELD_CUSTOM_ID_BASE">FIELD_CUSTOM_ID_BASE</a></span></code></th>
<td class="colLast">
<div class="block">Defines a minimum field id value for subclasses to use when implementing <a href="#toBundle()"><code>toBundle()</code></a>
<div class="block">Defines a minimum field ID value for subclasses to use when implementing <a href="#toBundle()"><code>toBundle()</code></a>
and <a href="Bundleable.Creator.html" title="interface in com.google.android.exoplayer2"><code>Bundleable.Creator</code></a>.</div>
</td>
</tr>
......@@ -578,10 +571,10 @@ implements <a href="Bundleable.html" title="interface in com.google.android.exop
</tr>
<tr id="i3" class="rowColor">
<td class="colFirst"><code>protected static <a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#keyForField(@com.google.android.exoplayer2.PlaybackException.FieldNumberint)">keyForField</a></span>&#8203;(@com.google.android.exoplayer2.PlaybackException.FieldNumber int&nbsp;field)</code></th>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#keyForField(int)">keyForField</a></span>&#8203;(int&nbsp;field)</code></th>
<td class="colLast">
<div class="block">Converts the given <a href="PlaybackException.FieldNumber.html" title="annotation in com.google.android.exoplayer2"><code>PlaybackException.FieldNumber</code></a> to a string which can be used as a field key when
implementing <a href="#toBundle()"><code>toBundle()</code></a> and <a href="Bundleable.Creator.html" title="interface in com.google.android.exoplayer2"><code>Bundleable.Creator</code></a>.</div>
<div class="block">Converts the given field number to a string which can be used as a field key when implementing
<a href="#toBundle()"><code>toBundle()</code></a> and <a href="Bundleable.Creator.html" title="interface in com.google.android.exoplayer2"><code>Bundleable.Creator</code></a>.</div>
</td>
</tr>
<tr id="i4" class="altColor">
......@@ -1169,11 +1162,11 @@ public final&nbsp;@com.google.android.exoplayer2.PlaybackException.ErrorCode int
<li class="blockList">
<h4>FIELD_CUSTOM_ID_BASE</h4>
<pre>protected static final&nbsp;int FIELD_CUSTOM_ID_BASE</pre>
<div class="block">Defines a minimum field id value for subclasses to use when implementing <a href="#toBundle()"><code>toBundle()</code></a>
<div class="block">Defines a minimum field ID value for subclasses to use when implementing <a href="#toBundle()"><code>toBundle()</code></a>
and <a href="Bundleable.Creator.html" title="interface in com.google.android.exoplayer2"><code>Bundleable.Creator</code></a>.
<p>Subclasses should obtain their <a href="https://developer.android.com/reference/android/os/Bundle.html" title="class or interface in android.os" class="externalLink" target="_top"><code>Bundle's</code></a> field keys by applying a non-negative
offset on this constant and passing the result to <a href="#keyForField(@com.google.android.exoplayer2.PlaybackException.FieldNumberint)"><code>keyForField(int)</code></a>.</div>
offset on this constant and passing the result to <a href="#keyForField(int)"><code>keyForField(int)</code></a>.</div>
<dl>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="../../../../constant-values.html#com.google.android.exoplayer2.PlaybackException.FIELD_CUSTOM_ID_BASE">Constant Field Values</a></dd>
......@@ -1309,15 +1302,17 @@ public&nbsp;<a href="https://developer.android.com/reference/android/os/Bundle.h
</dl>
</li>
</ul>
<a id="keyForField(@com.google.android.exoplayer2.PlaybackException.FieldNumberint)">
<a id="keyForField(int)">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>keyForField</h4>
<pre class="methodSignature">protected static&nbsp;<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&nbsp;keyForField&#8203;(@com.google.android.exoplayer2.PlaybackException.FieldNumber int&nbsp;field)</pre>
<div class="block">Converts the given <a href="PlaybackException.FieldNumber.html" title="annotation in com.google.android.exoplayer2"><code>PlaybackException.FieldNumber</code></a> to a string which can be used as a field key when
implementing <a href="#toBundle()"><code>toBundle()</code></a> and <a href="Bundleable.Creator.html" title="interface in com.google.android.exoplayer2"><code>Bundleable.Creator</code></a>.</div>
<pre class="methodSignature">protected static&nbsp;<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&nbsp;keyForField&#8203;(int&nbsp;field)</pre>
<div class="block">Converts the given field number to a string which can be used as a field key when implementing
<a href="#toBundle()"><code>toBundle()</code></a> and <a href="Bundleable.Creator.html" title="interface in com.google.android.exoplayer2"><code>Bundleable.Creator</code></a>.
<p>Subclasses should use <code>field</code> values greater than or equal to <a href="#FIELD_CUSTOM_ID_BASE"><code>FIELD_CUSTOM_ID_BASE</code></a>.</div>
</li>
</ul>
</li>
......
......@@ -117,7 +117,7 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<a href="https://developer.android.com/reference/java/lang/annotation/Retention.html" title="class or interface in java.lang.annotation" class="externalLink">@Retention</a>(<a href="https://developer.android.com/reference/java/lang/annotation/RetentionPolicy.html?is-external=true#SOURCE" title="class or interface in java.lang.annotation" class="externalLink" target="_top">SOURCE</a>)
<a href="https://developer.android.com/reference/java/lang/annotation/Target.html" title="class or interface in java.lang.annotation" class="externalLink">@Target</a>({<a href="https://developer.android.com/reference/java/lang/annotation/ElementType.html?is-external=true#FIELD" title="class or interface in java.lang.annotation" class="externalLink">FIELD</a>,<a href="https://developer.android.com/reference/java/lang/annotation/ElementType.html?is-external=true#METHOD" title="class or interface in java.lang.annotation" class="externalLink">METHOD</a>,<a href="https://developer.android.com/reference/java/lang/annotation/ElementType.html?is-external=true#PARAMETER" title="class or interface in java.lang.annotation" class="externalLink">PARAMETER</a>,<a href="https://developer.android.com/reference/java/lang/annotation/ElementType.html?is-external=true#LOCAL_VARIABLE" title="class or interface in java.lang.annotation" class="externalLink">LOCAL_VARIABLE</a>,<a href="https://developer.android.com/reference/java/lang/annotation/ElementType.html?is-external=true#TYPE_USE" title="class or interface in java.lang.annotation" class="externalLink" target="_top">TYPE_USE</a>})
public static @interface <span class="memberNameLabel">Player.Command</span></pre>
<div class="block">Commands that can be executed on a <code>Player</code>. One of <a href="Player.html#COMMAND_PLAY_PAUSE"><code>Player.COMMAND_PLAY_PAUSE</code></a>, <a href="Player.html#COMMAND_PREPARE"><code>Player.COMMAND_PREPARE</code></a>, <a href="Player.html#COMMAND_STOP"><code>Player.COMMAND_STOP</code></a>, <a href="Player.html#COMMAND_SEEK_TO_DEFAULT_POSITION"><code>Player.COMMAND_SEEK_TO_DEFAULT_POSITION</code></a>, <a href="Player.html#COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM"><code>Player.COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM</code></a>, <a href="Player.html#COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM"><code>Player.COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM</code></a>, <a href="Player.html#COMMAND_SEEK_TO_PREVIOUS"><code>Player.COMMAND_SEEK_TO_PREVIOUS</code></a>, <a href="Player.html#COMMAND_SEEK_TO_NEXT_MEDIA_ITEM"><code>Player.COMMAND_SEEK_TO_NEXT_MEDIA_ITEM</code></a>, <a href="Player.html#COMMAND_SEEK_TO_NEXT"><code>Player.COMMAND_SEEK_TO_NEXT</code></a>, <a href="Player.html#COMMAND_SEEK_TO_MEDIA_ITEM"><code>Player.COMMAND_SEEK_TO_MEDIA_ITEM</code></a>, <a href="Player.html#COMMAND_SEEK_BACK"><code>Player.COMMAND_SEEK_BACK</code></a>, <a href="Player.html#COMMAND_SEEK_FORWARD"><code>Player.COMMAND_SEEK_FORWARD</code></a>, <a href="Player.html#COMMAND_SET_SPEED_AND_PITCH"><code>Player.COMMAND_SET_SPEED_AND_PITCH</code></a>, <a href="Player.html#COMMAND_SET_SHUFFLE_MODE"><code>Player.COMMAND_SET_SHUFFLE_MODE</code></a>, <a href="Player.html#COMMAND_SET_REPEAT_MODE"><code>Player.COMMAND_SET_REPEAT_MODE</code></a>, <a href="Player.html#COMMAND_GET_CURRENT_MEDIA_ITEM"><code>Player.COMMAND_GET_CURRENT_MEDIA_ITEM</code></a>, <a href="Player.html#COMMAND_GET_TIMELINE"><code>Player.COMMAND_GET_TIMELINE</code></a>, <a href="Player.html#COMMAND_GET_MEDIA_ITEMS_METADATA"><code>Player.COMMAND_GET_MEDIA_ITEMS_METADATA</code></a>, <a href="Player.html#COMMAND_SET_MEDIA_ITEMS_METADATA"><code>Player.COMMAND_SET_MEDIA_ITEMS_METADATA</code></a>, <a href="Player.html#COMMAND_CHANGE_MEDIA_ITEMS"><code>Player.COMMAND_CHANGE_MEDIA_ITEMS</code></a>, <a href="Player.html#COMMAND_GET_AUDIO_ATTRIBUTES"><code>Player.COMMAND_GET_AUDIO_ATTRIBUTES</code></a>, <a href="Player.html#COMMAND_GET_VOLUME"><code>Player.COMMAND_GET_VOLUME</code></a>, <a href="Player.html#COMMAND_GET_DEVICE_VOLUME"><code>Player.COMMAND_GET_DEVICE_VOLUME</code></a>, <a href="Player.html#COMMAND_SET_VOLUME"><code>Player.COMMAND_SET_VOLUME</code></a>, <a href="Player.html#COMMAND_SET_DEVICE_VOLUME"><code>Player.COMMAND_SET_DEVICE_VOLUME</code></a>, <a href="Player.html#COMMAND_ADJUST_DEVICE_VOLUME"><code>Player.COMMAND_ADJUST_DEVICE_VOLUME</code></a>, <a href="Player.html#COMMAND_SET_VIDEO_SURFACE"><code>Player.COMMAND_SET_VIDEO_SURFACE</code></a>, <a href="Player.html#COMMAND_GET_TEXT"><code>Player.COMMAND_GET_TEXT</code></a>, <a href="Player.html#COMMAND_SET_TRACK_SELECTION_PARAMETERS"><code>Player.COMMAND_SET_TRACK_SELECTION_PARAMETERS</code></a> or <a href="Player.html#COMMAND_GET_TRACK_INFOS"><code>Player.COMMAND_GET_TRACK_INFOS</code></a>.</div>
<div class="block">Commands that can be executed on a <code>Player</code>. One of <a href="Player.html#COMMAND_PLAY_PAUSE"><code>Player.COMMAND_PLAY_PAUSE</code></a>, <a href="Player.html#COMMAND_PREPARE"><code>Player.COMMAND_PREPARE</code></a>, <a href="Player.html#COMMAND_STOP"><code>Player.COMMAND_STOP</code></a>, <a href="Player.html#COMMAND_SEEK_TO_DEFAULT_POSITION"><code>Player.COMMAND_SEEK_TO_DEFAULT_POSITION</code></a>, <a href="Player.html#COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM"><code>Player.COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM</code></a>, <a href="Player.html#COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM"><code>Player.COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM</code></a>, <a href="Player.html#COMMAND_SEEK_TO_PREVIOUS"><code>Player.COMMAND_SEEK_TO_PREVIOUS</code></a>, <a href="Player.html#COMMAND_SEEK_TO_NEXT_MEDIA_ITEM"><code>Player.COMMAND_SEEK_TO_NEXT_MEDIA_ITEM</code></a>, <a href="Player.html#COMMAND_SEEK_TO_NEXT"><code>Player.COMMAND_SEEK_TO_NEXT</code></a>, <a href="Player.html#COMMAND_SEEK_TO_MEDIA_ITEM"><code>Player.COMMAND_SEEK_TO_MEDIA_ITEM</code></a>, <a href="Player.html#COMMAND_SEEK_BACK"><code>Player.COMMAND_SEEK_BACK</code></a>, <a href="Player.html#COMMAND_SEEK_FORWARD"><code>Player.COMMAND_SEEK_FORWARD</code></a>, <a href="Player.html#COMMAND_SET_SPEED_AND_PITCH"><code>Player.COMMAND_SET_SPEED_AND_PITCH</code></a>, <a href="Player.html#COMMAND_SET_SHUFFLE_MODE"><code>Player.COMMAND_SET_SHUFFLE_MODE</code></a>, <a href="Player.html#COMMAND_SET_REPEAT_MODE"><code>Player.COMMAND_SET_REPEAT_MODE</code></a>, <a href="Player.html#COMMAND_GET_CURRENT_MEDIA_ITEM"><code>Player.COMMAND_GET_CURRENT_MEDIA_ITEM</code></a>, <a href="Player.html#COMMAND_GET_TIMELINE"><code>Player.COMMAND_GET_TIMELINE</code></a>, <a href="Player.html#COMMAND_GET_MEDIA_ITEMS_METADATA"><code>Player.COMMAND_GET_MEDIA_ITEMS_METADATA</code></a>, <a href="Player.html#COMMAND_SET_MEDIA_ITEMS_METADATA"><code>Player.COMMAND_SET_MEDIA_ITEMS_METADATA</code></a>, <a href="Player.html#COMMAND_CHANGE_MEDIA_ITEMS"><code>Player.COMMAND_CHANGE_MEDIA_ITEMS</code></a>, <a href="Player.html#COMMAND_GET_AUDIO_ATTRIBUTES"><code>Player.COMMAND_GET_AUDIO_ATTRIBUTES</code></a>, <a href="Player.html#COMMAND_GET_VOLUME"><code>Player.COMMAND_GET_VOLUME</code></a>, <a href="Player.html#COMMAND_GET_DEVICE_VOLUME"><code>Player.COMMAND_GET_DEVICE_VOLUME</code></a>, <a href="Player.html#COMMAND_SET_VOLUME"><code>Player.COMMAND_SET_VOLUME</code></a>, <a href="Player.html#COMMAND_SET_DEVICE_VOLUME"><code>Player.COMMAND_SET_DEVICE_VOLUME</code></a>, <a href="Player.html#COMMAND_ADJUST_DEVICE_VOLUME"><code>Player.COMMAND_ADJUST_DEVICE_VOLUME</code></a>, <a href="Player.html#COMMAND_SET_VIDEO_SURFACE"><code>Player.COMMAND_SET_VIDEO_SURFACE</code></a>, <a href="Player.html#COMMAND_GET_TEXT"><code>Player.COMMAND_GET_TEXT</code></a>, <a href="Player.html#COMMAND_SET_TRACK_SELECTION_PARAMETERS"><code>Player.COMMAND_SET_TRACK_SELECTION_PARAMETERS</code></a>, <a href="Player.html#COMMAND_GET_TRACKS"><code>Player.COMMAND_GET_TRACKS</code></a> or <a href="Player.html#COMMAND_SET_MEDIA_ITEM"><code>Player.COMMAND_SET_MEDIA_ITEM</code></a>.</div>
</li>
</ul>
</div>
......
......@@ -25,7 +25,7 @@
catch(err) {
}
//-->
var data = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10};
var data = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10,"i7":10};
var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]};
var altColor = "altColor";
var rowColor = "rowColor";
......@@ -243,29 +243,36 @@ implements <a href="Bundleable.html" title="interface in com.google.android.exop
</tr>
<tr id="i2" class="altColor">
<td class="colFirst"><code>boolean</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#containsAny(@com.google.android.exoplayer2.Player.Commandint...)">containsAny</a></span>&#8203;(@com.google.android.exoplayer2.Player.Command int...&nbsp;commands)</code></th>
<td class="colLast">
<div class="block">Returns whether the set of commands contains at least one of the given <code>commands</code>.</div>
</td>
</tr>
<tr id="i3" class="rowColor">
<td class="colFirst"><code>boolean</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#equals(java.lang.Object)">equals</a></span>&#8203;(<a href="https://developer.android.com/reference/java/lang/Object.html" title="class or interface in java.lang" class="externalLink" target="_top">Object</a>&nbsp;obj)</code></th>
<td class="colLast">&nbsp;</td>
</tr>
<tr id="i3" class="rowColor">
<tr id="i4" class="altColor">
<td class="colFirst"><code>@com.google.android.exoplayer2.Player.Command int</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#get(int)">get</a></span>&#8203;(int&nbsp;index)</code></th>
<td class="colLast">
<div class="block">Returns the <a href="Player.Command.html" title="annotation in com.google.android.exoplayer2"><code>Player.Command</code></a> at the given index.</div>
</td>
</tr>
<tr id="i4" class="altColor">
<tr id="i5" class="rowColor">
<td class="colFirst"><code>int</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#hashCode()">hashCode</a></span>()</code></th>
<td class="colLast">&nbsp;</td>
</tr>
<tr id="i5" class="rowColor">
<tr id="i6" class="altColor">
<td class="colFirst"><code>int</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#size()">size</a></span>()</code></th>
<td class="colLast">
<div class="block">Returns the number of commands in this set.</div>
</td>
</tr>
<tr id="i6" class="altColor">
<tr id="i7" class="rowColor">
<td class="colFirst"><code><a href="https://developer.android.com/reference/android/os/Bundle.html" title="class or interface in android.os" class="externalLink" target="_top">Bundle</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#toBundle()">toBundle</a></span>()</code></th>
<td class="colLast">
......@@ -347,6 +354,17 @@ implements <a href="Bundleable.html" title="interface in com.google.android.exop
<div class="block">Returns whether the set of commands contains the specified <a href="Player.Command.html" title="annotation in com.google.android.exoplayer2"><code>Player.Command</code></a>.</div>
</li>
</ul>
<a id="containsAny(@com.google.android.exoplayer2.Player.Commandint...)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>containsAny</h4>
<pre class="methodSignature">public&nbsp;boolean&nbsp;containsAny&#8203;(<a href="Player.Command.html" title="annotation in com.google.android.exoplayer2">@Command</a>
@com.google.android.exoplayer2.Player.Command int...&nbsp;commands)</pre>
<div class="block">Returns whether the set of commands contains at least one of the given <code>commands</code>.</div>
</li>
</ul>
<a id="size()">
<!-- -->
</a>
......
......@@ -185,13 +185,6 @@ implements <a href="Bundleable.html" title="interface in com.google.android.exop
<div class="block">Object that can restore a <a href="Rating.html" title="class in com.google.android.exoplayer2"><code>Rating</code></a> from a <a href="https://developer.android.com/reference/android/os/Bundle.html" title="class or interface in android.os" class="externalLink" target="_top"><code>Bundle</code></a>.</div>
</td>
</tr>
<tr class="rowColor">
<td class="colFirst"><code>static float</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#RATING_UNSET">RATING_UNSET</a></span></code></th>
<td class="colLast">
<div class="block">A float value that denotes the rating is unset.</div>
</td>
</tr>
</table>
</li>
</ul>
......@@ -248,20 +241,6 @@ implements <a href="Bundleable.html" title="interface in com.google.android.exop
<!-- -->
</a>
<h3>Field Detail</h3>
<a id="RATING_UNSET">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>RATING_UNSET</h4>
<pre>public static final&nbsp;float RATING_UNSET</pre>
<div class="block">A float value that denotes the rating is unset.</div>
<dl>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="../../../../constant-values.html#com.google.android.exoplayer2.Rating.RATING_UNSET">Constant Field Values</a></dd>
</dl>
</li>
</ul>
<a id="CREATOR">
<!-- -->
</a>
......
......@@ -152,7 +152,7 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
</tr>
<tr id="i0" class="altColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#onSleep(long)">onSleep</a></span>&#8203;(long&nbsp;wakeupDeadlineMs)</code></th>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#onSleep()">onSleep</a></span>()</code></th>
<td class="colLast">
<div class="block">The renderer no longer needs to render until the next wakeup.</div>
</td>
......@@ -181,21 +181,16 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<!-- -->
</a>
<h3>Method Detail</h3>
<a id="onSleep(long)">
<a id="onSleep()">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>onSleep</h4>
<pre class="methodSignature">void&nbsp;onSleep&#8203;(long&nbsp;wakeupDeadlineMs)</pre>
<pre class="methodSignature">void&nbsp;onSleep()</pre>
<div class="block">The renderer no longer needs to render until the next wakeup.
<p>Must be called from the thread ExoPlayer invokes the renderer from.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>wakeupDeadlineMs</code> - Maximum time in milliseconds until <a href="#onWakeup()"><code>onWakeup()</code></a> will be
called.</dd>
</dl>
</li>
</ul>
<a id="onWakeup()">
......
......@@ -186,13 +186,6 @@ extends <a href="Rating.html" title="class in com.google.android.exoplayer2">Rat
</td>
</tr>
</table>
<ul class="blockList">
<li class="blockList"><a id="fields.inherited.from.class.com.google.android.exoplayer2.Rating">
<!-- -->
</a>
<h3>Fields inherited from class&nbsp;com.google.android.exoplayer2.<a href="Rating.html" title="class in com.google.android.exoplayer2">Rating</a></h3>
<code><a href="Rating.html#RATING_UNSET">RATING_UNSET</a></code></li>
</ul>
</li>
</ul>
</section>
......
......@@ -186,13 +186,6 @@ extends <a href="Rating.html" title="class in com.google.android.exoplayer2">Rat
</td>
</tr>
</table>
<ul class="blockList">
<li class="blockList"><a id="fields.inherited.from.class.com.google.android.exoplayer2.Rating">
<!-- -->
</a>
<h3>Fields inherited from class&nbsp;com.google.android.exoplayer2.<a href="Rating.html" title="class in com.google.android.exoplayer2">Rating</a></h3>
<code><a href="Rating.html#RATING_UNSET">RATING_UNSET</a></code></li>
</ul>
</li>
</ul>
</section>
......
......@@ -393,7 +393,7 @@ extends <a href="../Player.Listener.html" title="interface in com.google.android
<!-- -->
</a>
<h3>Methods inherited from interface&nbsp;com.google.android.exoplayer2.<a href="../Player.Listener.html" title="interface in com.google.android.exoplayer2">Player.Listener</a></h3>
<code><a href="../Player.Listener.html#onAudioAttributesChanged(com.google.android.exoplayer2.audio.AudioAttributes)">onAudioAttributesChanged</a>, <a href="../Player.Listener.html#onAudioSessionIdChanged(int)">onAudioSessionIdChanged</a>, <a href="../Player.Listener.html#onAvailableCommandsChanged(com.google.android.exoplayer2.Player.Commands)">onAvailableCommandsChanged</a>, <a href="../Player.Listener.html#onCues(java.util.List)">onCues</a>, <a href="../Player.Listener.html#onDeviceInfoChanged(com.google.android.exoplayer2.DeviceInfo)">onDeviceInfoChanged</a>, <a href="../Player.Listener.html#onDeviceVolumeChanged(int,boolean)">onDeviceVolumeChanged</a>, <a href="../Player.Listener.html#onEvents(com.google.android.exoplayer2.Player,com.google.android.exoplayer2.Player.Events)">onEvents</a>, <a href="../Player.Listener.html#onIsLoadingChanged(boolean)">onIsLoadingChanged</a>, <a href="../Player.Listener.html#onIsPlayingChanged(boolean)">onIsPlayingChanged</a>, <a href="../Player.Listener.html#onLoadingChanged(boolean)">onLoadingChanged</a>, <a href="../Player.Listener.html#onMaxSeekToPreviousPositionChanged(long)">onMaxSeekToPreviousPositionChanged</a>, <a href="../Player.Listener.html#onMediaItemTransition(com.google.android.exoplayer2.MediaItem,@com.google.android.exoplayer2.Player.MediaItemTransitionReasonint)">onMediaItemTransition</a>, <a href="../Player.Listener.html#onMediaMetadataChanged(com.google.android.exoplayer2.MediaMetadata)">onMediaMetadataChanged</a>, <a href="../Player.Listener.html#onMetadata(com.google.android.exoplayer2.metadata.Metadata)">onMetadata</a>, <a href="../Player.Listener.html#onPlaybackParametersChanged(com.google.android.exoplayer2.PlaybackParameters)">onPlaybackParametersChanged</a>, <a href="../Player.Listener.html#onPlaybackStateChanged(@com.google.android.exoplayer2.Player.Stateint)">onPlaybackStateChanged</a>, <a href="../Player.Listener.html#onPlaybackSuppressionReasonChanged(@com.google.android.exoplayer2.Player.PlaybackSuppressionReasonint)">onPlaybackSuppressionReasonChanged</a>, <a href="../Player.Listener.html#onPlayerError(com.google.android.exoplayer2.PlaybackException)">onPlayerError</a>, <a href="../Player.Listener.html#onPlayerErrorChanged(com.google.android.exoplayer2.PlaybackException)">onPlayerErrorChanged</a>, <a href="../Player.Listener.html#onPlayerStateChanged(boolean,@com.google.android.exoplayer2.Player.Stateint)">onPlayerStateChanged</a>, <a href="../Player.Listener.html#onPlaylistMetadataChanged(com.google.android.exoplayer2.MediaMetadata)">onPlaylistMetadataChanged</a>, <a href="../Player.Listener.html#onPlayWhenReadyChanged(boolean,@com.google.android.exoplayer2.Player.PlayWhenReadyChangeReasonint)">onPlayWhenReadyChanged</a>, <a href="../Player.Listener.html#onPositionDiscontinuity(@com.google.android.exoplayer2.Player.DiscontinuityReasonint)">onPositionDiscontinuity</a>, <a href="../Player.Listener.html#onPositionDiscontinuity(com.google.android.exoplayer2.Player.PositionInfo,com.google.android.exoplayer2.Player.PositionInfo,@com.google.android.exoplayer2.Player.DiscontinuityReasonint)">onPositionDiscontinuity</a>, <a href="../Player.Listener.html#onRenderedFirstFrame()">onRenderedFirstFrame</a>, <a href="../Player.Listener.html#onRepeatModeChanged(@com.google.android.exoplayer2.Player.RepeatModeint)">onRepeatModeChanged</a>, <a href="../Player.Listener.html#onSeekBackIncrementChanged(long)">onSeekBackIncrementChanged</a>, <a href="../Player.Listener.html#onSeekForwardIncrementChanged(long)">onSeekForwardIncrementChanged</a>, <a href="../Player.Listener.html#onSeekProcessed()">onSeekProcessed</a>, <a href="../Player.Listener.html#onShuffleModeEnabledChanged(boolean)">onShuffleModeEnabledChanged</a>, <a href="../Player.Listener.html#onSkipSilenceEnabledChanged(boolean)">onSkipSilenceEnabledChanged</a>, <a href="../Player.Listener.html#onSurfaceSizeChanged(int,int)">onSurfaceSizeChanged</a>, <a href="../Player.Listener.html#onTimelineChanged(com.google.android.exoplayer2.Timeline,@com.google.android.exoplayer2.Player.TimelineChangeReasonint)">onTimelineChanged</a>, <a href="../Player.Listener.html#onTracksChanged(com.google.android.exoplayer2.source.TrackGroupArray,com.google.android.exoplayer2.trackselection.TrackSelectionArray)">onTracksChanged</a>, <a href="../Player.Listener.html#onTrackSelectionParametersChanged(com.google.android.exoplayer2.trackselection.TrackSelectionParameters)">onTrackSelectionParametersChanged</a>, <a href="../Player.Listener.html#onTracksInfoChanged(com.google.android.exoplayer2.TracksInfo)">onTracksInfoChanged</a>, <a href="../Player.Listener.html#onVideoSizeChanged(com.google.android.exoplayer2.video.VideoSize)">onVideoSizeChanged</a>, <a href="../Player.Listener.html#onVolumeChanged(float)">onVolumeChanged</a></code></li>
<code><a href="../Player.Listener.html#onAudioAttributesChanged(com.google.android.exoplayer2.audio.AudioAttributes)">onAudioAttributesChanged</a>, <a href="../Player.Listener.html#onAudioSessionIdChanged(int)">onAudioSessionIdChanged</a>, <a href="../Player.Listener.html#onAvailableCommandsChanged(com.google.android.exoplayer2.Player.Commands)">onAvailableCommandsChanged</a>, <a href="../Player.Listener.html#onCues(com.google.android.exoplayer2.text.CueGroup)">onCues</a>, <a href="../Player.Listener.html#onCues(java.util.List)">onCues</a>, <a href="../Player.Listener.html#onDeviceInfoChanged(com.google.android.exoplayer2.DeviceInfo)">onDeviceInfoChanged</a>, <a href="../Player.Listener.html#onDeviceVolumeChanged(int,boolean)">onDeviceVolumeChanged</a>, <a href="../Player.Listener.html#onEvents(com.google.android.exoplayer2.Player,com.google.android.exoplayer2.Player.Events)">onEvents</a>, <a href="../Player.Listener.html#onIsLoadingChanged(boolean)">onIsLoadingChanged</a>, <a href="../Player.Listener.html#onIsPlayingChanged(boolean)">onIsPlayingChanged</a>, <a href="../Player.Listener.html#onLoadingChanged(boolean)">onLoadingChanged</a>, <a href="../Player.Listener.html#onMaxSeekToPreviousPositionChanged(long)">onMaxSeekToPreviousPositionChanged</a>, <a href="../Player.Listener.html#onMediaItemTransition(com.google.android.exoplayer2.MediaItem,@com.google.android.exoplayer2.Player.MediaItemTransitionReasonint)">onMediaItemTransition</a>, <a href="../Player.Listener.html#onMediaMetadataChanged(com.google.android.exoplayer2.MediaMetadata)">onMediaMetadataChanged</a>, <a href="../Player.Listener.html#onMetadata(com.google.android.exoplayer2.metadata.Metadata)">onMetadata</a>, <a href="../Player.Listener.html#onPlaybackParametersChanged(com.google.android.exoplayer2.PlaybackParameters)">onPlaybackParametersChanged</a>, <a href="../Player.Listener.html#onPlaybackStateChanged(@com.google.android.exoplayer2.Player.Stateint)">onPlaybackStateChanged</a>, <a href="../Player.Listener.html#onPlaybackSuppressionReasonChanged(@com.google.android.exoplayer2.Player.PlaybackSuppressionReasonint)">onPlaybackSuppressionReasonChanged</a>, <a href="../Player.Listener.html#onPlayerError(com.google.android.exoplayer2.PlaybackException)">onPlayerError</a>, <a href="../Player.Listener.html#onPlayerErrorChanged(com.google.android.exoplayer2.PlaybackException)">onPlayerErrorChanged</a>, <a href="../Player.Listener.html#onPlayerStateChanged(boolean,@com.google.android.exoplayer2.Player.Stateint)">onPlayerStateChanged</a>, <a href="../Player.Listener.html#onPlaylistMetadataChanged(com.google.android.exoplayer2.MediaMetadata)">onPlaylistMetadataChanged</a>, <a href="../Player.Listener.html#onPlayWhenReadyChanged(boolean,@com.google.android.exoplayer2.Player.PlayWhenReadyChangeReasonint)">onPlayWhenReadyChanged</a>, <a href="../Player.Listener.html#onPositionDiscontinuity(@com.google.android.exoplayer2.Player.DiscontinuityReasonint)">onPositionDiscontinuity</a>, <a href="../Player.Listener.html#onPositionDiscontinuity(com.google.android.exoplayer2.Player.PositionInfo,com.google.android.exoplayer2.Player.PositionInfo,@com.google.android.exoplayer2.Player.DiscontinuityReasonint)">onPositionDiscontinuity</a>, <a href="../Player.Listener.html#onRenderedFirstFrame()">onRenderedFirstFrame</a>, <a href="../Player.Listener.html#onRepeatModeChanged(@com.google.android.exoplayer2.Player.RepeatModeint)">onRepeatModeChanged</a>, <a href="../Player.Listener.html#onSeekBackIncrementChanged(long)">onSeekBackIncrementChanged</a>, <a href="../Player.Listener.html#onSeekForwardIncrementChanged(long)">onSeekForwardIncrementChanged</a>, <a href="../Player.Listener.html#onSeekProcessed()">onSeekProcessed</a>, <a href="../Player.Listener.html#onShuffleModeEnabledChanged(boolean)">onShuffleModeEnabledChanged</a>, <a href="../Player.Listener.html#onSkipSilenceEnabledChanged(boolean)">onSkipSilenceEnabledChanged</a>, <a href="../Player.Listener.html#onSurfaceSizeChanged(int,int)">onSurfaceSizeChanged</a>, <a href="../Player.Listener.html#onTimelineChanged(com.google.android.exoplayer2.Timeline,@com.google.android.exoplayer2.Player.TimelineChangeReasonint)">onTimelineChanged</a>, <a href="../Player.Listener.html#onTracksChanged(com.google.android.exoplayer2.Tracks)">onTracksChanged</a>, <a href="../Player.Listener.html#onTrackSelectionParametersChanged(com.google.android.exoplayer2.trackselection.TrackSelectionParameters)">onTrackSelectionParametersChanged</a>, <a href="../Player.Listener.html#onVideoSizeChanged(com.google.android.exoplayer2.video.VideoSize)">onVideoSizeChanged</a>, <a href="../Player.Listener.html#onVolumeChanged(float)">onVolumeChanged</a></code></li>
</ul>
</li>
</ul>
......
......@@ -2,7 +2,7 @@
<!-- NewPage -->
<html lang="en">
<head><!-- start favicons snippet, use https://realfavicongenerator.net/ --><link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16.png"><link rel="manifest" href="/assets/site.webmanifest"><link rel="mask-icon" href="/assets/safari-pinned-tab.svg" color="#fc4d50"><link rel="shortcut icon" href="/assets/favicon.ico"><meta name="msapplication-TileColor" content="#ffc40d"><meta name="msapplication-config" content="/assets/browserconfig.xml"><meta name="theme-color" content="#ffffff"><!-- end favicons snippet -->
<title>NetworkTypeObserver.Config (ExoPlayer library)</title>
<title>AudioAttributes.AudioAttributesV21 (ExoPlayer library)</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style">
<link rel="stylesheet" type="text/css" href="../../../../../jquery/jquery-ui.css" title="Style">
......@@ -19,18 +19,12 @@
<script type="text/javascript"><!--
try {
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="NetworkTypeObserver.Config (ExoPlayer library)";
parent.document.title="AudioAttributes.AudioAttributesV21 (ExoPlayer library)";
}
}
catch(err) {
}
//-->
var data = {"i0":9};
var tabs = {65535:["t0","All Methods"],1:["t1","Static Methods"],8:["t4","Concrete Methods"]};
var altColor = "altColor";
var rowColor = "rowColor";
var tableTab = "tableTab";
var activeTableTab = "activeTableTab";
var pathtoroot = "../../../../../";
var useModuleDirectories = false;
loadScripts(document, 'script');</script>
......@@ -87,15 +81,15 @@ loadScripts(document, 'script');</script>
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li>Nested&nbsp;|&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#field.summary">Field</a>&nbsp;|&nbsp;</li>
<li>Constr&nbsp;|&nbsp;</li>
<li><a href="#method.summary">Method</a></li>
</ul>
<ul class="subNavList">
<li>Detail:&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#field.detail">Field</a>&nbsp;|&nbsp;</li>
<li>Constr&nbsp;|&nbsp;</li>
<li><a href="#method.detail">Method</a></li>
<li>Method</li>
</ul>
</div>
<a id="skip.navbar.top">
......@@ -113,15 +107,15 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<!-- ======== START OF CLASS DATA ======== -->
<main role="main">
<div class="header">
<div class="subTitle"><span class="packageLabelInType">Package</span>&nbsp;<a href="package-summary.html">com.google.android.exoplayer2.util</a></div>
<h2 title="Class NetworkTypeObserver.Config" class="title">Class NetworkTypeObserver.Config</h2>
<div class="subTitle"><span class="packageLabelInType">Package</span>&nbsp;<a href="package-summary.html">com.google.android.exoplayer2.audio</a></div>
<h2 title="Class AudioAttributes.AudioAttributesV21" class="title">Class AudioAttributes.AudioAttributesV21</h2>
</div>
<div class="contentContainer">
<ul class="inheritance">
<li><a href="https://developer.android.com/reference/java/lang/Object.html" title="class or interface in java.lang" class="externalLink" target="_top">java.lang.Object</a></li>
<li>
<ul class="inheritance">
<li>com.google.android.exoplayer2.util.NetworkTypeObserver.Config</li>
<li>com.google.android.exoplayer2.audio.AudioAttributes.AudioAttributesV21</li>
</ul>
</li>
</ul>
......@@ -130,40 +124,49 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<li class="blockList">
<dl>
<dt>Enclosing class:</dt>
<dd><a href="NetworkTypeObserver.html" title="class in com.google.android.exoplayer2.util">NetworkTypeObserver</a></dd>
<dd><a href="AudioAttributes.html" title="class in com.google.android.exoplayer2.audio">AudioAttributes</a></dd>
</dl>
<hr>
<pre>public static final class <span class="typeNameLabel">NetworkTypeObserver.Config</span>
<pre>@RequiresApi(21)
public static final class <span class="typeNameLabel">AudioAttributes.AudioAttributesV21</span>
extends <a href="https://developer.android.com/reference/java/lang/Object.html" title="class or interface in java.lang" class="externalLink" target="_top">Object</a></pre>
<div class="block">Configuration for <a href="NetworkTypeObserver.html" title="class in com.google.android.exoplayer2.util"><code>NetworkTypeObserver</code></a>.</div>
<div class="block">A direct wrapper around <a href="https://developer.android.com/reference/android/media/AudioAttributes.html" title="class or interface in android.media" class="externalLink" target="_top"><code>AudioAttributes</code></a>.</div>
</li>
</ul>
</div>
<div class="summary">
<ul class="blockList">
<li class="blockList">
<!-- ========== METHOD SUMMARY =========== -->
<!-- =========== FIELD SUMMARY =========== -->
<section role="region">
<ul class="blockList">
<li class="blockList"><a id="method.summary">
<li class="blockList"><a id="field.summary">
<!-- -->
</a>
<h3>Method Summary</h3>
<h3>Field Summary</h3>
<table class="memberSummary">
<caption><span id="t0" class="activeTableTab"><span>All Methods</span><span class="tabEnd">&nbsp;</span></span><span id="t1" class="tableTab"><span><a href="javascript:show(1);">Static Methods</a></span><span class="tabEnd">&nbsp;</span></span><span id="t4" class="tableTab"><span><a href="javascript:show(8);">Concrete Methods</a></span><span class="tabEnd">&nbsp;</span></span></caption>
<caption><span>Fields</span><span class="tabEnd">&nbsp;</span></caption>
<tr>
<th class="colFirst" scope="col">Modifier and Type</th>
<th class="colSecond" scope="col">Method</th>
<th class="colSecond" scope="col">Field</th>
<th class="colLast" scope="col">Description</th>
</tr>
<tr id="i0" class="altColor">
<td class="colFirst"><code>static void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#disable5GNsaDisambiguation()">disable5GNsaDisambiguation</a></span>()</code></th>
<td class="colLast">
<div class="block">Disables logic to disambiguate 5G-NSA networks from 4G networks.</div>
</td>
<tr class="altColor">
<td class="colFirst"><code><a href="https://developer.android.com/reference/android/media/AudioAttributes.html" title="class or interface in android.media" class="externalLink" target="_top">AudioAttributes</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#audioAttributes">audioAttributes</a></span></code></th>
<td class="colLast">&nbsp;</td>
</tr>
</table>
</li>
</ul>
</section>
<!-- ========== METHOD SUMMARY =========== -->
<section role="region">
<ul class="blockList">
<li class="blockList"><a id="method.summary">
<!-- -->
</a>
<h3>Method Summary</h3>
<ul class="blockList">
<li class="blockList"><a id="methods.inherited.from.class.java.lang.Object">
<!-- -->
......@@ -180,21 +183,20 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<div class="details">
<ul class="blockList">
<li class="blockList">
<!-- ============ METHOD DETAIL ========== -->
<!-- ============ FIELD DETAIL =========== -->
<section role="region">
<ul class="blockList">
<li class="blockList"><a id="method.detail">
<li class="blockList"><a id="field.detail">
<!-- -->
</a>
<h3>Method Detail</h3>
<a id="disable5GNsaDisambiguation()">
<h3>Field Detail</h3>
<a id="audioAttributes">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>disable5GNsaDisambiguation</h4>
<pre class="methodSignature">public static&nbsp;void&nbsp;disable5GNsaDisambiguation()</pre>
<div class="block">Disables logic to disambiguate 5G-NSA networks from 4G networks.</div>
<h4>audioAttributes</h4>
<pre>public final&nbsp;<a href="https://developer.android.com/reference/android/media/AudioAttributes.html" title="class or interface in android.media" class="externalLink" target="_top">AudioAttributes</a> audioAttributes</pre>
</li>
</ul>
</li>
......@@ -249,15 +251,15 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li>Nested&nbsp;|&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#field.summary">Field</a>&nbsp;|&nbsp;</li>
<li>Constr&nbsp;|&nbsp;</li>
<li><a href="#method.summary">Method</a></li>
</ul>
<ul class="subNavList">
<li>Detail:&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#field.detail">Field</a>&nbsp;|&nbsp;</li>
<li>Constr&nbsp;|&nbsp;</li>
<li><a href="#method.detail">Method</a></li>
<li>Method</li>
</ul>
</div>
<a id="skip.navbar.bottom">
......
......@@ -211,7 +211,7 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<td class="colFirst"><code><a href="AudioAttributes.Builder.html" title="class in com.google.android.exoplayer2.audio">AudioAttributes.Builder</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setSpatializationBehavior(@com.google.android.exoplayer2.C.SpatializationBehaviorint)">setSpatializationBehavior</a></span>&#8203;(@com.google.android.exoplayer2.C.SpatializationBehavior int&nbsp;spatializationBehavior)</code></th>
<td class="colLast">
<div class="block">See <code>android.media.AudioAttributes.Builder.setSpatializationBehavior(int)</code>.</div>
<div class="block">See <a href="https://developer.android.com/reference/android/media/AudioAttributes.Builder.html#setSpatializationBehavior(int)" title="class or interface in android.media" class="externalLink" target="_top"><code>AudioAttributes.Builder.setSpatializationBehavior(int)</code></a>.</div>
</td>
</tr>
<tr id="i5" class="rowColor">
......@@ -254,7 +254,7 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<pre>public&nbsp;Builder()</pre>
<div class="block">Creates a new builder for <a href="AudioAttributes.html" title="class in com.google.android.exoplayer2.audio"><code>AudioAttributes</code></a>.
<p>By default the content type is <a href="../C.html#CONTENT_TYPE_UNKNOWN"><code>C.CONTENT_TYPE_UNKNOWN</code></a>, usage is <a href="../C.html#USAGE_MEDIA"><code>C.USAGE_MEDIA</code></a>, capture policy is <a href="../C.html#ALLOW_CAPTURE_BY_ALL"><code>C.ALLOW_CAPTURE_BY_ALL</code></a> and no flags are set.</div>
<p>By default the content type is <a href="../C.html#AUDIO_CONTENT_TYPE_UNKNOWN"><code>C.AUDIO_CONTENT_TYPE_UNKNOWN</code></a>, usage is <a href="../C.html#USAGE_MEDIA"><code>C.USAGE_MEDIA</code></a>, capture policy is <a href="../C.html#ALLOW_CAPTURE_BY_ALL"><code>C.ALLOW_CAPTURE_BY_ALL</code></a> and no flags are set.</div>
</li>
</ul>
</li>
......@@ -318,7 +318,7 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<li class="blockList">
<h4>setSpatializationBehavior</h4>
<pre class="methodSignature">public&nbsp;<a href="AudioAttributes.Builder.html" title="class in com.google.android.exoplayer2.audio">AudioAttributes.Builder</a>&nbsp;setSpatializationBehavior&#8203;(@com.google.android.exoplayer2.C.SpatializationBehavior int&nbsp;spatializationBehavior)</pre>
<div class="block">See <code>android.media.AudioAttributes.Builder.setSpatializationBehavior(int)</code>.</div>
<div class="block">See <a href="https://developer.android.com/reference/android/media/AudioAttributes.Builder.html#setSpatializationBehavior(int)" title="class or interface in android.media" class="externalLink" target="_top"><code>AudioAttributes.Builder.setSpatializationBehavior(int)</code></a>.</div>
</li>
</ul>
<a id="build()">
......
......@@ -166,6 +166,13 @@ implements <a href="../Bundleable.html" title="interface in com.google.android.e
</tr>
<tr class="altColor">
<td class="colFirst"><code>static class&nbsp;</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="AudioAttributes.AudioAttributesV21.html" title="class in com.google.android.exoplayer2.audio">AudioAttributes.AudioAttributesV21</a></span></code></th>
<td class="colLast">
<div class="block">A direct wrapper around <a href="https://developer.android.com/reference/android/media/AudioAttributes.html" title="class or interface in android.media" class="externalLink" target="_top"><code>AudioAttributes</code></a>.</div>
</td>
</tr>
<tr class="rowColor">
<td class="colFirst"><code>static class&nbsp;</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="AudioAttributes.Builder.html" title="class in com.google.android.exoplayer2.audio">AudioAttributes.Builder</a></span></code></th>
<td class="colLast">
<div class="block">Builder for <a href="AudioAttributes.html" title="class in com.google.android.exoplayer2.audio"><code>AudioAttributes</code></a>.</div>
......@@ -221,9 +228,9 @@ implements <a href="../Bundleable.html" title="interface in com.google.android.e
<td class="colFirst"><code>static <a href="AudioAttributes.html" title="class in com.google.android.exoplayer2.audio">AudioAttributes</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#DEFAULT">DEFAULT</a></span></code></th>
<td class="colLast">
<div class="block">The default audio attributes, where the content type is <a href="../C.html#CONTENT_TYPE_UNKNOWN"><code>C.CONTENT_TYPE_UNKNOWN</code></a>, usage
is <a href="../C.html#USAGE_MEDIA"><code>C.USAGE_MEDIA</code></a>, capture policy is <a href="../C.html#ALLOW_CAPTURE_BY_ALL"><code>C.ALLOW_CAPTURE_BY_ALL</code></a> and no flags are
set.</div>
<div class="block">The default audio attributes, where the content type is <a href="../C.html#AUDIO_CONTENT_TYPE_UNKNOWN"><code>C.AUDIO_CONTENT_TYPE_UNKNOWN</code></a>,
usage is <a href="../C.html#USAGE_MEDIA"><code>C.USAGE_MEDIA</code></a>, capture policy is <a href="../C.html#ALLOW_CAPTURE_BY_ALL"><code>C.ALLOW_CAPTURE_BY_ALL</code></a> and no flags
are set.</div>
</td>
</tr>
<tr class="altColor">
......@@ -271,10 +278,10 @@ implements <a href="../Bundleable.html" title="interface in com.google.android.e
<td class="colLast">&nbsp;</td>
</tr>
<tr id="i1" class="rowColor">
<td class="colFirst"><code><a href="https://developer.android.com/reference/android/media/AudioAttributes.html" title="class or interface in android.media" class="externalLink" target="_top">AudioAttributes</a></code></td>
<td class="colFirst"><code><a href="AudioAttributes.AudioAttributesV21.html" title="class in com.google.android.exoplayer2.audio">AudioAttributes.AudioAttributesV21</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#getAudioAttributesV21()">getAudioAttributesV21</a></span>()</code></th>
<td class="colLast">
<div class="block">Returns a <a href="https://developer.android.com/reference/android/media/AudioAttributes.html" title="class or interface in android.media" class="externalLink" target="_top"><code>AudioAttributes</code></a> from this instance.</div>
<div class="block">Returns a <a href="AudioAttributes.AudioAttributesV21.html" title="class in com.google.android.exoplayer2.audio"><code>AudioAttributes.AudioAttributesV21</code></a> from this instance.</div>
</td>
</tr>
<tr id="i2" class="altColor">
......@@ -320,9 +327,9 @@ implements <a href="../Bundleable.html" title="interface in com.google.android.e
<li class="blockList">
<h4>DEFAULT</h4>
<pre>public static final&nbsp;<a href="AudioAttributes.html" title="class in com.google.android.exoplayer2.audio">AudioAttributes</a> DEFAULT</pre>
<div class="block">The default audio attributes, where the content type is <a href="../C.html#CONTENT_TYPE_UNKNOWN"><code>C.CONTENT_TYPE_UNKNOWN</code></a>, usage
is <a href="../C.html#USAGE_MEDIA"><code>C.USAGE_MEDIA</code></a>, capture policy is <a href="../C.html#ALLOW_CAPTURE_BY_ALL"><code>C.ALLOW_CAPTURE_BY_ALL</code></a> and no flags are
set.</div>
<div class="block">The default audio attributes, where the content type is <a href="../C.html#AUDIO_CONTENT_TYPE_UNKNOWN"><code>C.AUDIO_CONTENT_TYPE_UNKNOWN</code></a>,
usage is <a href="../C.html#USAGE_MEDIA"><code>C.USAGE_MEDIA</code></a>, capture policy is <a href="../C.html#ALLOW_CAPTURE_BY_ALL"><code>C.ALLOW_CAPTURE_BY_ALL</code></a> and no flags
are set.</div>
</li>
</ul>
<a id="contentType">
......@@ -406,10 +413,11 @@ public final&nbsp;@com.google.android.exoplayer2.C.AudioAllowedCapturePolicy int
<li class="blockList">
<h4>getAudioAttributesV21</h4>
<pre class="methodSignature">@RequiresApi(21)
public&nbsp;<a href="https://developer.android.com/reference/android/media/AudioAttributes.html" title="class or interface in android.media" class="externalLink" target="_top">AudioAttributes</a>&nbsp;getAudioAttributesV21()</pre>
<div class="block">Returns a <a href="https://developer.android.com/reference/android/media/AudioAttributes.html" title="class or interface in android.media" class="externalLink" target="_top"><code>AudioAttributes</code></a> from this instance.
public&nbsp;<a href="AudioAttributes.AudioAttributesV21.html" title="class in com.google.android.exoplayer2.audio">AudioAttributes.AudioAttributesV21</a>&nbsp;getAudioAttributesV21()</pre>
<div class="block">Returns a <a href="AudioAttributes.AudioAttributesV21.html" title="class in com.google.android.exoplayer2.audio"><code>AudioAttributes.AudioAttributesV21</code></a> from this instance.
<p>Field <a href="#allowedCapturePolicy"><code>allowedCapturePolicy</code></a> is ignored for API levels prior to 29.</div>
<p>Some fields are ignored if the corresponding <a href="https://developer.android.com/reference/android/media/AudioAttributes.Builder.html" title="class or interface in android.media" class="externalLink" target="_top"><code>AudioAttributes.Builder</code></a>
setter is not available on the current API level.</div>
</li>
</ul>
<a id="equals(java.lang.Object)">
......
......@@ -25,7 +25,7 @@
catch(err) {
}
//-->
var data = {"i0":10,"i1":9,"i2":10,"i3":10,"i4":10,"i5":10};
var data = {"i0":10,"i1":9,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10,"i7":10};
var tabs = {65535:["t0","All Methods"],1:["t1","Static Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]};
var altColor = "altColor";
var rowColor = "rowColor";
......@@ -215,25 +215,40 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
</td>
</tr>
<tr id="i2" class="altColor">
<td class="colFirst"><code><a href="https://developer.android.com/reference/android/util/Pair.html" title="class or interface in android.util" class="externalLink">Pair</a>&lt;<a href="https://developer.android.com/reference/java/lang/Integer.html?is-external=true" title="class or interface in java.lang" class="externalLink">Integer</a>,&#8203;<a href="https://developer.android.com/reference/java/lang/Integer.html?is-external=true" title="class or interface in java.lang" class="externalLink" target="_top">Integer</a>&gt;</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#getEncodingAndChannelConfigForPassthrough(com.google.android.exoplayer2.Format)">getEncodingAndChannelConfigForPassthrough</a></span>&#8203;(<a href="../Format.html" title="class in com.google.android.exoplayer2">Format</a>&nbsp;format)</code></th>
<td class="colLast">
<div class="block">Returns the encoding and channel config to use when configuring an <a href="https://developer.android.com/reference/android/media/AudioTrack.html" title="class or interface in android.media" class="externalLink" target="_top"><code>AudioTrack</code></a> in
passthrough mode for the specified <a href="../Format.html" title="class in com.google.android.exoplayer2"><code>Format</code></a>.</div>
</td>
</tr>
<tr id="i3" class="rowColor">
<td class="colFirst"><code>int</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#getMaxChannelCount()">getMaxChannelCount</a></span>()</code></th>
<td class="colLast">
<div class="block">Returns the maximum number of channels the device can play at the same time.</div>
</td>
</tr>
<tr id="i3" class="rowColor">
<tr id="i4" class="altColor">
<td class="colFirst"><code>int</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#hashCode()">hashCode</a></span>()</code></th>
<td class="colLast">&nbsp;</td>
</tr>
<tr id="i4" class="altColor">
<tr id="i5" class="rowColor">
<td class="colFirst"><code>boolean</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#isPassthroughPlaybackSupported(com.google.android.exoplayer2.Format)">isPassthroughPlaybackSupported</a></span>&#8203;(<a href="../Format.html" title="class in com.google.android.exoplayer2">Format</a>&nbsp;format)</code></th>
<td class="colLast">
<div class="block">Returns whether the device can do passthrough playback for <code>format</code>.</div>
</td>
</tr>
<tr id="i6" class="altColor">
<td class="colFirst"><code>boolean</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#supportsEncoding(@com.google.android.exoplayer2.C.Encodingint)">supportsEncoding</a></span>&#8203;(@com.google.android.exoplayer2.C.Encoding int&nbsp;encoding)</code></th>
<td class="colLast">
<div class="block">Returns whether this device supports playback of the specified audio <code>encoding</code>.</div>
</td>
</tr>
<tr id="i5" class="rowColor">
<tr id="i7" class="rowColor">
<td class="colFirst"><code><a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#toString()">toString</a></span>()</code></th>
<td class="colLast">&nbsp;</td>
......@@ -357,6 +372,36 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<div class="block">Returns the maximum number of channels the device can play at the same time.</div>
</li>
</ul>
<a id="isPassthroughPlaybackSupported(com.google.android.exoplayer2.Format)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>isPassthroughPlaybackSupported</h4>
<pre class="methodSignature">public&nbsp;boolean&nbsp;isPassthroughPlaybackSupported&#8203;(<a href="../Format.html" title="class in com.google.android.exoplayer2">Format</a>&nbsp;format)</pre>
<div class="block">Returns whether the device can do passthrough playback for <code>format</code>.</div>
</li>
</ul>
<a id="getEncodingAndChannelConfigForPassthrough(com.google.android.exoplayer2.Format)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>getEncodingAndChannelConfigForPassthrough</h4>
<pre class="methodSignature">@Nullable
public&nbsp;<a href="https://developer.android.com/reference/android/util/Pair.html" title="class or interface in android.util" class="externalLink">Pair</a>&lt;<a href="https://developer.android.com/reference/java/lang/Integer.html?is-external=true" title="class or interface in java.lang" class="externalLink">Integer</a>,&#8203;<a href="https://developer.android.com/reference/java/lang/Integer.html?is-external=true" title="class or interface in java.lang" class="externalLink">Integer</a>&gt;&nbsp;getEncodingAndChannelConfigForPassthrough&#8203;(<a href="../Format.html" title="class in com.google.android.exoplayer2" target="_top">Format</a>&nbsp;format)</pre>
<div class="block">Returns the encoding and channel config to use when configuring an <a href="https://developer.android.com/reference/android/media/AudioTrack.html" title="class or interface in android.media" class="externalLink" target="_top"><code>AudioTrack</code></a> in
passthrough mode for the specified <a href="../Format.html" title="class in com.google.android.exoplayer2"><code>Format</code></a>. Returns <code>null</code> if passthrough of the
format is unsupported.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>format</code> - The <a href="../Format.html" title="class in com.google.android.exoplayer2"><code>Format</code></a>.</dd>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>The encoding and channel config to use, or <code>null</code> if passthrough of the format is
unsupported.</dd>
</dl>
</li>
</ul>
<a id="equals(java.lang.Object)">
<!-- -->
</a>
......
......@@ -163,7 +163,7 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
</tr>
<tr id="i2" class="altColor">
<td class="colFirst"><code>default void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#onOffloadBufferFull(long)">onOffloadBufferFull</a></span>&#8203;(long&nbsp;bufferEmptyingDeadlineMs)</code></th>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#onOffloadBufferFull()">onOffloadBufferFull</a></span>()</code></th>
<td class="colLast">
<div class="block">Called when the offload buffer has been filled completely.</div>
</td>
......@@ -291,18 +291,14 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<div class="block">Called when the offload buffer has been partially emptied.</div>
</li>
</ul>
<a id="onOffloadBufferFull(long)">
<a id="onOffloadBufferFull()">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>onOffloadBufferFull</h4>
<pre class="methodSignature">default&nbsp;void&nbsp;onOffloadBufferFull&#8203;(long&nbsp;bufferEmptyingDeadlineMs)</pre>
<pre class="methodSignature">default&nbsp;void&nbsp;onOffloadBufferFull()</pre>
<div class="block">Called when the offload buffer has been filled completely.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>bufferEmptyingDeadlineMs</code> - Maximum time in milliseconds until <a href="#onOffloadBufferEmptying()"><code>onOffloadBufferEmptying()</code></a> will be called.</dd>
</dl>
</li>
</ul>
<a id="onAudioSinkError(java.lang.Exception)">
......
......@@ -110,6 +110,7 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<li class="circle">com.google.android.exoplayer2.audio.<a href="Ac4Util.html" title="class in com.google.android.exoplayer2.audio"><span class="typeNameLink">Ac4Util</span></a></li>
<li class="circle">com.google.android.exoplayer2.audio.<a href="Ac4Util.SyncFrameInfo.html" title="class in com.google.android.exoplayer2.audio"><span class="typeNameLink">Ac4Util.SyncFrameInfo</span></a></li>
<li class="circle">com.google.android.exoplayer2.audio.<a href="AudioAttributes.html" title="class in com.google.android.exoplayer2.audio"><span class="typeNameLink">AudioAttributes</span></a> (implements com.google.android.exoplayer2.<a href="../Bundleable.html" title="interface in com.google.android.exoplayer2">Bundleable</a>)</li>
<li class="circle">com.google.android.exoplayer2.audio.<a href="AudioAttributes.AudioAttributesV21.html" title="class in com.google.android.exoplayer2.audio"><span class="typeNameLink">AudioAttributes.AudioAttributesV21</span></a></li>
<li class="circle">com.google.android.exoplayer2.audio.<a href="AudioAttributes.Builder.html" title="class in com.google.android.exoplayer2.audio"><span class="typeNameLink">AudioAttributes.Builder</span></a></li>
<li class="circle">com.google.android.exoplayer2.audio.<a href="AudioCapabilities.html" title="class in com.google.android.exoplayer2.audio"><span class="typeNameLink">AudioCapabilities</span></a></li>
<li class="circle">com.google.android.exoplayer2.audio.<a href="AudioCapabilitiesReceiver.html" title="class in com.google.android.exoplayer2.audio"><span class="typeNameLink">AudioCapabilitiesReceiver</span></a></li>
......
......@@ -25,7 +25,7 @@
catch(err) {
}
//-->
var data = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10,"i7":10,"i8":10};
var data = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10,"i7":10,"i8":10,"i9":10};
var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]};
var altColor = "altColor";
var rowColor = "rowColor";
......@@ -228,12 +228,19 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
</tr>
<tr id="i7" class="rowColor">
<td class="colFirst"><code>boolean</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#isFirstSample()">isFirstSample</a></span>()</code></th>
<td class="colLast">
<div class="block">Returns whether the <a href="../C.html#BUFFER_FLAG_FIRST_SAMPLE"><code>C.BUFFER_FLAG_FIRST_SAMPLE</code></a> flag is set.</div>
</td>
</tr>
<tr id="i8" class="altColor">
<td class="colFirst"><code>boolean</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#isKeyFrame()">isKeyFrame</a></span>()</code></th>
<td class="colLast">
<div class="block">Returns whether the <a href="../C.html#BUFFER_FLAG_KEY_FRAME"><code>C.BUFFER_FLAG_KEY_FRAME</code></a> flag is set.</div>
</td>
</tr>
<tr id="i8" class="altColor">
<tr id="i9" class="rowColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setFlags(@com.google.android.exoplayer2.C.BufferFlagsint)">setFlags</a></span>&#8203;(@com.google.android.exoplayer2.C.BufferFlags int&nbsp;flags)</code></th>
<td class="colLast">
......@@ -303,6 +310,16 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<div class="block">Returns whether the <a href="../C.html#BUFFER_FLAG_DECODE_ONLY"><code>C.BUFFER_FLAG_DECODE_ONLY</code></a> flag is set.</div>
</li>
</ul>
<a id="isFirstSample()">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>isFirstSample</h4>
<pre class="methodSignature">public final&nbsp;boolean&nbsp;isFirstSample()</pre>
<div class="block">Returns whether the <a href="../C.html#BUFFER_FLAG_FIRST_SAMPLE"><code>C.BUFFER_FLAG_FIRST_SAMPLE</code></a> flag is set.</div>
</li>
</ul>
<a id="isEndOfStream()">
<!-- -->
</a>
......
......@@ -356,7 +356,7 @@ extends <a href="Buffer.html" title="class in com.google.android.exoplayer2.deco
<!-- -->
</a>
<h3>Methods inherited from class&nbsp;com.google.android.exoplayer2.decoder.<a href="Buffer.html" title="class in com.google.android.exoplayer2.decoder">Buffer</a></h3>
<code><a href="Buffer.html#addFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">addFlag</a>, <a href="Buffer.html#clearFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">clearFlag</a>, <a href="Buffer.html#getFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">getFlag</a>, <a href="Buffer.html#hasSupplementalData()">hasSupplementalData</a>, <a href="Buffer.html#isDecodeOnly()">isDecodeOnly</a>, <a href="Buffer.html#isEndOfStream()">isEndOfStream</a>, <a href="Buffer.html#isKeyFrame()">isKeyFrame</a>, <a href="Buffer.html#setFlags(@com.google.android.exoplayer2.C.BufferFlagsint)">setFlags</a></code></li>
<code><a href="Buffer.html#addFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">addFlag</a>, <a href="Buffer.html#clearFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">clearFlag</a>, <a href="Buffer.html#getFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">getFlag</a>, <a href="Buffer.html#hasSupplementalData()">hasSupplementalData</a>, <a href="Buffer.html#isDecodeOnly()">isDecodeOnly</a>, <a href="Buffer.html#isEndOfStream()">isEndOfStream</a>, <a href="Buffer.html#isFirstSample()">isFirstSample</a>, <a href="Buffer.html#isKeyFrame()">isKeyFrame</a>, <a href="Buffer.html#setFlags(@com.google.android.exoplayer2.C.BufferFlagsint)">setFlags</a></code></li>
</ul>
<ul class="blockList">
<li class="blockList"><a id="methods.inherited.from.class.java.lang.Object">
......
......@@ -252,7 +252,7 @@ extends <a href="Buffer.html" title="class in com.google.android.exoplayer2.deco
<!-- -->
</a>
<h3>Methods inherited from class&nbsp;com.google.android.exoplayer2.decoder.<a href="Buffer.html" title="class in com.google.android.exoplayer2.decoder">Buffer</a></h3>
<code><a href="Buffer.html#addFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">addFlag</a>, <a href="Buffer.html#clear()">clear</a>, <a href="Buffer.html#clearFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">clearFlag</a>, <a href="Buffer.html#getFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">getFlag</a>, <a href="Buffer.html#hasSupplementalData()">hasSupplementalData</a>, <a href="Buffer.html#isDecodeOnly()">isDecodeOnly</a>, <a href="Buffer.html#isEndOfStream()">isEndOfStream</a>, <a href="Buffer.html#isKeyFrame()">isKeyFrame</a>, <a href="Buffer.html#setFlags(@com.google.android.exoplayer2.C.BufferFlagsint)">setFlags</a></code></li>
<code><a href="Buffer.html#addFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">addFlag</a>, <a href="Buffer.html#clear()">clear</a>, <a href="Buffer.html#clearFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">clearFlag</a>, <a href="Buffer.html#getFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">getFlag</a>, <a href="Buffer.html#hasSupplementalData()">hasSupplementalData</a>, <a href="Buffer.html#isDecodeOnly()">isDecodeOnly</a>, <a href="Buffer.html#isEndOfStream()">isEndOfStream</a>, <a href="Buffer.html#isFirstSample()">isFirstSample</a>, <a href="Buffer.html#isKeyFrame()">isKeyFrame</a>, <a href="Buffer.html#setFlags(@com.google.android.exoplayer2.C.BufferFlagsint)">setFlags</a></code></li>
</ul>
<ul class="blockList">
<li class="blockList"><a id="methods.inherited.from.class.java.lang.Object">
......
......@@ -258,7 +258,7 @@ extends <a href="DecoderOutputBuffer.html" title="class in com.google.android.ex
<!-- -->
</a>
<h3>Methods inherited from class&nbsp;com.google.android.exoplayer2.decoder.<a href="Buffer.html" title="class in com.google.android.exoplayer2.decoder">Buffer</a></h3>
<code><a href="Buffer.html#addFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">addFlag</a>, <a href="Buffer.html#clearFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">clearFlag</a>, <a href="Buffer.html#getFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">getFlag</a>, <a href="Buffer.html#hasSupplementalData()">hasSupplementalData</a>, <a href="Buffer.html#isDecodeOnly()">isDecodeOnly</a>, <a href="Buffer.html#isEndOfStream()">isEndOfStream</a>, <a href="Buffer.html#isKeyFrame()">isKeyFrame</a>, <a href="Buffer.html#setFlags(@com.google.android.exoplayer2.C.BufferFlagsint)">setFlags</a></code></li>
<code><a href="Buffer.html#addFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">addFlag</a>, <a href="Buffer.html#clearFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">clearFlag</a>, <a href="Buffer.html#getFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">getFlag</a>, <a href="Buffer.html#hasSupplementalData()">hasSupplementalData</a>, <a href="Buffer.html#isDecodeOnly()">isDecodeOnly</a>, <a href="Buffer.html#isEndOfStream()">isEndOfStream</a>, <a href="Buffer.html#isFirstSample()">isFirstSample</a>, <a href="Buffer.html#isKeyFrame()">isKeyFrame</a>, <a href="Buffer.html#setFlags(@com.google.android.exoplayer2.C.BufferFlagsint)">setFlags</a></code></li>
</ul>
<ul class="blockList">
<li class="blockList"><a id="methods.inherited.from.class.java.lang.Object">
......
......@@ -350,7 +350,7 @@ extends <a href="DecoderOutputBuffer.html" title="class in com.google.android.ex
<!-- -->
</a>
<h3>Methods inherited from class&nbsp;com.google.android.exoplayer2.decoder.<a href="Buffer.html" title="class in com.google.android.exoplayer2.decoder">Buffer</a></h3>
<code><a href="Buffer.html#addFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">addFlag</a>, <a href="Buffer.html#clear()">clear</a>, <a href="Buffer.html#clearFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">clearFlag</a>, <a href="Buffer.html#getFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">getFlag</a>, <a href="Buffer.html#hasSupplementalData()">hasSupplementalData</a>, <a href="Buffer.html#isDecodeOnly()">isDecodeOnly</a>, <a href="Buffer.html#isEndOfStream()">isEndOfStream</a>, <a href="Buffer.html#isKeyFrame()">isKeyFrame</a>, <a href="Buffer.html#setFlags(@com.google.android.exoplayer2.C.BufferFlagsint)">setFlags</a></code></li>
<code><a href="Buffer.html#addFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">addFlag</a>, <a href="Buffer.html#clear()">clear</a>, <a href="Buffer.html#clearFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">clearFlag</a>, <a href="Buffer.html#getFlag(@com.google.android.exoplayer2.C.BufferFlagsint)">getFlag</a>, <a href="Buffer.html#hasSupplementalData()">hasSupplementalData</a>, <a href="Buffer.html#isDecodeOnly()">isDecodeOnly</a>, <a href="Buffer.html#isEndOfStream()">isEndOfStream</a>, <a href="Buffer.html#isFirstSample()">isFirstSample</a>, <a href="Buffer.html#isKeyFrame()">isKeyFrame</a>, <a href="Buffer.html#setFlags(@com.google.android.exoplayer2.C.BufferFlagsint)">setFlags</a></code></li>
</ul>
<ul class="blockList">
<li class="blockList"><a id="methods.inherited.from.class.java.lang.Object">
......
......@@ -25,8 +25,8 @@
catch(err) {
}
//-->
var data = {"i0":10,"i1":10,"i2":10};
var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]};
var data = {"i0":10,"i1":10,"i2":42};
var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"],32:["t6","Deprecated Methods"]};
var altColor = "altColor";
var rowColor = "rowColor";
var tableTab = "tableTab";
......@@ -172,7 +172,7 @@ implements <a href="DrmSessionManagerProvider.html" title="interface in com.goog
</a>
<h3>Method Summary</h3>
<table class="memberSummary">
<caption><span id="t0" class="activeTableTab"><span>All Methods</span><span class="tabEnd">&nbsp;</span></span><span id="t2" class="tableTab"><span><a href="javascript:show(2);">Instance Methods</a></span><span class="tabEnd">&nbsp;</span></span><span id="t4" class="tableTab"><span><a href="javascript:show(8);">Concrete Methods</a></span><span class="tabEnd">&nbsp;</span></span></caption>
<caption><span id="t0" class="activeTableTab"><span>All Methods</span><span class="tabEnd">&nbsp;</span></span><span id="t2" class="tableTab"><span><a href="javascript:show(2);">Instance Methods</a></span><span class="tabEnd">&nbsp;</span></span><span id="t4" class="tableTab"><span><a href="javascript:show(8);">Concrete Methods</a></span><span class="tabEnd">&nbsp;</span></span><span id="t6" class="tableTab"><span><a href="javascript:show(32);">Deprecated Methods</a></span><span class="tabEnd">&nbsp;</span></span></caption>
<tr>
<th class="colFirst" scope="col">Modifier and Type</th>
<th class="colSecond" scope="col">Method</th>
......@@ -187,16 +187,20 @@ implements <a href="DrmSessionManagerProvider.html" title="interface in com.goog
</tr>
<tr id="i1" class="rowColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setDrmHttpDataSourceFactory(com.google.android.exoplayer2.upstream.HttpDataSource.Factory)">setDrmHttpDataSourceFactory</a></span>&#8203;(<a href="../upstream/HttpDataSource.Factory.html" title="interface in com.google.android.exoplayer2.upstream">HttpDataSource.Factory</a>&nbsp;drmHttpDataSourceFactory)</code></th>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setDrmHttpDataSourceFactory(com.google.android.exoplayer2.upstream.DataSource.Factory)">setDrmHttpDataSourceFactory</a></span>&#8203;(<a href="../upstream/DataSource.Factory.html" title="interface in com.google.android.exoplayer2.upstream">DataSource.Factory</a>&nbsp;drmDataSourceFactory)</code></th>
<td class="colLast">
<div class="block">Sets the <a href="../upstream/HttpDataSource.Factory.html" title="interface in com.google.android.exoplayer2.upstream"><code>HttpDataSource.Factory</code></a> to be used for creating <a href="HttpMediaDrmCallback.html" title="class in com.google.android.exoplayer2.drm"><code>HttpMediaDrmCallbacks</code></a> which executes key and provisioning requests over HTTP.</div>
<div class="block">Sets the <a href="../upstream/DataSource.Factory.html" title="interface in com.google.android.exoplayer2.upstream"><code>DataSource.Factory</code></a> which is used to create <a href="HttpMediaDrmCallback.html" title="class in com.google.android.exoplayer2.drm"><code>HttpMediaDrmCallback</code></a>
instances.</div>
</td>
</tr>
<tr id="i2" class="altColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setDrmUserAgent(java.lang.String)">setDrmUserAgent</a></span>&#8203;(<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&nbsp;userAgent)</code></th>
<td class="colLast">
<div class="block">Sets the optional user agent to be used for DRM requests.</div>
<div class="block"><span class="deprecatedLabel">Deprecated.</span>
<div class="deprecationComment">Pass a custom <a href="../upstream/DataSource.Factory.html" title="interface in com.google.android.exoplayer2.upstream"><code>DataSource.Factory</code></a> to <a href="#setDrmHttpDataSourceFactory(com.google.android.exoplayer2.upstream.DataSource.Factory)"><code>setDrmHttpDataSourceFactory(DataSource.Factory)</code></a> which sets the desired user agent on
outgoing requests.</div>
</div>
</td>
</tr>
</table>
......@@ -242,19 +246,19 @@ implements <a href="DrmSessionManagerProvider.html" title="interface in com.goog
<!-- -->
</a>
<h3>Method Detail</h3>
<a id="setDrmHttpDataSourceFactory(com.google.android.exoplayer2.upstream.HttpDataSource.Factory)">
<a id="setDrmHttpDataSourceFactory(com.google.android.exoplayer2.upstream.DataSource.Factory)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>setDrmHttpDataSourceFactory</h4>
<pre class="methodSignature">public&nbsp;void&nbsp;setDrmHttpDataSourceFactory&#8203;(@Nullable
<a href="../upstream/HttpDataSource.Factory.html" title="interface in com.google.android.exoplayer2.upstream">HttpDataSource.Factory</a>&nbsp;drmHttpDataSourceFactory)</pre>
<div class="block">Sets the <a href="../upstream/HttpDataSource.Factory.html" title="interface in com.google.android.exoplayer2.upstream"><code>HttpDataSource.Factory</code></a> to be used for creating <a href="HttpMediaDrmCallback.html" title="class in com.google.android.exoplayer2.drm"><code>HttpMediaDrmCallbacks</code></a> which executes key and provisioning requests over HTTP. If <code>null</code>
is passed the <a href="../upstream/DefaultHttpDataSource.Factory.html" title="class in com.google.android.exoplayer2.upstream"><code>DefaultHttpDataSource.Factory</code></a> is used.</div>
<a href="../upstream/DataSource.Factory.html" title="interface in com.google.android.exoplayer2.upstream">DataSource.Factory</a>&nbsp;drmDataSourceFactory)</pre>
<div class="block">Sets the <a href="../upstream/DataSource.Factory.html" title="interface in com.google.android.exoplayer2.upstream"><code>DataSource.Factory</code></a> which is used to create <a href="HttpMediaDrmCallback.html" title="class in com.google.android.exoplayer2.drm"><code>HttpMediaDrmCallback</code></a>
instances. If <code>null</code> is passed a <a href="../upstream/DefaultHttpDataSource.Factory.html" title="class in com.google.android.exoplayer2.upstream"><code>DefaultHttpDataSource.Factory</code></a> is used.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>drmHttpDataSourceFactory</code> - The HTTP data source factory or <code>null</code> to use <a href="../upstream/DefaultHttpDataSource.Factory.html" title="class in com.google.android.exoplayer2.upstream"><code>DefaultHttpDataSource.Factory</code></a>.</dd>
<dd><code>drmDataSourceFactory</code> - The data source factory or <code>null</code> to use <a href="../upstream/DefaultHttpDataSource.Factory.html" title="class in com.google.android.exoplayer2.upstream"><code>DefaultHttpDataSource.Factory</code></a>.</dd>
</dl>
</li>
</ul>
......@@ -264,15 +268,13 @@ implements <a href="DrmSessionManagerProvider.html" title="interface in com.goog
<ul class="blockList">
<li class="blockList">
<h4>setDrmUserAgent</h4>
<pre class="methodSignature">public&nbsp;void&nbsp;setDrmUserAgent&#8203;(@Nullable
<pre class="methodSignature"><a href="https://developer.android.com/reference/java/lang/Deprecated.html" title="class or interface in java.lang" class="externalLink" target="_top">@Deprecated</a>
public&nbsp;void&nbsp;setDrmUserAgent&#8203;(@Nullable
<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&nbsp;userAgent)</pre>
<div class="block">Sets the optional user agent to be used for DRM requests.
<p>In case a factory has been set by <a href="#setDrmHttpDataSourceFactory(com.google.android.exoplayer2.upstream.HttpDataSource.Factory)"><code>setDrmHttpDataSourceFactory(HttpDataSource.Factory)</code></a>, this user agent is ignored.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>userAgent</code> - The user agent to be used for DRM requests.</dd>
</dl>
<div class="deprecationBlock"><span class="deprecatedLabel">Deprecated.</span>
<div class="deprecationComment">Pass a custom <a href="../upstream/DataSource.Factory.html" title="interface in com.google.android.exoplayer2.upstream"><code>DataSource.Factory</code></a> to <a href="#setDrmHttpDataSourceFactory(com.google.android.exoplayer2.upstream.DataSource.Factory)"><code>setDrmHttpDataSourceFactory(DataSource.Factory)</code></a> which sets the desired user agent on
outgoing requests.</div>
</div>
</li>
</ul>
<a id="get(com.google.android.exoplayer2.MediaItem)">
......
......@@ -136,7 +136,7 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<pre>public final class <span class="typeNameLabel">HttpMediaDrmCallback</span>
extends <a href="https://developer.android.com/reference/java/lang/Object.html" title="class or interface in java.lang" class="externalLink" target="_top">Object</a>
implements <a href="MediaDrmCallback.html" title="interface in com.google.android.exoplayer2.drm">MediaDrmCallback</a></pre>
<div class="block">A <a href="MediaDrmCallback.html" title="interface in com.google.android.exoplayer2.drm"><code>MediaDrmCallback</code></a> that makes requests using <a href="../upstream/HttpDataSource.html" title="interface in com.google.android.exoplayer2.upstream"><code>HttpDataSource</code></a> instances.</div>
<div class="block">A <a href="MediaDrmCallback.html" title="interface in com.google.android.exoplayer2.drm"><code>MediaDrmCallback</code></a> that makes requests using <a href="../upstream/DataSource.html" title="interface in com.google.android.exoplayer2.upstream"><code>DataSource</code></a> instances.</div>
</li>
</ul>
</div>
......@@ -157,15 +157,19 @@ implements <a href="MediaDrmCallback.html" title="interface in com.google.androi
<th class="colLast" scope="col">Description</th>
</tr>
<tr class="altColor">
<th class="colConstructorName" scope="row"><code><span class="memberNameLink"><a href="#%3Cinit%3E(java.lang.String,boolean,com.google.android.exoplayer2.upstream.HttpDataSource.Factory)">HttpMediaDrmCallback</a></span>&#8203;(<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&nbsp;defaultLicenseUrl,
<th class="colConstructorName" scope="row"><code><span class="memberNameLink"><a href="#%3Cinit%3E(java.lang.String,boolean,com.google.android.exoplayer2.upstream.DataSource.Factory)">HttpMediaDrmCallback</a></span>&#8203;(<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&nbsp;defaultLicenseUrl,
boolean&nbsp;forceDefaultLicenseUrl,
<a href="../upstream/HttpDataSource.Factory.html" title="interface in com.google.android.exoplayer2.upstream">HttpDataSource.Factory</a>&nbsp;dataSourceFactory)</code></th>
<td class="colLast">&nbsp;</td>
<a href="../upstream/DataSource.Factory.html" title="interface in com.google.android.exoplayer2.upstream">DataSource.Factory</a>&nbsp;dataSourceFactory)</code></th>
<td class="colLast">
<div class="block">Constructs an instance.</div>
</td>
</tr>
<tr class="rowColor">
<th class="colConstructorName" scope="row"><code><span class="memberNameLink"><a href="#%3Cinit%3E(java.lang.String,com.google.android.exoplayer2.upstream.HttpDataSource.Factory)">HttpMediaDrmCallback</a></span>&#8203;(<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&nbsp;defaultLicenseUrl,
<a href="../upstream/HttpDataSource.Factory.html" title="interface in com.google.android.exoplayer2.upstream">HttpDataSource.Factory</a>&nbsp;dataSourceFactory)</code></th>
<td class="colLast">&nbsp;</td>
<th class="colConstructorName" scope="row"><code><span class="memberNameLink"><a href="#%3Cinit%3E(java.lang.String,com.google.android.exoplayer2.upstream.DataSource.Factory)">HttpMediaDrmCallback</a></span>&#8203;(<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&nbsp;defaultLicenseUrl,
<a href="../upstream/DataSource.Factory.html" title="interface in com.google.android.exoplayer2.upstream">DataSource.Factory</a>&nbsp;dataSourceFactory)</code></th>
<td class="colLast">
<div class="block">Constructs an instance.</div>
</td>
</tr>
</table>
</li>
......@@ -247,7 +251,7 @@ implements <a href="MediaDrmCallback.html" title="interface in com.google.androi
<!-- -->
</a>
<h3>Constructor Detail</h3>
<a id="&lt;init&gt;(java.lang.String,com.google.android.exoplayer2.upstream.HttpDataSource.Factory)">
<a id="&lt;init&gt;(java.lang.String,com.google.android.exoplayer2.upstream.DataSource.Factory)">
<!-- -->
</a>
<ul class="blockList">
......@@ -255,17 +259,19 @@ implements <a href="MediaDrmCallback.html" title="interface in com.google.androi
<h4>HttpMediaDrmCallback</h4>
<pre>public&nbsp;HttpMediaDrmCallback&#8203;(@Nullable
<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&nbsp;defaultLicenseUrl,
<a href="../upstream/HttpDataSource.Factory.html" title="interface in com.google.android.exoplayer2.upstream">HttpDataSource.Factory</a>&nbsp;dataSourceFactory)</pre>
<a href="../upstream/DataSource.Factory.html" title="interface in com.google.android.exoplayer2.upstream">DataSource.Factory</a>&nbsp;dataSourceFactory)</pre>
<div class="block">Constructs an instance.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>defaultLicenseUrl</code> - The default license URL. Used for key requests that do not specify
their own license URL. May be <code>null</code> if it's known that all key requests will specify
their own URLs.</dd>
<dd><code>dataSourceFactory</code> - A factory from which to obtain <a href="../upstream/HttpDataSource.html" title="interface in com.google.android.exoplayer2.upstream"><code>HttpDataSource</code></a> instances.</dd>
<dd><code>dataSourceFactory</code> - A factory from which to obtain <a href="../upstream/DataSource.html" title="interface in com.google.android.exoplayer2.upstream"><code>DataSource</code></a> instances. This will
usually be an HTTP-based <a href="../upstream/DataSource.html" title="interface in com.google.android.exoplayer2.upstream"><code>DataSource</code></a>.</dd>
</dl>
</li>
</ul>
<a id="&lt;init&gt;(java.lang.String,boolean,com.google.android.exoplayer2.upstream.HttpDataSource.Factory)">
<a id="&lt;init&gt;(java.lang.String,boolean,com.google.android.exoplayer2.upstream.DataSource.Factory)">
<!-- -->
</a>
<ul class="blockListLast">
......@@ -274,7 +280,8 @@ implements <a href="MediaDrmCallback.html" title="interface in com.google.androi
<pre>public&nbsp;HttpMediaDrmCallback&#8203;(@Nullable
<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&nbsp;defaultLicenseUrl,
boolean&nbsp;forceDefaultLicenseUrl,
<a href="../upstream/HttpDataSource.Factory.html" title="interface in com.google.android.exoplayer2.upstream">HttpDataSource.Factory</a>&nbsp;dataSourceFactory)</pre>
<a href="../upstream/DataSource.Factory.html" title="interface in com.google.android.exoplayer2.upstream">DataSource.Factory</a>&nbsp;dataSourceFactory)</pre>
<div class="block">Constructs an instance.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>defaultLicenseUrl</code> - The default license URL. Used for key requests that do not specify
......@@ -283,7 +290,8 @@ implements <a href="MediaDrmCallback.html" title="interface in com.google.androi
known that all key requests will specify their own URLs.</dd>
<dd><code>forceDefaultLicenseUrl</code> - Whether to force use of <code>defaultLicenseUrl</code> for key
requests that include their own license URL.</dd>
<dd><code>dataSourceFactory</code> - A factory from which to obtain <a href="../upstream/HttpDataSource.html" title="interface in com.google.android.exoplayer2.upstream"><code>HttpDataSource</code></a> instances.</dd>
<dd><code>dataSourceFactory</code> - A factory from which to obtain <a href="../upstream/DataSource.html" title="interface in com.google.android.exoplayer2.upstream"><code>DataSource</code></a> instances. This will
* usually be an HTTP-based <a href="../upstream/DataSource.html" title="interface in com.google.android.exoplayer2.upstream"><code>DataSource</code></a>.</dd>
</dl>
</li>
</ul>
......
......@@ -275,7 +275,7 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<tr class="rowColor">
<th class="colFirst" scope="row"><a href="HttpMediaDrmCallback.html" title="class in com.google.android.exoplayer2.drm">HttpMediaDrmCallback</a></th>
<td class="colLast">
<div class="block">A <a href="MediaDrmCallback.html" title="interface in com.google.android.exoplayer2.drm"><code>MediaDrmCallback</code></a> that makes requests using <a href="../upstream/HttpDataSource.html" title="interface in com.google.android.exoplayer2.upstream"><code>HttpDataSource</code></a> instances.</div>
<div class="block">A <a href="MediaDrmCallback.html" title="interface in com.google.android.exoplayer2.drm"><code>MediaDrmCallback</code></a> that makes requests using <a href="../upstream/DataSource.html" title="interface in com.google.android.exoplayer2.upstream"><code>DataSource</code></a> instances.</div>
</td>
</tr>
<tr class="altColor">
......
......@@ -367,7 +367,9 @@ implements <a href="../../upstream/HttpDataSource.html" title="interface in com.
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setContentTypePredicate(com.google.common.base.Predicate)">setContentTypePredicate</a></span>&#8203;(<a href="https://guava.dev/releases/31.0.1-android/api/docs/com/google/common/base/Predicate.html?is-external=true" title="class or interface in com.google.common.base" class="externalLink">Predicate</a>&lt;<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&gt;&nbsp;contentTypePredicate)</code></th>
<td class="colLast">
<div class="block"><span class="deprecatedLabel">Deprecated.</span></div>
<div class="block"><span class="deprecatedLabel">Deprecated.</span>
<div class="deprecationComment">Use <a href="CronetDataSource.Factory.html#setContentTypePredicate(com.google.common.base.Predicate)"><code>CronetDataSource.Factory.setContentTypePredicate(Predicate)</code></a> instead.</div>
</div>
</td>
</tr>
<tr id="i13" class="rowColor">
......@@ -495,14 +497,9 @@ implements <a href="../../upstream/HttpDataSource.html" title="interface in com.
<pre class="methodSignature"><a href="https://developer.android.com/reference/java/lang/Deprecated.html" title="class or interface in java.lang" class="externalLink" target="_top">@Deprecated</a>
public&nbsp;void&nbsp;setContentTypePredicate&#8203;(@Nullable
<a href="https://guava.dev/releases/31.0.1-android/api/docs/com/google/common/base/Predicate.html?is-external=true" title="class or interface in com.google.common.base" class="externalLink">Predicate</a>&lt;<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&gt;&nbsp;contentTypePredicate)</pre>
<div class="deprecationBlock"><span class="deprecatedLabel">Deprecated.</span></div>
<div class="block">Sets a content type <a href="https://guava.dev/releases/31.0.1-android/api/docs/com/google/common/base/Predicate.html?is-external=true" title="class or interface in com.google.common.base" class="externalLink"><code>Predicate</code></a>. If a content type is rejected by the predicate then a
<a href="../../upstream/HttpDataSource.InvalidContentTypeException.html" title="class in com.google.android.exoplayer2.upstream"><code>HttpDataSource.InvalidContentTypeException</code></a> is thrown from <a href="#open(com.google.android.exoplayer2.upstream.DataSpec)"><code>open(DataSpec)</code></a>.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>contentTypePredicate</code> - The content type <a href="https://guava.dev/releases/31.0.1-android/api/docs/com/google/common/base/Predicate.html?is-external=true" title="class or interface in com.google.common.base" class="externalLink"><code>Predicate</code></a>, or <code>null</code> to clear a
predicate that was previously set.</dd>
</dl>
<div class="deprecationBlock"><span class="deprecatedLabel">Deprecated.</span>
<div class="deprecationComment">Use <a href="CronetDataSource.Factory.html#setContentTypePredicate(com.google.common.base.Predicate)"><code>CronetDataSource.Factory.setContentTypePredicate(Predicate)</code></a> instead.</div>
</div>
</li>
</ul>
<a id="setRequestProperty(java.lang.String,java.lang.String)">
......
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment