mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
DONT UPDATE TO THIS IF YOU WANT A WORKING APP
extreme player fuckery
This commit is contained in:
parent
9db6206e68
commit
0849bffe49
2 changed files with 146 additions and 72 deletions
|
@ -7,9 +7,13 @@ import android.util.Log
|
|||
import android.widget.FrameLayout
|
||||
import com.google.android.exoplayer2.*
|
||||
import com.google.android.exoplayer2.database.StandaloneDatabaseProvider
|
||||
import com.google.android.exoplayer2.extractor.ExtractorsFactory
|
||||
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory
|
||||
import com.google.android.exoplayer2.source.MergingMediaSource
|
||||
import com.google.android.exoplayer2.source.ProgressiveMediaSource
|
||||
import com.google.android.exoplayer2.source.SingleSampleMediaSource
|
||||
import com.google.android.exoplayer2.text.SubtitleDecoderFactory
|
||||
import com.google.android.exoplayer2.text.SubtitleExtractor
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelector
|
||||
import com.google.android.exoplayer2.ui.SubtitleView
|
||||
|
@ -367,7 +371,7 @@ class CS3IPlayer : IPlayer {
|
|||
private fun buildExoPlayer(
|
||||
context: Context,
|
||||
mediaItem: MediaItem,
|
||||
subSources: List<SingleSampleMediaSource>,
|
||||
subSources: List<ProgressiveMediaSource>,
|
||||
currentWindow: Int,
|
||||
playbackPosition: Long,
|
||||
playBackSpeed: Float,
|
||||
|
@ -466,7 +470,7 @@ class CS3IPlayer : IPlayer {
|
|||
private fun loadExo(
|
||||
context: Context,
|
||||
mediaItem: MediaItem,
|
||||
subSources: List<SingleSampleMediaSource>,
|
||||
subSources: List<ProgressiveMediaSource>,
|
||||
cacheFactory: CacheDataSource.Factory? = null
|
||||
) {
|
||||
Log.i(TAG, "loadExo")
|
||||
|
@ -579,6 +583,39 @@ class CS3IPlayer : IPlayer {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* https://github.com/google/ExoPlayer/blob/029a2b27cbdc27cf9d51d4a73ebeb503968849f6/library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactory.java
|
||||
* */
|
||||
private fun createProgressiveMediaSources(
|
||||
subSources: List<SingleSampleMediaSource>,
|
||||
factory: DataSource.Factory
|
||||
): List<ProgressiveMediaSource> {
|
||||
val extractorFactory = ExtractorsFactory {
|
||||
subSources.map {
|
||||
val currentSub = it.mediaItem.localConfiguration?.subtitleConfigurations?.firstOrNull()
|
||||
val format = Format.Builder()
|
||||
.setSampleMimeType(currentSub?.mimeType)
|
||||
.setLanguage(currentSub?.language)
|
||||
.setLabel(currentSub?.label)
|
||||
.build()
|
||||
|
||||
SubtitleExtractor(
|
||||
CustomSubtitleDecoderFactory().createDecoder(format), format
|
||||
)
|
||||
}.toTypedArray()
|
||||
}
|
||||
|
||||
return subSources.mapNotNull {
|
||||
val uri = it.mediaItem.localConfiguration?.subtitleConfigurations?.firstOrNull()?.uri ?: return@mapNotNull null
|
||||
if (uri.toString().isBlank()) return@mapNotNull null
|
||||
|
||||
ProgressiveMediaSource.Factory(factory, extractorFactory)
|
||||
.createMediaSource(
|
||||
MediaItem.fromUri(uri)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadOfflinePlayer(context: Context, data: ExtractorUri) {
|
||||
Log.i(TAG, "loadOfflinePlayer")
|
||||
try {
|
||||
|
@ -591,8 +628,12 @@ class CS3IPlayer : IPlayer {
|
|||
offlineSourceFactory,
|
||||
subtitleHelper
|
||||
)
|
||||
|
||||
val progressiveMediaSources =
|
||||
createProgressiveMediaSources(subSources, offlineSourceFactory)
|
||||
|
||||
subtitleHelper.setActiveSubtitles(activeSubtitles.toSet())
|
||||
loadExo(context, mediaItem, subSources)
|
||||
loadExo(context, mediaItem, progressiveMediaSources)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "loadOfflinePlayer error", e)
|
||||
playerError?.invoke(e)
|
||||
|
@ -630,6 +671,10 @@ class CS3IPlayer : IPlayer {
|
|||
offlineSourceFactory,
|
||||
subtitleHelper
|
||||
)
|
||||
|
||||
val progressiveMediaSources =
|
||||
createProgressiveMediaSources(subSources, onlineSourceFactory)
|
||||
|
||||
subtitleHelper.setActiveSubtitles(activeSubtitles.toSet())
|
||||
|
||||
if (simpleCache == null)
|
||||
|
@ -640,7 +685,7 @@ class CS3IPlayer : IPlayer {
|
|||
setUpstreamDataSourceFactory(onlineSourceFactory)
|
||||
}
|
||||
|
||||
loadExo(context, mediaItem, subSources, cacheFactory)
|
||||
loadExo(context, mediaItem, progressiveMediaSources, cacheFactory)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "loadOnlinePlayer error", e)
|
||||
playerError?.invoke(e)
|
||||
|
|
|
@ -1,49 +1,77 @@
|
|||
package com.lagradost.cloudstream3.ui.player
|
||||
|
||||
import android.util.Log
|
||||
import com.google.android.exoplayer2.Format
|
||||
import com.google.android.exoplayer2.text.*
|
||||
import com.google.android.exoplayer2.util.MimeTypes
|
||||
import com.google.android.exoplayer2.text.webvtt.WebvttDecoder
|
||||
import com.google.android.exoplayer2.text.ssa.SsaDecoder
|
||||
import com.google.android.exoplayer2.text.webvtt.Mp4WebvttDecoder
|
||||
import com.google.android.exoplayer2.text.ttml.TtmlDecoder
|
||||
import com.google.android.exoplayer2.text.subrip.SubripDecoder
|
||||
import com.google.android.exoplayer2.text.tx3g.Tx3gDecoder
|
||||
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 java.lang.IllegalArgumentException
|
||||
import com.google.android.exoplayer2.text.ttml.TtmlDecoder
|
||||
import com.google.android.exoplayer2.text.webvtt.WebvttDecoder
|
||||
import com.google.android.exoplayer2.util.MimeTypes
|
||||
import okio.ByteString.Companion.toByteString
|
||||
import java.nio.charset.Charset
|
||||
|
||||
//class CustomDecoder : SubtitleDecoder {
|
||||
// override fun getName(): String {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// override fun dequeueInputBuffer(): SubtitleInputBuffer? {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// override fun queueInputBuffer(inputBuffer: SubtitleInputBuffer) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// override fun dequeueOutputBuffer(): SubtitleOutputBuffer? {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// override fun flush() {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// override fun release() {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// override fun setPositionUs(positionUs: Long) {
|
||||
//
|
||||
// }
|
||||
//}
|
||||
|
||||
class CustomDecoder : SubtitleDecoder {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "CustomDecoder"
|
||||
}
|
||||
|
||||
var realDecoder: SimpleSubtitleDecoder? = null
|
||||
|
||||
override fun getName(): String {
|
||||
return realDecoder?.name ?: this::class.java.name
|
||||
}
|
||||
|
||||
override fun dequeueInputBuffer(): SubtitleInputBuffer {
|
||||
return realDecoder?.dequeueInputBuffer() ?: SubtitleInputBuffer()
|
||||
}
|
||||
|
||||
override fun queueInputBuffer(inputBuffer: SubtitleInputBuffer) {
|
||||
println("STARTTT ${inputBuffer.format?.language}")
|
||||
if (realDecoder == null)
|
||||
inputBuffer.data?.let { data ->
|
||||
|
||||
val pos = data.position()
|
||||
data.position(0)
|
||||
val arr = ByteArray(minOf(data.remaining(), 100))
|
||||
data.get(arr)
|
||||
data.position(pos)
|
||||
|
||||
val str = arr.decodeToString().trimStart()
|
||||
Log.i(TAG, "Got data from queueInputBuffer")
|
||||
Log.i(TAG, "first string is $str")
|
||||
|
||||
//https://github.com/LagradOst/CloudStream-2/blob/ddd774ee66810137ff7bd65dae70bcf3ba2d2489/CloudStreamForms/CloudStreamForms/Script/MainChrome.cs#L388
|
||||
realDecoder = when {
|
||||
str.startsWith("WEBVTT") -> WebvttDecoder()
|
||||
str.startsWith("<?xml version=\"") -> TtmlDecoder()
|
||||
str.startsWith("[Script Info]") || str.startsWith("Title:") -> SsaDecoder()
|
||||
str.startsWith("1") -> SubripDecoder()
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
realDecoder?.dequeueInputBuffer().also { println("RETURNED ddddd") }
|
||||
}
|
||||
|
||||
override fun dequeueOutputBuffer(): SubtitleOutputBuffer? {
|
||||
return realDecoder?.dequeueOutputBuffer()
|
||||
}
|
||||
|
||||
override fun flush() {
|
||||
realDecoder?.flush()
|
||||
}
|
||||
|
||||
override fun release() {
|
||||
realDecoder?.release()
|
||||
}
|
||||
|
||||
override fun setPositionUs(positionUs: Long) {
|
||||
realDecoder?.setPositionUs(positionUs)
|
||||
}
|
||||
}
|
||||
|
||||
/** See https://github.com/google/ExoPlayer/blob/release-v2/library/core/src/main/java/com/google/android/exoplayer2/text/SubtitleDecoderFactory.java */
|
||||
class CustomSubtitleDecoderFactory : SubtitleDecoderFactory {
|
||||
|
@ -55,38 +83,39 @@ class CustomSubtitleDecoderFactory : SubtitleDecoderFactory {
|
|||
MimeTypes.APPLICATION_TTML,
|
||||
MimeTypes.APPLICATION_MP4VTT,
|
||||
MimeTypes.APPLICATION_SUBRIP,
|
||||
MimeTypes.APPLICATION_TX3G,
|
||||
MimeTypes.APPLICATION_CEA608,
|
||||
MimeTypes.APPLICATION_MP4CEA608,
|
||||
MimeTypes.APPLICATION_CEA708,
|
||||
MimeTypes.APPLICATION_DVBSUBS,
|
||||
MimeTypes.APPLICATION_PGS,
|
||||
MimeTypes.TEXT_EXOPLAYER_CUES
|
||||
//MimeTypes.APPLICATION_TX3G,
|
||||
//MimeTypes.APPLICATION_CEA608,
|
||||
//MimeTypes.APPLICATION_MP4CEA608,
|
||||
//MimeTypes.APPLICATION_CEA708,
|
||||
//MimeTypes.APPLICATION_DVBSUBS,
|
||||
//MimeTypes.APPLICATION_PGS,
|
||||
//MimeTypes.TEXT_EXOPLAYER_CUES
|
||||
).contains(format.sampleMimeType)
|
||||
}
|
||||
|
||||
override fun createDecoder(format: Format): SubtitleDecoder {
|
||||
return when (val mimeType = format.sampleMimeType) {
|
||||
MimeTypes.TEXT_VTT -> WebvttDecoder()
|
||||
MimeTypes.TEXT_SSA -> SsaDecoder(format.initializationData)
|
||||
MimeTypes.APPLICATION_MP4VTT -> Mp4WebvttDecoder()
|
||||
MimeTypes.APPLICATION_TTML -> TtmlDecoder()
|
||||
MimeTypes.APPLICATION_SUBRIP -> SubripDecoder()
|
||||
MimeTypes.APPLICATION_TX3G -> Tx3gDecoder(format.initializationData)
|
||||
MimeTypes.APPLICATION_CEA608, MimeTypes.APPLICATION_MP4CEA608 -> return Cea608Decoder(
|
||||
mimeType,
|
||||
format.accessibilityChannel,
|
||||
Cea608Decoder.MIN_DATA_CHANNEL_TIMEOUT_MS
|
||||
)
|
||||
MimeTypes.APPLICATION_CEA708 -> Cea708Decoder(
|
||||
format.accessibilityChannel,
|
||||
format.initializationData
|
||||
)
|
||||
MimeTypes.APPLICATION_DVBSUBS -> DvbDecoder(format.initializationData)
|
||||
MimeTypes.APPLICATION_PGS -> PgsDecoder()
|
||||
MimeTypes.TEXT_EXOPLAYER_CUES -> ExoplayerCuesDecoder()
|
||||
// Default WebVttDecoder
|
||||
else -> WebvttDecoder()
|
||||
}
|
||||
return CustomDecoder()
|
||||
//return when (val mimeType = format.sampleMimeType) {
|
||||
// MimeTypes.TEXT_VTT -> WebvttDecoder()
|
||||
// MimeTypes.TEXT_SSA -> SsaDecoder(format.initializationData)
|
||||
// MimeTypes.APPLICATION_MP4VTT -> Mp4WebvttDecoder()
|
||||
// MimeTypes.APPLICATION_TTML -> TtmlDecoder()
|
||||
// MimeTypes.APPLICATION_SUBRIP -> SubripDecoder()
|
||||
// MimeTypes.APPLICATION_TX3G -> Tx3gDecoder(format.initializationData)
|
||||
// MimeTypes.APPLICATION_CEA608, MimeTypes.APPLICATION_MP4CEA608 -> return Cea608Decoder(
|
||||
// mimeType,
|
||||
// format.accessibilityChannel,
|
||||
// Cea608Decoder.MIN_DATA_CHANNEL_TIMEOUT_MS
|
||||
// )
|
||||
// MimeTypes.APPLICATION_CEA708 -> Cea708Decoder(
|
||||
// format.accessibilityChannel,
|
||||
// format.initializationData
|
||||
// )
|
||||
// MimeTypes.APPLICATION_DVBSUBS -> DvbDecoder(format.initializationData)
|
||||
// MimeTypes.APPLICATION_PGS -> PgsDecoder()
|
||||
// MimeTypes.TEXT_EXOPLAYER_CUES -> ExoplayerCuesDecoder()
|
||||
// // Default WebVttDecoder
|
||||
// else -> WebvttDecoder()
|
||||
//}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue