Commit e6bf7bd0 by jaewan Committed by kim-vde

Migrate to use Player's top level playlist API

Being specific, this includes following changes
  - Remove PlaylistManager and TimelinePlaylistManager
    and use Player's playlist API directly.
  - Replace ConcatenatingMediaSource uses with
    ExoPlayer MediaItem.
  - Replace PlaybackPreparer uses with Player#prepare()
  - Add MediaItemConverter for developers to customize
    converting AndroidX MediaItems to ExoPlayer MediaItems
    and vice-versa.
  - Add DefaultMediaItemConverter for providing default
    implementation of both MediaItemConverter
    and MediaSourceFactory.

Note that removing PlaylistManager loses the ability
to suppress individual playlist API. But decided to remove
for simpler API set. The feature can be added back later
via explicit request.

PiperOrigin-RevId: 326463492
parent 1b9992cf
......@@ -22,7 +22,6 @@ import android.os.Looper;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.platform.app.InstrumentationRegistry;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.junit.rules.ExternalResource;
......@@ -52,14 +51,13 @@ public class PlayerTestRule extends ExternalResource {
AudioManager audioManager =
(AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
exoPlayer = new SimpleExoPlayer.Builder(context).setLooper(Looper.myLooper()).build();
ConcatenatingMediaSource concatenatingMediaSource = new ConcatenatingMediaSource();
TimelinePlaylistManager manager =
new TimelinePlaylistManager(context, concatenatingMediaSource);
ConcatenatingMediaSourcePlaybackPreparer playbackPreparer =
new ConcatenatingMediaSourcePlaybackPreparer(exoPlayer, concatenatingMediaSource);
sessionPlayerConnector =
new SessionPlayerConnector(exoPlayer, manager, playbackPreparer);
DefaultMediaItemConverter converter = new DefaultMediaItemConverter(context);
exoPlayer =
new SimpleExoPlayer.Builder(context)
.setLooper(Looper.myLooper())
.setMediaSourceFactory(converter)
.build();
sessionPlayerConnector = new SessionPlayerConnector(exoPlayer, converter);
});
}
......
......@@ -30,6 +30,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.media.AudioManager;
import android.os.Build;
import android.os.Looper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.media.AudioAttributesCompat;
......@@ -53,7 +54,6 @@ import com.google.android.exoplayer2.DefaultControlDispatcher;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.ext.media2.test.R;
import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
import com.google.common.util.concurrent.ListenableFuture;
import java.io.IOException;
import java.util.ArrayList;
......@@ -176,6 +176,10 @@ public class SessionPlayerConnectorTest {
@LargeTest
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
public void play_withCustomControlDispatcher_isSkipped() throws Exception {
if (Looper.myLooper() == null) {
Looper.prepare();
}
ControlDispatcher controlDispatcher =
new DefaultControlDispatcher() {
@Override
......@@ -183,17 +187,22 @@ public class SessionPlayerConnectorTest {
return false;
}
};
SimpleExoPlayer simpleExoPlayer = playerTestRule.getSimpleExoPlayer();
ConcatenatingMediaSource concatenatingMediaSource = new ConcatenatingMediaSource();
TimelinePlaylistManager timelinePlaylistManager =
new TimelinePlaylistManager(context, concatenatingMediaSource);
ConcatenatingMediaSourcePlaybackPreparer playbackPreparer =
new ConcatenatingMediaSourcePlaybackPreparer(simpleExoPlayer, concatenatingMediaSource);
try (SessionPlayerConnector player =
new SessionPlayerConnector(
simpleExoPlayer, timelinePlaylistManager, playbackPreparer, controlDispatcher)) {
assertPlayerResult(player.play(), RESULT_INFO_SKIPPED);
DefaultMediaItemConverter converter = new DefaultMediaItemConverter(context);
SimpleExoPlayer simpleExoPlayer = null;
try {
simpleExoPlayer =
new SimpleExoPlayer.Builder(context)
.setLooper(Looper.myLooper())
.setMediaSourceFactory(converter)
.build();
try (SessionPlayerConnector player =
new SessionPlayerConnector(simpleExoPlayer, converter, controlDispatcher)) {
assertPlayerResult(player.play(), RESULT_INFO_SKIPPED);
}
} finally {
if (simpleExoPlayer != null) {
simpleExoPlayer.release();
}
}
}
......
/*
* 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 com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.PlaybackPreparer;
import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
import com.google.android.exoplayer2.util.Assertions;
/** Prepares an {@link ExoPlayer} instance with a {@link ConcatenatingMediaSource}. */
public final class ConcatenatingMediaSourcePlaybackPreparer implements PlaybackPreparer {
private final ExoPlayer exoPlayer;
private final ConcatenatingMediaSource concatenatingMediaSource;
/**
* Creates a concatenating media source playback preparer.
*
* @param exoPlayer The player to prepare.
* @param concatenatingMediaSource The concatenating media source with which to prepare the
* player.
*/
public ConcatenatingMediaSourcePlaybackPreparer(
ExoPlayer exoPlayer, ConcatenatingMediaSource concatenatingMediaSource) {
this.exoPlayer = exoPlayer;
this.concatenatingMediaSource = Assertions.checkNotNull(concatenatingMediaSource);
}
@Override
public void preparePlayback() {
exoPlayer.setMediaSource(concatenatingMediaSource);
exoPlayer.prepare();
}
}
/*
* Copyright 2020 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.content.Context;
import android.net.Uri;
import androidx.annotation.Nullable;
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
@Override
public MediaItem convertToExoPlayerMediaItem(androidx.media2.common.MediaItem androidXMediaItem) {
if (androidXMediaItem instanceof FileMediaItem) {
throw new IllegalStateException("FileMediaItem isn't supported");
}
com.google.android.exoplayer2.MediaItem.Builder exoplayerMediaItemBuilder =
new com.google.android.exoplayer2.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;
if (androidXMediaItem instanceof UriMediaItem) {
UriMediaItem uriMediaItem = (UriMediaItem) androidXMediaItem;
uri = uriMediaItem.getUri();
}
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) {
uri = Uri.parse(uriString);
}
}
if (uri == null) {
// Generate a Uri to make it non-null. If not, tag will be ignored.
uri = Uri.parse("exoplayer://" + androidXMediaItem.hashCode());
}
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);
}
if (androidXMediaItem.getEndPosition() != androidx.media2.common.MediaItem.POSITION_UNKNOWN) {
exoplayerMediaItemBuilder.setClipEndPositionMs(androidXMediaItem.getEndPosition());
exoplayerMediaItemBuilder.setClipRelativeToDefaultPosition(true);
}
return exoplayerMediaItemBuilder.build();
}
@Override
public androidx.media2.common.MediaItem convertToAndroidXMediaItem(MediaItem exoplayerMediaItem) {
Assertions.checkNotNull(exoplayerMediaItem);
MediaItem.PlaybackProperties playbackProperties =
Assertions.checkNotNull(exoplayerMediaItem.playbackProperties);
Object tag = playbackProperties.tag;
if (!(tag instanceof androidx.media2.common.MediaItem)) {
throw new IllegalStateException(
"DefaultMediaItemConverter cannot understand "
+ exoplayerMediaItem
+ ". Unexpected tag "
+ tag
+ " in PlaybackProperties");
}
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;
}
}
/*
* Copyright 2020 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 com.google.android.exoplayer2.MediaItem;
/**
* Converter for between {@link MediaItem AndroidX MediaItem} and {@link
* com.google.android.exoplayer2.MediaItem ExoPlayer MediaItem}.
*/
public interface MediaItemConverter {
/**
* Converts {@link androidx.media2.common.MediaItem AndroidX MediaItem} to {@link MediaItem
* ExoPlayer MediaItem}.
*/
MediaItem convertToExoPlayerMediaItem(androidx.media2.common.MediaItem androidXMediaItem);
/**
* Converts {@link MediaItem ExoPlayer MediaItem} to {@link androidx.media2.common.MediaItem
* AndroidX MediaItem}.
*/
androidx.media2.common.MediaItem convertToAndroidXMediaItem(MediaItem exoplayerMediaItem);
}
/*
* 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 androidx.annotation.Nullable;
import androidx.media2.common.MediaItem;
import androidx.media2.common.MediaMetadata;
import androidx.media2.common.SessionPlayer;
import com.google.android.exoplayer2.ControlDispatcher;
import com.google.android.exoplayer2.Player;
import java.util.List;
/** Interface that handles playlist edit and navigation operations. */
public interface PlaylistManager {
/**
* See {@link SessionPlayer#setPlaylist(List, MediaMetadata)}.
*
* @param player The player used to build SessionPlayer together.
* @param playlist A list of {@link MediaItem} objects to set as a play list.
* @param metadata The metadata of the playlist.
* @return true if the operation was dispatched. False if suppressed.
*/
boolean setPlaylist(Player player, List<MediaItem> playlist, @Nullable MediaMetadata metadata);
/**
* See {@link SessionPlayer#addPlaylistItem(int, MediaItem)}.
*
* @param player The player used to build SessionPlayer together.
* @param index The index of the item you want to add in the playlist.
* @param mediaItem The media item you want to add.
* @return true if the operation was dispatched. False if suppressed.
*/
boolean addPlaylistItem(Player player, int index, MediaItem mediaItem);
/**
* See {@link SessionPlayer#removePlaylistItem(int)}.
*
* @param player The player used to build SessionPlayer together.
* @param index The index of the item you want to remove in the playlist.
* @return true if the operation was dispatched. False if suppressed.
*/
boolean removePlaylistItem(Player player, int index);
/**
* See {@link SessionPlayer#replacePlaylistItem(int, MediaItem)}.
*
* @param player The player used to build SessionPlayer together.
* @param mediaItem The media item you want to replace with.
* @return true if the operation was dispatched. False if suppressed.
*/
boolean replacePlaylistItem(Player player, int index, MediaItem mediaItem);
/**
* See {@link SessionPlayer#setMediaItem(MediaItem)}.
*
* @param player The player used to build SessionPlayer together.
* @param mediaItem The media item you want to set.
* @return true if the operation was dispatched. False if suppressed.
*/
boolean setMediaItem(Player player, MediaItem mediaItem);
/**
* See {@link SessionPlayer#updatePlaylistMetadata(MediaMetadata)}.
*
* @param player The player used to build SessionPlayer together.
* @param metadata The metadata of the playlist.
* @return true if the operation was dispatched. False if suppressed.
*/
boolean updatePlaylistMetadata(Player player, @Nullable MediaMetadata metadata);
/**
* See {@link SessionPlayer#skipToNextPlaylistItem()}.
*
* @param player The player used to build SessionPlayer together.
* @param controlDispatcher A {@link ControlDispatcher} that should be used for dispatching
* changes to the player.
* @return true if the operation was dispatched. False if suppressed.
*/
boolean skipToNextPlaylistItem(Player player, ControlDispatcher controlDispatcher);
/**
* See {@link SessionPlayer#skipToPreviousPlaylistItem()}.
*
* @param player The player used to build SessionPlayer together.
* @param controlDispatcher A {@link ControlDispatcher} that should be used for dispatching
* changes to the player.
* @return true if the operation was dispatched. False if suppressed.
*/
boolean skipToPreviousPlaylistItem(Player player, ControlDispatcher controlDispatcher);
/**
* See {@link SessionPlayer#skipToPlaylistItem(int)}.
*
* @param player The player used to build SessionPlayer together.
* @param controlDispatcher A {@link ControlDispatcher} that should be used for dispatching
* changes to the player.
* @return true if the operation was dispatched. False if suppressed.
*/
boolean skipToPlaylistItem(Player player, ControlDispatcher controlDispatcher, int index);
/**
* See {@link SessionPlayer#getCurrentMediaItemIndex()}.
*
* @param player The player used to build SessionPlayer together.
* @return The current media item index
*/
int getCurrentMediaItemIndex(Player player);
/**
* See {@link SessionPlayer#getCurrentMediaItem()}.
*
* @param player The player used to build SessionPlayer together.
* @return The current media item index
*/
@Nullable
MediaItem getCurrentMediaItem(Player player);
/**
* See {@link SessionPlayer#setPlaylist(List, MediaMetadata)}.
*
* @param player The player used to build SessionPlayer together.
* @return The playlist.
*/
@Nullable
List<MediaItem> getPlaylist(Player player);
/**
* See {@link SessionPlayer#getPlaylistMetadata()}.
*
* @param player The player used to build SessionPlayer together.
* @return The metadata of the playlist.
*/
@Nullable
MediaMetadata getPlaylistMetadata(Player player);
/**
* Called when the player's timeline is changed.
*
* @param player The player used to build SessionPlayer together.
*/
void onTimelineChanged(Player player);
}
......@@ -31,7 +31,6 @@ import androidx.media2.common.SessionPlayer;
import com.google.android.exoplayer2.ControlDispatcher;
import com.google.android.exoplayer2.DefaultControlDispatcher;
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
import com.google.android.exoplayer2.PlaybackPreparer;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.util.Assertions;
import com.google.common.util.concurrent.ListenableFuture;
......@@ -101,30 +100,23 @@ public final class SessionPlayerConnector extends SessionPlayer {
* Creates an instance using {@link DefaultControlDispatcher} to dispatch player commands.
*
* @param player The player to wrap.
* @param playlistManager The {@link PlaylistManager}.
* @param playbackPreparer The {@link PlaybackPreparer}.
* @param mediaItemConverter The {@link MediaItemConverter}.
*/
public SessionPlayerConnector(
Player player, PlaylistManager playlistManager, PlaybackPreparer playbackPreparer) {
this(player, playlistManager, playbackPreparer, new DefaultControlDispatcher());
public SessionPlayerConnector(Player player, MediaItemConverter mediaItemConverter) {
this(player, mediaItemConverter, new DefaultControlDispatcher());
}
/**
* Creates an instance using the provided {@link ControlDispatcher} to dispatch player commands.
*
* @param player The player to wrap.
* @param playlistManager The {@link PlaylistManager}.
* @param playbackPreparer The {@link PlaybackPreparer}.
* @param mediaItemConverter The {@link MediaItemConverter}.
* @param controlDispatcher The {@link ControlDispatcher}.
*/
public SessionPlayerConnector(
Player player,
PlaylistManager playlistManager,
PlaybackPreparer playbackPreparer,
ControlDispatcher controlDispatcher) {
Player player, MediaItemConverter mediaItemConverter, ControlDispatcher controlDispatcher) {
Assertions.checkNotNull(player);
Assertions.checkNotNull(playlistManager);
Assertions.checkNotNull(playbackPreparer);
Assertions.checkNotNull(mediaItemConverter);
Assertions.checkNotNull(controlDispatcher);
state = PLAYER_STATE_IDLE;
......@@ -132,8 +124,7 @@ public final class SessionPlayerConnector extends SessionPlayer {
taskHandlerExecutor = taskHandler::postOrRun;
ExoPlayerWrapperListener playerListener = new ExoPlayerWrapperListener();
PlayerWrapper playerWrapper =
new PlayerWrapper(
playerListener, player, playlistManager, playbackPreparer, controlDispatcher);
new PlayerWrapper(playerListener, player, mediaItemConverter, controlDispatcher);
this.player = playerWrapper;
playerCommandQueue = new PlayerCommandQueue(this.player, taskHandler);
......@@ -393,7 +384,7 @@ public final class SessionPlayerConnector extends SessionPlayer {
@Override
@Nullable
public List<MediaItem> getPlaylist() {
return runPlayerCallableBlockingWithNullOnException(/* callable= */ player::getPlaylist);
return runPlayerCallableBlockingWithNullOnException(/* callable= */ player::getCachedPlaylist);
}
@Override
......@@ -566,7 +557,7 @@ public final class SessionPlayerConnector extends SessionPlayer {
}
private void handlePlaylistChangedOnHandler() {
List<MediaItem> currentPlaylist = player.getPlaylist();
List<MediaItem> currentPlaylist = player.getCachedPlaylist();
boolean notifyCurrentPlaylist = !ObjectsCompat.equals(this.currentPlaylist, currentPlaylist);
this.currentPlaylist = currentPlaylist;
MediaMetadata playlistMetadata = player.getPlaylistMetadata();
......
......@@ -54,9 +54,9 @@ import com.google.android.exoplayer2.util.Util;
* as the tag of the source.
*/
public static MediaSource createUnclippedMediaSource(
Context context, DataSource.Factory dataSourceFactory, MediaItem mediaItem) {
if (mediaItem instanceof UriMediaItem) {
Uri uri = ((UriMediaItem) mediaItem).getUri();
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;
......@@ -74,16 +74,16 @@ import com.google.android.exoplayer2.util.Util;
Assertions.checkState(resourceIdentifier != 0);
uri = RawResourceDataSource.buildRawResourceUri(resourceIdentifier);
}
return createMediaSource(uri, dataSourceFactory, /* tag= */ mediaItem);
} else if (mediaItem instanceof CallbackMediaItem) {
CallbackMediaItem callbackMediaItem = (CallbackMediaItem) mediaItem;
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(mediaItem)
.setTag(androidXMediaItem)
.build());
} else {
throw new IllegalStateException();
......
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