Hooks
Hooks
为了业务定制或者复用播放器的内置功能,播放器内部实现了一个hook机制, hook分为两类
- 1. 内置插件在触发用户行为处理的hook
此类hook通常在由用户行为触发的时候执行,方便业务自由定制内置插件行为,例如定制error
插件内部的重试行为
- 2. 播放器核心控制播放流程的hook
此类hook用于实现一些高阶功能,例如hls、flv插件等在用户调用play之前要加载数据源之类的功能,业务层面使用不到, 也不建议使用
hook的执行流程如下所示
pluginHook
hookName | pluginName | 执行时机 |
---|---|---|
errorRetry | error | 错误插件用户点击刷新重试 |
showError | error | 错误插件监听到出错显示错误提示信息之前 |
fullscreenChange | fullscreen | 用户点击全屏按钮的时候 |
playNext | playnext | 用户点击播放下一个按钮的时候 |
previewClick | progresspreview | 进度条预览图插件用户点击某个预览图的时候 |
replayHandler | replay | 重播插件用户点击重播按钮的时候 |
click | start | 用户点击中间大播放按钮的时候 |
mutedChange | volume | 音量调节插件用户调节音量的时候 |
demo
在播放出错的时候,显示错误面板,用户点击刷新按钮的时候,重新请求服务端获取播放地址,然后重新恢复播放
import Player, { Events } from 'xgplayer'
const player = new Player({...})
/**
* 以下demo为启用error插件的errorRetry hook, 在出现错误的时候,用户点击【刷新】按钮的时候调用
*/
// hook逻辑为同步的时候
player.usePluginHooks('error', 'errorRetry', (plugin, ...args) => {
/**
* handler接收到的第一个参数为插件实例
* 其余参数根据不同hook的不同实现,具体看插件内hook的说明
*/
// playerInfo为提前获取到的对象
const url = playerInfo.back_up_url
const { player } = plugin
if (url) {
player.config.url = player.src = url
player.play()
// 阻止重试插件默认逻辑
return false
} else {
// 执行插件默认重试逻辑
return true
}
/**
* return true, 会执行插件内默认行为;
* return false, 插件内默认行为将不执行
*/
})
// hook逻辑为异步的时候
player.usePluginHooks('error', 'errorRetry', (plugin, ...args) => {
return new Promise(resolve => {
/**
* resolve(true) 继续执行默认行为
* resolve(false)或者reject() 不再执行默认行为
*/
const { player } = plugin
// getPlayerInfo为服务端播放数据
getPlayerInfo().then(data => {
// 重置播放源
player.config.url = player.src = data.url
player.play()
// 阻止重试插件默认逻辑
resolve(false)
}).catch(() => {
// 执行插件默认重试逻辑
resolve(true)
})
})
})
// 以上调用等同于在error插件上调用useHook
player.getPlugin('error').useHooks('errorRetry', (plugin, ...args) => {
// hook
})
playerHook
播放器可使用的hook如下列表如下所示
hookName | 含义 |
---|---|
play | 用户调用player.play的时候执行 |
pause | 用户调用player.pause()的时候执行 |
replay | 用户调用player.replay()的时候执行 |
retry | 用户调用player.retry()的时候执行 |
demo
假设hls插件需要在用户调用play接口之前加载相关的播放资源,实现如下
import Player, { Events } from 'xgplayer'
const player = new Player({...})
player.on(Events.PLAY, () => {
console.log('play Callback')
})
// 启用hook
player.useHooks('play', (player, ...args) => {
return new Promise(resolve => {
console.log('step1: play hook handler')
setTimeout() => {
if (资源ready) {
console.log('step2: source ready, can executed player.play()')
resolve(true)
} else {
console.log('step3: source not ready, block player.play()')
resolve(false)
}
}
})
})
// 用户点击按钮调用play接口
player.play()
// 以上代码执行顺序如下
/**
* 资源ready
* -- player.play()
* -- step1: play hook handler
* -- step2: source ready, can executed player.play()
* -- player.video.play()
* -- console.log('play Callback')
*/
/**
* !资源ready
* -- player.play()
* -- step1: play hook handler
* -- step3: source not ready, block player.play()
*/
EventsMiddleware
事件中间件,在媒体事件emit之前执行,用于决定某个事件是否下发,所有媒体事件都可添加中间件,使用demo如下
// 以下demo实现功能为
import Player, { Events } from 'xgplayer'
const player = new Player({...})
player.on(Events.WAITING, () => {
console.log('waiting Callback')
})
player.setEventsMiddleware({
waiting: (e, callback) => {
const { player, eventName } = e
if (canEmit) {
callback(eventName, e)
} else {
console.log('not need emit waiting')
}
}
})