video.js与plyr.js
前台feed流中需要做视频播放功能,自己本来采用的是第三方库
video.js
,再去自定义皮肤。做出来的效果还不错,嘻嘻。奈何老大说太大了,video.js
gzip压缩过后在300kb
左右,而plyr
不超过30kb
。
为了这个
html5
播放器,自己也是花了点时间去比对研究这两个js库,中间也是遇到了各种各样的坑。以下是我对这两个js库的拙见
视频容器
之所以采用
div
来作为视频容器,还是由于后台的富文本编辑器需要插入视频
和预览视频
的功能,复杂的dom结构不利于存储。自定义属性用来存储视频信息
-
class
容器类名 -
data-src
视频资源地址 -
data-img
封面图地址 -
width
容器宽度 -
height
容器高度
<div class="customvideo"
data-src="https://video.lanehub.cn/48f7c11baafc44a7a1f1a959ac1d2de3/7112d8d643864053b942b71d7566b1fc-1a97605ef90cc213707b52e4c15cecea-od-S00000001-200000.mp4"
data-img="https://www.lanehub.cn/static/img/about_img_01.f38c6d0.jpg"
width="750px" height="750px"></div>
初始化
将video初始化等一系列操作封装在函数中,便于封装为独立的组件。
-
video.js
的初始化函数
function videoInit() {
// 获取video容器(文章中可能插入多个视频)
const videoBox = document.getElementsByClassName('customvideo');
for(let i = 0, LEN = videoBox.length; i < LEN; i++){
if(!videoBox[i]) break;
// 清空所有子节点
videoBox[i].innerHTML = '';
// 获取属性值
const video_url = videoBox[i].getAttribute('data-src');
const poster_url = videoBox[i].getAttribute('data-img');
const video_width = parseInt(videoBox[i].getAttribute('width'), 10);
const video_height = parseInt(videoBox[i].getAttribute('height'), 10);
// video配置项(根据具体需求去设置options)
const options = {
aspectRatio: `${video_width}:${video_height}` || '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值
sources: [ // 资源
{
type: 'video/mp4', // 资源类型
src: video_url // 资源url
}
],
poster: poster_url, // 封面地址
notSupportedMessage: '此视频暂无法播放,请稍后再试', // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
controlBar: {
playToggle: false, // 播放按钮
progressControl: true, // 进度条
volumePanel: false && { // 是否显示声音按钮
inline: false,
vertical: true
},
timeDivider: false, // 时间分割线
durationDisplay: true, // 总时间
remainingTimeDisplay: false, // 剩余时间
fullscreenToggle: true // 全屏按钮
}
};
// 创建video标签并设置属性
const myVideo = document.createElement('video');
const videoId = `my-video-${String(Math.random()).slice(2)}`; // 随机数
myVideo.setAttribute('id', videoId);
myVideo.setAttribute('class', 'video-js');
myVideo.setAttribute('controls', true);
// 阻止自动全屏
myVideo.setAttribute('playsinline', true);
myVideo.setAttribute('x5-playsinline', true);
myVideo.setAttribute('webkit-playsinline', true);
myVideo.setAttribute('x-webkit-airplay', 'allow');
// 插入video标签
videoBox[i].appendChild(myVideo);
// video初始化
videojs(videoId, options, function ready() {
// 给中间的大播放按钮添加事件(应该还有其他好的方案)
let isPlaying = false;
this.on('play', () => {
isPlaying = true;
});
this.on('pause', () => {
isPlaying = false;
});
function toggle() {
if(isPlaying){
this.pause();
} else {
this.play();
}
}
// 播放暂停按钮事件
this.bigPlayButton.on('touchend', toggle.bind(this));
this.bigPlayButton.on('click', toggle.bind(this));
});
}
}
-
plyr.js
的初始化函数
function plyrInit() {
// 获取video容器
const videoBox = document.getElementsByClassName('customvideo');
for(let i = 0, LEN = videoBox.length; i < LEN; i++){
if(!videoBox[i]) break;
// 清空所有子节点
videoBox[i].innerHTML = '';
// 获取属性值
const video_url = videoBox[i].getAttribute('data-src');
const poster_url = videoBox[i].getAttribute('data-img');
const video_width = parseInt(videoBox[i].getAttribute('width'), 10);
const video_height = parseInt(videoBox[i].getAttribute('height'), 10);
// video配置项
const options = {
fullscreen: {
iosNative: true // 进入全屏时是否使用原生iOS全屏(建议开启)
},
controls: ['play-large', 'duration', 'progress', 'current-time', 'fullscreen']
};
// 创建video标签并设置属性
const myVideo = document.createElement('video');
const videoId = `my-video-${String(Math.random()).slice(2)}`; // ETC 随机数
myVideo.setAttribute('id', videoId);
// 插入video标签
videoBox[i].appendChild(myVideo);
// video初始化
const player = new Plyr(`#${videoId}`, options);
// 设置video资源文件
player.source = {
type: 'video',
sources: [
{
src: video_url,
type: 'video/mp4'
}
],
poster: poster_url
};
const contain = document.querySelector('.customvideo').offsetWidth;
const video = document.querySelector('.customvideo .plyr video');
video.muted = false;
// plyr中ratio属性不支持h5播放器,不得已采用这种方式
video.style.height = (contain / (video_height >= video_width ? 1 : video_width / video_height)) + 'px';
}
}
自定义皮肤
以上的
html
结构和javascript
交互基本可以实现我们看片的需求了,但要想更愉悦的观赏,必然少不了css来美化。
相信不同的设计师小伙伴都会给出她们独有的controlBar样式。这个大一点,这边差了一像素,总之就是要花里胡哨的黑。这里我就不赘述了,有疑问的小伙伴欢迎一起讨论。最后来一波预览图