mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-15 09:06:16 -08:00
分离播放器功能
This commit is contained in:
1 parent
3919ee2f3d
commit
617fd9681e
24 files changed
+671
-505
No files matched your search
@@ -1,9 +1,29 @@
|
||||
import { append, tooltip, setStyle } from '../utils';
|
||||
import icons from '../icons';
|
||||
|
||||
export default class FullscreenWeb {
|
||||
constructor(option) {
|
||||
this.option = option;
|
||||
this.state = false;
|
||||
}
|
||||
|
||||
apply(art, $control) {
|
||||
this.art = art;
|
||||
const { events: { proxy }, i18n, player, refs: { $player } } = art;
|
||||
this.$fullscreenWeb = append($control, icons.fullscreenWeb);
|
||||
tooltip(this.$fullscreenWeb, i18n.get('Web fullscreen'));
|
||||
proxy($control, 'click', () => {
|
||||
if (this.state) {
|
||||
this.state = false;
|
||||
$player.classList.remove('artplayer-web-fullscreen');
|
||||
setStyle(this.$fullscreenWeb, 'opacity', '1');
|
||||
tooltip(this.$fullscreenWeb, i18n.get('Web fullscreen'));
|
||||
} else {
|
||||
this.state = true;
|
||||
$player.classList.add('artplayer-web-fullscreen');
|
||||
setStyle(this.$fullscreenWeb, 'opacity', '0.8');
|
||||
tooltip(this.$fullscreenWeb, i18n.get('Exit web fullscreen'));
|
||||
}
|
||||
player.resetAspectRatio();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,8 @@ let i18nMap = {
|
||||
'Normal': '正常',
|
||||
'Switch video': '切换',
|
||||
'Switch subtitle': '切换字幕',
|
||||
'Web fullscreen': '网页全屏',
|
||||
'Exit web fullscreen': '退出网页全屏',
|
||||
'Common': '常规',
|
||||
'Hide setting': '隐藏设置',
|
||||
'Show setting': '显示设置'
|
||||
@@ -47,6 +49,8 @@ let i18nMap = {
|
||||
'Normal': '正常',
|
||||
'Switch video': '切換',
|
||||
'Switch subtitle': '切換字幕',
|
||||
'Web fullscreen': '網頁全屏',
|
||||
'Exit web fullscreen': '退出網頁全屏',
|
||||
'Common': '常規',
|
||||
'Hide setting': '隱藏設置',
|
||||
'Show setting': '顯示設置'
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22" style="width: 80%; height: 80%">
|
||||
<path d="M4,18h14V4H4V18z M6,6h10v10H6V6z"/>
|
||||
<polygon points="2,16 0,16 0,22 6,22 6,20 2,20"/>
|
||||
<polygon points="2,2 6,2 6,0 0,0 0,6 2,6"/>
|
||||
<polygon points="20,20 16,20 16,22 22,22 22,16 20,16"/>
|
||||
<polygon points="16,0 16,2 20,2 20,6 22,6 22,0"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 350 B |
+3
-1
@@ -8,6 +8,7 @@ import subtitle from './subtitle.svg';
|
||||
import screenshot from './screenshot.svg';
|
||||
import danmu from './danmu.svg';
|
||||
import setting from './setting.svg';
|
||||
import fullscreenWeb from './fullscreen-web.svg';
|
||||
|
||||
const icons = {
|
||||
loading,
|
||||
@@ -19,7 +20,8 @@ const icons = {
|
||||
subtitle,
|
||||
screenshot,
|
||||
danmu,
|
||||
setting
|
||||
setting,
|
||||
fullscreenWeb
|
||||
};
|
||||
|
||||
function creatDomFromSvg(map) {
|
||||
|
||||
-257
@@ -1,257 +0,0 @@
|
||||
import { clamp, secondToTime, setStorage, sleep, setStyle, sublings } from './utils';
|
||||
import config from './config';
|
||||
|
||||
export default class Player {
|
||||
constructor(art) {
|
||||
this.art = art;
|
||||
this.init();
|
||||
this.eventBind();
|
||||
this.firstCanplay = false;
|
||||
this.reconnectTime = 0;
|
||||
this.maxReconnectTime = 5;
|
||||
}
|
||||
|
||||
init() {
|
||||
const { option, refs: { $player, $video }, events: { proxy, hover } } = this.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;
|
||||
|
||||
hover($player, () => {
|
||||
$player.classList.add('artplayer-hover');
|
||||
this.art.emit('hoverenter');
|
||||
}, () => {
|
||||
$player.classList.remove('artplayer-hover');
|
||||
this.art.emit('hoverleave');
|
||||
});
|
||||
|
||||
proxy($video, 'click', () => {
|
||||
this.toggle();
|
||||
});
|
||||
|
||||
// TODO
|
||||
$video.src = option.url;
|
||||
}
|
||||
|
||||
eventBind() {
|
||||
const { option, 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', () => {
|
||||
if (!this.firstCanplay) {
|
||||
this.firstCanplay = true;
|
||||
this.art.emit('firstCanplay');
|
||||
}
|
||||
|
||||
this.art.controls.show();
|
||||
this.art.mask.show();
|
||||
this.art.loading.hide();
|
||||
if (option.autoplay) {
|
||||
this.play();
|
||||
}
|
||||
});
|
||||
|
||||
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 (option.loop) {
|
||||
this.seek(0);
|
||||
this.play();
|
||||
}
|
||||
});
|
||||
|
||||
this.art.on('video:error', () => {
|
||||
if (this.reconnectTime < this.maxReconnectTime) {
|
||||
sleep(1000).then(() => {
|
||||
this.reconnectTime++;
|
||||
$video.src = option.url;
|
||||
notice.show(`${i18n.get('Reconnect')}: ${this.reconnectTime}`);
|
||||
});
|
||||
} else {
|
||||
this.art.isError = true;
|
||||
this.art.isPlaying = false;
|
||||
this.art.loading.hide();
|
||||
this.art.controls.hide();
|
||||
$player.classList.add('artplayer-error');
|
||||
sleep(1000).then(() => {
|
||||
notice.show(i18n.get('Video load failed'), false);
|
||||
this.art.destroy();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
play() {
|
||||
const { refs: { $video }, i18n, notice } = this.art;
|
||||
const promise = $video.play();
|
||||
if (promise !== undefined) {
|
||||
promise.then().catch(err => {
|
||||
notice.show(err, true, 3000);
|
||||
console.warn(err);
|
||||
});
|
||||
}
|
||||
notice.show(i18n.get('Play'));
|
||||
this.art.emit('play', $video);
|
||||
}
|
||||
|
||||
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)}`);
|
||||
if ($video.volume !== 0) {
|
||||
setStorage('volume', $video.volume);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
switch(url, name = 'Unknown') {
|
||||
const { refs: { $video }, i18n, notice, isPlaying, option } = this.art;
|
||||
const currentTime = this.currentTime();
|
||||
$video.src = url;
|
||||
option.url = url;
|
||||
this.reconnectTime = 0;
|
||||
this.seek(currentTime);
|
||||
if (isPlaying) {
|
||||
this.play();
|
||||
}
|
||||
this.resetStyle();
|
||||
notice.show(`${i18n.get('Switch video')}: ${name}`);
|
||||
this.art.emit('switch', url);
|
||||
}
|
||||
|
||||
playbackRate(rate) {
|
||||
const { refs: { $video, $player }, i18n, notice } = this.art;
|
||||
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`}`);
|
||||
this.art.emit('playbackRate', newRate);
|
||||
}
|
||||
|
||||
aspectRatio(ratio) {
|
||||
const { refs: { $video, $player }, i18n, notice } = this.art;
|
||||
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 {
|
||||
setStyle($video, 'width', null);
|
||||
setStyle($video, 'height', null);
|
||||
setStyle($video, 'padding', null);
|
||||
delete $player.dataset.aspectRatio;
|
||||
}
|
||||
|
||||
notice.show(`${i18n.get('Aspect ratio')}: ${ratioName}`);
|
||||
this.art.emit('aspectRatio', ratio);
|
||||
}
|
||||
|
||||
resetStyle() {
|
||||
const { refs: { $video }, contextmenu } = this.art;
|
||||
|
||||
if (contextmenu.$playbackRate) {
|
||||
const $normal = contextmenu.$playbackRate.querySelector('.normal');
|
||||
sublings($normal).forEach(item => item.classList.remove('current'));
|
||||
$normal.classList.add('current');
|
||||
}
|
||||
|
||||
setStyle($video, 'width', null);
|
||||
setStyle($video, 'height', null);
|
||||
setStyle($video, 'padding', null);
|
||||
if (contextmenu.$aspectRatio) {
|
||||
const $default = contextmenu.$aspectRatio.querySelector('.default');
|
||||
sublings($default).forEach(item => item.classList.remove('current'));
|
||||
$default.classList.add('current');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import { setStyle, sublings } from '../utils';
|
||||
|
||||
export default function aspectRatioMix(art, player) {
|
||||
Object.defineProperty(player, 'aspectRatio', {
|
||||
value: ratio => {
|
||||
console.log(1);
|
||||
const { refs: { $video, $player }, i18n, notice } = art;
|
||||
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 {
|
||||
setStyle($video, 'width', null);
|
||||
setStyle($video, 'height', null);
|
||||
setStyle($video, 'padding', null);
|
||||
delete $player.dataset.aspectRatio;
|
||||
}
|
||||
|
||||
notice.show(`${i18n.get('Aspect ratio')}: ${ratioName}`);
|
||||
art.emit('aspectRatio', ratio);
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(player, 'removeAspectRatio', {
|
||||
value: () => {
|
||||
const { refs: { $video }, contextmenu: { $aspectRatio } } = art;
|
||||
setStyle($video, 'width', null);
|
||||
setStyle($video, 'height', null);
|
||||
setStyle($video, 'padding', null);
|
||||
if ($aspectRatio) {
|
||||
const $default = $aspectRatio.querySelector('.default');
|
||||
sublings($default).forEach(item => item.classList.remove('current'));
|
||||
$default.classList.add('current');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(player, 'resetAspectRatio', {
|
||||
value: () => {
|
||||
const { refs: { $player } } = art;
|
||||
const { aspectRatio } = $player.dataset;
|
||||
console.log($player.dataset);
|
||||
console.log(aspectRatio);
|
||||
if (aspectRatio) {
|
||||
player.aspectRatio(aspectRatio.split(':'));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { clamp } from '../utils';
|
||||
|
||||
export default function attrInit(art) {
|
||||
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;
|
||||
$video.src = 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,97 @@
|
||||
import config from '../config';
|
||||
import { sleep } from '../utils';
|
||||
|
||||
export default function eventInit(art, player) {
|
||||
const { option, events: { proxy, hover }, refs: { $player, $video }, i18n, notice } = art;
|
||||
let firstCanplay = false;
|
||||
|
||||
hover($player, () => {
|
||||
$player.classList.add('artplayer-hover');
|
||||
art.emit('hoverenter');
|
||||
}, () => {
|
||||
$player.classList.remove('artplayer-hover');
|
||||
art.emit('hoverleave');
|
||||
});
|
||||
|
||||
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.isError = true;
|
||||
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,32 @@
|
||||
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';
|
||||
|
||||
export default class Player {
|
||||
constructor(art) {
|
||||
this.reconnectTime = 0;
|
||||
this.maxReconnectTime = 5;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
export default function pauseMin(art, player) {
|
||||
Object.defineProperty(player, 'pause', {
|
||||
value: () => {
|
||||
const { refs: { $video }, i18n, notice } = art;
|
||||
$video.pause();
|
||||
notice.show(i18n.get('Pause'));
|
||||
art.emit('pause', $video);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
export default function playMix(art, player) {
|
||||
Object.defineProperty(player, 'play', {
|
||||
value: () => {
|
||||
const { refs: { $video }, i18n, notice } = art;
|
||||
const promise = $video.play();
|
||||
if (promise !== undefined) {
|
||||
promise.then().catch(err => {
|
||||
notice.show(err, true, 3000);
|
||||
console.warn(err);
|
||||
});
|
||||
}
|
||||
notice.show(i18n.get('Play'));
|
||||
art.emit('play', $video);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { clamp, sublings } from '../utils';
|
||||
|
||||
export default function playbackRateMix(art, player) {
|
||||
Object.defineProperty(player, 'playbackRate', {
|
||||
value: rate => {
|
||||
const { refs: { $video, $player }, i18n, notice } = art;
|
||||
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, 'removePlaybackRate', {
|
||||
value: () => {
|
||||
const { contextmenu: { $playbackRate } } = art;
|
||||
if ($playbackRate) {
|
||||
const $normal = $playbackRate.querySelector('.normal');
|
||||
sublings($normal).forEach(item => item.classList.remove('current'));
|
||||
$normal.classList.add('current');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { secondToTime } from '../utils';
|
||||
|
||||
export default function seekMix(art, player) {
|
||||
Object.defineProperty(player, 'seek', {
|
||||
value: time => {
|
||||
const { refs: { $video }, notice } = 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)}`);
|
||||
art.emit('seek', newTime);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
export default function switchMix(art, player) {
|
||||
Object.defineProperty(player, 'switch', {
|
||||
value: (url, name = 'Unknown') => {
|
||||
const { refs: { $video }, i18n, notice, isPlaying, option } = art;
|
||||
const currentTime = player.currentTime();
|
||||
$video.src = url;
|
||||
option.url = url;
|
||||
player.removePlaybackRate();
|
||||
player.removeAspectRatio();
|
||||
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,18 @@
|
||||
import { clamp, setStorage } from '../utils';
|
||||
|
||||
export default function volumeMix(art, player) {
|
||||
Object.defineProperty(player, 'volume', {
|
||||
value: percentage => {
|
||||
const { refs: { $video }, i18n, notice } = art;
|
||||
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;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
.art-icon {
|
||||
display: inline-block;
|
||||
line-height: 1.5;
|
||||
svg {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
.artplayer-video-player {
|
||||
&.artplayer-web-fullscreen {
|
||||
position: fixed;
|
||||
z-index: 9999;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
@@ -11,3 +11,4 @@ import './contextmenu.scss';
|
||||
import './setting.scss';
|
||||
import './info.scss';
|
||||
import './aspectRatio.scss';
|
||||
import './fullscreenWeb.scss';
|
||||
Reference in new issue
Block a user