mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
Unexoplayered IPlayer
This commit is contained in:
parent
e855ccfb25
commit
5c1ae65835
4 changed files with 99 additions and 50 deletions
|
@ -8,6 +8,8 @@ import android.util.Log
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import com.google.android.exoplayer2.*
|
import com.google.android.exoplayer2.*
|
||||||
|
import com.google.android.exoplayer2.C.TRACK_TYPE_AUDIO
|
||||||
|
import com.google.android.exoplayer2.C.TRACK_TYPE_VIDEO
|
||||||
import com.google.android.exoplayer2.database.StandaloneDatabaseProvider
|
import com.google.android.exoplayer2.database.StandaloneDatabaseProvider
|
||||||
import com.google.android.exoplayer2.ext.okhttp.OkHttpDataSource
|
import com.google.android.exoplayer2.ext.okhttp.OkHttpDataSource
|
||||||
import com.google.android.exoplayer2.source.*
|
import com.google.android.exoplayer2.source.*
|
||||||
|
@ -212,7 +214,7 @@ class CS3IPlayer : IPlayer {
|
||||||
|
|
||||||
var currentSubtitles: SubtitleData? = null
|
var currentSubtitles: SubtitleData? = null
|
||||||
|
|
||||||
override fun setExoplayerVideoSize(width: Int, height: Int) {
|
override fun setMaxVideoSize(width: Int, height: Int) {
|
||||||
exoPlayer?.trackSelectionParameters = exoPlayer?.trackSelectionParameters
|
exoPlayer?.trackSelectionParameters = exoPlayer?.trackSelectionParameters
|
||||||
?.buildUpon()
|
?.buildUpon()
|
||||||
?.setMaxVideoSize(width, height)
|
?.setMaxVideoSize(width, height)
|
||||||
|
@ -220,7 +222,7 @@ class CS3IPlayer : IPlayer {
|
||||||
?: return
|
?: return
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setExoplayerAudioTrack(trackLanguage: String?) {
|
override fun setPreferredAudioTrack(trackLanguage: String?) {
|
||||||
preferredAudioTrackLanguage = trackLanguage
|
preferredAudioTrackLanguage = trackLanguage
|
||||||
exoPlayer?.trackSelectionParameters = exoPlayer?.trackSelectionParameters
|
exoPlayer?.trackSelectionParameters = exoPlayer?.trackSelectionParameters
|
||||||
?.buildUpon()
|
?.buildUpon()
|
||||||
|
@ -229,11 +231,52 @@ class CS3IPlayer : IPlayer {
|
||||||
?: return
|
?: return
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getExoplayerTracks(): ExoplayerTracks {
|
|
||||||
return ExoplayerTracks(
|
/**
|
||||||
exoPlayer?.videoFormat,
|
* Gets all supported formats in a list
|
||||||
exoPlayer?.audioFormat,
|
* */
|
||||||
exoPlayer?.currentTracksInfo?.trackGroupInfos ?: emptyList()
|
private fun List<TracksInfo.TrackGroupInfo>.getFormats(): List<Format> {
|
||||||
|
return this.map {
|
||||||
|
(0 until it.trackGroup.length).mapNotNull { i ->
|
||||||
|
if (it.isSupported)
|
||||||
|
it.trackGroup.getFormat(i) // to it.isSelected
|
||||||
|
else null
|
||||||
|
}
|
||||||
|
}.flatten()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Format.toAudioTrack(): AudioTrack {
|
||||||
|
return AudioTrack(
|
||||||
|
this.id,
|
||||||
|
this.label,
|
||||||
|
// isPlaying,
|
||||||
|
this.language
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Format.toVideoTrack(): VideoTrack {
|
||||||
|
return VideoTrack(
|
||||||
|
this.id,
|
||||||
|
this.label,
|
||||||
|
// isPlaying,
|
||||||
|
this.language,
|
||||||
|
this.width,
|
||||||
|
this.height
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getVideoTracks(): CurrentTracks {
|
||||||
|
val allTracks = exoPlayer?.currentTracksInfo?.trackGroupInfos ?: emptyList()
|
||||||
|
val videoTracks = allTracks.filter { it.trackType == TRACK_TYPE_VIDEO }.getFormats()
|
||||||
|
.map { it.toVideoTrack() }
|
||||||
|
val audioTracks = allTracks.filter { it.trackType == TRACK_TYPE_AUDIO }.getFormats()
|
||||||
|
.map { it.toAudioTrack() }
|
||||||
|
|
||||||
|
return CurrentTracks(
|
||||||
|
exoPlayer?.videoFormat?.toVideoTrack(),
|
||||||
|
exoPlayer?.audioFormat?.toAudioTrack(),
|
||||||
|
videoTracks,
|
||||||
|
audioTracks
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,12 +113,8 @@ class GeneratorPlayer : FullScreenPlayer() {
|
||||||
|
|
||||||
override fun embeddedSubtitlesFetched(subtitles: List<SubtitleData>) {
|
override fun embeddedSubtitlesFetched(subtitles: List<SubtitleData>) {
|
||||||
viewModel.addSubtitles(subtitles.toSet())
|
viewModel.addSubtitles(subtitles.toSet())
|
||||||
|
val tracks = player.getVideoTracks()
|
||||||
val tracks = player.getExoplayerTracks().allTracks
|
player_tracks_btt?.isVisible = tracks.allVideoTracks.size > 1 || tracks.allAudioTracks.size > 1
|
||||||
val videoTracks = tracks.filter { it.trackType == TRACK_TYPE_VIDEO }.getFormats().size
|
|
||||||
val audioTracks = tracks.filter { it.trackType == TRACK_TYPE_AUDIO }.getFormats().size
|
|
||||||
|
|
||||||
player_tracks_btt?.isVisible = videoTracks > 1 || audioTracks > 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun noSubtitles(): Boolean {
|
private fun noSubtitles(): Boolean {
|
||||||
|
@ -682,37 +678,19 @@ class GeneratorPlayer : FullScreenPlayer() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets all supported formats in a list
|
|
||||||
* */
|
|
||||||
private fun List<TracksInfo.TrackGroupInfo>.getFormats(): List<Format> {
|
|
||||||
return this.map {
|
|
||||||
(0 until it.trackGroup.length).mapNotNull { i ->
|
|
||||||
if (it.isSupported)
|
|
||||||
it.trackGroup.getFormat(i) // to it.isSelected
|
|
||||||
else null
|
|
||||||
}
|
|
||||||
}.flatten()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun showTracksDialogue() {
|
override fun showTracksDialogue() {
|
||||||
try {
|
try {
|
||||||
//println("CURRENT SELECTED :$currentSelectedSubtitles of $currentSubs")
|
//println("CURRENT SELECTED :$currentSelectedSubtitles of $currentSubs")
|
||||||
context?.let { ctx ->
|
context?.let { ctx ->
|
||||||
val tracks = player.getExoplayerTracks()
|
val tracks = player.getVideoTracks()
|
||||||
|
|
||||||
val isPlaying = player.getIsPlaying()
|
val isPlaying = player.getIsPlaying()
|
||||||
player.handleEvent(CSPlayerEvent.Pause)
|
player.handleEvent(CSPlayerEvent.Pause)
|
||||||
|
|
||||||
val currentVideoTracks = tracks.allTracks.filter {
|
val currentVideoTracks = tracks.allVideoTracks.sortedBy {
|
||||||
it.trackType == TRACK_TYPE_VIDEO
|
it.height?.times(-1)
|
||||||
}.getFormats().sortedBy {
|
|
||||||
-it.height
|
|
||||||
}
|
}
|
||||||
|
val currentAudioTracks = tracks.allAudioTracks
|
||||||
val currentAudioTracks = tracks.allTracks.filter {
|
|
||||||
it.trackType == TRACK_TYPE_AUDIO
|
|
||||||
}.getFormats()
|
|
||||||
|
|
||||||
val trackBuilder = AlertDialog.Builder(ctx, R.style.AlertDialogCustomBlack)
|
val trackBuilder = AlertDialog.Builder(ctx, R.style.AlertDialogCustomBlack)
|
||||||
.setView(R.layout.player_select_tracks)
|
.setView(R.layout.player_select_tracks)
|
||||||
|
@ -747,10 +725,10 @@ class GeneratorPlayer : FullScreenPlayer() {
|
||||||
videosList.adapter = videosArrayAdapter
|
videosList.adapter = videosArrayAdapter
|
||||||
|
|
||||||
// Sometimes the data is not the same because some data gets resolved at different stages i think
|
// Sometimes the data is not the same because some data gets resolved at different stages i think
|
||||||
var videoIndex = currentVideoTracks.indexOf(tracks.currentVideoFormat).takeIf {
|
var videoIndex = currentVideoTracks.indexOf(tracks.currentVideoTrack).takeIf {
|
||||||
it != -1
|
it != -1
|
||||||
} ?: currentVideoTracks.indexOfFirst {
|
} ?: currentVideoTracks.indexOfFirst {
|
||||||
tracks.currentVideoFormat?.id == it.id
|
tracks.currentVideoTrack?.id == it.id
|
||||||
}
|
}
|
||||||
|
|
||||||
videosList.setSelection(videoIndex)
|
videosList.setSelection(videoIndex)
|
||||||
|
@ -766,10 +744,10 @@ class GeneratorPlayer : FullScreenPlayer() {
|
||||||
// selectTracksDialog = null
|
// selectTracksDialog = null
|
||||||
}
|
}
|
||||||
|
|
||||||
var audioIndexStart = currentAudioTracks.indexOf(tracks.currentAudioFormat).takeIf {
|
var audioIndexStart = currentAudioTracks.indexOf(tracks.currentAudioTrack).takeIf {
|
||||||
it != -1
|
it != -1
|
||||||
} ?: currentVideoTracks.indexOfFirst {
|
} ?: currentVideoTracks.indexOfFirst {
|
||||||
tracks.currentAudioFormat?.id == it.id
|
tracks.currentAudioTrack?.id == it.id
|
||||||
}
|
}
|
||||||
|
|
||||||
val audioArrayAdapter =
|
val audioArrayAdapter =
|
||||||
|
@ -795,7 +773,7 @@ class GeneratorPlayer : FullScreenPlayer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
tracksDialog.apply_btt?.setOnClickListener {
|
tracksDialog.apply_btt?.setOnClickListener {
|
||||||
player.setExoplayerAudioTrack(
|
player.setPreferredAudioTrack(
|
||||||
currentAudioTracks.getOrNull(audioIndexStart)?.language
|
currentAudioTracks.getOrNull(audioIndexStart)?.language
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -803,7 +781,7 @@ class GeneratorPlayer : FullScreenPlayer() {
|
||||||
val width = currentVideo?.width ?: NO_VALUE
|
val width = currentVideo?.width ?: NO_VALUE
|
||||||
val height = currentVideo?.height ?: NO_VALUE
|
val height = currentVideo?.height ?: NO_VALUE
|
||||||
if (width != NO_VALUE && height != NO_VALUE) {
|
if (width != NO_VALUE && height != NO_VALUE) {
|
||||||
player.setExoplayerVideoSize(width, height)
|
player.setMaxVideoSize(width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
tracksDialog.dismissSafe(activity)
|
tracksDialog.dismissSafe(activity)
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package com.lagradost.cloudstream3.ui.player
|
package com.lagradost.cloudstream3.ui.player
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.google.android.exoplayer2.Format
|
|
||||||
import com.google.android.exoplayer2.TracksInfo
|
|
||||||
import com.lagradost.cloudstream3.ui.subtitles.SaveCaptionStyle
|
import com.lagradost.cloudstream3.ui.subtitles.SaveCaptionStyle
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorUri
|
import com.lagradost.cloudstream3.utils.ExtractorUri
|
||||||
|
@ -48,10 +46,39 @@ enum class CSPlayerLoading {
|
||||||
//IsDone,
|
//IsDone,
|
||||||
}
|
}
|
||||||
|
|
||||||
data class ExoplayerTracks(
|
|
||||||
val currentVideoFormat: Format?,
|
interface Track {
|
||||||
val currentAudioFormat: Format?,
|
/**
|
||||||
val allTracks: List<TracksInfo.TrackGroupInfo>
|
* Unique among the class, used to check which track is used.
|
||||||
|
* VideoTrack and AudioTrack can have the same id
|
||||||
|
**/
|
||||||
|
val id: String?
|
||||||
|
val label: String?
|
||||||
|
// val isCurrentlyPlaying: Boolean
|
||||||
|
val language: String?
|
||||||
|
}
|
||||||
|
|
||||||
|
data class VideoTrack(
|
||||||
|
override val id: String?,
|
||||||
|
override val label: String?,
|
||||||
|
// override val isCurrentlyPlaying: Boolean,
|
||||||
|
override val language: String?,
|
||||||
|
val width: Int?,
|
||||||
|
val height: Int?,
|
||||||
|
) : Track
|
||||||
|
|
||||||
|
data class AudioTrack(
|
||||||
|
override val id: String?,
|
||||||
|
override val label: String?,
|
||||||
|
// override val isCurrentlyPlaying: Boolean,
|
||||||
|
override val language: String?,
|
||||||
|
) : Track
|
||||||
|
|
||||||
|
data class CurrentTracks(
|
||||||
|
val currentVideoTrack: VideoTrack?,
|
||||||
|
val currentAudioTrack: AudioTrack?,
|
||||||
|
val allVideoTracks: List<VideoTrack>,
|
||||||
|
val allAudioTracks: List<AudioTrack>,
|
||||||
)
|
)
|
||||||
|
|
||||||
class InvalidFileException(msg: String) : Exception(msg)
|
class InvalidFileException(msg: String) : Exception(msg)
|
||||||
|
@ -131,11 +158,11 @@ interface IPlayer {
|
||||||
/** Get if player is actually used */
|
/** Get if player is actually used */
|
||||||
fun isActive(): Boolean
|
fun isActive(): Boolean
|
||||||
|
|
||||||
fun getExoplayerTracks(): ExoplayerTracks
|
fun getVideoTracks(): CurrentTracks
|
||||||
|
|
||||||
/** If no parameters are set it'll default to no set size */
|
/** If no parameters are set it'll default to no set size */
|
||||||
fun setExoplayerVideoSize(width: Int = Int.MAX_VALUE, height: Int = Int.MAX_VALUE)
|
fun setMaxVideoSize(width: Int = Int.MAX_VALUE, height: Int = Int.MAX_VALUE)
|
||||||
|
|
||||||
/** If no trackLanguage is set it'll default to first track */
|
/** If no trackLanguage is set it'll default to first track */
|
||||||
fun setExoplayerAudioTrack(trackLanguage: String?)
|
fun setPreferredAudioTrack(trackLanguage: String?)
|
||||||
}
|
}
|
|
@ -117,6 +117,7 @@ class M3u8Helper {
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun m3u8Generation(m3u8: M3u8Stream, returnThis: Boolean? = true): List<M3u8Stream> {
|
suspend fun m3u8Generation(m3u8: M3u8Stream, returnThis: Boolean? = true): List<M3u8Stream> {
|
||||||
|
// return listOf(m3u8)
|
||||||
val list = mutableListOf<M3u8Stream>()
|
val list = mutableListOf<M3u8Stream>()
|
||||||
|
|
||||||
val m3u8Parent = getParentLink(m3u8.streamUrl)
|
val m3u8Parent = getParentLink(m3u8.streamUrl)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue