eneim / kohii

Android Video Playback made easy.
https://eneim.github.io/kohii/
Apache License 2.0
373 stars 50 forks source link

The last video in the recycler view doesn't play. #106

Open musaabshirgar1 opened 3 years ago

musaabshirgar1 commented 3 years ago

I have a recycler view which contains a TextView along with the PlayerView and everything is working fine except that the last video in the recycler view doesn't play. I think that's because I noticed that the video only starts playing when the PlayerView is in focus but since the last item in the recycler view stays at the end, it doesn't come in the middle of the screen to get focus. Is there a work around for this?

eneim commented 3 years ago

@musaabshirgar1 How many PlayerView you have in the screen when you oberve the issue?

musaabshirgar1 commented 3 years ago

@eneim i am using a recycler view so in theory i am just using the same player view for every data in the recycler view. But if you are asking about how many items can fit in the screen at once then the answer would be 2

eneim commented 3 years ago

@musaabshirgar1 Yeah. I mean when you observe the issue, how many Videos are being shown in the screen. One scenario is when you have 2 Videos in the screen at the same time, and both are visible enough, the one on the bottom will never be played. I guess it is not your case, but I want to clarify first. (If you can share a screenshot of the screen that time it will be helpful).

musaabshirgar1 commented 3 years ago

@eneim yes that's exactly what happens. When i scroll down to the bottom most elements of my recycler view, only 2 items are visible, the top one is playing perfectly fine but the bottom one will never play because since it is the last item in the recycler view and i can't scroll down further. Is there a way through which i can play atleast the last one?

eneim commented 3 years ago

@musaabshirgar1 I have thought about this a few time and to be honest, it is not really easy from library's point of view. The reason is as below:

Considering the scenario where the user is seeing 2 Videos at the same time (let's say, A and B, where A is above B), we need to answer the following questions to be able to decide what to do next:

Right now, there is no way that the library can give you the power to make the decision by your own. I have something here that might help, but it is kinda a work-around at the moment:

Index: kohii-core/src/main/java/kohii/v1/core/Playback.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- kohii-core/src/main/java/kohii/v1/core/Playback.kt  (revision 4ee0d39e848fc1e361cdbd0085e37de5818969ff)
+++ kohii-core/src/main/java/kohii/v1/core/Playback.kt  (date 1601125096000)
@@ -139,9 +139,12 @@
   private var playbackToken: Token =
     Token(config.threshold, -1F, Rect(), 0, 0)

-  internal var lock: Boolean = bucket.lock
+  /**
+   * Return `true` if this [Playback] is locked, `false` otherwise.
+   */
+  var lock: Boolean = bucket.lock
     get() = field || bucket.lock
-    set(value) {
+    internal set(value) {
       field = value
       manager.refresh()
     }
Index: kohii-core/src/main/java/kohii/v1/core/Bucket.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- kohii-core/src/main/java/kohii/v1/core/Bucket.kt    (revision 4ee0d39e848fc1e361cdbd0085e37de5818969ff)
+++ kohii-core/src/main/java/kohii/v1/core/Bucket.kt    (date 1601125060000)
@@ -265,13 +265,17 @@
         .groupBy { it.tag != Master.NO_TAG && it.config.controller != null }
         .withDefault { emptyList() }

-    val manualCandidate = with(manualToAutoPlaybackGroups.getValue(true)) {
+    val manualCandidate: Collection<Playback> = with(manualToAutoPlaybackGroups.getValue(true)) {
       val started = find { manager.master.manuallyStartedPlayable.get() === it.playable }
-      listOfNotNull(started ?: firstOrNull())
+      return@with if (started == null) {
+        this
+      } else {
+        listOf(started)
+      }
     }

     return if (manualCandidate.isNotEmpty()) {
-      manualCandidate
+      selector(manualCandidate)
     } else {
       selector(manualToAutoPlaybackGroups.getValue(false))
     }

In your code, when you have multiple Videos shown at the same time, you can decide which to play by your own using the selector API:

kohii.register(this)
        .addBucket(
            binding.scrollView,
            strategy = Strategy.SINGLE_PLAYER,
            selector = { candidates ->
              listOfNotNull(candidates.firstOrNull { !it.lock })
            }
        )

The snippet above means: pick the first Playback which is not locked. This works in the co-operation with the lockPlayback and unlockPlayback API. So the idea is: when user interacts so that the second Video should be played, you call kohii.lockPlayback against the first Video's Playback. It will trigger a refresh and ask the selector to re-select the Video. Of course you need to unlock that Playback later or else it will never be played again.

The patch above exposes the way for you to check if a Playback is locked or not. So unless you use the lockPlayback/unlockPlayback API, you don't need that though.

I will try to think about a better way around this.

musaabshirgar1 commented 3 years ago

@eneim I appreciate your time but the code that you had sent above just increases the complexity. I mean to implement Kohii in recycler view is very easy (Thanks to your awesomeness) but the only problem i am facing is for playing the last video in the recycler view. Can you suggest something else? Other thing that i can do is play all the videos at once but I tried "strategy = Strategy.MULTI_PLAYER" but it didn't work. Can you help me with that?

ahmedsalemelzeiny commented 3 years ago

@musaabshirgar1 Did you fix it ?