import { clamp, secondToTime } from './utils'; import config from './config'; export default class Player { constructor(art) { this.art = art; this.init(); this.eventBind(); } init() { const { option } = this.art; const { $video } = this.art.refs; $video.controls = false; $video.poster = option.poster; $video.volume = clamp(option.volume, 0, 1); $video.autoplay = option.autoplay; $video.preload = option.preload; $video.src = option.url; } eventBind() { const { events: { proxy }, refs: { $player, $video }, i18n, notice } = this.art; config.video.events.forEach(eventName => { proxy($video, eventName, event => { this.art.emit(`video:${event.type}`, event); }); }); this.art.on('video:loadstart', () => { this.art.loading.show(); }); this.art.on('video:loadeddata', () => { this.art.loading.hide(); }); this.art.on('video:waiting', () => { this.art.loading.show(); }); this.art.on('video:seeking', () => { this.art.loading.show(); }); this.art.on('video:canplay', () => { this.art.controls.show(); this.art.mask.show(); this.art.loading.hide(); if (this.art.option.autoplay) { const promise = this.play(); if (promise !== undefined) { promise.then().catch(err => { console.warn(err); }); } } }); this.art.on('video:playing', () => { this.art.isPlaying = true; this.art.controls.hide(); this.art.mask.hide(); }); this.art.on('video:pause', () => { this.art.isPlaying = false; this.art.controls.show(); this.art.mask.show(); }); this.art.on('video:ended', () => { this.art.isPlaying = false; this.art.controls.show(); this.art.mask.show(); if (this.art.option.loop) { this.seek(0); this.play(); } }); this.art.on('video:error', () => { this.art.isError = true; this.art.isPlaying = false; this.art.loading.hide(); this.art.controls.hide(); $player.classList.add('artplayer-error'); notice.show(i18n.get('Video load failed'), false); this.art.destroy(); }); } play() { const { refs: { $video }, i18n, notice } = this.art; const promise = $video.play(); notice.show(i18n.get('Start')); this.art.emit('play', $video); return promise; } pause() { const { refs: { $video }, i18n, notice } = this.art; $video.pause(); notice.show(i18n.get('Pause')); this.art.emit('pause', $video); } toggle() { if (this.art.isPlaying) { this.pause(); } else { this.play(); } } seek(time) { const { refs: { $video }, notice } = this.art; let newTime = Math.max(time, 0); if ($video.duration) { newTime = Math.min(newTime, $video.duration); } $video.currentTime = newTime; notice.show(`${secondToTime(newTime)} / ${secondToTime($video.duration)}`); this.art.emit('seek', newTime); } volume(percentage) { const { refs: { $video }, i18n, notice } = this.art; if (percentage !== undefined) { $video.volume = clamp(percentage, 0, 1); notice.show(`${i18n.get('Volume')}: ${parseInt($video.volume * 100)}`); this.art.emit('volume', $video.volume); } return $video.volume || 0; } currentTime() { return this.art.refs.$video.currentTime || 0; } duration() { return this.art.refs.$video.duration || 0; } playbackRate(rate) { const { refs: { $video }, i18n, notice } = this.art; const newRate = clamp(rate, 0.1, 10); $video.playbackRate = newRate; notice.show(`${i18n.get('Rate')}: ${newRate}x`); this.art.emit('playbackRate', newRate); } }