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 android.widget.FrameLayout | ||||||
| import com.google.android.exoplayer2.* | import com.google.android.exoplayer2.* | ||||||
| import com.google.android.exoplayer2.database.StandaloneDatabaseProvider | 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.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.SingleSampleMediaSource | 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.DefaultTrackSelector | ||||||
| import com.google.android.exoplayer2.trackselection.TrackSelector | import com.google.android.exoplayer2.trackselection.TrackSelector | ||||||
| import com.google.android.exoplayer2.ui.SubtitleView | import com.google.android.exoplayer2.ui.SubtitleView | ||||||
|  | @ -367,7 +371,7 @@ class CS3IPlayer : IPlayer { | ||||||
|         private fun buildExoPlayer( |         private fun buildExoPlayer( | ||||||
|             context: Context, |             context: Context, | ||||||
|             mediaItem: MediaItem, |             mediaItem: MediaItem, | ||||||
|             subSources: List<SingleSampleMediaSource>, |             subSources: List<ProgressiveMediaSource>, | ||||||
|             currentWindow: Int, |             currentWindow: Int, | ||||||
|             playbackPosition: Long, |             playbackPosition: Long, | ||||||
|             playBackSpeed: Float, |             playBackSpeed: Float, | ||||||
|  | @ -466,7 +470,7 @@ class CS3IPlayer : IPlayer { | ||||||
|     private fun loadExo( |     private fun loadExo( | ||||||
|         context: Context, |         context: Context, | ||||||
|         mediaItem: MediaItem, |         mediaItem: MediaItem, | ||||||
|         subSources: List<SingleSampleMediaSource>, |         subSources: List<ProgressiveMediaSource>, | ||||||
|         cacheFactory: CacheDataSource.Factory? = null |         cacheFactory: CacheDataSource.Factory? = null | ||||||
|     ) { |     ) { | ||||||
|         Log.i(TAG, "loadExo") |         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) { |     private fun loadOfflinePlayer(context: Context, data: ExtractorUri) { | ||||||
|         Log.i(TAG, "loadOfflinePlayer") |         Log.i(TAG, "loadOfflinePlayer") | ||||||
|         try { |         try { | ||||||
|  | @ -591,8 +628,12 @@ class CS3IPlayer : IPlayer { | ||||||
|                 offlineSourceFactory, |                 offlineSourceFactory, | ||||||
|                 subtitleHelper |                 subtitleHelper | ||||||
|             ) |             ) | ||||||
|  | 
 | ||||||
|  |             val progressiveMediaSources = | ||||||
|  |                 createProgressiveMediaSources(subSources, offlineSourceFactory) | ||||||
|  | 
 | ||||||
|             subtitleHelper.setActiveSubtitles(activeSubtitles.toSet()) |             subtitleHelper.setActiveSubtitles(activeSubtitles.toSet()) | ||||||
|             loadExo(context, mediaItem, subSources) |             loadExo(context, mediaItem, progressiveMediaSources) | ||||||
|         } catch (e: Exception) { |         } catch (e: Exception) { | ||||||
|             Log.e(TAG, "loadOfflinePlayer error", e) |             Log.e(TAG, "loadOfflinePlayer error", e) | ||||||
|             playerError?.invoke(e) |             playerError?.invoke(e) | ||||||
|  | @ -630,6 +671,10 @@ class CS3IPlayer : IPlayer { | ||||||
|                 offlineSourceFactory, |                 offlineSourceFactory, | ||||||
|                 subtitleHelper |                 subtitleHelper | ||||||
|             ) |             ) | ||||||
|  | 
 | ||||||
|  |             val progressiveMediaSources = | ||||||
|  |                 createProgressiveMediaSources(subSources, onlineSourceFactory) | ||||||
|  | 
 | ||||||
|             subtitleHelper.setActiveSubtitles(activeSubtitles.toSet()) |             subtitleHelper.setActiveSubtitles(activeSubtitles.toSet()) | ||||||
| 
 | 
 | ||||||
|             if (simpleCache == null) |             if (simpleCache == null) | ||||||
|  | @ -640,7 +685,7 @@ class CS3IPlayer : IPlayer { | ||||||
|                 setUpstreamDataSourceFactory(onlineSourceFactory) |                 setUpstreamDataSourceFactory(onlineSourceFactory) | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             loadExo(context, mediaItem, subSources, cacheFactory) |             loadExo(context, mediaItem, progressiveMediaSources, cacheFactory) | ||||||
|         } catch (e: Exception) { |         } catch (e: Exception) { | ||||||
|             Log.e(TAG, "loadOnlinePlayer error", e) |             Log.e(TAG, "loadOnlinePlayer error", e) | ||||||
|             playerError?.invoke(e) |             playerError?.invoke(e) | ||||||
|  |  | ||||||
|  | @ -1,49 +1,77 @@ | ||||||
| package com.lagradost.cloudstream3.ui.player | package com.lagradost.cloudstream3.ui.player | ||||||
| 
 | 
 | ||||||
|  | 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.* | ||||||
| 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.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.subrip.SubripDecoder | ||||||
| import com.google.android.exoplayer2.text.tx3g.Tx3gDecoder | import com.google.android.exoplayer2.text.ttml.TtmlDecoder | ||||||
| import com.google.android.exoplayer2.text.cea.Cea608Decoder | import com.google.android.exoplayer2.text.webvtt.WebvttDecoder | ||||||
| import com.google.android.exoplayer2.text.cea.Cea708Decoder | import com.google.android.exoplayer2.util.MimeTypes | ||||||
| import com.google.android.exoplayer2.text.dvb.DvbDecoder | import okio.ByteString.Companion.toByteString | ||||||
| import com.google.android.exoplayer2.text.pgs.PgsDecoder | import java.nio.charset.Charset | ||||||
| import java.lang.IllegalArgumentException |  | ||||||
| 
 | 
 | ||||||
| //class CustomDecoder : SubtitleDecoder { | 
 | ||||||
| //    override fun getName(): String { | class CustomDecoder : SubtitleDecoder { | ||||||
| // | 
 | ||||||
| //    } |     companion object { | ||||||
| // |         private const val TAG = "CustomDecoder" | ||||||
| //    override fun dequeueInputBuffer(): SubtitleInputBuffer? { |     } | ||||||
| // | 
 | ||||||
| //    } |     var realDecoder: SimpleSubtitleDecoder? = null | ||||||
| // | 
 | ||||||
| //    override fun queueInputBuffer(inputBuffer: SubtitleInputBuffer) { |     override fun getName(): String { | ||||||
| // |         return realDecoder?.name ?: this::class.java.name | ||||||
| //    } |     } | ||||||
| // | 
 | ||||||
| //    override fun dequeueOutputBuffer(): SubtitleOutputBuffer? { |     override fun dequeueInputBuffer(): SubtitleInputBuffer { | ||||||
| // |         return realDecoder?.dequeueInputBuffer() ?: SubtitleInputBuffer() | ||||||
| //    } |     } | ||||||
| // | 
 | ||||||
| //    override fun flush() { |     override fun queueInputBuffer(inputBuffer: SubtitleInputBuffer) { | ||||||
| // |         println("STARTTT ${inputBuffer.format?.language}") | ||||||
| //    } |         if (realDecoder == null) | ||||||
| // |             inputBuffer.data?.let { data -> | ||||||
| //    override fun release() { | 
 | ||||||
| // |                 val pos = data.position() | ||||||
| //    } |                 data.position(0) | ||||||
| // |                 val arr = ByteArray(minOf(data.remaining(), 100)) | ||||||
| //    override fun setPositionUs(positionUs: Long) { |                 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 */ | /** See https://github.com/google/ExoPlayer/blob/release-v2/library/core/src/main/java/com/google/android/exoplayer2/text/SubtitleDecoderFactory.java */ | ||||||
| class CustomSubtitleDecoderFactory : SubtitleDecoderFactory { | class CustomSubtitleDecoderFactory : SubtitleDecoderFactory { | ||||||
|  | @ -55,38 +83,39 @@ class CustomSubtitleDecoderFactory : SubtitleDecoderFactory { | ||||||
|             MimeTypes.APPLICATION_TTML, |             MimeTypes.APPLICATION_TTML, | ||||||
|             MimeTypes.APPLICATION_MP4VTT, |             MimeTypes.APPLICATION_MP4VTT, | ||||||
|             MimeTypes.APPLICATION_SUBRIP, |             MimeTypes.APPLICATION_SUBRIP, | ||||||
|             MimeTypes.APPLICATION_TX3G, |             //MimeTypes.APPLICATION_TX3G, | ||||||
|             MimeTypes.APPLICATION_CEA608, |             //MimeTypes.APPLICATION_CEA608, | ||||||
|             MimeTypes.APPLICATION_MP4CEA608, |             //MimeTypes.APPLICATION_MP4CEA608, | ||||||
|             MimeTypes.APPLICATION_CEA708, |             //MimeTypes.APPLICATION_CEA708, | ||||||
|             MimeTypes.APPLICATION_DVBSUBS, |             //MimeTypes.APPLICATION_DVBSUBS, | ||||||
|             MimeTypes.APPLICATION_PGS, |             //MimeTypes.APPLICATION_PGS, | ||||||
|             MimeTypes.TEXT_EXOPLAYER_CUES |             //MimeTypes.TEXT_EXOPLAYER_CUES | ||||||
|         ).contains(format.sampleMimeType) |         ).contains(format.sampleMimeType) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun createDecoder(format: Format): SubtitleDecoder { |     override fun createDecoder(format: Format): SubtitleDecoder { | ||||||
|         return when (val mimeType = format.sampleMimeType) { |         return CustomDecoder() | ||||||
|             MimeTypes.TEXT_VTT -> WebvttDecoder() |         //return when (val mimeType = format.sampleMimeType) { | ||||||
|             MimeTypes.TEXT_SSA -> SsaDecoder(format.initializationData) |         //    MimeTypes.TEXT_VTT -> WebvttDecoder() | ||||||
|             MimeTypes.APPLICATION_MP4VTT -> Mp4WebvttDecoder() |         //    MimeTypes.TEXT_SSA -> SsaDecoder(format.initializationData) | ||||||
|             MimeTypes.APPLICATION_TTML -> TtmlDecoder() |         //    MimeTypes.APPLICATION_MP4VTT -> Mp4WebvttDecoder() | ||||||
|             MimeTypes.APPLICATION_SUBRIP -> SubripDecoder() |         //    MimeTypes.APPLICATION_TTML -> TtmlDecoder() | ||||||
|             MimeTypes.APPLICATION_TX3G -> Tx3gDecoder(format.initializationData) |         //    MimeTypes.APPLICATION_SUBRIP -> SubripDecoder() | ||||||
|             MimeTypes.APPLICATION_CEA608, MimeTypes.APPLICATION_MP4CEA608 -> return Cea608Decoder( |         //    MimeTypes.APPLICATION_TX3G -> Tx3gDecoder(format.initializationData) | ||||||
|                 mimeType, |         //    MimeTypes.APPLICATION_CEA608, MimeTypes.APPLICATION_MP4CEA608 -> return Cea608Decoder( | ||||||
|                 format.accessibilityChannel, |         //        mimeType, | ||||||
|                 Cea608Decoder.MIN_DATA_CHANNEL_TIMEOUT_MS |         //        format.accessibilityChannel, | ||||||
|             ) |         //        Cea608Decoder.MIN_DATA_CHANNEL_TIMEOUT_MS | ||||||
|             MimeTypes.APPLICATION_CEA708 -> Cea708Decoder( |         //    ) | ||||||
|                 format.accessibilityChannel, |         //    MimeTypes.APPLICATION_CEA708 -> Cea708Decoder( | ||||||
|                 format.initializationData |         //        format.accessibilityChannel, | ||||||
|             ) |         //        format.initializationData | ||||||
|             MimeTypes.APPLICATION_DVBSUBS -> DvbDecoder(format.initializationData) |         //    ) | ||||||
|             MimeTypes.APPLICATION_PGS -> PgsDecoder() |         //    MimeTypes.APPLICATION_DVBSUBS -> DvbDecoder(format.initializationData) | ||||||
|             MimeTypes.TEXT_EXOPLAYER_CUES -> ExoplayerCuesDecoder() |         //    MimeTypes.APPLICATION_PGS -> PgsDecoder() | ||||||
|             // Default WebVttDecoder |         //    MimeTypes.TEXT_EXOPLAYER_CUES -> ExoplayerCuesDecoder() | ||||||
|             else -> WebvttDecoder() |         //    // Default WebVttDecoder | ||||||
|         } |         //    else -> WebvttDecoder() | ||||||
|  |         //} | ||||||
|     } |     } | ||||||
| } | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue