remove UnknownMediaSourceFactory and infer if transcoding

This commit is contained in:
Jakob Kukla 2021-11-15 12:33:20 +01:00 committed by jakobkukla
commit fc3de93c3d
2 changed files with 28 additions and 84 deletions

View file

@ -17,7 +17,7 @@ import com.google.android.exoplayer2.Player.EventListener;
import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.database.ExoDatabaseProvider; import com.google.android.exoplayer2.database.ExoDatabaseProvider;
import com.google.android.exoplayer2.source.MediaSourceFactory; import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.upstream.FileDataSource; import com.google.android.exoplayer2.upstream.FileDataSource;
@ -25,8 +25,12 @@ import com.google.android.exoplayer2.upstream.cache.CacheDataSink;
import com.google.android.exoplayer2.upstream.cache.CacheDataSource; import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor; import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor;
import com.google.android.exoplayer2.upstream.cache.SimpleCache; import com.google.android.exoplayer2.upstream.cache.SimpleCache;
import com.google.android.exoplayer2.util.MimeTypes;
import java.io.File; import java.io.File;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
public class LocalPlayer implements Playback { public class LocalPlayer implements Playback {
public static final String TAG = LocalPlayer.class.getSimpleName(); public static final String TAG = LocalPlayer.class.getSimpleName();
@ -89,14 +93,13 @@ public class LocalPlayer implements Playback {
public LocalPlayer(Context context) { public LocalPlayer(Context context) {
this.context = context; this.context = context;
MediaSourceFactory mediaSourceFactory = new UnknownMediaSourceFactory(buildDataSourceFactory());
AudioAttributes audioAttributes = new AudioAttributes.Builder() AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setUsage(C.USAGE_MEDIA) .setUsage(C.USAGE_MEDIA)
.setContentType(C.CONTENT_TYPE_MUSIC) .setContentType(C.CONTENT_TYPE_MUSIC)
.build(); .build();
exoPlayer = new SimpleExoPlayer.Builder(context) exoPlayer = new SimpleExoPlayer.Builder(context)
.setMediaSourceFactory(mediaSourceFactory) .setMediaSourceFactory(new DefaultMediaSourceFactory(buildDataSourceFactory()))
.setAudioAttributes(audioAttributes, true) .setAudioAttributes(audioAttributes, true)
.build(); .build();
@ -141,8 +144,28 @@ public class LocalPlayer implements Playback {
uri = Uri.parse(MusicUtil.getTranscodeUri(song)); uri = Uri.parse(MusicUtil.getTranscodeUri(song));
} }
MediaItem mediaItem = MediaItem.fromUri(uri); List<String> containers = PreferenceUtil.getInstance(context).getDirectPlayCodecs().stream()
mediaItem = mediaItem.buildUpon().setMediaId(song.id).build(); .map(codec -> codec.container.toLowerCase(Locale.ROOT))
.collect(Collectors.toList());
List<String> codecs = PreferenceUtil.getInstance(context).getDirectPlayCodecs().stream()
.map(codec -> codec.codec.toLowerCase(Locale.ROOT))
.collect(Collectors.toList());
String maxBitrate = PreferenceUtil.getInstance(context).getMaximumBitrate();
MediaItem mediaItem;
if (uri.toString().contains("file://") || (containers.contains(song.container.toLowerCase(Locale.ROOT)) && codecs.contains(song.codec.toLowerCase(Locale.ROOT)) && song.bitRate <= Integer.parseInt(maxBitrate))) {
mediaItem = new MediaItem.Builder()
.setUri(uri)
.setMediaId(song.id)
.build();
} else {
mediaItem = new MediaItem.Builder()
.setUri(uri)
.setMediaId(song.id)
.setMimeType(MimeTypes.APPLICATION_M3U8)
.build();
}
exoPlayer.addMediaItem(mediaItem); exoPlayer.addMediaItem(mediaItem);
} }

View file

@ -1,79 +0,0 @@
package com.dkanada.gramophone.service.playback
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.drm.DrmSessionManager
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory
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.source.hls.HlsMediaSource
import com.google.android.exoplayer2.upstream.*
import kotlinx.coroutines.*
import java.net.HttpURLConnection
import java.net.URL
@Suppress("JoinDeclarationAndAssignment")
class UnknownMediaSourceFactory(dataSourceFactory: DataSource.Factory) : MediaSourceFactory {
private val hlsMediaSource : HlsMediaSource.Factory
private val progressiveMediaSource : ProgressiveMediaSource.Factory
private var loadErrorHandlingPolicy: LoadErrorHandlingPolicy
override fun setDrmSessionManager(drmSessionManager: DrmSessionManager?): MediaSourceFactory {
return this
}
override fun setDrmHttpDataSourceFactory(drmHttpDataSourceFactory: HttpDataSource.Factory?): MediaSourceFactory {
return this
}
override fun setDrmUserAgent(drmUserAgent: String?): MediaSourceFactory {
return this
}
override fun setLoadErrorHandlingPolicy(loadErrorHandlingPolicy: LoadErrorHandlingPolicy?): MediaSourceFactory {
this.loadErrorHandlingPolicy = loadErrorHandlingPolicy!!
return this
}
override fun getSupportedTypes(): IntArray {
return intArrayOf()
}
override fun createMediaSource(mediaItem: MediaItem): MediaSource {
if (mediaItem.playbackProperties?.uri.toString().contains("file://")) {
return progressiveMediaSource.createMediaSource(mediaItem)
}
val type: String? = runBlocking {
httpGet(mediaItem.playbackProperties!!.uri.toString())
}
val sourceFactory: MediaSourceFactory = if (type == "application/x-mpegURL") {
hlsMediaSource
} else {
progressiveMediaSource
}
return sourceFactory.createMediaSource(mediaItem)
}
@Suppress("BlockingMethodInNonBlockingContext")
private suspend fun httpGet(url: String?): String? {
return withContext(Dispatchers.IO) {
val request = URL(url)
val conn = request.openConnection() as HttpURLConnection
return@withContext conn.getHeaderField("Content-Type")
}
}
init {
hlsMediaSource = HlsMediaSource.Factory(dataSourceFactory)
progressiveMediaSource = ProgressiveMediaSource.Factory(dataSourceFactory, DefaultExtractorsFactory())
loadErrorHandlingPolicy = DefaultLoadErrorHandlingPolicy()
}
}