forked from recloudstream/cloudstream
		
	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…
	
	Add table
		Add a link
		
	
		Reference in a new issue