larkplayer 是一款轻量级 & 易扩展的 html5 播放器,是为解决一些中小型的视频业务场景。这些业务不一定需要大而全的解决方案,并且他们往往有自己的定制化需求。

背景

为什么要编写 larkplayer?(注意,这里面有一些我的个人观点)

目前 html5 web player 社区已经比较成熟,videojs 和 jwplayer 等都是优秀的解决方案。然而,社区的两极分化也比较严重:

排名靠前的播放器基本都是一种『大而全』的状态:功能丰富&定制化,体积动辄几百K。对于一些相对简单的业务,还是有点太重了,尤其是在移动端,在做扩展时也可能由于一些已有的功能而碍手碍脚

一些小一点的播放器,往往只是解决了自己特定的业务场景的问题,缺乏扩展性

一些播放器存在对某些大型库(比如 jQuery、AngularJS 等)的依赖,通用性与可移植性不是很好

因此,对于一些中小型的视频业务场景,其实并没有一个舒服的播放器方案可供选择。

思考

如何解决上诉问题?

业务上:

轻量,尽量不提供"多余"的功能,代码体积小

易扩展,能轻易地支持如广告、皮肤、统计等各种定制化需求

代码上:

解决兼容性问题,把琐碎的细节留在内部,对外接口统一

插件化机制,解耦各功能,提供方便扩展的接口与方式

原生 javascript 编写,减少对类库的依赖,便于在各种环境下使用与移植

设计

larkplayer 的灵感来自 videojs,采用插件化的设计:播放器本身只是一个精巧的核心,包含一些必备的机制和 API,其余功能由插件提供。

你可以自由选择和编写自己的插件,做到按需取用,渐进增强。在 ugilfy + gzip 后,larkplayer 代码体积约 12KB.

1. 内部模块及说明

Html5 模块负责抹平兼容性问题,对外提供统一的 API

Event 模块提供事件机制,支持原生事件及自定义事件

Plugin 模块用于提供插件机制,为各类插件提供基类,约定其接口及运行方式

Util 中包含一些常用的工具方法,比如对 DOM 的一些便捷操作函数

Player 模块聚合以上模块,用以实例化播放器以及对外提供接口

3. 事件机制

事件作为播放器内部核心的沟通机制,为内部的状态流转以及后续的扩展提供底层支持。

目前自定义事件系统的实现方式主要有 2 种:

DOM Event:HTML 原生 API,能够监听 DOM 相关事件,支持自定义事件,具有捕获、冒泡机制,需要一些兼容性处理

EventEmitter:JS 实现的事件机制,核心是一套『订阅发布模式』,允许自定义事件,拥有更加灵活的 API,无法监听 DOM 相关事件,基本无兼容性问题

由于 DOM Event 能够监听 DOM 相关事件,同时冒泡机制对后续 UI 插件的控制有一定的帮助,因此选用其作为自定义事件系统实现的基础。

通过 DOM Event 实现以下几类主要功能:

事件监听

事件注销

支持自定义事件类型

支持手动触发事件(通过 JS 触发而不是用户交互触发)

DOM Event 流程可通过下图概览:

4. 插件机制

插件是一种常用的『依赖反转』的方式,使得播放器不必依赖外部或下层组件,而是所有外部插件都依赖播放器本身。

同时各插件由于是面向的播放器接口,插件 A 不知道 插件 B 的存在,因此能极大地降低各插件(功能)间的耦合。

如何设计插件的类型和接口便关系到后续长期的发展,经过业务经验的总结以及对其他解决方案的参考,总结出以下 3 类插件类型:

UI 插件,DOM 相关,往往是要添加某些样式或交互,如皮肤、弹幕等

MSE 插件,播放技术相关,基于 Media Source Extension,可扩展播放器对其他视频类型的支持,如 m3u8、flv 等

其他插件,可以看做是一种保留类型,上述两种类型无法满足时,落到此类型,后续某类新的插件高频出现时,可再次抽离出新的类型

这几类插件如何运行呢?这里简单介绍下,具体可以参见设计文档或源码。

1.UI 插件

Component 类作为基类,提供事件、DOM 操作工具函数支持,可获取到播放器引用

组件化的方式开发,通过构建工具与代码配合,支持 JSX 语法

可在播放器初始化时传递参数,以及从播放器上获取插件实例

2.MSE 插件

MSEHandler 类作为基类,提供事件支持,可获取播放器引用,给予修改播放器 play 等方法的权限

可在播放器初始化时传递参数,以及从播放器上获取插件实例

3.其他插件

Plugin 类作为基类,提供事件支持,可获取播放器引用

可在播放器初始化时传递参数,以及从播放器上获取插件实例

实践

