diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b3318675..42ca93fd 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -155,10 +155,10 @@ dependencies { // implementation("androidx.leanback:leanback-paging:1.1.0-alpha09") // Exoplayer - implementation("com.google.android.exoplayer:exoplayer:2.18.1") - implementation("com.google.android.exoplayer:extension-cast:2.18.1") - implementation("com.google.android.exoplayer:extension-mediasession:2.18.1") - implementation("com.google.android.exoplayer:extension-okhttp:2.18.1") + implementation("com.google.android.exoplayer:exoplayer:2.16.1") + implementation("com.google.android.exoplayer:extension-cast:2.16.1") + implementation("com.google.android.exoplayer:extension-mediasession:2.16.1") + implementation("com.google.android.exoplayer:extension-okhttp:2.16.1") //implementation("com.google.android.exoplayer:extension-leanback:2.14.0") diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt index 46ddce09..ad0b4399 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt @@ -150,7 +150,7 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi } else { ChromecastSubtitlesFragment.getCurrentSavedStyle().apply { val font = TextTrackStyle() - font.setFontFamily(fontFamily ?: "Google Sans") + font.fontFamily = fontFamily ?: "Google Sans" fontGenericFamily?.let { font.fontGenericFamily = it } @@ -183,9 +183,7 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi val contentUrl = (remoteMediaClient?.currentItem?.media?.contentUrl ?: remoteMediaClient?.currentItem?.media?.contentId) - val sortingMethods = - items.map { "${it.name} ${Qualities.getStringByInt(it.quality)}" } - .toTypedArray() + val sortingMethods = items.map { "${it.name} ${Qualities.getStringByInt(it.quality)}" }.toTypedArray() val sotringIndex = items.indexOfFirst { it.url == contentUrl } val arrayAdapter = @@ -281,7 +279,7 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi val currentPosition = remoteMediaClient?.approximateStreamPosition if (currentDuration != null && currentPosition != null) DataStoreHelper.setViewPos(epData.id, currentPosition, currentDuration) - } catch (t: Throwable) { + } catch (t : Throwable) { logError(t) } @@ -360,8 +358,10 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi } } - override fun onSessionConnected(castSession: CastSession) { - super.onSessionConnected(castSession) + override fun onSessionConnected(castSession: CastSession?) { + castSession?.let { + super.onSessionConnected(it) + } remoteMediaClient?.queueSetRepeatMode(REPEAT_MODE_REPEAT_OFF, JSONObject()) } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/CS3IPlayer.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/CS3IPlayer.kt index f60d8c78..a838c85c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/CS3IPlayer.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/CS3IPlayer.kt @@ -15,7 +15,6 @@ import com.google.android.exoplayer2.ext.okhttp.OkHttpDataSource import com.google.android.exoplayer2.source.* import com.google.android.exoplayer2.text.TextRenderer import com.google.android.exoplayer2.trackselection.DefaultTrackSelector -import com.google.android.exoplayer2.trackselection.TrackSelectionOverride import com.google.android.exoplayer2.trackselection.TrackSelector import com.google.android.exoplayer2.ui.SubtitleView import com.google.android.exoplayer2.upstream.* @@ -219,43 +218,7 @@ class CS3IPlayer : IPlayer { var currentSubtitles: SubtitleData? = null - private fun List.getTrack(id: String?): Pair? { - if (id == null) return null - // This beast of an expression does: - // 1. Filter all audio tracks - // 2. Get all formats in said audio tacks - // 3. Gets all ids of the formats - // 4. Filters to find the first audio track with the same id as the audio track we are looking for - // 5. Returns the media group and the index of the audio track in the group - return this.firstNotNullOfOrNull { group -> - (0 until group.mediaTrackGroup.length).map { - group.getTrackFormat(it) to it - }.firstOrNull { it.first.id == id } - ?.let { group.mediaTrackGroup to it.second } - } - } - - override fun setMaxVideoSize(width: Int, height: Int, id: String?) { - if (id != null) { - val videoTrack = - exoPlayer?.currentTracks?.groups?.filter { it.type == TRACK_TYPE_VIDEO } - ?.getTrack(id) - - if (videoTrack != null) { - exoPlayer?.trackSelectionParameters = exoPlayer?.trackSelectionParameters - ?.buildUpon() - ?.setOverrideForType( - TrackSelectionOverride( - videoTrack.first, - videoTrack.second - ) - ) - ?.build() - ?: return - return - } - } - + override fun setMaxVideoSize(width: Int, height: Int) { exoPlayer?.trackSelectionParameters = exoPlayer?.trackSelectionParameters ?.buildUpon() ?.setMaxVideoSize(width, height) @@ -263,29 +226,8 @@ class CS3IPlayer : IPlayer { ?: return } - override fun setPreferredAudioTrack(trackLanguage: String?, id: String?) { + override fun setPreferredAudioTrack(trackLanguage: String?) { preferredAudioTrackLanguage = trackLanguage - - if (id != null) { - val audioTrack = - exoPlayer?.currentTracks?.groups?.filter { it.type == TRACK_TYPE_AUDIO } - ?.getTrack(id) - - if (audioTrack != null) { - exoPlayer?.trackSelectionParameters = exoPlayer?.trackSelectionParameters - ?.buildUpon() - ?.setOverrideForType( - TrackSelectionOverride( - audioTrack.first, - audioTrack.second - ) - ) - ?.build() - ?: return - return - } - } - exoPlayer?.trackSelectionParameters = exoPlayer?.trackSelectionParameters ?.buildUpon() ?.setPreferredAudioLanguage(trackLanguage) @@ -297,11 +239,11 @@ class CS3IPlayer : IPlayer { /** * Gets all supported formats in a list * */ - private fun List.getFormats(): List> { + private fun List.getFormats(): List { return this.map { - (0 until it.mediaTrackGroup.length).mapNotNull { i -> + (0 until it.trackGroup.length).mapNotNull { i -> if (it.isSupported) - it.mediaTrackGroup.getFormat(i) to i + it.trackGroup.getFormat(i) // to it.isSelected else null } }.flatten() @@ -328,12 +270,11 @@ class CS3IPlayer : IPlayer { } override fun getVideoTracks(): CurrentTracks { - val allTracks = exoPlayer?.currentTracks?.groups ?: emptyList() - val videoTracks = allTracks.filter { it.type == TRACK_TYPE_VIDEO } - .getFormats() - .map { it.first.toVideoTrack() } - val audioTracks = allTracks.filter { it.type == TRACK_TYPE_AUDIO }.getFormats() - .map { it.first.toAudioTrack() } + val allTracks = exoPlayer?.currentTracksInfo?.trackGroupInfos ?: emptyList() + val videoTracks = allTracks.filter { it.trackType == TRACK_TYPE_VIDEO }.getFormats() + .map { it.toVideoTrack() } + val audioTracks = allTracks.filter { it.trackType == TRACK_TYPE_AUDIO }.getFormats() + .map { it.toAudioTrack() } return CurrentTracks( exoPlayer?.videoFormat?.toVideoTrack(), @@ -670,12 +611,7 @@ class CS3IPlayer : IPlayer { } else it }.toTypedArray() } - .setTrackSelector( - trackSelector ?: getTrackSelector( - context, - maxVideoHeight - ) - ) + .setTrackSelector(trackSelector ?: getTrackSelector(context, maxVideoHeight)) .setLoadControl( DefaultLoadControl.Builder() .setTargetBufferBytes( @@ -845,7 +781,10 @@ class CS3IPlayer : IPlayer { isPlaying = exo.isPlaying } exoPlayer?.addListener(object : Player.Listener { - override fun onTracksChanged(tracks: Tracks) { + /** + * Records the current used subtitle/track. Needed as exoplayer seems to have loose track language selection. + * */ + override fun onTracksInfoChanged(tracksInfo: TracksInfo) { fun Format.isSubtitle(): Boolean { return this.sampleMimeType?.contains("video/") == false && this.sampleMimeType?.contains("audio/") == false @@ -853,17 +792,17 @@ class CS3IPlayer : IPlayer { normalSafeApiCall { exoPlayerSelectedTracks = - tracks.groups.mapNotNull { - val format = it.mediaTrackGroup.getFormat(0) + tracksInfo.trackGroupInfos.mapNotNull { + val format = it.trackGroup.getFormat(0) if (format.isSubtitle()) format.language?.let { lang -> lang to it.isSelected } else null } - val exoPlayerReportedTracks = tracks.groups.mapNotNull { + val exoPlayerReportedTracks = tracksInfo.trackGroupInfos.mapNotNull { // Filter out unsupported tracks if (it.isSupported) - it.mediaTrackGroup.getFormat(0) + it.trackGroup.getFormat(0) else null }.mapNotNull { @@ -888,6 +827,7 @@ class CS3IPlayer : IPlayer { onTracksInfoChanged?.invoke() subtitlesUpdates?.invoke() } + super.onTracksInfoChanged(tracksInfo) } override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt index 172984a2..e20a6c7b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt @@ -796,16 +796,15 @@ class GeneratorPlayer : FullScreenPlayer() { } tracksDialog.apply_btt?.setOnClickListener { - val currentTrack = currentAudioTracks.getOrNull(audioIndexStart) player.setPreferredAudioTrack( - currentTrack?.language, currentTrack?.id + currentAudioTracks.getOrNull(audioIndexStart)?.language ) val currentVideo = currentVideoTracks.getOrNull(videoIndex) val width = currentVideo?.width ?: NO_VALUE val height = currentVideo?.height ?: NO_VALUE if (width != NO_VALUE && height != NO_VALUE) { - player.setMaxVideoSize(width, height, currentVideo?.id) + player.setMaxVideoSize(width, height) } tracksDialog.dismissSafe(activity) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/IPlayer.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/IPlayer.kt index 473b3e65..e8934250 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/IPlayer.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/IPlayer.kt @@ -161,9 +161,9 @@ interface IPlayer { fun getVideoTracks(): CurrentTracks - /** If no parameters are set it'll default to no set size, Specifying the id allows for track overrides to force the player to pick the quality. */ - fun setMaxVideoSize(width: Int = Int.MAX_VALUE, height: Int = Int.MAX_VALUE, id: String? = null) + /** If no parameters are set it'll default to no set size */ + fun setMaxVideoSize(width: Int = Int.MAX_VALUE, height: Int = Int.MAX_VALUE) - /** If no trackLanguage is set it'll default to first track. Specifying the id allows for track overrides as the language can be identical. */ - fun setPreferredAudioTrack(trackLanguage: String?, id: String? = null) + /** If no trackLanguage is set it'll default to first track */ + fun setPreferredAudioTrack(trackLanguage: String?) } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/NonFinalTextRenderer.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/NonFinalTextRenderer.kt index 7acb7c34..f7fb3139 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/NonFinalTextRenderer.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/NonFinalTextRenderer.kt @@ -75,7 +75,7 @@ open class NonFinalTextRenderer @JvmOverloads constructor( return TAG } -// @RendererCapabilities.Capabilities + @RendererCapabilities.Capabilities override fun supportsFormat(format: Format): Int { return if (decoderFactory.supportsFormat(format)) { RendererCapabilities.create( @@ -202,8 +202,7 @@ open class NonFinalTextRenderer @JvmOverloads constructor( return } // Try and read the next subtitle from the source. -// @ReadDataResult - val result = + @ReadDataResult val result = readSource(formatHold, nextInputBuffer, /* readFlags= */0) if (result == C.RESULT_BUFFER_READ) { if (nextInputBuffer.isEndOfStream) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/subtitles/SubtitlesFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/subtitles/SubtitlesFragment.kt index 05a9416d..b97468e7 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/subtitles/SubtitlesFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/subtitles/SubtitlesFragment.kt @@ -49,7 +49,7 @@ data class SaveCaptionStyle( @JsonProperty("foregroundColor") var foregroundColor: Int, @JsonProperty("backgroundColor") var backgroundColor: Int, @JsonProperty("windowColor") var windowColor: Int, -// @CaptionStyleCompat.EdgeType + @CaptionStyleCompat.EdgeType @JsonProperty("edgeType") var edgeType: Int, @JsonProperty("edgeColor") var edgeColor: Int, @FontRes diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/CastOptionsProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/CastOptionsProvider.kt index ece9a4c0..17ec775b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/CastOptionsProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/CastOptionsProvider.kt @@ -20,13 +20,10 @@ class CastOptionsProvider : OptionsProvider { MediaIntentReceiver.ACTION_FORWARD, MediaIntentReceiver.ACTION_STOP_CASTING ) - - val name = ControllerActivity::class.qualifiedName!! - val compatButtonAction = intArrayOf(1, 3) val notificationOptions = NotificationOptions.Builder() - .setTargetActivityClassName(name) + .setTargetActivityClassName(ControllerActivity::class.qualifiedName) .setActions(buttonActions, compatButtonAction) .setForward30DrawableResId(R.drawable.go_forward_30) .setRewind30DrawableResId(R.drawable.go_back_30) @@ -35,7 +32,7 @@ class CastOptionsProvider : OptionsProvider { val mediaOptions = CastMediaOptions.Builder() .setNotificationOptions(notificationOptions) - .setExpandedControllerActivityClassName(name) + .setExpandedControllerActivityClassName(ControllerActivity::class.qualifiedName) .build() return CastOptions.Builder() @@ -47,7 +44,7 @@ class CastOptionsProvider : OptionsProvider { .build() } - override fun getAdditionalSessionProviders(p0: Context): MutableList { + override fun getAdditionalSessionProviders(p0: Context?): MutableList { return Collections.emptyList() } } \ No newline at end of file