修改包管理

This commit is contained in:
Harvey Zack committed 2018-11-07 17:12:42 +08:00
1 parent c5c673ae79
commit 0aa018db6d
99 files changed
+70 -70

No files matched your search

@@ -0,0 +1,60 @@
import { setStyle, sublings } from '../utils';
export default function aspectRatioMix(art, player) {
const { refs: { $video, $player }, i18n, notice } = art;
Object.defineProperty(player, 'aspectRatio', {
value: ratio => {
const ratioName = ratio.length === 2 ? `${ratio[0]}:${ratio[1]}` : i18n.get('Default');
if (ratio.length === 2) {
const { videoWidth, videoHeight } = $video;
const { clientWidth, clientHeight } = $player;
const videoRatio = videoWidth / videoHeight;
const setupRatio = Number(ratio[0]) / Number(ratio[1]);
if (videoRatio > setupRatio) {
const percentage = setupRatio * videoHeight / videoWidth;
setStyle($video, 'width', `${percentage * 100}%`);
setStyle($video, 'height', '100%');
setStyle($video, 'padding', `0 ${(clientWidth - clientWidth * percentage) / 2}px`);
} else {
const percentage = videoWidth / setupRatio / videoHeight;
setStyle($video, 'width', '100%');
setStyle($video, 'height', `${percentage * 100}%`);
setStyle($video, 'padding', `${(clientHeight - clientHeight * percentage) / 2}px 0`);
}
$player.dataset.aspectRatio = ratioName;
} else {
player.aspectRatioRemove();
}
notice.show(`${i18n.get('Aspect ratio')}: ${ratioName}`);
art.emit('aspectRatio', ratio);
}
});
Object.defineProperty(player, 'aspectRatioRemove', {
value: () => {
setStyle($video, 'width', null);
setStyle($video, 'height', null);
setStyle($video, 'padding', null);
delete $player.dataset.aspectRatio;
if (art.contextmenu.$aspectRatio) {
const $default = art.contextmenu.$aspectRatio.querySelector('.default');
sublings($default).forEach(item => item.classList.remove('current'));
$default.classList.add('current');
}
}
});
Object.defineProperty(player, 'aspectRatioReset', {
value: () => {
const { aspectRatio } = $player.dataset;
if (aspectRatio) {
player.aspectRatio(aspectRatio.split(':'));
}
}
});
}
+15
View File
@@ -0,0 +1,15 @@
import { clamp, sleep } from '../utils';
export default function attrInit(art, player) {
const { option, refs: { $video } } = art;
Object.keys(option.moreVideoAttr).forEach(key => {
$video[key] = option.moreVideoAttr[key];
});
$video.volume = clamp(option.volume, 0, 1);
$video.poster = option.poster;
$video.autoplay = option.autoplay;
sleep().then(() => {
art.emit('beforeMountUrl', option.url);
$video.src = player.mountUrl(option.url);
});
}
@@ -0,0 +1,5 @@
export default function currentTimeMix(art, player) {
Object.defineProperty(player, 'currentTime', {
value: () => art.refs.$video.currentTime || 0
});
}
@@ -0,0 +1,5 @@
export default function durationMix(art, player) {
Object.defineProperty(player, 'duration', {
value: () => art.refs.$video.duration || 0
});
}
@@ -0,0 +1,88 @@
import config from '../config';
import { sleep } from '../utils';
export default function eventInit(art, player) {
const { option, events: { proxy }, refs: { $player, $video }, i18n, notice } = art;
let firstCanplay = false;
proxy($video, 'click', () => {
player.toggle();
});
config.video.events.forEach(eventName => {
proxy($video, eventName, event => {
art.emit(`video:${event.type}`, event);
});
});
art.on('video:loadstart', () => {
art.loading.show();
});
art.on('video:loadeddata', () => {
art.loading.hide();
});
art.on('video:waiting', () => {
art.loading.show();
});
art.on('video:seeking', () => {
art.loading.show();
});
art.on('video:canplay', () => {
if (!firstCanplay) {
firstCanplay = true;
art.emit('firstCanplay');
}
art.controls.show();
art.mask.show();
art.loading.hide();
if (option.autoplay) {
player.play();
}
});
art.on('video:playing', () => {
art.isPlaying = true;
art.controls.hide();
art.mask.hide();
});
art.on('video:pause', () => {
art.isPlaying = false;
art.controls.show();
art.mask.show();
});
art.on('video:ended', () => {
art.isPlaying = false;
art.controls.show();
art.mask.show();
if (option.loop) {
player.seek(0);
player.play();
}
});
art.on('video:error', () => {
if (player.reconnectTime < player.maxReconnectTime) {
sleep(1000).then(() => {
player.reconnectTime++;
$video.src = option.url;
notice.show(`${i18n.get('Reconnect')}: ${player.reconnectTime}`);
});
} else {
art.isPlaying = false;
art.loading.hide();
art.controls.hide();
$player.classList.add('artplayer-error');
sleep(1000).then(() => {
notice.show(i18n.get('Video load failed'), false);
art.destroy();
});
}
});
}
@@ -0,0 +1,57 @@
import screenfull from 'screenfull';
export default function fullscreenMix(art, player) {
const { notice, events: { destroyEvents }, refs: { $player } } = art;
const screenfullChange = () => {
player.aspectRatioReset();
art.emit('fullscreen', screenfull.isFullscreen);
};
const screenfullError = () => {
notice.show('Your browser does not seem to support full screen functionality.');
};
screenfull.on('change', screenfullChange);
screenfull.on('error', screenfullError);
destroyEvents.push(() => {
screenfull.off('change', screenfullChange);
screenfull.off('error', screenfullError);
});
Object.defineProperty(player, 'fullscreenState', {
get: () => screenfull.isFullscreen
});
Object.defineProperty(player, 'fullscreenEnabled', {
value: () => {
if (player.fullscreenWebState) {
player.fullscreenWebExit();
}
$player.classList.add('artplayer-fullscreen');
screenfull.request($player);
art.emit('fullscreen:enabled');
}
});
Object.defineProperty(player, 'fullscreenExit', {
value: () => {
if (player.fullscreenWebState) {
player.fullscreenWebExit();
}
$player.classList.remove('artplayer-fullscreen');
screenfull.exit();
art.emit('fullscreen:exit');
}
});
Object.defineProperty(player, 'fullscreenToggle', {
value: () => {
if (player.fullscreenState) {
player.fullscreenExit();
} else {
player.fullscreenEnabled();
}
}
});
}
@@ -0,0 +1,39 @@
export default function fullscreenWebMix(art, player) {
const { refs: { $player } } = art;
Object.defineProperty(player, 'fullscreenWebState', {
get: () => $player.classList.contains('artplayer-web-fullscreen')
});
Object.defineProperty(player, 'fullscreenWebEnabled', {
value: () => {
if (player.fullscreenState) {
player.fullscreenExit();
}
$player.classList.add('artplayer-web-fullscreen');
player.aspectRatioReset();
art.emit('fullscreenWeb:enabled');
}
});
Object.defineProperty(player, 'fullscreenWebExit', {
value: () => {
if (player.fullscreenState) {
player.fullscreenExit();
}
$player.classList.remove('artplayer-web-fullscreen');
player.aspectRatioReset();
art.emit('fullscreenWeb:exit');
}
});
Object.defineProperty(player, 'fullscreenWebToggle', {
value: () => {
if (player.fullscreenWebState) {
player.fullscreenWebExit();
} else {
player.fullscreenWebEnabled();
}
}
});
}
+42
View File
@@ -0,0 +1,42 @@
import mountUrlMix from './mountUrlMix';
import attrInit from './attrInit';
import eventInit from './eventInit';
import playMix from './playMix';
import pauseMin from './pauseMin';
import toggleMix from './toggleMix';
import seekMix from './seekMix';
import volumeMix from './volumeMix';
import currentTimeMix from './currentTimeMix';
import durationMix from './durationMix';
import switchMix from './switchMix';
import playbackRateMix from './playbackRateMix';
import aspectRatioMix from './aspectRatioMix';
import screenshotMix from './screenshotMix';
import fullscreenMix from './fullscreenMix';
import fullscreenWebMix from './fullscreenWebMix';
import pipMix from './pipMix';
export default class Player {
constructor(art) {
this.reconnectTime = 0;
this.maxReconnectTime = 5;
mountUrlMix(art, this);
attrInit(art, this);
eventInit(art, this);
playMix(art, this);
pauseMin(art, this);
toggleMix(art, this);
seekMix(art, this);
volumeMix(art, this);
currentTimeMix(art, this);
durationMix(art, this);
switchMix(art, this);
playbackRateMix(art, this);
aspectRatioMix(art, this);
screenshotMix(art, this);
fullscreenMix(art, this);
fullscreenWebMix(art, this);
pipMix(art, this);
}
}
@@ -0,0 +1,6 @@
export default function mountUrlMix(art, player) {
Object.defineProperty(player, 'mountUrl', {
writable: true,
value: url => url
});
}
+11
View File
@@ -0,0 +1,11 @@
export default function pauseMin(art, player) {
const { refs: { $video }, i18n, notice } = art;
Object.defineProperty(player, 'pause', {
value: () => {
$video.pause();
notice.show(i18n.get('Pause'));
art.emit('pause', $video);
}
});
}
+69
View File
@@ -0,0 +1,69 @@
import Draggabilly from 'draggabilly';
import { setStyle, append } from '../utils';
export default function pipMix(art, player) {
const { option, i18n, refs: { $player, $pipClose, $pipTitle }, events: { destroyEvents, proxy } } = art;
let cachePos = null;
let draggie = null;
Object.defineProperty(player, 'pipState', {
get: () => $player.classList.contains('artplayer-pip')
});
Object.defineProperty(player, 'pipDraggie', {
get: () => draggie
});
Object.defineProperty(player, 'pipEnabled', {
value: () => {
if (!draggie) {
draggie = new Draggabilly($player, {
handle: '.artplayer-pip-header'
});
append($pipTitle, option.title || i18n.get('Mini player'));
proxy($pipClose, 'click', () => {
player.pipExit();
});
destroyEvents.push(() => {
draggie.destroy();
});
} else {
setStyle($player, 'left', `${cachePos.x}px`);
setStyle($player, 'top', `${cachePos.y}px`);
}
$player.classList.add('artplayer-pip');
player.fullscreenExit();
player.fullscreenWebExit();
player.aspectRatioRemove();
player.playbackRateRemove();
art.emit('pip', true);
}
});
Object.defineProperty(player, 'pipExit', {
value: () => {
$player.classList.remove('artplayer-pip');
cachePos = draggie.position;
setStyle($player, 'left', null);
setStyle($player, 'top', null);
player.fullscreenExit();
player.fullscreenWebExit();
player.aspectRatioRemove();
player.playbackRateRemove();
art.emit('pip', false);
}
});
Object.defineProperty(player, 'pipToggle', {
value: () => {
if (player.pipState) {
player.pipExit();
} else {
player.pipEnabled();
}
}
});
}
+24
View File
@@ -0,0 +1,24 @@
export default function playMix(art, player) {
const { refs: { $video }, i18n, notice, option: { mutex } } = art;
Object.defineProperty(player, 'play', {
value: () => {
const promise = $video.play();
if (promise !== undefined) {
promise.then().catch(err => {
notice.show(err, true, 3000);
console.warn(err);
});
}
if (mutex) {
art.constructor.instances
.filter(item => item !== art)
.forEach(item => item.player.pause());
}
notice.show(i18n.get('Play'));
art.emit('play', $video);
}
});
}
@@ -0,0 +1,36 @@
import { clamp, sublings } from '../utils';
export default function playbackRateMix(art, player) {
const { refs: { $video, $player }, i18n, notice } = art;
Object.defineProperty(player, 'playbackRate', {
value: rate => {
const newRate = clamp(rate, 0.1, 10);
$video.playbackRate = newRate;
$player.dataset.playbackRate = newRate;
notice.show(`${i18n.get('Rate')}: ${newRate === 1 ? i18n.get('Normal') : `${newRate}x`}`);
art.emit('playbackRate', newRate);
}
});
Object.defineProperty(player, 'playbackRateRemove', {
value: () => {
player.playbackRate(1);
delete $player.dataset.playbackRate;
if (art.contextmenu.$playbackRate) {
const $normal = art.contextmenu.$playbackRate.querySelector('.normal');
sublings($normal).forEach(item => item.classList.remove('current'));
$normal.classList.add('current');
}
}
});
Object.defineProperty(player, 'playbackRateReset', {
value: () => {
const { playbackRate } = $player.dataset;
if (playbackRate) {
player.playbackRate(Number(playbackRate));
}
}
});
}
@@ -0,0 +1,33 @@
import { setStyle, secondToTime } from '../utils';
export default function screenshotMix(art, player) {
const { option, notice } = art;
function captureFrame() {
const { $video } = art.refs;
const canvas = document.createElement('canvas');
canvas.width = $video.videoWidth;
canvas.height = $video.videoHeight;
canvas.getContext('2d').drawImage($video, 0, 0);
const dataUri = canvas.toDataURL('image/png');
const elink = document.createElement('a');
setStyle(elink, 'display', 'none');
elink.href = dataUri;
elink.download = `${option.title || 'artplayer'}_${secondToTime($video.currentTime)}.png`;
document.body.appendChild(elink);
elink.click();
document.body.removeChild(elink);
}
Object.defineProperty(player, 'screenshot', {
value: () => {
try {
captureFrame();
art.emit('screenshot');
} catch (error) {
notice.show(error);
console.warn(error);
}
}
});
}
+17
View File
@@ -0,0 +1,17 @@
import { secondToTime } from '../utils';
export default function seekMix(art, player) {
const { refs: { $video }, notice } = art;
Object.defineProperty(player, 'seek', {
value: time => {
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)}`);
art.emit('seek', newTime);
}
});
}
@@ -0,0 +1,21 @@
export default function switchMix(art, player) {
const { refs: { $video }, i18n, notice, isPlaying, option } = art;
Object.defineProperty(player, 'switch', {
value: (url, name = 'unknown') => {
const currentTime = player.currentTime();
art.emit('beforeMountUrl', url);
$video.src = player.mountUrl(url);
option.url = url;
player.playbackRateRemove();
player.aspectRatioRemove();
player.reconnectTime = 0;
player.seek(currentTime);
if (isPlaying) {
player.play();
}
notice.show(`${i18n.get('Switch video')}: ${name}`);
art.emit('switch', url);
}
});
}
@@ -0,0 +1,11 @@
export default function toggleMix(art, player) {
Object.defineProperty(player, 'toggle', {
value: () => {
if (art.isPlaying) {
player.pause();
} else {
player.play();
}
}
});
}
@@ -0,0 +1,19 @@
import { clamp, setStorage } from '../utils';
export default function volumeMix(art, player) {
const { refs: { $video }, i18n, notice } = art;
Object.defineProperty(player, 'volume', {
value: percentage => {
if (percentage !== undefined) {
$video.volume = clamp(percentage, 0, 1);
notice.show(`${i18n.get('Volume')}: ${parseInt($video.volume * 100)}`);
if ($video.volume !== 0) {
setStorage('volume', $video.volume);
}
art.emit('volume', $video.volume);
}
return $video.volume || 0;
}
});
}