larkplayer is a lightweight & easy to expand html5 player, it is to solve some of the small and medium business video scene. These services do not necessarily need a large and comprehensive solutions, and they often have their own customization requirements.
background
Why write larkplayer ? (Note that there are some of my personal views)
Currently html5 web player community has been more mature, videojs and jwplayer are all excellent solutions. However, the polarization of the community is more serious:
- Top-ranking players are basically a kind of "large and comprehensive" state: feature-rich & customization, volume several hundred K. For some relatively simple business, or a little too heavy, especially in the mobile side, doing the expansion may be due to some existing functions out of the way
- Some smaller players, often only solved the problem of their own particular business scenarios, the lack of scalability
- The existence of some large libraries (such as some players
jQuery
,AngularJS
rely, etc.), versatility and portability is not very good
Thus, for some small and medium sized business video scene, in fact, not a comfortable player options are available.
Think
How to solve the issue on appeal?
Business on:
- Lightweight, does not provide as much as possible "superfluous" function code small
- Easy to expand and can easily support a variety of customization requirements, such as advertising, skin, statistics, etc.
Code:
- Solve the compatibility problems, the trivial details remain inside, unified external interfaces
- Plug-in mechanism, decoupling the functions, interfaces and provide a convenient way to expand
- JavaScript prepared native, reduce dependence on libraries, and easy to use in various environments Transplantation
design
larkplayer inspiration from videojs , the use of plug-in design: the player itself is just a compact core, containing some of the necessary mechanisms and API, the remaining functions provided by the plug.
You are free to choose and write your own plug-ins, so that on-demand access, progressive enhancement. In the ugilfy
+ gzip
after, larkplayer code size about 12KB
.
1. Description internal modules and
-
Html5
Module is responsible for smooth compatibility issues, external to provide a unified API -
Event
Event module provides mechanisms to support native events and custom events -
Plugin
Means for providing plug-in mechanism provides the base class for all types of plug-ins, and run mode stipulated its interface -
Util
It contains some tools commonly used methods, such as easy operation of some DOM functions -
Player
Block polymerization more modules, for example of the player and provide external interfaces
2. API
3. The event mechanism
Event as an internal core player communication mechanism for the transfer of internal state and the subsequent extension provides the underlying support.
Currently implementation of custom event system are mainly two kinds:
- Event DOM : HTML native API, can listen DOM-related events, support for custom events, with capture, bubbling mechanism, it requires some compatibility processing
- EventEmitter : JS event mechanism implemented, the core is a set of "subscriptions to the publication mode" that allows custom events, have a more flexible API, not listen DOM-related events, almost no compatibility issues
Due to DOM Event
be able to listen for DOM-related events, while bubbling mechanism will certainly help to control the subsequent UI plug-in, so use it as the basis for custom event system implementation.
By DOM Event
realization of the main functions of the following categories:
- Event Listeners
- Event cancellation
- Support for custom event type
- Supports manual trigger events (JS triggered by user interaction rather than trigger)
DOM Event
FIG overview by the flow may:
4. The plug-in mechanism
Plug-in is a commonly used "Dependency Inversion" in a way that the player does not have to rely on external or underlying component, but all external plug-ins rely on the player itself.
At the same time because each plug is oriented player interface, plug A plug unaware of the existence of B, it is possible to greatly reduce the coupling between the respective insert (function).
How to design plug-in type and interface will be related to the development of long-term follow-up, after summary business experience as well as references to other solutions, summed up the following three categories of plug-in type:
- UI plug-ins, DOM related, often to add some style or interaction, such as skin, barrage, etc.
- MSE plug-in, play-related technology, based on
Media Source Extension
scalable video player supports other types, such as m3u8, flv, etc. - Other plug-in, it can be seen as a reservation type, the above two types can not be met, this type fall, the subsequent emergence of certain new high-frequency plug may be pulled out of a new type of re
How these types of plug-ins to run it? Here a brief introduction, you can see specific design documentation or source code .
1.UI plug
-
Component
Class as a base class that provides the event, DOM functions operating tool support, can be obtained by reference to the player - Development of component-based way, by building tools and codes with the support of
JSX
grammar - Passing parameters during playback initialization, and obtaining from the player plug-in instance
2.MSE plug
-
MSEHandler
Class as a base class that provides support for the event, players can get a reference, giving players modifyplay
permissions and other methods of - Passing parameters during playback initialization, and obtaining from the player plug-in instance
3. Other plug-ins
-
Plugin
Class as a base class that provides support for the event, players can get a reference - Passing parameters during playback initialization, and obtaining from the player plug-in instance
practice
我们已经在多个业务中使用 larkplayer,并开发了十几个插件用于解决各种业务需求,支持了千万级/天的视频播放。
larkplayer 及其插件均支持以 script
、npm
以及各种模块化
的方式引用,你可以怎么舒服怎么来。
基本使用
larkplayer 使用方式十分简单,将以下代码粘贴到任意编辑器中,用浏览器打开即可运行,更详细的使用文档可以参考这里。
<!DOCTYPE html>
<html>
<head>
<title>larkplayer quick start</title>
</head>
<body>
<div id="container"></div>
<script type="text/javascript" src="https://unpkg.com/larkplayer@latest/dist/larkplayer.js"></script>
<script type="text/javascript">
// 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('播放完成!');
});
</script>
</body>
</html>
larkplayer 本身已经包含一些基础而核心的功能和机制,比如
- 功能上,支持
pause()
、play()
、requestFullscreen()
、exitFullscreen()
、currentTime(second)
(跳转到某一时刻) 等 - 事件上,可以监听
play
、pause
、end
、error
、timeupdate
、loadstart
、fullscreen
等
更多的功能和事件可以查看 API。
使用插件
另外有一些常用但可能不是必须的功能,比如自定义样式、m3u8 文件播放、断点续播等,我们已经提供了一些插件:
- larkplayer-ui 提供了一套适应 PC 与 WAP 的皮肤
- larkplayer-hls 提供播放 m3u8 文件的功能
- larkplayer-vr 提供全景视频播放功能
- larkplayer-auto-resume 提供自动续播功能
- larkplayer-play-muted 提供静音播放时的 UI
插件的使用也十分简单,只需在 larkplayer 之后引入插件即可。
下面的代码为播放器添加了自定义的样式
以及断点续播
功能,将其粘贴到任意编辑器,用浏览器打开即可运行。
<!DOCTYPE html>
<html>
<head>
<title>larkplayer plugin exmaple</title>
</head>
<body>
<div id="container"></div>
<script type="text/javascript" src="https://unpkg.com/larkplayer@latest/dist/larkplayer.js"></script>
<!-- 自定义样式插件 https://github.com/dblate/larkplayer-ui -->
<script src="https://unpkg.com/larkplayer-ui@latest/dist/larkplayer-ui.js"></script>
<!-- 断点续播插件 https://github.com/dblate/larkplayer-auto-resume -->
<script type="text/javascript" src="https://unpkg.com/larkplayer-auto-resume@latest/dist/index.js"></script>
<script type="text/javascript">
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'
});
</script>
</body>
</html>
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 (
<div className={classnames(
'lark-custom-controls',
'lark-custom-controls--mobile',
this.options.className)}
>
<ControlBar />
<PlayButton />
<Loading />
<Error />
<ProgressBarSimple />
<NotSupport />
</div>
);
}
}
如果你有兴趣,也可以自己查看源码。
管理插件
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
从代码注释生成
构建
Using grunt
construct modular completion, packing, compression, transcoding, and so on.
Overview
The following is the structure and composition of the entire project
Finally, if you've seen here, to wish on a star point github it, thank you :)