add media session & update exo player to 2.14.0
This commit is contained in:
		| @ -26,9 +26,7 @@ import com.google.android.exoplayer2.ui.StyledPlayerControlView | ||||
| import com.google.android.exoplayer2.util.Util | ||||
| import kotlinx.android.synthetic.main.activity_player.* | ||||
| import kotlinx.android.synthetic.main.player_controls.* | ||||
| import kotlinx.coroutines.Dispatchers | ||||
| import kotlinx.coroutines.launch | ||||
| import kotlinx.coroutines.withContext | ||||
| import org.mosad.teapod.R | ||||
| import org.mosad.teapod.preferences.Preferences | ||||
| import org.mosad.teapod.ui.components.EpisodesListPlayer | ||||
| @ -187,7 +185,7 @@ class PlayerActivity : AppCompatActivity() { | ||||
|      * set play when ready and listeners | ||||
|      */ | ||||
|     private fun initExoPlayer() { | ||||
|         model.player.addListener(object : Player.EventListener { | ||||
|         model.player.addListener(object : Player.Listener { | ||||
|             override fun onPlaybackStateChanged(state: Int) { | ||||
|                 super.onPlaybackStateChanged(state) | ||||
|  | ||||
| @ -208,7 +206,7 @@ class PlayerActivity : AppCompatActivity() { | ||||
|                 } | ||||
|             } | ||||
|         }) | ||||
|  | ||||
|          | ||||
|         // start playing the current episode, after all needed player components have been initialized | ||||
|         model.playEpisode(model.currentEpisode, true) | ||||
|     } | ||||
| @ -256,30 +254,26 @@ class PlayerActivity : AppCompatActivity() { | ||||
|  | ||||
|         timerUpdates = Timer().scheduleAtFixedRate(0, 500) { | ||||
|             lifecycleScope.launch { | ||||
|                 var btnNextEpIsVisible: Boolean | ||||
|                 var controlsVisible: Boolean | ||||
|                 val btnNextEpIsVisible = button_next_ep.isVisible | ||||
|                 val controlsVisible = controller.isVisible | ||||
|  | ||||
|                 withContext(Dispatchers.Main) { | ||||
|                     if (model.player.duration > 0) { | ||||
|                         remainingTime = model.player.duration - model.player.currentPosition | ||||
|                         remainingTime = if (remainingTime < 0) 0 else remainingTime | ||||
|                     } | ||||
|                     btnNextEpIsVisible = button_next_ep.isVisible | ||||
|                     controlsVisible = controller.isVisible | ||||
|                 if (model.player.duration > 0) { | ||||
|                     remainingTime = model.player.duration - model.player.currentPosition | ||||
|                     remainingTime = if (remainingTime < 0) 0 else remainingTime | ||||
|                 } | ||||
|  | ||||
|                 if (remainingTime in 1..20000) { | ||||
|                     // if the next ep button is not visible, make it visible. Don't show in pip mode | ||||
|                     if (!btnNextEpIsVisible && model.nextEpisode != null && Preferences.autoplay && !isInPiPMode()) { | ||||
|                         withContext(Dispatchers.Main) { showButtonNextEp() } | ||||
|                         showButtonNextEp() | ||||
|                     } | ||||
|                 } else if (btnNextEpIsVisible) { | ||||
|                     withContext(Dispatchers.Main) { hideButtonNextEp() } | ||||
|                     hideButtonNextEp() | ||||
|                 } | ||||
|  | ||||
|                 // if controls are visible, update them | ||||
|                 if (controlsVisible) { | ||||
|                     withContext(Dispatchers.Main) { updateControls() } | ||||
|                     updateControls() | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @ -2,12 +2,15 @@ package org.mosad.teapod.ui.activity.player | ||||
|  | ||||
| import android.app.Application | ||||
| import android.net.Uri | ||||
| import android.support.v4.media.session.MediaSessionCompat | ||||
| import android.support.v4.media.session.PlaybackStateCompat | ||||
| import android.util.Log | ||||
| import androidx.lifecycle.AndroidViewModel | ||||
| import androidx.lifecycle.viewModelScope | ||||
| import com.google.android.exoplayer2.C | ||||
| import com.google.android.exoplayer2.MediaItem | ||||
| import com.google.android.exoplayer2.SimpleExoPlayer | ||||
| import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector | ||||
| import com.google.android.exoplayer2.source.MediaSource | ||||
| import com.google.android.exoplayer2.source.hls.HlsMediaSource | ||||
| import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory | ||||
| @ -23,6 +26,7 @@ import org.mosad.teapod.util.Media | ||||
| import java.util.* | ||||
| import kotlin.collections.ArrayList | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * PlayerViewModel handles all stuff related to media/episodes. | ||||
|  * When currentEpisode is changed the player will start playing it (not initial media), | ||||
| @ -31,10 +35,13 @@ import kotlin.collections.ArrayList | ||||
| class PlayerViewModel(application: Application) : AndroidViewModel(application) { | ||||
|  | ||||
|     val player = SimpleExoPlayer.Builder(application).build() | ||||
|     val dataSourceFactory = DefaultDataSourceFactory(application, Util.getUserAgent(application, "Teapod")) | ||||
|     private val dataSourceFactory = DefaultDataSourceFactory(application, Util.getUserAgent(application, "Teapod")) | ||||
|     private val mediaSession = MediaSessionCompat(application, "TEAPOD_PLAYER_SESSION") | ||||
|  | ||||
|     lateinit var mStateBuilder: PlaybackStateCompat | ||||
|  | ||||
|     val currentEpisodeChangedListener = ArrayList<() -> Unit>() | ||||
|     val preferredLanguage = if (Preferences.preferSecondary) Locale.JAPANESE else Locale.GERMAN | ||||
|     private val preferredLanguage = if (Preferences.preferSecondary) Locale.JAPANESE else Locale.GERMAN | ||||
|  | ||||
|     var media: Media = Media(-1, "", DataTypes.MediaType.OTHER) | ||||
|         internal set | ||||
| @ -45,13 +52,30 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application) | ||||
|     var currentLanguage: Locale = Locale.ROOT | ||||
|         internal set | ||||
|  | ||||
|     init { | ||||
|         initMediaSession() | ||||
|     } | ||||
|  | ||||
|     override fun onCleared() { | ||||
|         super.onCleared() | ||||
|  | ||||
|         mediaSession.release() | ||||
|         player.release() | ||||
|  | ||||
|         Log.d(javaClass.name, "Released player") | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * set the media session to active | ||||
|      * create a media session connector to set title and description | ||||
|      */ | ||||
|     private fun initMediaSession() { | ||||
|         val mediaSessionConnector = MediaSessionConnector(mediaSession) | ||||
|         mediaSessionConnector.setPlayer(player) | ||||
|  | ||||
|         mediaSession.isActive = true | ||||
|     } | ||||
|  | ||||
|     fun loadMedia(mediaId: Int, episodeId: Int) { | ||||
|         runBlocking { | ||||
|             media = AoDParser.getMediaById(mediaId) | ||||
| @ -115,6 +139,9 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * change the players media source and start playback | ||||
|      */ | ||||
|     fun playMedia(source: MediaSource, replace: Boolean = false, seekPosition: Long = 0) { | ||||
|         if (replace || player.contentDuration == C.TIME_UNSET) { | ||||
|             player.setMediaSource(source) | ||||
|  | ||||
		Reference in New Issue
	
	Block a user