2020-11-25 16:04:04 +01:00
package org.mosad.teapod.player
2020-12-15 23:15:14 +01:00
import android.util.Log
2020-11-25 16:04:04 +01:00
import androidx.lifecycle.ViewModel
2020-11-27 11:06:16 +01:00
import kotlinx.coroutines.runBlocking
2020-11-25 16:04:04 +01:00
import org.mosad.teapod.parser.AoDParser
2020-12-15 23:15:14 +01:00
import org.mosad.teapod.preferences.Preferences
2020-11-25 16:04:04 +01:00
import org.mosad.teapod.ui.fragments.MediaFragment
import org.mosad.teapod.util.DataTypes
import org.mosad.teapod.util.Episode
import org.mosad.teapod.util.Media
2020-12-15 23:15:14 +01:00
import kotlin.properties.Delegates
2020-11-25 16:04:04 +01:00
2020-12-15 23:15:14 +01:00
/ * *
* PlayerViewModel handles all stuff related to media / episodes .
* When currentEpisode is changed the player will start playing it ( not initial media ) ,
* the next episode will be update and the callback is handled .
* /
2020-11-25 16:04:04 +01:00
class PlayerViewModel : ViewModel ( ) {
2020-12-15 23:15:14 +01:00
val currentEpisodeChangedListener = ArrayList < ( ) -> Unit > ( )
2020-11-25 16:04:04 +01:00
var mediaId = 0
internal set
var episodeId = 0
internal set
var media : Media = Media ( 0 , " " , DataTypes . MediaType . OTHER )
internal set
2020-12-15 23:15:14 +01:00
var currentEpisode : Episode by Delegates . observable ( Episode ( ) ) { _ , _ , _ ->
currentEpisodeChangedListener . forEach { it ( ) }
MediaFragment . instance . updateWatchedState ( currentEpisode ) // watchedCallback for the new episode
nextEpisode = selectNextEpisode ( ) // update next ep
}
2020-11-25 16:04:04 +01:00
var nextEpisode : Episode ? = null
internal set
fun loadMedia ( iMediaId : Int , iEpisodeId : Int ) {
mediaId = iMediaId
episodeId = iEpisodeId
2020-11-27 11:06:16 +01:00
runBlocking {
media = AoDParser . getMediaById ( mediaId )
}
2020-11-25 16:04:04 +01:00
currentEpisode = media . episodes . first { it . id == episodeId }
nextEpisode = selectNextEpisode ( )
2020-12-15 23:15:14 +01:00
currentEpisode
}
/ * *
* If preferSecondary or priStreamUrl is empty and secondary is present ( secStreamOmU ) ,
* use the secondary stream . Else , if the primary stream is set use the primary stream .
* If no stream is present , return empty string .
* /
fun autoSelectStream ( episode : Episode ) : String {
return if ( ( Preferences . preferSecondary || episode . priStreamUrl . isEmpty ( ) ) && episode . secStreamOmU ) {
episode . secStreamUrl
} else if ( episode . priStreamUrl . isNotEmpty ( ) ) {
episode . priStreamUrl
} else {
Log . e ( javaClass . name , " No stream url set. ${episode.id} " )
" "
}
2020-11-25 16:04:04 +01:00
}
2020-12-20 20:21:27 +01:00
fun changeLanguage ( id : Int ) {
println ( " new Language is ABC with id $id " )
}
2020-11-25 16:04:04 +01:00
/ * *
* update currentEpisode , episodeId , nextEpisode to new episode
* updateWatchedState for the next ( now current ) episode
* /
fun nextEpisode ( ) = nextEpisode ?. let { nextEp ->
currentEpisode = nextEp // set current ep to next ep
episodeId = nextEp . id
}
/ * *
* Based on the current episodeId , get the next episode . If there is no next
* episode , return null
* /
private fun selectNextEpisode ( ) : Episode ? {
val nextEpIndex = media . episodes . indexOfFirst { it . id == currentEpisode . id } + 1
2020-12-15 23:15:14 +01:00
return if ( nextEpIndex < media . episodes . size ) {
2020-11-25 16:04:04 +01:00
media . episodes [ nextEpIndex ]
} else {
null
}
}
}