我们已经在多个业务中使用 larkplayer,并开发了十几个插件用于解决各种业务需求,支持了千万级/天的视频播放。

larkplayer 及其插件均支持以 script、npm 以及各种模块化的方式引用,你可以怎么舒服怎么来。

基本使用

larkplayer 使用方式十分简单,将以下代码粘贴到任意编辑器中,用浏览器打开即可运行,更详细的使用文档可以参考这里。

larkplayer quick start

// js 文件以 umd 的形式包装,以 script 的形式引用时,larkplayer 会直接挂载在 window 上

var width = Math.min(document.body.clientWidth, 640);

var player = larkplayer('container', {

width: width,

height: width * 9 / 16,

controls: true,

src: 'https://baikebcs.bdimg.com/baike-other/big-buck-bunny.mp4'

});

// 支持所有的 html5 标准事件以及一些自定义事件

player.on('play', function () {

console.log('play');

});

player.on('ended', function () {

console.log('播放完成!');

});

larkplayer 本身已经包含一些基础而核心的功能和机制,比如

功能上,支持 pause()、play()、requestFullscreen()、exitFullscreen()、currentTime(second)(跳转到某一时刻) 等

事件上,可以监听 play、pause、end、error、timeupdate、loadstart、fullscreen 等

更多的功能和事件可以查看 API。

使用插件

另外有一些常用但可能不是必须的功能,比如自定义样式、m3u8 文件播放、断点续播等,我们已经提供了一些插件:

插件的使用也十分简单,只需在 larkplayer 之后引入插件即可。

下面的代码为播放器添加了自定义的样式以及断点续播功能,将其粘贴到任意编辑器,用浏览器打开即可运行。

larkplayer plugin exmaple

var width = Math.min(document.body.clientWidth, 640);

var player = larkplayer('container', {

width: width,

height: width * 9 / 16,

controls: true,

src: 'https://baikebcs.bdimg.com/baike-other/big-buck-bunny.mp4'

});

larkplayer-ui 插件 能够自适应 PC 与 WAP 展现以下两种样式:

WAP 端样式

PC 端样式

值得一提的是,larkplayer-ui 是一种典型的 UI 类插件,这类插件支持 JSX 语法,书写起来非常方便。比如 WAP 端的样式,在代码中最终就像这样:

import classnames from 'classnames';

import {Component, util} from 'larkplayer';

import ControlBar from './control-bar';

import ProgressBarSimple from './progress-bar-simple';

import Loading from '../component/loading';

import PlayButton from '../component/play-button';

import NotSupport from '../component/not-support';

import Error from '../component/error';

export default class ControlsMobile extends Component {

createEl() {

return (

'lark-custom-controls',

'lark-custom-controls--mobile',

this.options.className)}

>

);

}

}

如果你有兴趣,也可以自己查看源码。

管理插件

larkplayer 的这种设计,使得他可能存在大量的插件,每次调用播放器后面都跟着大量的插件引用会导致重复的代码。这里给出一种解决方案:

1.新建 common/player.js 文件,将 larkplayer 和公用的插件封装在里面,业务上调用 common/player.js 即可

/**

* @file 视频播放器,包含 larkplayer 及所有公用插件

*/

import larkplayer from 'larkplayer';

import 'larkplayer-ui';

import 'larkplayer-hls';

import 'larkplaer-auto-resume';

...

export default larkplayer;

2.对于只在特定场景使用的插件,由于引用次数较少,在对应的场景引用即可

/**

* @file VR 视频播放

*/

import player from 'common/player.js';

import 'larkplayer-vr';

const myPlayer = player('video-el');

...

编写插件

以下是 3 类插件的编写示例:

其他

测试

采用 karma + jasmine 完成单测编码编写&运行

BrowserStack 提供真机环境用于测试回归

文档

一些示例、思想说明的文档手动编写

API 一类的文档由 nodejs 插件 jsdoc 从代码注释生成

构建

采用 grunt 构建,完成模块化、打包、压缩、代码转换等工作。

总览

以下是目前整个项目的结构组成

最后,如果你已经看到了这里,不妨到 github 上点个 star 吧,谢谢 :)

