mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
Self similarity/master (#525)
* Migrated to Media3 --------- Co-authored-by: self-similarity <137652432+self-similarity@users.noreply.github.com>
This commit is contained in:
parent
6b87fb7831
commit
8dae4c2b0f
23 changed files with 189 additions and 130 deletions
|
@ -18,7 +18,7 @@ fun String.execute() = ByteArrayOutputStream().use { baot ->
|
|||
workingDir = projectDir
|
||||
commandLine = this@execute.split(Regex("\\s"))
|
||||
standardOutput = baot
|
||||
}.exitValue == 0)
|
||||
}.exitValue == 0)
|
||||
String(baot.toByteArray()).trim()
|
||||
else null
|
||||
}
|
||||
|
@ -78,12 +78,18 @@ android {
|
|||
isDebuggable = false
|
||||
isMinifyEnabled = false
|
||||
isShrinkResources = false
|
||||
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro"
|
||||
)
|
||||
}
|
||||
debug {
|
||||
isDebuggable = true
|
||||
applicationIdSuffix = ".debug"
|
||||
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro"
|
||||
)
|
||||
}
|
||||
}
|
||||
flavorDimensions.add("state")
|
||||
|
@ -160,10 +166,16 @@ dependencies {
|
|||
// implementation("androidx.leanback:leanback-paging:1.1.0-alpha09")
|
||||
|
||||
// Exoplayer
|
||||
implementation("com.google.android.exoplayer:exoplayer:2.18.2")
|
||||
implementation("com.google.android.exoplayer:extension-cast:2.18.2")
|
||||
implementation("com.google.android.exoplayer:extension-mediasession:2.18.2")
|
||||
implementation("com.google.android.exoplayer:extension-okhttp:2.18.2")
|
||||
implementation("androidx.media3:media3-common:1.1.0")
|
||||
implementation("androidx.media3:media3-exoplayer:1.1.0")
|
||||
implementation("androidx.media3:media3-datasource-okhttp:1.1.0")
|
||||
implementation("androidx.media3:media3-ui:1.1.0")
|
||||
implementation("androidx.media3:media3-session:1.1.0")
|
||||
implementation("androidx.media3:media3-cast:1.1.0")
|
||||
implementation("androidx.media3:media3-exoplayer-hls:1.1.0")
|
||||
implementation("androidx.media3:media3-exoplayer-dash:1.1.0")
|
||||
|
||||
|
||||
// Use the Jellyfin ffmpeg extension for easy ffmpeg audio decoding in exoplayer. Thank you Jellyfin <3
|
||||
// implementation("org.jellyfin.exoplayer:exoplayer-ffmpeg-extension:2.18.2+1")
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ import androidx.preference.PreferenceManager
|
|||
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||
import com.google.android.gms.cast.framework.CastButtonFactory
|
||||
import com.google.android.gms.cast.framework.CastContext
|
||||
import com.google.android.gms.cast.framework.Session
|
||||
import com.google.android.gms.cast.framework.SessionManager
|
||||
|
@ -62,10 +63,10 @@ import com.lagradost.cloudstream3.CommonActivity.onDialogDismissedEvent
|
|||
import com.lagradost.cloudstream3.CommonActivity.onUserLeaveHint
|
||||
import com.lagradost.cloudstream3.CommonActivity.showToast
|
||||
import com.lagradost.cloudstream3.CommonActivity.updateLocale
|
||||
import com.lagradost.cloudstream3.mvvm.Resource
|
||||
import com.lagradost.cloudstream3.databinding.ActivityMainBinding
|
||||
import com.lagradost.cloudstream3.databinding.ActivityMainTvBinding
|
||||
import com.lagradost.cloudstream3.databinding.BottomResultviewPreviewBinding
|
||||
import com.lagradost.cloudstream3.mvvm.Resource
|
||||
import com.lagradost.cloudstream3.mvvm.debugAssert
|
||||
import com.lagradost.cloudstream3.mvvm.logError
|
||||
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
||||
|
|
|
@ -7,7 +7,6 @@ import android.graphics.drawable.AnimatedVectorDrawable
|
|||
import android.media.metrics.PlaybackErrorEvent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.support.v4.media.session.MediaSessionCompat
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
@ -20,15 +19,14 @@ import androidx.annotation.LayoutRes
|
|||
import androidx.annotation.StringRes
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.media.session.MediaButtonReceiver
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat
|
||||
import com.google.android.exoplayer2.ExoPlayer
|
||||
import com.google.android.exoplayer2.PlaybackException
|
||||
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector
|
||||
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout
|
||||
import com.google.android.exoplayer2.ui.PlayerView
|
||||
import com.google.android.exoplayer2.ui.SubtitleView
|
||||
import androidx.media3.common.PlaybackException
|
||||
import androidx.media3.exoplayer.ExoPlayer
|
||||
import androidx.media3.session.MediaSession
|
||||
import androidx.media3.ui.AspectRatioFrameLayout
|
||||
import androidx.media3.ui.PlayerView
|
||||
import androidx.media3.ui.SubtitleView
|
||||
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
||||
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
||||
import com.lagradost.cloudstream3.CommonActivity.canEnterPipMode
|
||||
|
@ -38,6 +36,7 @@ import com.lagradost.cloudstream3.CommonActivity.playerEventListener
|
|||
import com.lagradost.cloudstream3.CommonActivity.showToast
|
||||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.mvvm.logError
|
||||
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
||||
import com.lagradost.cloudstream3.ui.subtitles.SaveCaptionStyle
|
||||
import com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment
|
||||
import com.lagradost.cloudstream3.utils.AppUtils
|
||||
|
@ -179,15 +178,16 @@ abstract class AbstractPlayerFragment(
|
|||
}
|
||||
|
||||
canEnterPipMode = isPlayingRightNow && hasPipModeSupport
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && isInPIPMode) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
activity?.let { act ->
|
||||
PlayerPipHelper.updatePIPModeActions(act, isPlayingRightNow)
|
||||
PlayerPipHelper.updatePIPModeActions(act, isPlayingRightNow, player.getAspectRatio())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var pipReceiver: BroadcastReceiver? = null
|
||||
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean) {
|
||||
super.onPictureInPictureModeChanged(isInPictureInPictureMode)
|
||||
try {
|
||||
isInPIPMode = isInPictureInPictureMode
|
||||
if (isInPictureInPictureMode) {
|
||||
|
@ -210,9 +210,7 @@ abstract class AbstractPlayerFragment(
|
|||
}
|
||||
}
|
||||
val filter = IntentFilter()
|
||||
filter.addAction(
|
||||
ACTION_MEDIA_CONTROL
|
||||
)
|
||||
filter.addAction(ACTION_MEDIA_CONTROL)
|
||||
activity?.registerReceiver(pipReceiver, filter)
|
||||
val isPlaying = player.getIsPlaying()
|
||||
val isPlayingValue =
|
||||
|
@ -223,7 +221,10 @@ abstract class AbstractPlayerFragment(
|
|||
piphide?.isVisible = true
|
||||
exitedPipMode()
|
||||
pipReceiver?.let {
|
||||
activity?.unregisterReceiver(it)
|
||||
// Prevents java.lang.IllegalArgumentException: Receiver not registered
|
||||
normalSafeApiCall {
|
||||
activity?.unregisterReceiver(it)
|
||||
}
|
||||
}
|
||||
activity?.hideSystemUI()
|
||||
this.view?.let { UIHelper.hideKeyboard(it) }
|
||||
|
@ -276,18 +277,21 @@ abstract class AbstractPlayerFragment(
|
|||
gotoNext = true
|
||||
)
|
||||
}
|
||||
|
||||
PlaybackException.ERROR_CODE_REMOTE_ERROR, PlaybackException.ERROR_CODE_IO_BAD_HTTP_STATUS, PlaybackException.ERROR_CODE_TIMEOUT, PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED, PlaybackException.ERROR_CODE_IO_INVALID_HTTP_CONTENT_TYPE -> {
|
||||
showToast(
|
||||
"${ctx.getString(R.string.remote_error)}\n$errorName ($code)\n$msg",
|
||||
gotoNext = true
|
||||
)
|
||||
}
|
||||
|
||||
PlaybackException.ERROR_CODE_DECODING_FAILED, PlaybackErrorEvent.ERROR_AUDIO_TRACK_INIT_FAILED, PlaybackErrorEvent.ERROR_AUDIO_TRACK_OTHER, PlaybackException.ERROR_CODE_AUDIO_TRACK_WRITE_FAILED, PlaybackException.ERROR_CODE_DECODER_INIT_FAILED, PlaybackException.ERROR_CODE_DECODER_QUERY_FAILED -> {
|
||||
showToast(
|
||||
"${ctx.getString(R.string.render_error)}\n$errorName ($code)\n$msg",
|
||||
gotoNext = true
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
showToast(
|
||||
"${ctx.getString(R.string.unexpected_error)}\n$errorName ($code)\n$msg",
|
||||
|
@ -296,12 +300,14 @@ abstract class AbstractPlayerFragment(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
is InvalidFileException -> {
|
||||
showToast(
|
||||
"${ctx.getString(R.string.source_error)}\n${exception.message}",
|
||||
gotoNext = true
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
exception.message?.let {
|
||||
showToast(
|
||||
|
@ -322,15 +328,8 @@ abstract class AbstractPlayerFragment(
|
|||
private fun playerUpdated(player: Any?) {
|
||||
if (player is ExoPlayer) {
|
||||
context?.let { ctx ->
|
||||
val mediaButtonReceiver = ComponentName(ctx, MediaButtonReceiver::class.java)
|
||||
MediaSessionCompat(ctx, "Player", mediaButtonReceiver, null).let { media ->
|
||||
//media.setCallback(mMediaSessionCallback)
|
||||
//media.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS or MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS)
|
||||
val mediaSessionConnector = MediaSessionConnector(media)
|
||||
mediaSessionConnector.setPlayer(player)
|
||||
media.isActive = true
|
||||
mMediaSessionCompat = media
|
||||
}
|
||||
mMediaSession?.release()
|
||||
mMediaSession = MediaSession.Builder(ctx, player).build()
|
||||
}
|
||||
|
||||
// Necessary for multiple combined videos
|
||||
|
@ -340,8 +339,7 @@ abstract class AbstractPlayerFragment(
|
|||
}
|
||||
}
|
||||
|
||||
private var mediaSessionConnector: MediaSessionConnector? = null
|
||||
private var mMediaSessionCompat: MediaSessionCompat? = null
|
||||
private var mMediaSession: MediaSession? = null
|
||||
|
||||
// this can be used in the future for players other than exoplayer
|
||||
//private val mMediaSessionCallback: MediaSessionCompat.Callback = object : MediaSessionCompat.Callback() {
|
||||
|
@ -442,6 +440,7 @@ abstract class AbstractPlayerFragment(
|
|||
playerEventListener = null
|
||||
keyEventListener = null
|
||||
canEnterPipMode = false
|
||||
mMediaSession?.release()
|
||||
SubtitlesFragment.applyStyleEvent -= ::onSubStyleChanged
|
||||
|
||||
keepScreenOn(false)
|
||||
|
|
|
@ -5,30 +5,42 @@ import android.net.Uri
|
|||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import android.util.Rational
|
||||
import android.widget.FrameLayout
|
||||
import androidx.media3.common.C
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.google.android.exoplayer2.*
|
||||
import com.google.android.exoplayer2.C.*
|
||||
import com.google.android.exoplayer2.DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON
|
||||
import com.google.android.exoplayer2.DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER
|
||||
import com.google.android.exoplayer2.database.StandaloneDatabaseProvider
|
||||
import com.google.android.exoplayer2.ext.okhttp.OkHttpDataSource
|
||||
import com.google.android.exoplayer2.mediacodec.MediaCodecSelector
|
||||
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.DataSource
|
||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory
|
||||
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource
|
||||
import com.google.android.exoplayer2.upstream.HttpDataSource
|
||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSource
|
||||
import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor
|
||||
import com.google.android.exoplayer2.upstream.cache.SimpleCache
|
||||
import com.google.android.exoplayer2.util.MimeTypes
|
||||
import com.google.android.exoplayer2.video.VideoSize
|
||||
import androidx.media3.common.C.*
|
||||
import androidx.media3.common.Format
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.common.TrackSelectionOverride
|
||||
import androidx.media3.common.MimeTypes
|
||||
import androidx.media3.common.PlaybackException
|
||||
import androidx.media3.common.Player
|
||||
import androidx.media3.common.TrackGroup
|
||||
import androidx.media3.common.Tracks
|
||||
import androidx.media3.common.VideoSize
|
||||
import androidx.media3.database.StandaloneDatabaseProvider
|
||||
import androidx.media3.datasource.DataSource
|
||||
import androidx.media3.datasource.DefaultDataSourceFactory
|
||||
import androidx.media3.datasource.DefaultHttpDataSource
|
||||
import androidx.media3.datasource.HttpDataSource
|
||||
import androidx.media3.datasource.cache.CacheDataSource
|
||||
import androidx.media3.datasource.cache.LeastRecentlyUsedCacheEvictor
|
||||
import androidx.media3.datasource.cache.SimpleCache
|
||||
import androidx.media3.datasource.okhttp.OkHttpDataSource
|
||||
import androidx.media3.exoplayer.DefaultLoadControl
|
||||
import androidx.media3.exoplayer.DefaultRenderersFactory
|
||||
import androidx.media3.exoplayer.ExoPlayer
|
||||
import androidx.media3.exoplayer.SeekParameters
|
||||
import androidx.media3.exoplayer.source.ClippingMediaSource
|
||||
import androidx.media3.exoplayer.source.ConcatenatingMediaSource
|
||||
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
|
||||
import androidx.media3.exoplayer.source.MergingMediaSource
|
||||
import androidx.media3.exoplayer.source.SingleSampleMediaSource
|
||||
import androidx.media3.exoplayer.text.TextRenderer
|
||||
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector
|
||||
import androidx.media3.exoplayer.trackselection.TrackSelector
|
||||
import androidx.media3.ui.SubtitleView
|
||||
import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull
|
||||
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
||||
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
||||
|
@ -44,7 +56,6 @@ import com.lagradost.cloudstream3.utils.ExtractorLinkPlayList
|
|||
import com.lagradost.cloudstream3.utils.ExtractorUri
|
||||
import com.lagradost.cloudstream3.utils.SubtitleHelper.fromTwoLettersToLanguage
|
||||
import java.io.File
|
||||
import java.time.Duration
|
||||
import javax.net.ssl.HttpsURLConnection
|
||||
import javax.net.ssl.SSLContext
|
||||
import javax.net.ssl.SSLSession
|
||||
|
@ -451,6 +462,12 @@ class CS3IPlayer : IPlayer {
|
|||
}
|
||||
}
|
||||
|
||||
override fun getAspectRatio(): Rational? {
|
||||
return exoPlayer?.videoFormat?.let { format ->
|
||||
Rational(format.width, format.height)
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateSubtitleStyle(style: SaveCaptionStyle) {
|
||||
subtitleHelper.setSubStyle(style)
|
||||
}
|
||||
|
|
|
@ -3,19 +3,23 @@ package com.lagradost.cloudstream3.ui.player
|
|||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.google.android.exoplayer2.Format
|
||||
import com.google.android.exoplayer2.text.*
|
||||
import com.google.android.exoplayer2.text.cea.Cea608Decoder
|
||||
import com.google.android.exoplayer2.text.cea.Cea708Decoder
|
||||
import com.google.android.exoplayer2.text.dvb.DvbDecoder
|
||||
import com.google.android.exoplayer2.text.pgs.PgsDecoder
|
||||
import com.google.android.exoplayer2.text.ssa.SsaDecoder
|
||||
import com.google.android.exoplayer2.text.subrip.SubripDecoder
|
||||
import com.google.android.exoplayer2.text.ttml.TtmlDecoder
|
||||
import com.google.android.exoplayer2.text.tx3g.Tx3gDecoder
|
||||
import com.google.android.exoplayer2.text.webvtt.Mp4WebvttDecoder
|
||||
import com.google.android.exoplayer2.text.webvtt.WebvttDecoder
|
||||
import com.google.android.exoplayer2.util.MimeTypes
|
||||
import androidx.media3.common.Format
|
||||
import androidx.media3.common.MimeTypes
|
||||
import androidx.media3.exoplayer.text.ExoplayerCuesDecoder
|
||||
import androidx.media3.exoplayer.text.SubtitleDecoderFactory
|
||||
import androidx.media3.extractor.text.SubtitleDecoder
|
||||
import androidx.media3.extractor.text.SubtitleInputBuffer
|
||||
import androidx.media3.extractor.text.SubtitleOutputBuffer
|
||||
import androidx.media3.extractor.text.cea.Cea608Decoder
|
||||
import androidx.media3.extractor.text.cea.Cea708Decoder
|
||||
import androidx.media3.extractor.text.dvb.DvbDecoder
|
||||
import androidx.media3.extractor.text.pgs.PgsDecoder
|
||||
import androidx.media3.extractor.text.ssa.SsaDecoder
|
||||
import androidx.media3.extractor.text.subrip.SubripDecoder
|
||||
import androidx.media3.extractor.text.ttml.TtmlDecoder
|
||||
import androidx.media3.extractor.text.tx3g.Tx3gDecoder
|
||||
import androidx.media3.extractor.text.webvtt.Mp4WebvttDecoder
|
||||
import androidx.media3.extractor.text.webvtt.WebvttDecoder
|
||||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.mvvm.logError
|
||||
import org.mozilla.universalchardet.UniversalDetector
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.lagradost.cloudstream3.ui.player
|
||||
|
||||
import android.os.Looper
|
||||
import com.google.android.exoplayer2.text.SubtitleDecoderFactory
|
||||
import com.google.android.exoplayer2.text.TextOutput
|
||||
import androidx.media3.exoplayer.text.SubtitleDecoderFactory
|
||||
import androidx.media3.exoplayer.text.TextOutput
|
||||
|
||||
class CustomTextRenderer(
|
||||
offset: Long,
|
||||
|
|
|
@ -19,8 +19,8 @@ import androidx.core.view.isGone
|
|||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.google.android.exoplayer2.Format.NO_VALUE
|
||||
import com.google.android.exoplayer2.util.MimeTypes
|
||||
import androidx.media3.common.Format.NO_VALUE
|
||||
import androidx.media3.common.MimeTypes
|
||||
import com.hippo.unifile.UniFile
|
||||
import com.lagradost.cloudstream3.*
|
||||
import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.lagradost.cloudstream3.ui.player
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Rational
|
||||
import com.lagradost.cloudstream3.ui.subtitles.SaveCaptionStyle
|
||||
import com.lagradost.cloudstream3.utils.EpisodeSkip
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
|
@ -167,6 +168,19 @@ interface IPlayer {
|
|||
|
||||
fun getVideoTracks(): CurrentTracks
|
||||
|
||||
/**
|
||||
* Original video aspect ratio used for PiP mode
|
||||
*
|
||||
* Set using: Width, Height.
|
||||
* Example: Rational(16, 9)
|
||||
*
|
||||
* If null will default to set no aspect ratio.
|
||||
*
|
||||
* PiP functions calling this needs to coerce this value between 0.418410 and 2.390000
|
||||
* to prevent crashes.
|
||||
*/
|
||||
fun getAspectRatio(): Rational?
|
||||
|
||||
/** 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)
|
||||
|
||||
|
|
|
@ -15,10 +15,10 @@
|
|||
*/
|
||||
package com.lagradost.cloudstream3.ui.player;
|
||||
|
||||
import static com.google.android.exoplayer2.text.Cue.DIMEN_UNSET;
|
||||
import static com.google.android.exoplayer2.text.Cue.LINE_TYPE_NUMBER;
|
||||
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
|
||||
import static com.google.android.exoplayer2.util.Assertions.checkState;
|
||||
import static androidx.media3.common.text.Cue.DIMEN_UNSET;
|
||||
import static androidx.media3.common.text.Cue.LINE_TYPE_NUMBER;
|
||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||
import static androidx.media3.common.util.Assertions.checkState;
|
||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||
|
||||
import android.os.Handler;
|
||||
|
@ -28,25 +28,24 @@ import android.os.Message;
|
|||
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.exoplayer2.BaseRenderer;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.FormatHolder;
|
||||
import com.google.android.exoplayer2.RendererCapabilities;
|
||||
import com.google.android.exoplayer2.source.SampleStream.ReadDataResult;
|
||||
import com.google.android.exoplayer2.text.Cue;
|
||||
import com.google.android.exoplayer2.text.CueGroup;
|
||||
import com.google.android.exoplayer2.text.Subtitle;
|
||||
import com.google.android.exoplayer2.text.SubtitleDecoder;
|
||||
import com.google.android.exoplayer2.text.SubtitleDecoderException;
|
||||
import com.google.android.exoplayer2.text.SubtitleDecoderFactory;
|
||||
import com.google.android.exoplayer2.text.SubtitleInputBuffer;
|
||||
import com.google.android.exoplayer2.text.SubtitleOutputBuffer;
|
||||
import com.google.android.exoplayer2.text.TextOutput;
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.Format;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.text.CueGroup;
|
||||
import androidx.media3.common.MimeTypes;
|
||||
import androidx.media3.common.util.Log;
|
||||
import androidx.media3.common.util.Util;
|
||||
import androidx.media3.exoplayer.BaseRenderer;
|
||||
import androidx.media3.exoplayer.FormatHolder;
|
||||
import androidx.media3.exoplayer.RendererCapabilities;
|
||||
import androidx.media3.exoplayer.source.SampleStream;
|
||||
import androidx.media3.exoplayer.text.SubtitleDecoderFactory;
|
||||
import androidx.media3.exoplayer.text.TextOutput;
|
||||
import androidx.media3.extractor.text.Subtitle;
|
||||
import androidx.media3.extractor.text.SubtitleDecoder;
|
||||
import androidx.media3.extractor.text.SubtitleDecoderException;
|
||||
import androidx.media3.extractor.text.SubtitleInputBuffer;
|
||||
import androidx.media3.extractor.text.SubtitleOutputBuffer;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
|
@ -310,7 +309,7 @@ public class NonFinalTextRenderer extends BaseRenderer implements Callback {
|
|||
return;
|
||||
}
|
||||
// Try and read the next subtitle from the source.
|
||||
@ReadDataResult int result = readSource(formatHolder, nextInputBuffer, /* readFlags= */ 0);
|
||||
@SampleStream.ReadDataResult int result = readSource(formatHolder, nextInputBuffer, /* readFlags= */ 0);
|
||||
if (result == C.RESULT_BUFFER_READ) {
|
||||
if (nextInputBuffer.isEndOfStream()) {
|
||||
inputStreamEnded = true;
|
||||
|
|
|
@ -7,28 +7,22 @@ import android.app.RemoteAction
|
|||
import android.content.Intent
|
||||
import android.graphics.drawable.Icon
|
||||
import android.os.Build
|
||||
import android.util.Rational
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.annotation.StringRes
|
||||
import com.lagradost.cloudstream3.R
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class PlayerPipHelper {
|
||||
companion object {
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
private fun getPen(activity: Activity, code: Int): PendingIntent {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.getBroadcast(
|
||||
activity,
|
||||
code,
|
||||
Intent("media_control").putExtra("control_type", code),
|
||||
PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
} else {
|
||||
PendingIntent.getBroadcast(
|
||||
activity,
|
||||
code,
|
||||
Intent("media_control").putExtra("control_type", code),
|
||||
0
|
||||
)
|
||||
}
|
||||
return PendingIntent.getBroadcast(
|
||||
activity,
|
||||
code,
|
||||
Intent(ACTION_MEDIA_CONTROL).putExtra(EXTRA_CONTROL_TYPE, code),
|
||||
PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
|
@ -48,7 +42,7 @@ class PlayerPipHelper {
|
|||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
fun updatePIPModeActions(activity: Activity, isPlaying: Boolean) {
|
||||
fun updatePIPModeActions(activity: Activity, isPlaying: Boolean, aspectRatio: Rational?) {
|
||||
val actions: ArrayList<RemoteAction> = ArrayList()
|
||||
actions.add(
|
||||
getRemoteAction(
|
||||
|
@ -87,8 +81,28 @@ class PlayerPipHelper {
|
|||
CSPlayerEvent.SeekForward
|
||||
)
|
||||
)
|
||||
|
||||
// Nessecary to prevent crashing.
|
||||
val mixAspectRatio = 0.41841f // ~1/2.39
|
||||
val maxAspectRatio = 2.39f // widescreen standard
|
||||
val ratioAccuracy = 100000 // To convert the float to int
|
||||
|
||||
// java.lang.IllegalArgumentException: setPictureInPictureParams: Aspect ratio is too extreme (must be between 0.418410 and 2.390000)
|
||||
val fixedRational = aspectRatio?.toFloat()?.coerceIn(mixAspectRatio, maxAspectRatio)?.let {
|
||||
Rational((it * ratioAccuracy).roundToInt(), ratioAccuracy)
|
||||
}
|
||||
|
||||
activity.setPictureInPictureParams(
|
||||
PictureInPictureParams.Builder().setActions(actions).build()
|
||||
PictureInPictureParams.Builder()
|
||||
.apply {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
setSeamlessResizeEnabled(true)
|
||||
setAutoEnterEnabled(isPlaying)
|
||||
}
|
||||
}
|
||||
.setAspectRatio(fixedRational)
|
||||
.setActions(actions)
|
||||
.build()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ import android.util.Log
|
|||
import android.util.TypedValue
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import com.google.android.exoplayer2.ui.SubtitleView
|
||||
import com.google.android.exoplayer2.util.MimeTypes
|
||||
import androidx.media3.common.MimeTypes
|
||||
import androidx.media3.ui.SubtitleView
|
||||
import com.lagradost.cloudstream3.SubtitleFile
|
||||
import com.lagradost.cloudstream3.ui.player.CustomDecoder.Companion.regexSubtitlesToRemoveBloat
|
||||
import com.lagradost.cloudstream3.ui.player.CustomDecoder.Companion.regexSubtitlesToRemoveCaptions
|
||||
|
|
|
@ -14,7 +14,7 @@ import android.widget.TextView
|
|||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import com.google.android.exoplayer2.text.Cue
|
||||
import androidx.media3.common.text.Cue
|
||||
import com.google.android.gms.cast.TextTrackStyle
|
||||
import com.google.android.gms.cast.TextTrackStyle.*
|
||||
import com.jaredrummler.android.colorpicker.ColorPickerDialog
|
||||
|
|
|
@ -18,8 +18,8 @@ import androidx.core.content.res.ResourcesCompat
|
|||
import androidx.fragment.app.Fragment
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import com.google.android.exoplayer2.text.Cue
|
||||
import com.google.android.exoplayer2.ui.CaptionStyleCompat
|
||||
import androidx.media3.common.text.Cue
|
||||
import androidx.media3.ui.CaptionStyleCompat
|
||||
import com.jaredrummler.android.colorpicker.ColorPickerDialog
|
||||
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
||||
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.lagradost.cloudstream3.utils
|
||||
|
||||
import android.net.Uri
|
||||
import com.google.android.exoplayer2.util.MimeTypes
|
||||
import androidx.media3.common.MimeTypes
|
||||
import com.google.android.gms.cast.*
|
||||
import com.google.android.gms.cast.framework.CastSession
|
||||
import com.google.android.gms.cast.framework.media.RemoteMediaClient
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
android:layout_height="match_parent"
|
||||
android:contentDescription="@string/preview_background_img_des" />
|
||||
|
||||
<com.google.android.exoplayer2.ui.SubtitleView
|
||||
<androidx.media3.ui.SubtitleView
|
||||
android:id="@+id/subtitle_text"
|
||||
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<!--
|
||||
app:fastforward_increment="10000"
|
||||
app:rewind_increment="10000"-->
|
||||
<com.google.android.exoplayer2.ui.PlayerView
|
||||
<androidx.media3.ui.PlayerView
|
||||
android:id="@+id/player_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<!--
|
||||
app:fastforward_increment="10000"
|
||||
app:rewind_increment="10000"-->
|
||||
<com.google.android.exoplayer2.ui.PlayerView
|
||||
<androidx.media3.ui.PlayerView
|
||||
android:id="@+id/player_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<!--
|
||||
app:fastforward_increment="10000"
|
||||
app:rewind_increment="10000"-->
|
||||
<com.google.android.exoplayer2.ui.PlayerView
|
||||
<androidx.media3.ui.PlayerView
|
||||
android:id="@+id/player_view"
|
||||
app:show_timeout="0"
|
||||
app:hide_on_touch="false"
|
||||
|
|
|
@ -450,7 +450,7 @@
|
|||
android:textStyle="normal"
|
||||
tools:text="15:30" />
|
||||
<!--app:buffered_color="@color/videoCache"-->
|
||||
<com.google.android.exoplayer2.ui.DefaultTimeBar
|
||||
<androidx.media3.ui.DefaultTimeBar
|
||||
android:id="@id/exo_progress"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="30dp"
|
||||
|
|
|
@ -543,7 +543,7 @@
|
|||
android:textStyle="normal"
|
||||
tools:text="15:30" />
|
||||
<!--app:buffered_color="@color/videoCache"-->
|
||||
<com.google.android.exoplayer2.ui.DefaultTimeBar
|
||||
<androidx.media3.ui.DefaultTimeBar
|
||||
android:id="@id/exo_progress"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="30dp"
|
||||
|
|
|
@ -35,9 +35,8 @@
|
|||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/subtitles_preview_background" />
|
||||
|
||||
<com.google.android.exoplayer2.ui.SubtitleView
|
||||
<androidx.media3.ui.SubtitleView
|
||||
android:id="@+id/subtitle_text"
|
||||
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
|
|
|
@ -443,7 +443,7 @@
|
|||
android:textStyle="normal"
|
||||
tools:text="15:30" />
|
||||
<!--app:buffered_color="@color/videoCache"-->
|
||||
<com.google.android.exoplayer2.ui.DefaultTimeBar
|
||||
<androidx.media3.ui.DefaultTimeBar
|
||||
android:id="@id/exo_progress"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="30dp"
|
||||
|
|
|
@ -16,7 +16,7 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
|||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||
android.useAndroidX=true
|
||||
# Automatically convert third-party libraries to use AndroidX
|
||||
android.enableJetifier=true
|
||||
# android.enableJetifier=true
|
||||
# Kotlin code style for this project: "official" or "obsolete":
|
||||
kotlin.code.style=official
|
||||
android.defaults.buildfeatures.buildconfig=true
|
||||
|
|
Loading…
Reference in a new issue