Uses the new default factory instead of the 3 separate methods.
This commit is contained in:
@@ -23,62 +23,73 @@ package com.vitorpamplona.amethyst.service.playback
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.annotation.OptIn
|
import androidx.annotation.OptIn
|
||||||
|
import androidx.media3.common.MediaItem
|
||||||
import androidx.media3.common.util.UnstableApi
|
import androidx.media3.common.util.UnstableApi
|
||||||
import androidx.media3.datasource.okhttp.OkHttpDataSource
|
import androidx.media3.datasource.okhttp.OkHttpDataSource
|
||||||
import androidx.media3.exoplayer.hls.HlsMediaSource
|
import androidx.media3.exoplayer.drm.DrmSessionManagerProvider
|
||||||
|
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
|
||||||
import androidx.media3.exoplayer.source.MediaSource
|
import androidx.media3.exoplayer.source.MediaSource
|
||||||
import androidx.media3.exoplayer.source.ProgressiveMediaSource
|
import androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy
|
||||||
import androidx.media3.session.MediaSession
|
import androidx.media3.session.MediaSession
|
||||||
import androidx.media3.session.MediaSessionService
|
import androidx.media3.session.MediaSessionService
|
||||||
import com.vitorpamplona.amethyst.Amethyst
|
|
||||||
import com.vitorpamplona.amethyst.service.HttpClientManager
|
import com.vitorpamplona.amethyst.service.HttpClientManager
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
|
||||||
|
class WssOrHttpFactory(httpClient: OkHttpClient) : MediaSource.Factory {
|
||||||
|
@UnstableApi
|
||||||
|
val http = DefaultMediaSourceFactory(OkHttpDataSource.Factory(httpClient))
|
||||||
|
|
||||||
|
@UnstableApi
|
||||||
|
val wss = DefaultMediaSourceFactory(WssStreamDataSource.Factory(httpClient))
|
||||||
|
|
||||||
|
@OptIn(UnstableApi::class)
|
||||||
|
override fun setDrmSessionManagerProvider(drmSessionManagerProvider: DrmSessionManagerProvider): MediaSource.Factory {
|
||||||
|
http.setDrmSessionManagerProvider(drmSessionManagerProvider)
|
||||||
|
wss.setDrmSessionManagerProvider(drmSessionManagerProvider)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(UnstableApi::class)
|
||||||
|
override fun setLoadErrorHandlingPolicy(loadErrorHandlingPolicy: LoadErrorHandlingPolicy): MediaSource.Factory {
|
||||||
|
http.setLoadErrorHandlingPolicy(loadErrorHandlingPolicy)
|
||||||
|
wss.setLoadErrorHandlingPolicy(loadErrorHandlingPolicy)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(UnstableApi::class)
|
||||||
|
override fun getSupportedTypes(): IntArray {
|
||||||
|
return http.supportedTypes
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(UnstableApi::class)
|
||||||
|
override fun createMediaSource(mediaItem: MediaItem): MediaSource {
|
||||||
|
return if (mediaItem.mediaId.startsWith("wss")) {
|
||||||
|
wss.createMediaSource(mediaItem)
|
||||||
|
} else {
|
||||||
|
http.createMediaSource(mediaItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@UnstableApi // Extend MediaSessionService
|
@UnstableApi // Extend MediaSessionService
|
||||||
class PlaybackService : MediaSessionService() {
|
class PlaybackService : MediaSessionService() {
|
||||||
private var videoViewedPositionCache = VideoViewedPositionCache()
|
private var videoViewedPositionCache = VideoViewedPositionCache()
|
||||||
|
|
||||||
private var managerHls: MultiPlayerPlaybackManager? = null
|
private var managerAllInOne: MultiPlayerPlaybackManager? = null
|
||||||
private var managerProgressive: MultiPlayerPlaybackManager? = null
|
|
||||||
private var managerLocal: MultiPlayerPlaybackManager? = null
|
|
||||||
|
|
||||||
fun newHslDataSource(): MediaSource.Factory {
|
fun newAllInOneDataSource(): MediaSource.Factory {
|
||||||
return HlsMediaSource.Factory(OkHttpDataSource.Factory(HttpClientManager.getHttpClient()))
|
// This might be needed for live kit.
|
||||||
|
// return WssOrHttpFactory(HttpClientManager.getHttpClient())
|
||||||
|
return DefaultMediaSourceFactory(OkHttpDataSource.Factory(HttpClientManager.getHttpClient()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun newProgressiveDataSource(): MediaSource.Factory {
|
fun lazyDS(): MultiPlayerPlaybackManager {
|
||||||
return ProgressiveMediaSource.Factory(
|
managerAllInOne?.let {
|
||||||
(applicationContext as Amethyst).videoCache.get(HttpClientManager.getHttpClient()),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun lazyHlsDS(): MultiPlayerPlaybackManager {
|
|
||||||
managerHls?.let {
|
|
||||||
return it
|
return it
|
||||||
}
|
}
|
||||||
|
|
||||||
val newInstance = MultiPlayerPlaybackManager(newHslDataSource(), videoViewedPositionCache)
|
val newInstance = MultiPlayerPlaybackManager(newAllInOneDataSource(), videoViewedPositionCache)
|
||||||
managerHls = newInstance
|
managerAllInOne = newInstance
|
||||||
return newInstance
|
|
||||||
}
|
|
||||||
|
|
||||||
fun lazyProgressiveDS(): MultiPlayerPlaybackManager {
|
|
||||||
managerProgressive?.let {
|
|
||||||
return it
|
|
||||||
}
|
|
||||||
|
|
||||||
val newInstance =
|
|
||||||
MultiPlayerPlaybackManager(newProgressiveDataSource(), videoViewedPositionCache)
|
|
||||||
managerProgressive = newInstance
|
|
||||||
return newInstance
|
|
||||||
}
|
|
||||||
|
|
||||||
fun lazyLocalDS(): MultiPlayerPlaybackManager {
|
|
||||||
managerLocal?.let {
|
|
||||||
return it
|
|
||||||
}
|
|
||||||
|
|
||||||
val newInstance = MultiPlayerPlaybackManager(cachedPositions = videoViewedPositionCache)
|
|
||||||
managerLocal = newInstance
|
|
||||||
return newInstance
|
return newInstance
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,15 +105,11 @@ class PlaybackService : MediaSessionService() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun onProxyUpdated() {
|
private fun onProxyUpdated() {
|
||||||
val toDestroyHls = managerHls
|
val toDestroyAllInOne = managerAllInOne
|
||||||
val toDestroyProgressive = managerProgressive
|
|
||||||
|
|
||||||
managerHls = MultiPlayerPlaybackManager(newHslDataSource(), videoViewedPositionCache)
|
managerAllInOne = MultiPlayerPlaybackManager(newAllInOneDataSource(), videoViewedPositionCache)
|
||||||
managerProgressive =
|
|
||||||
MultiPlayerPlaybackManager(newProgressiveDataSource(), videoViewedPositionCache)
|
|
||||||
|
|
||||||
toDestroyHls?.releaseAppPlayers()
|
toDestroyAllInOne?.releaseAppPlayers()
|
||||||
toDestroyProgressive?.releaseAppPlayers()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTaskRemoved(rootIntent: Intent?) {
|
override fun onTaskRemoved(rootIntent: Intent?) {
|
||||||
@@ -116,23 +123,11 @@ class PlaybackService : MediaSessionService() {
|
|||||||
|
|
||||||
HttpClientManager.proxyChangeListeners.remove(this@PlaybackService::onProxyUpdated)
|
HttpClientManager.proxyChangeListeners.remove(this@PlaybackService::onProxyUpdated)
|
||||||
|
|
||||||
managerHls?.releaseAppPlayers()
|
managerAllInOne?.releaseAppPlayers()
|
||||||
managerLocal?.releaseAppPlayers()
|
|
||||||
managerProgressive?.releaseAppPlayers()
|
|
||||||
|
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getAppropriateMediaSessionManager(fileName: String): MultiPlayerPlaybackManager? {
|
|
||||||
return if (fileName.startsWith("file")) {
|
|
||||||
lazyLocalDS()
|
|
||||||
} else if (fileName.endsWith("m3u8")) {
|
|
||||||
lazyHlsDS()
|
|
||||||
} else {
|
|
||||||
lazyProgressiveDS()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onUpdateNotification(
|
override fun onUpdateNotification(
|
||||||
session: MediaSession,
|
session: MediaSession,
|
||||||
startInForegroundRequired: Boolean,
|
startInForegroundRequired: Boolean,
|
||||||
@@ -141,38 +136,18 @@ class PlaybackService : MediaSessionService() {
|
|||||||
super.onUpdateNotification(session, startInForegroundRequired)
|
super.onUpdateNotification(session, startInForegroundRequired)
|
||||||
|
|
||||||
// Overrides the notification with any player actually playing
|
// Overrides the notification with any player actually playing
|
||||||
managerHls?.playingContent()?.forEach {
|
managerAllInOne?.playingContent()?.forEach {
|
||||||
if (it.player.isPlaying) {
|
if (it.player.isPlaying) {
|
||||||
super.onUpdateNotification(it, startInForegroundRequired)
|
super.onUpdateNotification(it, startInForegroundRequired)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
managerLocal?.playingContent()?.forEach {
|
|
||||||
if (it.player.isPlaying) {
|
|
||||||
super.onUpdateNotification(session, startInForegroundRequired)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
managerProgressive?.playingContent()?.forEach {
|
|
||||||
if (it.player.isPlaying) {
|
|
||||||
super.onUpdateNotification(session, startInForegroundRequired)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Overrides again with playing with audio
|
// Overrides again with playing with audio
|
||||||
managerHls?.playingContent()?.forEach {
|
managerAllInOne?.playingContent()?.forEach {
|
||||||
if (it.player.isPlaying && it.player.volume > 0) {
|
if (it.player.isPlaying && it.player.volume > 0) {
|
||||||
super.onUpdateNotification(it, startInForegroundRequired)
|
super.onUpdateNotification(it, startInForegroundRequired)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
managerLocal?.playingContent()?.forEach {
|
|
||||||
if (it.player.isPlaying && it.player.volume > 0) {
|
|
||||||
super.onUpdateNotification(session, startInForegroundRequired)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
managerProgressive?.playingContent()?.forEach {
|
|
||||||
if (it.player.isPlaying && it.player.volume > 0) {
|
|
||||||
super.onUpdateNotification(session, startInForegroundRequired)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a MediaSession to link with the MediaController that is making
|
// Return a MediaSession to link with the MediaController that is making
|
||||||
@@ -182,9 +157,9 @@ class PlaybackService : MediaSessionService() {
|
|||||||
val uri = controllerInfo.connectionHints.getString("uri") ?: return null
|
val uri = controllerInfo.connectionHints.getString("uri") ?: return null
|
||||||
val callbackUri = controllerInfo.connectionHints.getString("callbackUri")
|
val callbackUri = controllerInfo.connectionHints.getString("callbackUri")
|
||||||
|
|
||||||
val manager = getAppropriateMediaSessionManager(uri)
|
val manager = lazyDS()
|
||||||
|
|
||||||
return manager?.getMediaSession(
|
return manager.getMediaSession(
|
||||||
id,
|
id,
|
||||||
uri,
|
uri,
|
||||||
callbackUri,
|
callbackUri,
|
||||||
|
|||||||
Reference in New Issue
Block a user