html5开发播放器,larkplayer: 插件化的 HTML5 播放器相关推荐

  1. larkplayer视频播放器: 同时支持PC、移动端 插件化的HTML5视频播放器。

    larkplayer:是一款轻量级 & 易扩展的 html5 播放器,是为解决一些中小型的视频业务场景.这些业务不一定需要大而全的解决方案,并且他们往往有自己的定制化需求. 介绍:larkpl ...

  2. android中的插件开发框架,设计并开发一个 Android 的插件化框架

    结合动态加载系列文章的分析,现在开始设计并开发一个 Android 的插件化框架,命名为 Frontia.Frontia 有 "前端" 的意思,寓意着 Android 插件能像前端 ...

  3. 开发日记-20190422 关键词 插件化(1)概述

    不知道什么时候,javaer这个名词已经成为了一个很通用的词汇,指代那些只知道使用新技术,在新技术出现之后静观其变,等其成熟之后,再用极短的时间学习其用法,然后宣布已经掌握这门新技术的程序员.所谓缺乏 ...

  4. 安卓 SDK 开发使用 VirtualAPK 实现插件化

    1. 背景 因为公司现在要在广告 SDK 开发中实现一部分代码的更新,或者是新增部分功能,因此需要从后台通过网络下载然后通过插件化的方式进行加载展示.本来想的是自己实现,但是遇到了一些问题,所以直接采 ...

  5. html5开发游戏的意义,web前端使用HTML5开发游戏的好处有哪些

    原标题:web前端使用HTML5开发游戏的好处有哪些 文章源于:http://www.makeru.com.cn/170613/000762.html 创客学院web前端培训讲师:众所周知,web前端 ...

  6. uniapp插件-腾讯云播放器sdk插件-腾讯云高清播放器-多码率支持-截图-播放控制-变速播放

    目前仅做了安卓版本,如果需求量可以的话我们会制作IOS版本的. 使用方法: 腾讯云播放器腾讯云目前是免费的,后期不知道,需要注册请访问腾讯云官网,优雅草伙伴注册链接: 点击访问腾讯云官网 关联优雅草科 ...

  7. html5开发wp8,WP7几则消息(HTML5,Sliverlight,WP8)

    Winrumors 又有关于WP7的几则新消息传出: 1. Windows Phone 7 的第一个更新将于 1月放出,包含包括复制粘贴在内的功能更新,而二月又将放出一次更新:第三方应用的多任务支持, ...

  8. flash 用 html 播放,使用flash插件在HTML上播放音频

    原文链接:WordPress Audio Player 非插件方式使用方法 Standalone version The standalone version comes with a JavaScr ...

  9. 【Android 插件化】“ 插桩式 “ 插件化框架 ( 代理 Activity 组件开发 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  10. Android插件化开发指南——Hook技术(一)【长文】

    文章目录 1. 前言 2. 将外部dex加载到宿主app的dexElements中 3. 插件中四大组件的调用思路 4. Hook 2.1 对startActivity进行Hook 2.1.1 AMS ...

最新文章

  1. jsp与java_JSP与JavaBeans
  2. Oracle审计--AUD$占用空间较大处理方案
  3. 第一次来写博客,这里可以记录很多故事。
  4. Linux 内核调试器 调试指南
  5. dockerfile构建镜像
  6. BZOJ 4992: [Usaco2017 Feb]Why Did the Cow Cross the Road
  7. 你的下一代iPhone何必是iPhone,苹果或将于2022年推出AR设备取代手机
  8. linux pwm 调屏_linux驱动---bl_pwm驱动与backlight class实现背光调整
  9. ASM1117-3.3V稳压芯片的典型电路图及分析
  10. mysql导入access2016_将 Access 2.0 和 Access 95 数据库导入到当前版本
  11. Deepin 20.1 安装nvidia显卡驱动 爬坑
  12. 关于宋宝华linux驱动学习视频的读后感
  13. ATX电源的基本描述
  14. 探究人工智能辅助新时代心理学研究
  15. android killer反编译闪退,Android Killer反编译失败
  16. 社会学与计算机哪个考研容易,国内几所较热的社会学系考研难度比较
  17. 如何屏蔽WPS广告弹窗
  18. 愿有岁月可回首,更敬年少一杯酒
  19. git总结的笔记分享给大家,git常用命令。
  20. python中用来返回序列的最大函数_Python程序设计2——列表和元组

热门文章

  1. HTML5第6章上机,第6章__HTML5的表单.ppt
  2. python抢演唱会门票_韩国演唱会抢票系统生产环境(Linux)配置记录
  3. Twitter数据抓取的方法(二)
  4. 论文笔记_S2D.75_2021-CoRL_TANDEM_基于深度多视图立体视觉的实时跟踪和稠密建图
  5. 论文笔记_S2D.63_2020-ICRA_LiStereo:从雷达和双目立体图像生成稠密深度图
  6. 论文笔记_S2D.62_VIL-SLAM_立体视觉惯性激光雷达同时定位和建图
  7. vector容器中是否应该放指针?解决方法
  8. ICCV2021 | 简单有效的长尾视觉识别新方案:蒸馏自监督(SSD)
  9. AI界的革命!终于可以自动标注了!
  10. a=a++问题引发的思考