2020-10-11 13:18:20 +02:00
package org.mosad.teapod
import android.net.Uri
2020-10-11 14:14:38 +02:00
import android.os.Build
2020-10-11 13:18:20 +02:00
import android.os.Bundle
2020-10-11 14:14:38 +02:00
import android.util.Log
2020-10-11 13:18:20 +02:00
import android.view.View
2020-10-11 14:14:38 +02:00
import android.view.WindowInsets
import android.view.WindowInsetsController
2020-10-11 13:18:20 +02:00
import androidx.appcompat.app.AppCompatActivity
import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.SimpleExoPlayer
import com.google.android.exoplayer2.source.hls.HlsMediaSource
import com.google.android.exoplayer2.upstream.DataSource
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory
import com.google.android.exoplayer2.util.Util
import kotlinx.android.synthetic.main.activity_player.*
2020-11-05 20:07:41 +01:00
import kotlinx.android.synthetic.main.player_controls.*
2020-10-11 13:18:20 +02:00
class PlayerActivity : AppCompatActivity ( ) {
private lateinit var player : SimpleExoPlayer
private lateinit var dataSourceFactory : DataSource . Factory
private var streamUrl = " "
private var playWhenReady = true
private var currentWindow = 0
private var playbackPosition : Long = 0
2020-11-05 20:07:41 +01:00
private val rwdTime = 10000
private val fwdTime = 10000
2020-10-11 14:14:38 +02:00
2020-10-11 13:18:20 +02:00
override fun onCreate ( savedInstanceState : Bundle ? ) {
super . onCreate ( savedInstanceState )
setContentView ( R . layout . activity _player )
2020-10-11 14:14:38 +02:00
hideBars ( ) // Initial hide the bars
2020-10-11 13:18:20 +02:00
2020-10-11 15:19:42 +02:00
savedInstanceState ?. let {
currentWindow = it . getInt ( getString ( R . string . state _resume _window ) )
playbackPosition = it . getLong ( getString ( R . string . state _resume _position ) )
playWhenReady = it . getBoolean ( getString ( R . string . state _is _playing ) )
}
streamUrl = intent . getStringExtra ( getString ( R . string . intent _stream _url ) ) . toString ( )
2020-11-05 20:07:41 +01:00
initActions ( )
2020-10-11 13:18:20 +02:00
}
override fun onStart ( ) {
super . onStart ( )
if ( Util . SDK _INT > 23 ) {
initPlayer ( )
if ( video _view != null ) video _view . onResume ( )
}
}
override fun onResume ( ) {
super . onResume ( )
if ( Util . SDK _INT <= 23 ) {
initPlayer ( )
if ( video _view != null ) video _view . onResume ( )
}
}
override fun onPause ( ) {
super . onPause ( )
if ( Util . SDK _INT <= 23 ) {
if ( video _view != null ) video _view . onPause ( )
releasePlayer ( )
}
}
override fun onStop ( ) {
super . onStop ( )
if ( Util . SDK _INT > 23 ) {
if ( video _view != null ) video _view . onPause ( )
releasePlayer ( )
}
}
2020-10-11 15:19:42 +02:00
override fun onSaveInstanceState ( outState : Bundle ) {
outState . putInt ( getString ( R . string . state _resume _window ) , currentWindow )
outState . putLong ( getString ( R . string . state _resume _position ) , playbackPosition )
outState . putBoolean ( getString ( R . string . state _is _playing ) , playWhenReady )
super . onSaveInstanceState ( outState )
}
2020-10-11 13:18:20 +02:00
private fun initPlayer ( ) {
if ( streamUrl . isEmpty ( ) ) {
2020-10-11 14:14:38 +02:00
Log . e ( javaClass . name , " No stream url was set. " )
2020-10-11 13:18:20 +02:00
return
}
player = SimpleExoPlayer . Builder ( this ) . build ( )
dataSourceFactory = DefaultDataSourceFactory ( this , Util . getUserAgent ( this , " Teapod " ) )
val mediaSource = HlsMediaSource . Factory ( dataSourceFactory )
. createMediaSource ( MediaItem . fromUri ( Uri . parse ( streamUrl ) ) )
2020-10-11 15:19:42 +02:00
player . playWhenReady = playWhenReady
2020-10-11 13:18:20 +02:00
player . setMediaSource ( mediaSource )
2020-10-11 15:19:42 +02:00
player . seekTo ( playbackPosition )
2020-10-11 13:18:20 +02:00
player . prepare ( )
2020-10-11 15:19:42 +02:00
2020-10-11 13:18:20 +02:00
player . addListener ( object : Player . EventListener {
override fun onPlaybackStateChanged ( state : Int ) {
super . onPlaybackStateChanged ( state )
loading . visibility = when ( state ) {
2020-10-11 14:14:38 +02:00
ExoPlayer . STATE _READY -> View . GONE
2020-10-11 13:18:20 +02:00
ExoPlayer . STATE _BUFFERING -> View . VISIBLE
else -> View . GONE
}
2020-11-05 20:07:41 +01:00
exo _play _pause . visibility = when ( loading . visibility ) {
View . GONE -> View . VISIBLE
View . VISIBLE -> View . INVISIBLE
else -> View . VISIBLE
}
2020-10-11 13:18:20 +02:00
}
} )
2020-10-11 14:14:38 +02:00
// when the player controls get hidden, hide the bars too
video _view . setControllerVisibilityListener {
if ( it == View . GONE ) hideBars ( )
}
2020-10-11 13:18:20 +02:00
video _view . player = player
}
2020-11-05 20:07:41 +01:00
private fun initActions ( ) {
exo _rew _10 . setOnClickListener {
player . seekTo ( player . currentPosition - rwdTime )
}
exo _ffwd _10 . setOnClickListener {
player . seekTo ( player . currentPosition + fwdTime )
}
}
2020-10-11 13:18:20 +02:00
private fun releasePlayer ( ) {
playbackPosition = player . currentPosition
currentWindow = player . currentWindowIndex
playWhenReady = player . playWhenReady
player . release ( )
}
2020-10-11 14:14:38 +02:00
/ * *
* hide the status and navigation bar
* /
private fun hideBars ( ) {
if ( Build . VERSION . SDK _INT >= Build . VERSION_CODES . R ) {
window . setDecorFitsSystemWindows ( false )
window . insetsController ?. apply {
hide ( WindowInsets . Type . statusBars ( ) or WindowInsets . Type . navigationBars ( ) )
systemBarsBehavior = WindowInsetsController . BEHAVIOR _SHOW _BARS _BY _SWIPE
}
} else {
@Suppress ( " deprecation " )
2020-10-11 15:19:42 +02:00
window . decorView . systemUiVisibility = ( View . SYSTEM _UI _FLAG _IMMERSIVE
or View . SYSTEM _UI _FLAG _LAYOUT _STABLE
or View . SYSTEM _UI _FLAG _LAYOUT _HIDE _NAVIGATION
or View . SYSTEM _UI _FLAG _LAYOUT _FULLSCREEN
or View . SYSTEM _UI _FLAG _HIDE _NAVIGATION
or View . SYSTEM _UI _FLAG _FULLSCREEN )
2020-10-11 14:14:38 +02:00
}
}
2020-10-11 13:18:20 +02:00
}