Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QMPlayer开发总结 #7

Open
lanjingling0510 opened this issue Feb 18, 2018 · 0 comments
Open

QMPlayer开发总结 #7

lanjingling0510 opened this issue Feb 18, 2018 · 0 comments

Comments

@lanjingling0510
Copy link
Owner

QMPlayer是为了将直播,弹幕,礼物动画等播放器脱离业务层,支持h5播放器而开发的组件。

设计成一个组件化框架

在面对如此多繁复的需求时,我们都会引入**“分治”**的概念。组件化正是我们需要的方案。

每个插件需要关心自己插件本身的功能和视频元素即可。
分治的核心在于插件间隔离,保持低耦合度。在编写插件的时候我们要注意:

  • 不关心其余插件的状态数据
  • 不承担非自己工作范畴内的任务

只有这样我们才能创造出低耦合的组件,这有利于我们:

  • 快速添加或移除插件
  • 添加新插件时不需要过分关心旧插件
  • 快速迁移已有插件

5

插件生命周期

插件的生命周期,方便对于插件某个时间点,如:初始化,销毁等执行其他的操作。video插件是基础插件,它会在播放时为其他插件提供beforePlay,afterPlay生命周期方法。

公共的继承BaseDomPlugin类的插件有如下生命周期:

  • created // 插件实例化完成
  • mounted // 插件DOM安装完成
  • playerCreated // 播放器实例化完成(所用插件实例化完成)
  • playerMounted // 播放器DOM安装完成(所有插件DOM安装完成)
  • destroy // 插件销毁
  • error // 插件出错
  • beforePlay // 播放前(返回true继续,返回false终止播放)
  • afterPlay // 播放后

事件驱动vs插件通讯

我用了webpack内部的事件管理机制Table,可以实现异步和同步的事件分发。

6

事件驱动很好的解决各个组件通讯的问题,各个插件可以随意通讯。
但随着插件的复杂程度和数量的增多,各个事件来回交互分发,会使插件之间的联系更加复杂错乱。

所以为了解决各个插件通讯清晰的问题,我将插件分为渲染插件管理中介插件

  • 渲染插件:只负责维护内部状态和插件dom的渲染,不直接监听其他插件通讯。
  • 管理中介插件:负责控制监听多个渲染插件的联系,相当于一个中介者。

7

层级管理

插件根据顺序来决定层级的高低

new QMPlayer(config).addPlugins([
    QMPlayer.plugins.Banner,
    [QMPlayer.plugins.Danmaku, { Danmaku: PIXIDanmaku }],
    QMPlayer.plugins.Animation,
    QMPlayer.plugins.VolumeTip,
    [QMPlayer.plugins.Waiting, { recommends: recommends ,vods: vods}],
    QMPlayer.plugins.EnterRoomButton,
    QMPlayer.plugins.Loading,
    [QMPlayer.plugins.Control, { widgets: widgets }],
    QMPlayer.plugins.FlashUpdate,
    QMPlayer.plugins.FlashUpdateButton,
    QMPlayer.plugins.Popup,
    QMPlayer.plugins.Monitor
  ]);

最高层级的DOM插件拥有最高鼠标交互事件的优先级。因此,底层级的DOM插件如果想实现交互事件,必须要根据最高层级的插件来转发事件。

例如:弹幕插件可以交互,同时又想点击空白区域实现暂停、播放的功能。
8

这个时候,我们需要将最顶层的弹幕插件的点击事件分发给底层级的DOM插件,这个过程都是通过架构内部自动实现的。因此无论哪个DOM插件的层级最高,都可以轻易的分发事件。

开发播放器遇到的问题

  1. swfobject swf 不加载

原因:
- 要添加当前域名
- flash元素必须可见,且在可视区域内.

  1. flash object元素导致无法触发父元素事件
    解决:在object上覆盖一层div

  2. 和老版本的css冲突
    解决:添加不一样的命名空间

  3. rollup打包压缩报错
    原因:各个依赖包不符合rollup规范
    解决:换成webpack打包

  4. plugins的数据状态共享
    解决:

    • 提供 Manage plugin 作为中介者管理共享数据
    • 提供store贯穿plugin 来操作store数据
  5. 组件的声明周期,loader.plugin监听不到其他组件的apply
    解决:将loader.applyPlugins调用放在 nextTick函数中,在下一个事件队列中调用

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant