“This is the 10th day of my participation in the First Challenge 2022. For details: First Challenge 2022.”
Preface:
Maybe you will meet players are bloated, player control logic complexity is high, the business high coupling, page logic dispersion (across pages animation, shoot logic), etc. This kind of problem, and these problems actually in the final analysis is the player itself is not “dry (players) wet (player control)”. If there is a variety of players in the product, it is extremely difficult to add certain requirements to the player. Therefore, it is necessary to separate the business of the player and abstract the core business and UI control layer of the player so as to reduce the dependence between each other.
The road to player refactoring
background
Project before I do business focus has been in the community and social aspects, in the video diary and long video made many attempts to do a lot of differentiation treatment, is the first player from a base class, gradually turned into multiple derived classes, and then in the optimization of product requirements have been patched, joined a lot of small functions, such as: Gesture fast forward, list sliding play optimization, continuous play, automatic play under network conditions, etc. At the beginning of the project, the overall architecture of the player was not considered, resulting in the logic of the player in the later stage being heavily dependent on the page, making it difficult to continue business changes and solve problems. (The new man did not dare to move, the old man took a look, ancestral “excrement mountain”, do not move)
explore
After a patient analysis, problems were found at several levels in the project:
- The interactive part of the player is coupled to the business UI, and multiple business layer modules depend on the basic player control layer, often doubling the impact of a single change.
- Too much repetitive intrusive code when listing plays
- The continuation logic is too complicated, because the original continuation scheme is built on the basis of patch, so the scheme is not reasonable;
- The architecture of the underlying player is not completely separated from the business.
Now that the problem has been identified, how to design the architecture of the player module? Or what kind of architecture is good for their business?
Then, according to its own business needs, some conditions must be met:
- Whether the player layer needs to support a player that does not allow kernel
Avplayer, ijkplayer
Or more; (Unified player adaptation protocol is required) - Whether the player control layer needs to achieve differentiated processing; (Unified control layer protocol is required)
- The realization scheme of automatic playing of player list is separated from service; (Need to be decoupled in the form of protocol or classification of tableView)
- Player gesture unified management; (Gesture Collection)
practice
Now that you know how to meet the conditions, go ahead and do it.
Following the six principles of the design pattern, we try to simplify the responsibilities of each class and abstract the modules that the bottom layer depends on, so as to achieve the maximum flexibility of the upper layer business.
Player Architecture
VideoPlayerCenter
The VideoPlayerCenter class is the intermediate control layer. Its responsibility is to integrate all the modules and distribute the events in the player (the player itself, or the events that actively trigger the control layer, or the events that are monitored at the network level, etc.) to the corresponding function modules. You can think of it as a dispatch.
Here is the structure of VideoPlayerCenter:
VideoPlayerCenter will be open to the external methods of each module to deal with, each new module can be added by adding categories to add their own functions.
In this class, function modules are assembled and triggered to the corresponding function module according to the callback of each function module, for example:
VideoPlayerPlaybackProtocol implementation class have players play callback, if the trigger after the callback, in VideoPlayerCenter forwarding events to VideoPlayerControlProtocol implementation class controlView, Used to deal with the control layer UI changes after the playback callback;
VideoPlayerGestureManager there are players in the class of gestures callback, if the trigger after the callback, in VideoPlayerCenter forwarding events to VideoPlayerControlProtocol implementation class controlView, Used to deal with UI changes of control layer after gesture operation;
The same VideoPlayerNetworkManager class is the same;
VideoPlayerPlaybackProtocol
VideoPlayerPlaybackProtocol class is the player control layer, it is used to abstract the responsibility of the player, reduce external dependence on players;
This class will define the basic attributes, methods, callbacks of the player, and the interface used to unify the player. When accessing different players, you only need to implement the corresponding player protocol.
VideoPlayerControlProtocol
VideoPlayerControlProtocol class player UI control layer, it is the responsibility of the layer is used to abstract the UI events, reduce external dependence on players;
ControlView VideoPlayerCenter is the VideoPlayerControlProtocol protocol implementation class, controlView custom own layout at the same time, When the page is switched, you can directly switch the controlView to complete the player’s transition.
This class will define control all the events, all events may affect the control layer through VideoPlayerCenter forwarded to VideoPlayerControlProtocol implementation class.
VideoPlayerGestureManager
VideoPlayerGestureManager class is a gesture of player control layer management, it is the responsibility of the management control layer gestures;
There are many kinds of gestures, you can click, double click, long press, drag, etc., which gesture to respond to depends on the configuration;
VideoPlayerNetworkManager
VideoPlayerGestureManager class is player of network monitoring, it is the responsibility of the monitoring network fluctuation;
The division of responsibility for each class is single and does not interfere with the logic of other classes. By abstracting the control layer, it solves the differential configuration of the control layer, solves the seamless continuation when the list player switches to the detail page, solves the over-dependence of the upper business on the player, and ensures the cleanliness of the business layer to a great extent.
subsequent
Because the business side of the player has done a lot of subtraction, the current feature classes meet the requirements. The logic of automatic list playing is in the classification of TableView (the original logic can be reused), and it is not managed in VideoPlayerCenter, which violates the original intention of the initial design. If the player is to be modular later, it may have some impact. I’m going to think about putting the list in VideoPlayerCenter as well. In the future, it will continue to improve the switch between vertical and horizontal screens, as well as the gestures of the control layer fast forward, fast back, long press three times the speed and other related functions.