有此需求能换就换吧,实在像我一样不能换的,那就一起改改源码吧。
一、自定义控制栏,步骤如下(以增加一个倍速按钮为例子)
1.修改ui模板:
<!-- 文件:player.art -->
<!-- 右侧按钮容器 -->
<div class="dplayer-icons dplayer-icons-right">
<!-- 新增一个按钮 -->
<div class="dplayer-speed">
<!-- 显示的按钮 -->
<button class="dplayer-icon dplayer-speed-icon" data-balloon="{{ tran('Setting') }}" data-balloon-pos="up">
<span class="dplayer-icon-content"><span class="speed-value">1</span>倍</span>
</button>
<!-- 弹出的菜单 没有可略 -->
<div class="dplayer-speed-box">
{{ each options.playbackSpeed }}
<div class="dplayer-speed-speed-item" data-speed="{{ $value }}">
<span class="dplayer-label">{{ $value === 1 ? tran('Normal') : $value }}</span>
</div>
{{ /each }}
</div>
</div>
</div>
2. 读取新增元素 template.js
// 文件 template.js
init() {
// 按钮
this.speedButton = this.container.querySelector('.dplayer-speed-icon');
// 以下可略
// 弹框
this.speedBox = this.container.querySelector('.dplayer-speed-box');
// 子元素
this.speedBoxItem = this.container.querySelectorAll('.dplayer-speed-speed-item');
// 按钮中显示当前的倍速
this.speedValueDom = this.container.querySelector('.dplayer-speed-icon .speed-value');
}
3. 样式(略):controller.scss
4. 为元素添加处理逻辑,可以在controller.js中处理,本人不想修改原来的代码新增了一个MyControllItem类。
// 此类在player.js中的构造方法实例化就好
class MyControllItem {
constructor(player) {
this.player = player;
// 透明蒙层,用来隐藏
this.player.template.mask.addEventListener('click', () => {
this.hide();
});
// 点击按钮显示菜单
this.player.template.speedButton.addEventListener('click', () => {
this.show();
});
// 为子菜单添加事件
for (let i = 0; i < this.player.template.speedBoxItem.length; i++) {
// speed item
this.player.template.speedBoxItem[i].addEventListener('click', () => {
const speed = this.player.template.speedItem[i].dataset.speed;
this.player.speed(speed);
this.player.template.speedValueDom.innerHTML = speed;
this.hide();
});
}
}
hide() {
this.player.template.speedBox.classList.remove('dplayer-speed-box-open');
this.player.template.mask.classList.remove('dplayer-mask-show');
this.player.controller.disableAutoHide = false;
}
show() {
this.player.template.speedBox.classList.add('dplayer-speed-box-open');
this.player.template.mask.classList.add('dplayer-mask-show');
this.player.controller.disableAutoHide = true;
}
}
export default MyControllItem;
二、新增on事件类型
1. events.js中新增click_time_progress事件类型,如下所示
// 修改events.js
class Events {
constructor() {
this.events = {};
// 1. 新增事件名称
this.videoEvents = [ // 视频播放状态变更事件
'abort',
'canplay',
'canplaythrough',
'durationchange',
'emptied',
'ended',
'error',
'loadeddata',
'loadedmetadata',
'loadstart',
'mozaudioavailable',
'pause',
'play',
'playing',
'progress',
'ratechange',
'seeked',
'seeking',
'stalled',
'suspend',
'timeupdate',
'volumechange',
'waiting',
];
this.playerEvents = [ // 视频操作事件
'click_time_progress', // 新增的名称
'screenshot',
'thumbnails_show',
'thumbnails_hide',
'danmaku_show',
'danmaku_hide',
'danmaku_clear',
'danmaku_loaded',
'danmaku_send',
'danmaku_opacity',
'contextmenu_show',
'contextmenu_hide',
'notice_show',
'notice_hide',
'quality_start',
'quality_end',
'destroy',
'resize',
'fullscreen',
'fullscreen_cancel',
'webfullscreen',
'webfullscreen_cancel',
'subtitle_show',
'subtitle_hide',
'subtitle_change',
];
}
on(name, callback) {
if (this.type(name) && typeof callback === 'function') {
if (!this.events[name]) {
this.events[name] = [];
}
this.events[name].push(callback);
}
}
// 2. 业务逻辑中
trigger(name, info) {
if (this.events[name] && this.events[name].length) {
for (let i = 0; i < this.events[name].length; i++) {
this.events[name][i](info);
}
}
}
}
export default Events;
2. 使用,以controller.js中使用为例:
this.player.events.trigger('click_time_progress', data); // this.player为player.js的实例
npm run build后就可以用拉,完整修改内容可在项目fork地址看一下提交记录。
就酱。