add permanently visible next episode button & fix autoplay
* autoplay / play next episode could sometimes skip episodes
This commit is contained in:
parent
dbd4b26a65
commit
20407d9cac
|
@ -302,7 +302,7 @@ object AoDParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse additional information for tv shows
|
// parse additional information for tv shows the episode title (description) is loaded from the "api"
|
||||||
if (media.type == MediaType.TVSHOW) {
|
if (media.type == MediaType.TVSHOW) {
|
||||||
res.select("div.three-box-container > div.episodebox").forEach { episodebox ->
|
res.select("div.three-box-container > div.episodebox").forEach { episodebox ->
|
||||||
// make sure the episode has a streaming link
|
// make sure the episode has a streaming link
|
||||||
|
|
|
@ -29,6 +29,7 @@ import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.mosad.teapod.R
|
import org.mosad.teapod.R
|
||||||
import org.mosad.teapod.preferences.Preferences
|
import org.mosad.teapod.preferences.Preferences
|
||||||
|
import org.mosad.teapod.util.DataTypes
|
||||||
import org.mosad.teapod.util.Episode
|
import org.mosad.teapod.util.Episode
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
@ -44,6 +45,7 @@ class PlayerActivity : AppCompatActivity() {
|
||||||
private lateinit var gestureDetector: GestureDetectorCompat
|
private lateinit var gestureDetector: GestureDetectorCompat
|
||||||
private lateinit var timerUpdates: TimerTask
|
private lateinit var timerUpdates: TimerTask
|
||||||
|
|
||||||
|
private var nextEpManually = false
|
||||||
private var playWhenReady = true
|
private var playWhenReady = true
|
||||||
private var currentWindow = 0
|
private var currentWindow = 0
|
||||||
private var playbackPosition: Long = 0
|
private var playbackPosition: Long = 0
|
||||||
|
@ -129,14 +131,9 @@ class PlayerActivity : AppCompatActivity() {
|
||||||
dataSourceFactory = DefaultDataSourceFactory(this, Util.getUserAgent(this, "Teapod"))
|
dataSourceFactory = DefaultDataSourceFactory(this, Util.getUserAgent(this, "Teapod"))
|
||||||
controller = video_view.findViewById(R.id.exo_controller)
|
controller = video_view.findViewById(R.id.exo_controller)
|
||||||
|
|
||||||
val mediaSource = HlsMediaSource.Factory(dataSourceFactory)
|
controller.isAnimationEnabled = false // disable controls (time-bar) animation
|
||||||
.createMediaSource(MediaItem.fromUri(Uri.parse(autoSelectStream(model.currentEpisode))))
|
|
||||||
|
|
||||||
player.playWhenReady = playWhenReady
|
player.playWhenReady = playWhenReady
|
||||||
player.setMediaSource(mediaSource)
|
|
||||||
player.seekTo(playbackPosition)
|
|
||||||
player.prepare()
|
|
||||||
|
|
||||||
player.addListener(object : Player.EventListener {
|
player.addListener(object : Player.EventListener {
|
||||||
override fun onPlaybackStateChanged(state: Int) {
|
override fun onPlaybackStateChanged(state: Int) {
|
||||||
super.onPlaybackStateChanged(state)
|
super.onPlaybackStateChanged(state)
|
||||||
|
@ -154,14 +151,16 @@ class PlayerActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == ExoPlayer.STATE_ENDED && model.nextEpisode != null && Preferences.autoplay) {
|
if (state == ExoPlayer.STATE_ENDED && model.nextEpisode != null && Preferences.autoplay) {
|
||||||
playNextEpisode()
|
if (nextEpManually) {
|
||||||
|
nextEpManually = false
|
||||||
|
} else {
|
||||||
|
playNextEpisode()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
controller.isAnimationEnabled = false // disable controls (time-bar) animation
|
playCurrentMedia(true)
|
||||||
exo_text_title.text = model.currentEpisode.title // set media title
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
@ -187,6 +186,7 @@ class PlayerActivity : AppCompatActivity() {
|
||||||
rwd_10.setOnButtonClickListener { rewind() }
|
rwd_10.setOnButtonClickListener { rewind() }
|
||||||
ffwd_10.setOnButtonClickListener { fastForward() }
|
ffwd_10.setOnButtonClickListener { fastForward() }
|
||||||
button_next_ep.setOnClickListener { playNextEpisode() }
|
button_next_ep.setOnClickListener { playNextEpisode() }
|
||||||
|
button_next_ep_c.setOnClickListener { playNextEpisode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initTimeUpdates() {
|
private fun initTimeUpdates() {
|
||||||
|
@ -299,18 +299,37 @@ class PlayerActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun playNextEpisode() = model.nextEpisode?.let { nextEp ->
|
private fun playNextEpisode() = model.nextEpisode?.let {
|
||||||
// update the gui
|
model.nextEpisode() // current = next, next = new or null
|
||||||
exo_text_title.text = nextEp.title
|
|
||||||
hideButtonNextEp()
|
hideButtonNextEp()
|
||||||
|
|
||||||
|
nextEpManually = true
|
||||||
|
playCurrentMedia(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* start playing a episode
|
||||||
|
* Note: movies are episodes too!
|
||||||
|
*/
|
||||||
|
private fun playCurrentMedia(seekToPosition: Boolean) {
|
||||||
|
// update the gui
|
||||||
|
exo_text_title.text = if (model.media.type == DataTypes.MediaType.TVSHOW) {
|
||||||
|
getString(R.string.component_episode_title, model.currentEpisode.number, model.currentEpisode.description)
|
||||||
|
} else {
|
||||||
|
model.currentEpisode.title
|
||||||
|
}
|
||||||
|
|
||||||
|
if (model.nextEpisode == null) {
|
||||||
|
button_next_ep_c.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
player.clearMediaItems() //remove previous item
|
player.clearMediaItems() //remove previous item
|
||||||
val mediaSource = HlsMediaSource.Factory(dataSourceFactory)
|
val mediaSource = HlsMediaSource.Factory(dataSourceFactory).createMediaSource(
|
||||||
.createMediaSource(MediaItem.fromUri(Uri.parse(autoSelectStream(nextEp))))
|
MediaItem.fromUri(Uri.parse(autoSelectStream(model.currentEpisode)))
|
||||||
|
)
|
||||||
|
if (seekToPosition) player.seekTo(playbackPosition)
|
||||||
player.setMediaSource(mediaSource)
|
player.setMediaSource(mediaSource)
|
||||||
player.prepare()
|
player.prepare()
|
||||||
|
|
||||||
model.nextEpisode()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M6,18l8.5,-6L6,6v12zM16,6v12h2V6h-2z"/>
|
||||||
|
</vector>
|
|
@ -1,10 +1,5 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||||
android:width="24dp"
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
android:height="24dp"
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
android:viewportWidth="24"
|
<path android:fillColor="@android:color/white" android:pathData="M4,6L2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6zM20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM12,14.5v-9l6,4.5 -6,4.5z"/>
|
||||||
android:viewportHeight="24"
|
|
||||||
android:tint="?attr/colorControlNormal">
|
|
||||||
<path
|
|
||||||
android:fillColor="@android:color/white"
|
|
||||||
android:pathData="M4,6L2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6zM20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM12,14.5v-9l6,4.5 -6,4.5z"/>
|
|
||||||
</vector>
|
</vector>
|
||||||
|
|
|
@ -108,4 +108,40 @@
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/exo_bottom_controls"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="42dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_marginEnd="12dp"
|
||||||
|
android:layout_marginBottom="7dp">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/button_next_ep_c"
|
||||||
|
style="@style/Widget.AppCompat.Button.Borderless"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/episode"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
app:icon="@drawable/ic_baseline_skip_next_24"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/button_episodes"
|
||||||
|
style="@style/Widget.AppCompat.Button.Borderless"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="7dp"
|
||||||
|
android:text="@string/episodes"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:icon="@drawable/ic_baseline_video_library_24"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/button_next_ep_c"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
|
@ -16,8 +16,8 @@
|
||||||
<string name="button_play">Abspielen</string>
|
<string name="button_play">Abspielen</string>
|
||||||
<string name="text_episodes_count">%1$d Episoden</string>
|
<string name="text_episodes_count">%1$d Episoden</string>
|
||||||
<string name="text_runtime">%1$d Minuten</string>
|
<string name="text_runtime">%1$d Minuten</string>
|
||||||
<string name="component_episode_title">Ep. %1$d %2$s</string>
|
<string name="component_episode_title">Flg. %1$d %2$s</string>
|
||||||
<string name="component_episode_title_sub">Ep. %1$d %2$s (OmU)</string>
|
<string name="component_episode_title_sub">Flg. %1$d %2$s (OmU)</string>
|
||||||
|
|
||||||
<!-- settings fragment -->
|
<!-- settings fragment -->
|
||||||
<string name="account">Account</string>
|
<string name="account">Account</string>
|
||||||
|
@ -40,7 +40,9 @@
|
||||||
<string name="rewind_10">10 Sekunden zurück</string>
|
<string name="rewind_10">10 Sekunden zurück</string>
|
||||||
<string name="play_pause">Abspielen/Pause</string>
|
<string name="play_pause">Abspielen/Pause</string>
|
||||||
<string name="forward_10">10 Sekunden vorwärts</string>
|
<string name="forward_10">10 Sekunden vorwärts</string>
|
||||||
<string name="next_episode">Nächste Episode</string>
|
<string name="next_episode">Nächste Folge</string>
|
||||||
|
<string name="episode">Folge</string>
|
||||||
|
<string name="episodes">Folgen</string>
|
||||||
|
|
||||||
<!-- dialogs -->
|
<!-- dialogs -->
|
||||||
<string name="save">speichern</string>
|
<string name="save">speichern</string>
|
||||||
|
|
|
@ -52,9 +52,11 @@
|
||||||
<string name="forward_10">forward 10 seconds</string>
|
<string name="forward_10">forward 10 seconds</string>
|
||||||
<string name="rwd_10_s" translatable="false">- 10 s</string>
|
<string name="rwd_10_s" translatable="false">- 10 s</string>
|
||||||
<string name="fwd_10_s" translatable="false">+ 10 s</string>
|
<string name="fwd_10_s" translatable="false">+ 10 s</string>
|
||||||
|
<string name="next_episode">Next Episode</string>
|
||||||
<string name="time_min_sec" translatable="false">%1$02d:%2$02d</string>
|
<string name="time_min_sec" translatable="false">%1$02d:%2$02d</string>
|
||||||
<string name="time_hour_min_sec" translatable="false">%1$d:%2$02d:%3$02d</string>
|
<string name="time_hour_min_sec" translatable="false">%1$d:%2$02d:%3$02d</string>
|
||||||
<string name="next_episode">Next Episode</string>
|
<string name="episode">Episode</string>
|
||||||
|
<string name="episodes">Episodes</string>
|
||||||
|
|
||||||
<!-- dialogs -->
|
<!-- dialogs -->
|
||||||
<string name="save">save</string>
|
<string name="save">save</string>
|
||||||
|
|
Loading…
Reference in New Issue