Video Player's AutoPlay Framework Design in RecyclerView
When I reviewed the notes, I found that this article was not uploaded to the blog. Although the code implementation is outdated, the idea has been used all the time, so today I simply sorted the content and sent it to the blog.
Auto-playing of the video is a common application scenario, which involves sliding distance monitoring of lists, lifecycle perception of pages, and changes in video state. This article describes an automatic playback architecture design for RecyclerView
component.
Design
Traditional Scheme
Common scenario: Get PlayerId
in Item
, instantiate Player
and play it.
The easiest way to think of this is to put a Player
in the layout of each item in the RecyclerView
, and listen to the RecyclerView
to determine the currently visible item, then instantiate the each Player
.
The problem with this solution is that when sliding the list, the Player
is constantly instantiated, causing additional overhead.
There are also proposals to use a player singleton, calling addView()
and removeView()
during the sliding process to handle the player. Although this solution solves the above-mentioned problem of constant re-instantiation, there are also specific scenarios. The next unsuitable problem, such as the vertical sliding RecyclerView
nested with a horizontal sliding RecyclerView
, two RecyclerView
have automatic playback player. In such a nested scenario, the player logic processing is more complicated.
My Scheme
Because the above scenario is very likely to be encountered in the actual development process, in order to reduce the repetitive coding, a set of automatic playback structure suitable for RecyclerView
is designed, which can solve the player in the case of multi-level nesting. The logic code is written and the idea of “Self-Management” is implemented, which also makes the trivial processing of the player’s lifecycle perception more cohesive.
Usually, we have a RecyclerView
in an Activity
, in which there are various types of Item
, such as pictures, videos, and other types, only the video needs to support automatic playback.
Here we abstract the player into an interface IPlayer
as shown below:
1 | interface IPlayer { |
Modify the corresponding player, such as MyPlayer, to inherit the interface. Note that its autoRemove() function is used to let the player remove its own parent layout and pause itself. The reference implementation is as follows:
1 | override fun autoRemove() { |
At this point, we have a universal player interface, as long as you follow this interface, you can change the implementation.
Then, you need a container of video. When the item has not been played, the video is filled by the container of the video. We assume here as IVideoContainer
, which encapsulates some trivial logic such as null processing, mainly providing two externally. Methods, as follows:
1 | interface IVideoContainer{ |
Next, we also need an Item interface to indicate that the Item supports autoplay, as follows:
1 | interface IAutoPlayItem { |
The item that inherits the interface can be played automatically.
Finally, we also need a play help class to help us monitor the distance change of RecyclerView
. The key functions are as follows:
1 | fun setListener() { |
At this point, the core function class of the scheme has been explained, and then the Lifecycle is introduced to the Player, that is, the lifecycle perception is realized, and the single-player processing of the core playback part of the Player can realize the cross-page single player architecture.
More
Although this article is for RecyclerView
, because it is only coupled with the listener helper class, it can be reused in other layouts, and the corresponding helper classes can be reused, such as ViewPager
.
The above example code only judges the playable state of the first visible Item
in the page. In the actual scene, the online example can be used to make a percentage judgment on each visible Item
in the page, and the priority processing is performed.
Summary
Compared with the traditional scheme, the advantage of the scheme described in this paper is that, when the page layout is complicated, the framework does not have to be modified for complex situations, and the logical processing of the complex page layout is sunk to the automatically played Item
interface. At the same time, it supports the fast resume function after the player is skipped in the multi-type layout. And the overall design removes the player logic from the page. For each page, you only need to add Observer
of Lifecycle
and give RecyclerView
to the help class, so the cost of access is very small.