mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
fixed subtitles
This commit is contained in:
parent
0849bffe49
commit
3f1e398ae8
2 changed files with 62 additions and 47 deletions
|
@ -11,8 +11,6 @@ import com.google.android.exoplayer2.extractor.ExtractorsFactory
|
||||||
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory
|
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory
|
||||||
import com.google.android.exoplayer2.source.MergingMediaSource
|
import com.google.android.exoplayer2.source.MergingMediaSource
|
||||||
import com.google.android.exoplayer2.source.ProgressiveMediaSource
|
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.text.SubtitleExtractor
|
||||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
|
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelector
|
import com.google.android.exoplayer2.trackselection.TrackSelector
|
||||||
|
@ -285,7 +283,7 @@ class CS3IPlayer : IPlayer {
|
||||||
return DefaultDataSourceFactory(this, USER_AGENT)
|
return DefaultDataSourceFactory(this, USER_AGENT)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSubSources(
|
/*private fun getSubSources(
|
||||||
onlineSourceFactory: DataSource.Factory?,
|
onlineSourceFactory: DataSource.Factory?,
|
||||||
offlineSourceFactory: DataSource.Factory?,
|
offlineSourceFactory: DataSource.Factory?,
|
||||||
subHelper: PlayerSubtitleHelper,
|
subHelper: PlayerSubtitleHelper,
|
||||||
|
@ -324,7 +322,7 @@ class CS3IPlayer : IPlayer {
|
||||||
}
|
}
|
||||||
println("SUBSRC: ${subSources.size} activeSubtitles : ${activeSubtitles.size} of ${subHelper.getAllSubtitles().size} ")
|
println("SUBSRC: ${subSources.size} activeSubtitles : ${activeSubtitles.size} of ${subHelper.getAllSubtitles().size} ")
|
||||||
return Pair(subSources, activeSubtitles)
|
return Pair(subSources, activeSubtitles)
|
||||||
}
|
}*/
|
||||||
|
|
||||||
private fun getCache(context: Context, cacheSize: Long): SimpleCache? {
|
private fun getCache(context: Context, cacheSize: Long): SimpleCache? {
|
||||||
return try {
|
return try {
|
||||||
|
@ -587,33 +585,47 @@ class CS3IPlayer : IPlayer {
|
||||||
* https://github.com/google/ExoPlayer/blob/029a2b27cbdc27cf9d51d4a73ebeb503968849f6/library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactory.java
|
* https://github.com/google/ExoPlayer/blob/029a2b27cbdc27cf9d51d4a73ebeb503968849f6/library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactory.java
|
||||||
* */
|
* */
|
||||||
private fun createProgressiveMediaSources(
|
private fun createProgressiveMediaSources(
|
||||||
subSources: List<SingleSampleMediaSource>,
|
subHelper: PlayerSubtitleHelper,
|
||||||
factory: DataSource.Factory
|
offlineSourceFactory: DataSource.Factory?,
|
||||||
): List<ProgressiveMediaSource> {
|
onlineSourceFactory: DataSource.Factory?,
|
||||||
val extractorFactory = ExtractorsFactory {
|
): Pair<List<SubtitleData>, List<ProgressiveMediaSource>> {
|
||||||
subSources.map {
|
val activeSubtitles = ArrayList<SubtitleData>()
|
||||||
val currentSub = it.mediaItem.localConfiguration?.subtitleConfigurations?.firstOrNull()
|
|
||||||
|
return Pair(activeSubtitles, subHelper.getAllSubtitles().mapNotNull { sub ->
|
||||||
val format = Format.Builder()
|
val format = Format.Builder()
|
||||||
.setSampleMimeType(currentSub?.mimeType)
|
.setSampleMimeType(sub.mimeType)
|
||||||
.setLanguage(currentSub?.language)
|
.setLanguage("_${sub.name}")
|
||||||
.setLabel(currentSub?.label)
|
.setSelectionFlags(C.SELECTION_FLAG_DEFAULT)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
val extractorFactory = ExtractorsFactory {
|
||||||
|
arrayOf(
|
||||||
SubtitleExtractor(
|
SubtitleExtractor(
|
||||||
CustomSubtitleDecoderFactory().createDecoder(format), format
|
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)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val factory = when (sub.origin) {
|
||||||
|
SubtitleOrigin.DOWNLOADED_FILE -> {
|
||||||
|
activeSubtitles.add(sub)
|
||||||
|
offlineSourceFactory
|
||||||
|
}
|
||||||
|
SubtitleOrigin.URL -> {
|
||||||
|
activeSubtitles.add(sub)
|
||||||
|
onlineSourceFactory
|
||||||
|
}
|
||||||
|
SubtitleOrigin.OPEN_SUBTITLES -> {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
} ?: return@mapNotNull null
|
||||||
|
|
||||||
|
return@mapNotNull ProgressiveMediaSource.Factory(factory, extractorFactory)
|
||||||
|
.createMediaSource(
|
||||||
|
MediaItem.fromUri(sub.url)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadOfflinePlayer(context: Context, data: ExtractorUri) {
|
private fun loadOfflinePlayer(context: Context, data: ExtractorUri) {
|
||||||
|
@ -623,14 +635,12 @@ class CS3IPlayer : IPlayer {
|
||||||
|
|
||||||
val mediaItem = getMediaItem(MimeTypes.VIDEO_MP4, data.uri)
|
val mediaItem = getMediaItem(MimeTypes.VIDEO_MP4, data.uri)
|
||||||
val offlineSourceFactory = context.createOfflineSource()
|
val offlineSourceFactory = context.createOfflineSource()
|
||||||
val (subSources, activeSubtitles) = getSubSources(
|
|
||||||
offlineSourceFactory,
|
|
||||||
offlineSourceFactory,
|
|
||||||
subtitleHelper
|
|
||||||
)
|
|
||||||
|
|
||||||
val progressiveMediaSources =
|
val (activeSubtitles, progressiveMediaSources) = createProgressiveMediaSources(
|
||||||
createProgressiveMediaSources(subSources, offlineSourceFactory)
|
subtitleHelper,
|
||||||
|
offlineSourceFactory,
|
||||||
|
offlineSourceFactory,
|
||||||
|
)
|
||||||
|
|
||||||
subtitleHelper.setActiveSubtitles(activeSubtitles.toSet())
|
subtitleHelper.setActiveSubtitles(activeSubtitles.toSet())
|
||||||
loadExo(context, mediaItem, progressiveMediaSources)
|
loadExo(context, mediaItem, progressiveMediaSources)
|
||||||
|
@ -666,15 +676,12 @@ class CS3IPlayer : IPlayer {
|
||||||
val onlineSourceFactory = createOnlineSource(link)
|
val onlineSourceFactory = createOnlineSource(link)
|
||||||
val offlineSourceFactory = context.createOfflineSource()
|
val offlineSourceFactory = context.createOfflineSource()
|
||||||
|
|
||||||
val (subSources, activeSubtitles) = getSubSources(
|
val (activeSubtitles, progressiveMediaSources) = createProgressiveMediaSources(
|
||||||
onlineSourceFactory,
|
subtitleHelper,
|
||||||
offlineSourceFactory,
|
offlineSourceFactory,
|
||||||
subtitleHelper
|
onlineSourceFactory,
|
||||||
)
|
)
|
||||||
|
|
||||||
val progressiveMediaSources =
|
|
||||||
createProgressiveMediaSources(subSources, onlineSourceFactory)
|
|
||||||
|
|
||||||
subtitleHelper.setActiveSubtitles(activeSubtitles.toSet())
|
subtitleHelper.setActiveSubtitles(activeSubtitles.toSet())
|
||||||
|
|
||||||
if (simpleCache == null)
|
if (simpleCache == null)
|
||||||
|
|
|
@ -2,35 +2,37 @@ package com.lagradost.cloudstream3.ui.player
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.google.android.exoplayer2.Format
|
import com.google.android.exoplayer2.Format
|
||||||
import com.google.android.exoplayer2.text.*
|
import com.google.android.exoplayer2.text.SubtitleDecoder
|
||||||
|
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.ssa.SsaDecoder
|
import com.google.android.exoplayer2.text.ssa.SsaDecoder
|
||||||
import com.google.android.exoplayer2.text.subrip.SubripDecoder
|
import com.google.android.exoplayer2.text.subrip.SubripDecoder
|
||||||
import com.google.android.exoplayer2.text.ttml.TtmlDecoder
|
import com.google.android.exoplayer2.text.ttml.TtmlDecoder
|
||||||
import com.google.android.exoplayer2.text.webvtt.WebvttDecoder
|
import com.google.android.exoplayer2.text.webvtt.WebvttDecoder
|
||||||
import com.google.android.exoplayer2.util.MimeTypes
|
import com.google.android.exoplayer2.util.MimeTypes
|
||||||
import okio.ByteString.Companion.toByteString
|
|
||||||
import java.nio.charset.Charset
|
|
||||||
|
|
||||||
|
|
||||||
class CustomDecoder : SubtitleDecoder {
|
class CustomDecoder : SubtitleDecoder {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "CustomDecoder"
|
private const val TAG = "CustomDecoder"
|
||||||
}
|
}
|
||||||
|
|
||||||
var realDecoder: SimpleSubtitleDecoder? = null
|
var realDecoder: SubtitleDecoder? = null
|
||||||
|
|
||||||
override fun getName(): String {
|
override fun getName(): String {
|
||||||
return realDecoder?.name ?: this::class.java.name
|
return realDecoder?.name ?: this::class.java.name
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dequeueInputBuffer(): SubtitleInputBuffer {
|
override fun dequeueInputBuffer(): SubtitleInputBuffer {
|
||||||
|
Log.i(TAG, "dequeueInputBuffer")
|
||||||
return realDecoder?.dequeueInputBuffer() ?: SubtitleInputBuffer()
|
return realDecoder?.dequeueInputBuffer() ?: SubtitleInputBuffer()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun queueInputBuffer(inputBuffer: SubtitleInputBuffer) {
|
override fun queueInputBuffer(inputBuffer: SubtitleInputBuffer) {
|
||||||
println("STARTTT ${inputBuffer.format?.language}")
|
Log.i(TAG, "queueInputBuffer")
|
||||||
if (realDecoder == null)
|
|
||||||
|
if (realDecoder == null) {
|
||||||
inputBuffer.data?.let { data ->
|
inputBuffer.data?.let { data ->
|
||||||
|
|
||||||
val pos = data.position()
|
val pos = data.position()
|
||||||
|
@ -51,9 +53,15 @@ class CustomDecoder : SubtitleDecoder {
|
||||||
str.startsWith("1") -> SubripDecoder()
|
str.startsWith("1") -> SubripDecoder()
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
realDecoder?.dequeueInputBuffer().also { println("RETURNED ddddd") }
|
realDecoder?.dequeueInputBuffer()?.let { buff ->
|
||||||
|
buff.data = data
|
||||||
|
realDecoder?.queueInputBuffer(buff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
realDecoder?.dequeueInputBuffer()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dequeueOutputBuffer(): SubtitleOutputBuffer? {
|
override fun dequeueOutputBuffer(): SubtitleOutputBuffer? {
|
||||||
|
|
Loading…
Reference in a new issue