');
this.$message.appendTo($(selector));
}
info(text, duration = 1500) {
this.$message.empty();
$(`
${text}
`).hide().appendTo(this.$message).fadeIn(150).delay(duration).fadeOut(150, function () {
$(this).remove();
});
}
destroy() {
this.$message.empty();
}
}
const speedList = [0.5, 0.75, 1, 1.25, 1.5, 2, 4];
class KPlayer {
/**
* Creates an instance of KPlayer.
* @param {stromg} selector
* @param {Plyr.Options} opts
*/
constructor(selector, opts) {
const $wrapper = $('
').replaceAll(selector);
const $loading = $(loadingHTML);
const $error = $(errorHTML);
const $video = $('
');
$wrapper.append($video);
this.plyr = new Plyr('#k-player', {
autoplay: true,
keyboard: {
global: true
},
controls: [// 'play-large', // The large play button in the center
'play', // Play/pause playback
'progress', // The progress bar and scrubber for playback and buffering
'current-time', // The current time of playback
'duration', // The full duration of the media
'mute', // Toggle mute
'volume', // Volume control
'settings', // Settings menu
'pip', // Picture-in-picture (currently Safari only)
'fullscreen' // Toggle fullscreen
],
seekTime: 5,
speed: {
options: speedList
},
i18n: {
restart: '重播',
rewind: '快退 {seektime}s',
play: '播放',
pause: '暂停',
fastForward: '快进 {seektime}s',
seek: 'Seek',
seekLabel: '{currentTime} / {duration}',
played: '已播放',
buffered: '已缓冲',
currentTime: '当前时间',
duration: '片长',
volume: '音量',
mute: '静音',
unmute: '取消静音',
enableCaptions: '显示字幕',
disableCaptions: '隐藏字幕',
download: '下载',
enterFullscreen: '进入全屏',
exitFullscreen: '退出全屏',
frameTitle: '标题名称: {title}',
captions: '字幕',
settings: '设置',
pip: '画中画',
menuBack: '返回上级',
speed: '倍速',
normal: '1.0x',
quality: '分辨率',
loop: '循环',
start: '开始',
end: '结束',
all: '全部',
reset: '重置',
disabled: '禁用',
enabled: '启用',
advertisement: '广告',
qualityBadge: {
2160: '4K',
1440: 'HD',
1080: 'HD',
720: 'HD',
576: 'SD',
480: 'SD'
}
},
tooltips: {
controls: true,
seek: true
},
...opts
});
this.$wrapper = $wrapper;
this.$loading = $loading;
this.$error = $error;
this.$video = $video;
this.$videoWrapper = $wrapper.find('.plyr');
this.$videoWrapper.append($loading).append($error);
this.message = new Message(this.$videoWrapper);
this.eventMap = {};
this.isWideScreen = false;
this.wideScreenBodyStyles = {};
this.statusSessionKey = 'k-player-status';
this._injectNext();
this._injectSreen();
this._initEvent();
/** @private */
this.isHoverControls = false;
/** @private */
this.hideCursorDebounced = debounce(() => {
const dom = document.querySelector('.plyr');
dom.classList.add('plyr--hide-cursor');
}, 1000);
/** @private */
this.hideControlsDebounced = debounce(() => {
const dom = document.querySelector('.plyr');
if (!this.isHoverControls) dom.classList.add('plyr--hide-controls');
}, 1000);
const status = window.sessionStorage.getItem(this.statusSessionKey);
if (status) {
window.sessionStorage.removeItem(this.statusSessionKey);
this._toggleFullscreen(JSON.parse(status));
}
}
/** @private */
_initEvent() {
this.on('loadstart', () => {
this.$loading.show();
this.hideError();
});
this.on('canplay', () => {
this.$loading.hide();
this.plyr.play();
});
this.on('error', () => {
this.$loading.hide();
this.showError(this.src);
});
this.on('pause', () => {
this.hideControlsDebounced();
});
$(window).on('keydown', e => {
let idx = speedList.indexOf(this.plyr.speed);
if (e.metaKey || e.shiftKey || e.altKey || e.ctrlKey) return;
switch (e.key) {
case 'n':
case 'PageDown':
e.preventDefault();
this.trigger('next');
break;
case 'p':
case 'PageUp':
e.preventDefault();
this.trigger('prev');
break;
case 'w':
if (this.plyr.fullscreen.active) break;
this._toggleFullscreen();
break;
case 'Escape':
if (this.plyr.fullscreen.active || !this.isWideScreen) break;
this._toggleFullscreen(false);
break;
case 'z':
this.plyr.speed = 1;
this.message.info(`视频速度:${1}`);
break;
case 'x':
case 'c':
{
const newIdx = e.key === 'x' ? Math.max(0, idx - 1) : Math.min(speedList.length - 1, idx + 1);
if (newIdx === idx) break;
const speed = speedList[newIdx];
this.message.info(`视频速度:${speed}`);
this.plyr.speed = speed;
break;
}
}
});
document.querySelectorAll('.plyr__controls .plyr__control').forEach(dom => {
dom.addEventListener('click', e => {
e.currentTarget.blur();
});
});
const playerEl = document.querySelector('.plyr');
playerEl.addEventListener('mousemove', () => {
playerEl.classList.remove('plyr--hide-cursor');
this.hideCursorDebounced();
if (this.plyr.paused) {
this.hideControlsDebounced();
}
});
const controlsEl = document.querySelector('.plyr__controls');
controlsEl.addEventListener('mouseenter', () => {
this.isHoverControls = true;
});
controlsEl.addEventListener('mouseleave', () => {
this.isHoverControls = false;
});
}
/** @typedef {'prev'|'next'|'enterwidescreen'|'exitwidescreen'} CustomEventMap */
/**
* @param {CustomEventMap | keyof Plyr.PlyrEventMap} event
* @param {function} callback
* @private
*/
on(event, callback) {
if (['prev', 'next', 'enterwidescreen', 'exitwidescreen'].includes(event)) {
if (!this.eventMap[event]) this.eventMap[event] = [];
this.eventMap[event].push(callback);
} else {
this.plyr.on(event, callback);
}
}
/**
* @param {CustomEventMap} event
* @param {*} [params]
*/
trigger(event, params) {
const fnList = this.eventMap[event] || [];
fnList.forEach(fn => {
fn(this, params);
});
}
/** @private */
_injectNext() {
$($('#plyr__next').html()).insertBefore('.plyr__controls__item.plyr__progress__container').on('click', () => {
this.trigger('next');
});
}
/** @private */
_injectSreen() {
$($('#plyr__widescreen').html()).insertBefore('[data-plyr="fullscreen"]').on('click', () => {
this._toggleFullscreen();
});
}
/** @private */
_toggleFullscreen(bool = !this.isWideScreen) {
if (this.isWideScreen === bool) return;
this.isWideScreen = bool;
window.sessionStorage.setItem(this.statusSessionKey, JSON.stringify(this.isWideScreen));
if (this.isWideScreen) {
this.wideScreenBodyStyles = $('body').css(['overflow']);
$('body').css('overflow', 'hidden');
this.$wrapper.addClass('k-player-widescreen');
$('.plyr__widescreen').addClass('plyr__control--pressed');
} else {
$('body').css(this.wideScreenBodyStyles);
this.$wrapper.removeClass('k-player-widescreen');
$('.plyr__widescreen').removeClass('plyr__control--pressed');
}
this.trigger(this.isWideScreen ? 'enterwidescreen' : 'exitwidescreen');
}
/**
* video src
* @param {string} src
*/
set src(src) {
this.$video.attr('src', src);
}
get src() {
return this.$video.attr('src');
}
set currentTime(value) {
this.plyr.currentTime = value;
}
get currentTime() {
return this.plyr.currentTime;
}
showError(text) {
this.$error.show().find('.error-info').text(text);
}
hideError() {
this.$error.hide();
}
}
function addReferrerMeta() {
if ($('meta[name=referrer]').length === 0) {
$('head').append('
');
} else {
const $meta = $('meta[name=referrer]');
$meta.attr('content', 'same-origin');
}
}
function showInfo() {
const video = $('#k-player')[0];
const githubIssueURL = genIssueURL({
title: '🐛[Bug]',
body: issueBody(video === null || video === void 0 ? void 0 : video.src)
});
modal({
title: '脚本信息',
content: scriptInfo(video, githubIssueURL)
});
}
$(window).on('keydown', e => {
if ('??'.includes(e.key) && !document.fullscreenElement) {
e.stopPropagation();
e.preventDefault();
showInfo();
}
});
function replacePlayer$1() {
const dom = document.getElementById('age_playfram');
const fn = () => {
if (!dom.src) return;
let url = new URL(dom.src);
if (url.hostname.includes('agefans')) {
let videoURL = url.searchParams.get('url');
if (videoURL) {
addReferrerMeta();
initPlayer(videoURL);
mutationOb.disconnect();
}
} else {
const message = new Message('#ageframediv');
message.info('这个视频似乎是第三方链接,并非由agefans自身提供,将使用默认播放器播放', 3000);
mutationOb.disconnect();
}
};
const mutationOb = new MutationObserver(fn);
mutationOb.observe(dom, {
attributes: true
});
fn();
}
function showCurrentLink(vurl) {
if ($('#current-link').length) {
return $('#current-link').text(vurl);
}
$(`
本集链接:
${decodeURIComponent(vurl)}
`).insertBefore($('.baseblock:contains(网盘资源)'));
}
function gotoPrevPart() {
const dom = getActivedom().parent().prev().find('a');
if (dom.length) {
switchPart(dom.data('href'), dom);
}
}
function gotoNextPart$1() {
const dom = getActivedom().parent().next().find('a');
if (dom.length) {
switchPart(dom.data('href'), dom);
}
}
function getActivedom() {
return $("li a[style*='color: rgb(238, 0, 0)']");
}
/**
*
* @param {string} href
* @param {JQuery
} $dom
* @param {boolean} [push]
*/
async function switchPart(href, $dom, push = true) {
try {
const vurl = await getVurlWithLocal(href);
player$1.src = vurl;
showCurrentLink(vurl);
const $active = getActivedom();
$active.css('color', '');
$active.css('border', '');
const title = document.title.replace($active.text(), $dom.text());
push && history.pushState({}, title, href);
document.title = title;
$dom.css('color', 'rgb(238, 0, 0)');
$dom.css('border', '1px solid rgb(238, 0, 0)');
his.logHistory();
} catch (error) {
console.error(error);
window.location.href = href;
}
}
function initPlayPageStyle() {
let dom = document.querySelector('.fullscn');
dom.remove();
let ageframediv = document.getElementById('ageframediv');
let {
width
} = ageframediv.getBoundingClientRect();
ageframediv.style.height = width / 16 * 9 + 'px';
}
function updateTime(time = 0) {
var _location$pathname$ma;
const id = (_location$pathname$ma = location.pathname.match(/\/play\/(\d*)/)) === null || _location$pathname$ma === void 0 ? void 0 : _location$pathname$ma[1];
if (!id) return;
his.setTime(id, Math.floor(time));
}
function videoJumpHistoryPosition() {
var _location$pathname$ma2, _his$get;
const id = (_location$pathname$ma2 = location.pathname.match(/\/play\/(\d*)/)) === null || _location$pathname$ma2 === void 0 ? void 0 : _location$pathname$ma2[1];
if (!id) return;
if (((_his$get = his.get(id)) === null || _his$get === void 0 ? void 0 : _his$get.time) > 3) {
player$1.currentTime = his.get(id).time;
player$1.message.info(`已自动跳转至历史播放位置 ${parseTime(his.get(id).time)}`);
}
}
function addListener() {
player$1.on('next', () => {
gotoNextPart$1();
});
player$1.on('ended', () => {
gotoNextPart$1();
});
player$1.on('prev', () => {
gotoPrevPart();
});
player$1.plyr.once('canplay', () => {
videoJumpHistoryPosition();
});
player$1.on('error', () => {
removeLocal(getActivedom().data('href'));
});
player$1.on('timeupdate', () => {
if (Math.floor(player$1.currentTime) % 3 === 0) {
updateTime(player$1.currentTime);
}
});
window.addEventListener('popstate', () => {
const href = location.pathname + location.search;
const $dom = $(`[data-href='${href}']`);
if ($dom.length) {
switchPart(href, $dom, false);
} else {
location.reload();
}
});
}
function replaceHref() {
$('.movurl:visible li a').each(function () {
const href = $(this).attr('href');
$(this).removeAttr('href').attr('data-href', href).css('cursor', 'pointer').on('click', e => {
e.preventDefault();
switchPart(href, $(this));
});
});
}
/** @type {KPlayer} */
let player$1;
function initPlayer(vurl) {
player$1 = new KPlayer('#age_playfram');
showCurrentLink(vurl);
addListener();
player$1.src = vurl;
saveLocal(getActivedom().data('href'), vurl);
}
function removeCpraid() {
$('#cpraid').remove();
}
function playModule$1() {
his.logHistory();
initPlayPageStyle();
replaceHref();
replacePlayer$1();
removeCpraid();
initGetAllVideoURL();
}
function agefans() {
if (self !== parent) return;
$('body').addClass('agefans-wrapper');
historyModule(); // log page to history
if (location.pathname.startsWith('/play')) {
playModule$1();
} // in detail pages show view history
if (location.pathname.startsWith('/detail')) {
detailModule();
}
}
/** @type {KPlayer} */
let player;
function replacePlayer() {
const vurl = $('#playbox').data('vid');
player = new KPlayer('.bofang iframe');
player.src = vurl.split('$')[0];
}
function gotoNextPart() {
let directionRight = true;
const re = /\/v\/\d+-(\d+)/;
let prevID;
Array.from($('.movurls a')).forEach(a => {
if (re.test(a.href)) {
const [, id] = a.href.match(re);
if (prevID) directionRight = +prevID < +id;
prevID = id;
}
});
if (directionRight) {
$('.movurls .sel').next().find('a')[0].click();
} else {
$('.movurls .sel').prev().find('a')[0].click();
}
}
function initEvent() {
player.on('next', gotoNextPart);
}
function playModule() {
replacePlayer();
initEvent();
}
var css = ".yhdm-wrapper {\n font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;\n}\n.yhdm-wrapper .play,\n.yhdm-wrapper #playbox,\n.yhdm-wrapper .bofang {\n height: 540px;\n}";
n(css,{});
function yhdm() {
$('body').addClass('yhdm-wrapper');
if (window.location.pathname.includes('/v/')) {
playModule();
}
}
if (window.location.href.includes('agefans')) {
agefans();
}
if (window.location.href.includes('yhdm')) {
yhdm();
}
}());