mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Media2: Remove MediaSourceFactory + DataSourceCallback
- Applications should generally use DefaultMediaSourceFactory, or their own custom implementation if they need one. Having the media2 extension implement its own version directly doesn't seem that useful. - Remove support for CallbackMediaItem. This type of MediaItem doesn't go cross-process, and it seems like there would never be a use case where an app would need to generate one locally. If an app needs to provide data from a custom source, it should hook into ExoPlayer's way of doing this (i.e., use a UriMediaItem with a custom scheme, and inject a custom DataSource that can handle this scheme). PiperOrigin-RevId: 326914465
This commit is contained in:
parent
42cf213aea
commit
49bf83a169
@ -1,28 +0,0 @@
|
||||
# Proguard rules specific to the media2 extension.
|
||||
|
||||
# Constructors and methods accessed via reflection in ExoPlayerUtils.
|
||||
-dontnote com.google.android.exoplayer2.source.dash.DashMediaSource$Factory
|
||||
-keepclasseswithmembers class com.google.android.exoplayer2.source.dash.DashMediaSource$Factory {
|
||||
public <init>(com.google.android.exoplayer2.upstream.DataSource$Factory);
|
||||
public com.google.android.exoplayer2.source.dash.DashMediaSource$Factory setTag(java.lang.Object);
|
||||
}
|
||||
-dontnote com.google.android.exoplayer2.source.hls.HlsMediaSource$Factory
|
||||
-keepclasseswithmembers class com.google.android.exoplayer2.source.hls.HlsMediaSource$Factory {
|
||||
public <init>(com.google.android.exoplayer2.upstream.DataSource$Factory);
|
||||
public com.google.android.exoplayer2.source.hls.HlsMediaSource$Factory setTag(java.lang.Object);
|
||||
}
|
||||
-dontnote com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource$Factory
|
||||
-keepclasseswithmembers class com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource$Factory {
|
||||
public <init>(com.google.android.exoplayer2.upstream.DataSource$Factory);
|
||||
public com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource$Factory setTag(java.lang.Object);
|
||||
}
|
||||
|
||||
# Don't warn about checkerframework and Kotlin annotations
|
||||
-dontwarn org.checkerframework.**
|
||||
-dontwarn kotlin.annotations.jvm.**
|
||||
-dontwarn javax.annotation.**
|
||||
|
||||
# Work around [internal: b/151134701]: keep non-public versionedparcelable
|
||||
# classes.
|
||||
-keep class * implements androidx.versionedparcelable.VersionedParcelable
|
||||
-keep class androidx.media2.common.MediaParcelUtils$MediaItemParcelImpl
|
@ -75,8 +75,8 @@ import org.junit.rules.ExternalResource;
|
||||
.setLooper(Looper.myLooper())
|
||||
.setMediaSourceFactory(new DefaultMediaSourceFactory(dataSourceFactory, null))
|
||||
.build();
|
||||
DefaultMediaItemConverter converter = new DefaultMediaItemConverter(context);
|
||||
sessionPlayerConnector = new SessionPlayerConnector(exoPlayer, converter);
|
||||
sessionPlayerConnector =
|
||||
new SessionPlayerConnector(exoPlayer, new DefaultMediaItemConverter());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -183,7 +183,6 @@ public class SessionPlayerConnectorTest {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
DefaultMediaItemConverter converter = new DefaultMediaItemConverter(context);
|
||||
SimpleExoPlayer simpleExoPlayer = null;
|
||||
try {
|
||||
simpleExoPlayer =
|
||||
@ -191,7 +190,8 @@ public class SessionPlayerConnectorTest {
|
||||
.setLooper(Looper.myLooper())
|
||||
.build();
|
||||
try (SessionPlayerConnector player =
|
||||
new SessionPlayerConnector(simpleExoPlayer, converter, controlDispatcher)) {
|
||||
new SessionPlayerConnector(
|
||||
simpleExoPlayer, new DefaultMediaItemConverter(), controlDispatcher)) {
|
||||
assertPlayerResult(player.play(), RESULT_INFO_SKIPPED);
|
||||
}
|
||||
} finally {
|
||||
|
@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 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.ext.media2;
|
||||
|
||||
import android.net.Uri;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media2.common.DataSourceCallback;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.upstream.BaseDataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
|
||||
/** An ExoPlayer {@link DataSource} for reading from a {@link DataSourceCallback}. */
|
||||
/* package */ final class DataSourceCallbackDataSource extends BaseDataSource {
|
||||
|
||||
/**
|
||||
* Returns a factory for {@link DataSourceCallbackDataSource}s.
|
||||
*
|
||||
* @return A factory for data sources that read from the data source callback.
|
||||
*/
|
||||
public static DataSource.Factory getFactory(DataSourceCallback dataSourceCallback) {
|
||||
Assertions.checkNotNull(dataSourceCallback);
|
||||
return () -> new DataSourceCallbackDataSource(dataSourceCallback);
|
||||
}
|
||||
|
||||
private final DataSourceCallback dataSourceCallback;
|
||||
|
||||
@Nullable private Uri uri;
|
||||
private long position;
|
||||
private long bytesRemaining;
|
||||
private boolean opened;
|
||||
|
||||
public DataSourceCallbackDataSource(DataSourceCallback dataSourceCallback) {
|
||||
super(/* isNetwork= */ false);
|
||||
this.dataSourceCallback = Assertions.checkNotNull(dataSourceCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long open(DataSpec dataSpec) throws IOException {
|
||||
uri = dataSpec.uri;
|
||||
position = dataSpec.position;
|
||||
transferInitializing(dataSpec);
|
||||
long dataSourceCallbackSize = dataSourceCallback.getSize();
|
||||
if (dataSpec.length != C.LENGTH_UNSET) {
|
||||
bytesRemaining = dataSpec.length;
|
||||
} else if (dataSourceCallbackSize != -1) {
|
||||
bytesRemaining = dataSourceCallbackSize - position;
|
||||
} else {
|
||||
bytesRemaining = C.LENGTH_UNSET;
|
||||
}
|
||||
opened = true;
|
||||
transferStarted(dataSpec);
|
||||
return bytesRemaining;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] buffer, int offset, int readLength) throws IOException {
|
||||
if (readLength == 0) {
|
||||
return 0;
|
||||
} else if (bytesRemaining == 0) {
|
||||
return C.RESULT_END_OF_INPUT;
|
||||
}
|
||||
int bytesToRead =
|
||||
bytesRemaining == C.LENGTH_UNSET ? readLength : (int) Math.min(bytesRemaining, readLength);
|
||||
int bytesRead = dataSourceCallback.readAt(position, buffer, offset, bytesToRead);
|
||||
if (bytesRead == -1) {
|
||||
if (bytesRemaining != C.LENGTH_UNSET) {
|
||||
throw new EOFException();
|
||||
}
|
||||
return C.RESULT_END_OF_INPUT;
|
||||
}
|
||||
position += bytesRead;
|
||||
if (bytesRemaining != C.LENGTH_UNSET) {
|
||||
bytesRemaining -= bytesRead;
|
||||
}
|
||||
bytesTransferred(bytesRead);
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Uri getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
uri = null;
|
||||
if (opened) {
|
||||
opened = false;
|
||||
transferEnded();
|
||||
}
|
||||
}
|
||||
}
|
@ -16,82 +16,44 @@
|
||||
|
||||
package com.google.android.exoplayer2.ext.media2;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media2.common.CallbackMediaItem;
|
||||
import androidx.media2.common.FileMediaItem;
|
||||
import androidx.media2.common.MediaMetadata;
|
||||
import androidx.media2.common.UriMediaItem;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
|
||||
import com.google.android.exoplayer2.MediaItem;
|
||||
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
||||
import com.google.android.exoplayer2.source.ClippingMediaSource;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
import com.google.android.exoplayer2.source.MediaSourceFactory;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
||||
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
|
||||
/** Default implementation of both {@link MediaItemConverter} and {@link MediaSourceFactory}. */
|
||||
public final class DefaultMediaItemConverter implements MediaItemConverter, MediaSourceFactory {
|
||||
private static final int[] SUPPORTED_TYPES =
|
||||
new int[] {C.TYPE_DASH, C.TYPE_SS, C.TYPE_HLS, C.TYPE_OTHER};
|
||||
private final Context context;
|
||||
private final DataSource.Factory dataSourceFactory;
|
||||
|
||||
/**
|
||||
* Default constructor with {@link DefaultDataSourceFactory}.
|
||||
*
|
||||
* @param context The context.
|
||||
*/
|
||||
public DefaultMediaItemConverter(Context context) {
|
||||
this(
|
||||
context,
|
||||
new DefaultDataSourceFactory(
|
||||
context, Util.getUserAgent(context, ExoPlayerLibraryInfo.VERSION_SLASHY)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor with {@link DataSource.Factory}.
|
||||
*
|
||||
* @param context The {@link Context}.
|
||||
* @param dataSourceFactory The {@link DataSource.Factory} to create {@link MediaSource} from
|
||||
* {@link MediaItem ExoPlayer MediaItem}.
|
||||
*/
|
||||
public DefaultMediaItemConverter(Context context, DataSource.Factory dataSourceFactory) {
|
||||
this.context = Assertions.checkNotNull(context);
|
||||
this.dataSourceFactory = Assertions.checkNotNull(dataSourceFactory);
|
||||
}
|
||||
|
||||
// Implements MediaItemConverter
|
||||
/** Default implementation of {@link MediaItemConverter}. */
|
||||
public final class DefaultMediaItemConverter implements MediaItemConverter {
|
||||
|
||||
@Override
|
||||
public MediaItem convertToExoPlayerMediaItem(androidx.media2.common.MediaItem androidXMediaItem) {
|
||||
if (androidXMediaItem instanceof FileMediaItem) {
|
||||
throw new IllegalStateException("FileMediaItem isn't supported");
|
||||
}
|
||||
if (androidXMediaItem instanceof CallbackMediaItem) {
|
||||
throw new IllegalStateException("CallbackMediaItem isn't supported");
|
||||
}
|
||||
|
||||
com.google.android.exoplayer2.MediaItem.Builder exoplayerMediaItemBuilder =
|
||||
new com.google.android.exoplayer2.MediaItem.Builder();
|
||||
MediaItem.Builder exoplayerMediaItemBuilder = new MediaItem.Builder();
|
||||
|
||||
// Set mediaItem as tag for creating MediaSource via MediaSourceFactory methods.
|
||||
exoplayerMediaItemBuilder.setTag(androidXMediaItem);
|
||||
|
||||
// Media id or Uri must be present. Get it from androidx.MediaItem if possible.
|
||||
Uri uri = null;
|
||||
String mediaId = null;
|
||||
// Media ID or URI must be present. Get it from androidx.MediaItem if possible.
|
||||
@Nullable Uri uri = null;
|
||||
@Nullable String mediaId = null;
|
||||
if (androidXMediaItem instanceof UriMediaItem) {
|
||||
UriMediaItem uriMediaItem = (UriMediaItem) androidXMediaItem;
|
||||
uri = uriMediaItem.getUri();
|
||||
}
|
||||
MediaMetadata metadata = androidXMediaItem.getMetadata();
|
||||
@Nullable MediaMetadata metadata = androidXMediaItem.getMetadata();
|
||||
if (metadata != null) {
|
||||
mediaId = metadata.getString(MediaMetadata.METADATA_KEY_MEDIA_ID);
|
||||
String uriString = metadata.getString(MediaMetadata.METADATA_KEY_MEDIA_URI);
|
||||
if (uriString != null) {
|
||||
@Nullable String uriString = metadata.getString(MediaMetadata.METADATA_KEY_MEDIA_URI);
|
||||
if (uri == null && uriString != null) {
|
||||
uri = Uri.parse(uriString);
|
||||
}
|
||||
}
|
||||
@ -102,8 +64,6 @@ public final class DefaultMediaItemConverter implements MediaItemConverter, Medi
|
||||
exoplayerMediaItemBuilder.setUri(uri);
|
||||
exoplayerMediaItemBuilder.setMediaId(mediaId);
|
||||
|
||||
// These are actually aren't needed, because MediaSource will be generated only via tag.
|
||||
// However, fills in the exoplayer2.MediaItem's fields as much as possible just in case.
|
||||
if (androidXMediaItem.getStartPosition() != androidx.media2.common.MediaItem.POSITION_UNKNOWN) {
|
||||
exoplayerMediaItemBuilder.setClipStartPositionMs(androidXMediaItem.getStartPosition());
|
||||
exoplayerMediaItemBuilder.setClipRelativeToDefaultPosition(true);
|
||||
@ -121,77 +81,11 @@ public final class DefaultMediaItemConverter implements MediaItemConverter, Medi
|
||||
Assertions.checkNotNull(exoplayerMediaItem);
|
||||
MediaItem.PlaybackProperties playbackProperties =
|
||||
Assertions.checkNotNull(exoplayerMediaItem.playbackProperties);
|
||||
Object tag = playbackProperties.tag;
|
||||
@Nullable Object tag = playbackProperties.tag;
|
||||
if (!(tag instanceof androidx.media2.common.MediaItem)) {
|
||||
throw new IllegalStateException(
|
||||
"DefaultMediaItemConverter cannot understand "
|
||||
+ exoplayerMediaItem
|
||||
+ ". Unexpected tag "
|
||||
+ tag
|
||||
+ " in PlaybackProperties");
|
||||
"MediaItem tag must be an instance of androidx.media2.common.MediaItem");
|
||||
}
|
||||
return (androidx.media2.common.MediaItem) tag;
|
||||
}
|
||||
|
||||
// Implements MediaSourceFactory
|
||||
|
||||
@Override
|
||||
public MediaSourceFactory setDrmSessionManager(@Nullable DrmSessionManager drmSessionManager) {
|
||||
// No-op
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MediaSourceFactory setLoadErrorHandlingPolicy(
|
||||
@Nullable LoadErrorHandlingPolicy loadErrorHandlingPolicy) {
|
||||
// No-op
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getSupportedTypes() {
|
||||
return SUPPORTED_TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MediaSource createMediaSource(com.google.android.exoplayer2.MediaItem exoplayerMediaItem) {
|
||||
Assertions.checkNotNull(
|
||||
exoplayerMediaItem.playbackProperties,
|
||||
"DefaultMediaItemConverter cannot understand "
|
||||
+ exoplayerMediaItem
|
||||
+ ". PlaybackProperties is missing.");
|
||||
Object tag = exoplayerMediaItem.playbackProperties.tag;
|
||||
if (!(tag instanceof androidx.media2.common.MediaItem)) {
|
||||
throw new IllegalStateException(
|
||||
"DefaultMediaItemConverter cannot understand "
|
||||
+ exoplayerMediaItem
|
||||
+ ". Unexpected tag "
|
||||
+ tag
|
||||
+ " in PlaybackProperties");
|
||||
}
|
||||
androidx.media2.common.MediaItem androidXMediaItem = (androidx.media2.common.MediaItem) tag;
|
||||
|
||||
// Create a source for the item.
|
||||
MediaSource mediaSource =
|
||||
Utils.createUnclippedMediaSource(context, dataSourceFactory, androidXMediaItem);
|
||||
|
||||
// Apply clipping if needed.
|
||||
long startPosition = androidXMediaItem.getStartPosition();
|
||||
long endPosition = androidXMediaItem.getEndPosition();
|
||||
if (startPosition != 0L || endPosition != androidx.media2.common.MediaItem.POSITION_UNKNOWN) {
|
||||
if (endPosition == androidx.media2.common.MediaItem.POSITION_UNKNOWN) {
|
||||
endPosition = C.TIME_END_OF_SOURCE;
|
||||
}
|
||||
// Disable the initial discontinuity to give seamless transitions to clips.
|
||||
mediaSource =
|
||||
new ClippingMediaSource(
|
||||
mediaSource,
|
||||
C.msToUs(startPosition),
|
||||
C.msToUs(endPosition),
|
||||
/* enableInitialDiscontinuity= */ false,
|
||||
/* allowDynamicClippingUpdates= */ false,
|
||||
/* relativeToDefaultPosition= */ true);
|
||||
}
|
||||
return mediaSource;
|
||||
}
|
||||
}
|
||||
|
@ -19,15 +19,15 @@ import android.annotation.SuppressLint;
|
||||
import android.support.v4.media.session.MediaSessionCompat;
|
||||
import androidx.media2.session.MediaSession;
|
||||
|
||||
/** Utility methods to use {@link MediaSession} with other existing Exo modules. */
|
||||
/** Utility methods to use {@link MediaSession} with other ExoPlayer modules. */
|
||||
public final class MediaSessionUtil {
|
||||
|
||||
/** Gets the {@link MediaSessionCompat.Token} from the {@link MediaSession}. */
|
||||
// TODO(b/152764014): Deprecate this API when MediaSession#getSessionCompatToken() is released.
|
||||
public static MediaSessionCompat.Token getSessionCompatToken(MediaSession session2) {
|
||||
public static MediaSessionCompat.Token getSessionCompatToken(MediaSession mediaSession) {
|
||||
@SuppressLint("RestrictedApi")
|
||||
@SuppressWarnings("RestrictTo")
|
||||
MediaSessionCompat sessionCompat = session2.getSessionCompat();
|
||||
MediaSessionCompat sessionCompat = mediaSession.getSessionCompat();
|
||||
return sessionCompat.getSessionToken();
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,7 @@ import java.util.List;
|
||||
* @param mediaItemConverter The {@link MediaItemConverter}.
|
||||
* @param controlDispatcher A {@link ControlDispatcher}.
|
||||
*/
|
||||
PlayerWrapper(
|
||||
public PlayerWrapper(
|
||||
Listener listener,
|
||||
Player player,
|
||||
MediaItemConverter mediaItemConverter,
|
||||
|
@ -15,81 +15,14 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.ext.media2;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media.AudioAttributesCompat;
|
||||
import androidx.media2.common.CallbackMediaItem;
|
||||
import androidx.media2.common.MediaItem;
|
||||
import androidx.media2.common.SessionPlayer;
|
||||
import androidx.media2.common.UriMediaItem;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.audio.AudioAttributes;
|
||||
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
|
||||
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
|
||||
import com.google.android.exoplayer2.extractor.ts.AdtsExtractor;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
import com.google.android.exoplayer2.source.MediaSourceFactory;
|
||||
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.RawResourceDataSource;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
|
||||
/**
|
||||
* Utility methods for the media2 extension (primarily for translating between the media2 and
|
||||
* ExoPlayer {@link Player} APIs).
|
||||
*/
|
||||
/** Utility methods for translating between the media2 and ExoPlayer APIs. */
|
||||
/* package */ final class Utils {
|
||||
|
||||
private static final ExtractorsFactory sExtractorsFactory =
|
||||
new DefaultExtractorsFactory()
|
||||
.setAdtsExtractorFlags(AdtsExtractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING);
|
||||
|
||||
/**
|
||||
* Returns an ExoPlayer media source for the given media item. The given {@link MediaItem} is set
|
||||
* as the tag of the source.
|
||||
*/
|
||||
public static MediaSource createUnclippedMediaSource(
|
||||
Context context, DataSource.Factory dataSourceFactory, MediaItem androidXMediaItem) {
|
||||
if (androidXMediaItem instanceof UriMediaItem) {
|
||||
Uri uri = ((UriMediaItem) androidXMediaItem).getUri();
|
||||
if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(uri.getScheme())) {
|
||||
String path = Assertions.checkNotNull(uri.getPath());
|
||||
int resourceIdentifier;
|
||||
if (uri.getPathSegments().size() == 1 && uri.getPathSegments().get(0).matches("\\d+")) {
|
||||
resourceIdentifier = Integer.parseInt(uri.getPathSegments().get(0));
|
||||
} else {
|
||||
if (path.startsWith("/")) {
|
||||
path = path.substring(1);
|
||||
}
|
||||
@Nullable String host = uri.getHost();
|
||||
String resourceName = (TextUtils.isEmpty(host) ? "" : (host + ":")) + path;
|
||||
resourceIdentifier =
|
||||
context.getResources().getIdentifier(resourceName, "raw", context.getPackageName());
|
||||
}
|
||||
Assertions.checkState(resourceIdentifier != 0);
|
||||
uri = RawResourceDataSource.buildRawResourceUri(resourceIdentifier);
|
||||
}
|
||||
return createMediaSource(uri, dataSourceFactory, /* tag= */ androidXMediaItem);
|
||||
} else if (androidXMediaItem instanceof CallbackMediaItem) {
|
||||
CallbackMediaItem callbackMediaItem = (CallbackMediaItem) androidXMediaItem;
|
||||
dataSourceFactory =
|
||||
DataSourceCallbackDataSource.getFactory(callbackMediaItem.getDataSourceCallback());
|
||||
return new ProgressiveMediaSource.Factory(dataSourceFactory, sExtractorsFactory)
|
||||
.createMediaSource(
|
||||
new com.google.android.exoplayer2.MediaItem.Builder()
|
||||
.setUri(Uri.EMPTY)
|
||||
.setTag(androidXMediaItem)
|
||||
.build());
|
||||
} else {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns ExoPlayer audio attributes for the given audio attributes. */
|
||||
public static AudioAttributes getAudioAttributes(AudioAttributesCompat audioAttributesCompat) {
|
||||
return new AudioAttributes.Builder()
|
||||
@ -156,49 +89,6 @@ import com.google.android.exoplayer2.util.Util;
|
||||
}
|
||||
}
|
||||
|
||||
private static MediaSource createMediaSource(
|
||||
Uri uri, DataSource.Factory dataSourceFactory, Object tag) {
|
||||
// TODO: Deduplicate with DefaultMediaSource once MediaItem support in ExoPlayer has been
|
||||
// released. See [Internal: b/150857202].
|
||||
@Nullable Class<? extends MediaSourceFactory> factoryClazz = null;
|
||||
try {
|
||||
// LINT.IfChange
|
||||
switch (Util.inferContentType(uri)) {
|
||||
case C.TYPE_DASH:
|
||||
factoryClazz =
|
||||
Class.forName("com.google.android.exoplayer2.source.dash.DashMediaSource$Factory")
|
||||
.asSubclass(MediaSourceFactory.class);
|
||||
break;
|
||||
case C.TYPE_HLS:
|
||||
factoryClazz =
|
||||
Class.forName("com.google.android.exoplayer2.source.hls.HlsMediaSource$Factory")
|
||||
.asSubclass(MediaSourceFactory.class);
|
||||
break;
|
||||
case C.TYPE_SS:
|
||||
factoryClazz =
|
||||
Class.forName(
|
||||
"com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource$Factory")
|
||||
.asSubclass(MediaSourceFactory.class);
|
||||
break;
|
||||
case C.TYPE_OTHER:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (factoryClazz != null) {
|
||||
MediaSourceFactory mediaSourceFactory =
|
||||
factoryClazz.getConstructor(DataSource.Factory.class).newInstance(dataSourceFactory);
|
||||
factoryClazz.getMethod("setTag", Object.class).invoke(mediaSourceFactory, tag);
|
||||
return mediaSourceFactory.createMediaSource(
|
||||
com.google.android.exoplayer2.MediaItem.fromUri(uri));
|
||||
}
|
||||
// LINT.ThenChange(../../../../../../../../../proguard-rules.txt)
|
||||
} catch (Exception e) {
|
||||
// Expected if the app was built without the corresponding module.
|
||||
}
|
||||
return new ProgressiveMediaSource.Factory(dataSourceFactory)
|
||||
.createMediaSource(
|
||||
new com.google.android.exoplayer2.MediaItem.Builder().setUri(uri).setTag(tag).build());
|
||||
}
|
||||
|
||||
private Utils() {
|
||||
// Prevent instantiation.
|
||||
|
@ -1 +0,0 @@
|
||||
../../proguard-rules.txt
|
Loading…
x
Reference in New Issue
Block a user