2018-05-10 22:28:31 +02:00
|
|
|
package org.schabi.newpipe.player.resolver;
|
|
|
|
|
|
|
|
import android.net.Uri;
|
2020-03-31 19:20:15 +02:00
|
|
|
import android.text.TextUtils;
|
|
|
|
|
2018-05-10 22:28:31 +02:00
|
|
|
import com.google.android.exoplayer2.C;
|
2021-03-31 10:05:44 +02:00
|
|
|
import com.google.android.exoplayer2.MediaItem;
|
2018-05-10 22:28:31 +02:00
|
|
|
import com.google.android.exoplayer2.source.MediaSource;
|
|
|
|
import com.google.android.exoplayer2.util.Util;
|
|
|
|
|
|
|
|
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
|
|
|
import org.schabi.newpipe.extractor.stream.StreamType;
|
|
|
|
import org.schabi.newpipe.player.helper.PlayerDataSource;
|
2022-03-13 06:22:47 +01:00
|
|
|
import org.schabi.newpipe.player.mediaitem.MediaItemTag;
|
|
|
|
import org.schabi.newpipe.player.mediaitem.StreamInfoTag;
|
2021-09-25 10:31:42 +02:00
|
|
|
import org.schabi.newpipe.util.StreamTypeUtil;
|
2018-05-10 22:28:31 +02:00
|
|
|
|
2022-03-13 06:22:47 +01:00
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
import androidx.annotation.Nullable;
|
|
|
|
|
|
|
|
import static org.schabi.newpipe.player.helper.PlayerDataSource.LIVE_STREAM_EDGE_GAP_MILLIS;
|
|
|
|
|
2018-05-10 22:28:31 +02:00
|
|
|
public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
default MediaSource maybeBuildLiveMediaSource(@NonNull final PlayerDataSource dataSource,
|
|
|
|
@NonNull final StreamInfo info) {
|
|
|
|
final StreamType streamType = info.getStreamType();
|
2021-09-25 10:31:42 +02:00
|
|
|
if (!StreamTypeUtil.isLiveStream(streamType)) {
|
2018-05-10 22:28:31 +02:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2022-03-13 06:22:47 +01:00
|
|
|
final StreamInfoTag tag = StreamInfoTag.of(info);
|
2018-05-10 22:28:31 +02:00
|
|
|
if (!info.getHlsUrl().isEmpty()) {
|
|
|
|
return buildLiveMediaSource(dataSource, info.getHlsUrl(), C.TYPE_HLS, tag);
|
|
|
|
} else if (!info.getDashMpdUrl().isEmpty()) {
|
|
|
|
return buildLiveMediaSource(dataSource, info.getDashMpdUrl(), C.TYPE_DASH, tag);
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
2021-10-22 12:07:25 +02:00
|
|
|
|
2018-05-10 22:28:31 +02:00
|
|
|
@NonNull
|
|
|
|
default MediaSource buildLiveMediaSource(@NonNull final PlayerDataSource dataSource,
|
|
|
|
@NonNull final String sourceUrl,
|
|
|
|
@C.ContentType final int type,
|
2022-03-13 06:22:47 +01:00
|
|
|
@NonNull final MediaItemTag metadata) {
|
|
|
|
final MediaSource.Factory factory;
|
2018-05-10 22:28:31 +02:00
|
|
|
switch (type) {
|
|
|
|
case C.TYPE_SS:
|
2021-11-12 20:14:39 +01:00
|
|
|
factory = dataSource.getLiveSsMediaSourceFactory();
|
|
|
|
break;
|
2018-05-10 22:28:31 +02:00
|
|
|
case C.TYPE_DASH:
|
2021-11-12 20:14:39 +01:00
|
|
|
factory = dataSource.getLiveDashMediaSourceFactory();
|
|
|
|
break;
|
2018-05-10 22:28:31 +02:00
|
|
|
case C.TYPE_HLS:
|
2021-11-12 20:14:39 +01:00
|
|
|
factory = dataSource.getLiveHlsMediaSourceFactory();
|
|
|
|
break;
|
2018-05-10 22:28:31 +02:00
|
|
|
default:
|
|
|
|
throw new IllegalStateException("Unsupported type: " + type);
|
|
|
|
}
|
2021-11-12 20:14:39 +01:00
|
|
|
|
|
|
|
return factory.createMediaSource(
|
|
|
|
new MediaItem.Builder()
|
|
|
|
.setTag(metadata)
|
|
|
|
.setUri(Uri.parse(sourceUrl))
|
2022-03-13 06:22:47 +01:00
|
|
|
.setLiveConfiguration(
|
|
|
|
new MediaItem.LiveConfiguration.Builder()
|
|
|
|
.setTargetOffsetMs(LIVE_STREAM_EDGE_GAP_MILLIS)
|
|
|
|
.build()
|
|
|
|
)
|
2021-11-12 20:14:39 +01:00
|
|
|
.build()
|
|
|
|
);
|
2018-05-10 22:28:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@NonNull
|
|
|
|
default MediaSource buildMediaSource(@NonNull final PlayerDataSource dataSource,
|
|
|
|
@NonNull final String sourceUrl,
|
|
|
|
@NonNull final String cacheKey,
|
|
|
|
@NonNull final String overrideExtension,
|
2022-03-13 06:22:47 +01:00
|
|
|
@NonNull final MediaItemTag metadata) {
|
2018-05-10 22:28:31 +02:00
|
|
|
final Uri uri = Uri.parse(sourceUrl);
|
2020-03-31 19:20:15 +02:00
|
|
|
@C.ContentType final int type = TextUtils.isEmpty(overrideExtension)
|
|
|
|
? Util.inferContentType(uri) : Util.inferContentType("." + overrideExtension);
|
2018-05-10 22:28:31 +02:00
|
|
|
|
2022-03-13 06:22:47 +01:00
|
|
|
final MediaSource.Factory factory;
|
2018-05-10 22:28:31 +02:00
|
|
|
switch (type) {
|
|
|
|
case C.TYPE_SS:
|
2021-11-12 20:14:39 +01:00
|
|
|
factory = dataSource.getLiveSsMediaSourceFactory();
|
|
|
|
break;
|
2018-05-10 22:28:31 +02:00
|
|
|
case C.TYPE_DASH:
|
2021-11-12 20:14:39 +01:00
|
|
|
factory = dataSource.getDashMediaSourceFactory();
|
|
|
|
break;
|
2018-05-10 22:28:31 +02:00
|
|
|
case C.TYPE_HLS:
|
2021-11-12 20:14:39 +01:00
|
|
|
factory = dataSource.getHlsMediaSourceFactory();
|
|
|
|
break;
|
2018-05-10 22:28:31 +02:00
|
|
|
case C.TYPE_OTHER:
|
2021-11-12 20:14:39 +01:00
|
|
|
factory = dataSource.getExtractorMediaSourceFactory();
|
|
|
|
break;
|
2018-05-10 22:28:31 +02:00
|
|
|
default:
|
|
|
|
throw new IllegalStateException("Unsupported type: " + type);
|
|
|
|
}
|
2021-11-12 20:14:39 +01:00
|
|
|
|
|
|
|
return factory.createMediaSource(
|
|
|
|
new MediaItem.Builder()
|
|
|
|
.setTag(metadata)
|
|
|
|
.setUri(uri)
|
|
|
|
.setCustomCacheKey(cacheKey)
|
|
|
|
.build()
|
|
|
|
);
|
2018-05-10 22:28:31 +02:00
|
|
|
}
|
|
|
|
}
|