add permanently visible next episode button & fix autoplay
* autoplay / play next episode could sometimes skip episodes
This commit is contained in:
		| @ -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) { | ||||
|             res.select("div.three-box-container > div.episodebox").forEach { episodebox -> | ||||
|                 // make sure the episode has a streaming link | ||||
|  | ||||
| @ -29,6 +29,7 @@ import kotlinx.coroutines.launch | ||||
| import kotlinx.coroutines.withContext | ||||
| import org.mosad.teapod.R | ||||
| import org.mosad.teapod.preferences.Preferences | ||||
| import org.mosad.teapod.util.DataTypes | ||||
| import org.mosad.teapod.util.Episode | ||||
| import java.util.* | ||||
| import java.util.concurrent.TimeUnit | ||||
| @ -44,6 +45,7 @@ class PlayerActivity : AppCompatActivity() { | ||||
|     private lateinit var gestureDetector: GestureDetectorCompat | ||||
|     private lateinit var timerUpdates: TimerTask | ||||
|  | ||||
|     private var nextEpManually = false | ||||
|     private var playWhenReady = true | ||||
|     private var currentWindow = 0 | ||||
|     private var playbackPosition: Long = 0 | ||||
| @ -129,14 +131,9 @@ class PlayerActivity : AppCompatActivity() { | ||||
|         dataSourceFactory = DefaultDataSourceFactory(this, Util.getUserAgent(this, "Teapod")) | ||||
|         controller = video_view.findViewById(R.id.exo_controller) | ||||
|  | ||||
|         val mediaSource = HlsMediaSource.Factory(dataSourceFactory) | ||||
|             .createMediaSource(MediaItem.fromUri(Uri.parse(autoSelectStream(model.currentEpisode)))) | ||||
|         controller.isAnimationEnabled = false // disable controls (time-bar) animation | ||||
|  | ||||
|         player.playWhenReady = playWhenReady | ||||
|         player.setMediaSource(mediaSource) | ||||
|         player.seekTo(playbackPosition) | ||||
|         player.prepare() | ||||
|  | ||||
|         player.addListener(object : Player.EventListener { | ||||
|             override fun onPlaybackStateChanged(state: Int) { | ||||
|                 super.onPlaybackStateChanged(state) | ||||
| @ -154,14 +151,16 @@ class PlayerActivity : AppCompatActivity() { | ||||
|                 } | ||||
|  | ||||
|                 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 | ||||
|         exo_text_title.text = model.currentEpisode.title // set media title | ||||
|         playCurrentMedia(true) | ||||
|     } | ||||
|  | ||||
|     @SuppressLint("ClickableViewAccessibility") | ||||
| @ -187,6 +186,7 @@ class PlayerActivity : AppCompatActivity() { | ||||
|         rwd_10.setOnButtonClickListener { rewind() } | ||||
|         ffwd_10.setOnButtonClickListener { fastForward() } | ||||
|         button_next_ep.setOnClickListener { playNextEpisode() } | ||||
|         button_next_ep_c.setOnClickListener { playNextEpisode() } | ||||
|     } | ||||
|  | ||||
|     private fun initTimeUpdates() { | ||||
| @ -299,18 +299,37 @@ class PlayerActivity : AppCompatActivity() { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private fun playNextEpisode() = model.nextEpisode?.let { nextEp -> | ||||
|         // update the gui | ||||
|         exo_text_title.text = nextEp.title | ||||
|     private fun playNextEpisode() = model.nextEpisode?.let { | ||||
|         model.nextEpisode() // current = next, next = new or null | ||||
|         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 | ||||
|         val mediaSource = HlsMediaSource.Factory(dataSourceFactory) | ||||
|             .createMediaSource(MediaItem.fromUri(Uri.parse(autoSelectStream(nextEp)))) | ||||
|         val mediaSource = HlsMediaSource.Factory(dataSourceFactory).createMediaSource( | ||||
|             MediaItem.fromUri(Uri.parse(autoSelectStream(model.currentEpisode))) | ||||
|         ) | ||||
|         if (seekToPosition) player.seekTo(playbackPosition) | ||||
|         player.setMediaSource(mediaSource) | ||||
|         player.prepare() | ||||
|  | ||||
|         model.nextEpisode() | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|  | ||||
							
								
								
									
										5
									
								
								app/src/main/res/drawable/ic_baseline_skip_next_24.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								app/src/main/res/drawable/ic_baseline_skip_next_24.xml
									
									
									
									
									
										Normal file
									
								
							| @ -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" | ||||
|     android:width="24dp" | ||||
|     android:height="24dp" | ||||
|     android:viewportWidth="24" | ||||
|     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 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="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> | ||||
|  | ||||
| @ -108,4 +108,40 @@ | ||||
|             app:layout_constraintTop_toTopOf="parent" /> | ||||
|     </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> | ||||
| @ -16,8 +16,8 @@ | ||||
|     <string name="button_play">Abspielen</string> | ||||
|     <string name="text_episodes_count">%1$d Episoden</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_sub">Ep. %1$d %2$s (OmU)</string> | ||||
|     <string name="component_episode_title">Flg. %1$d %2$s</string> | ||||
|     <string name="component_episode_title_sub">Flg. %1$d %2$s (OmU)</string> | ||||
|  | ||||
|     <!-- settings fragment --> | ||||
|     <string name="account">Account</string> | ||||
| @ -40,7 +40,9 @@ | ||||
|     <string name="rewind_10">10 Sekunden zurück</string> | ||||
|     <string name="play_pause">Abspielen/Pause</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 --> | ||||
|     <string name="save">speichern</string> | ||||
|  | ||||
| @ -52,9 +52,11 @@ | ||||
|     <string name="forward_10">forward 10 seconds</string> | ||||
|     <string name="rwd_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_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 --> | ||||
|     <string name="save">save</string> | ||||
|  | ||||
		Reference in New Issue
	
	Block a user