Merge branch 'preview' of https://github.com/the1812/Bilibili-Evolved into preview

This commit is contained in:
the1812 2021-11-28 18:00:21 +08:00
commit ec43b89734
11 changed files with 161 additions and 128 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["video/player/auto-light"]=t():e["video/player/auto-light"]=t()}(self,(function(){return function(){"use strict";var e,t,o={579:function(e){e.exports=coreApis.componentApis.video.playerLight},109:function(e){e.exports=coreApis.utils}},n={};function r(e){var t=n[e];if(void 0!==t)return t.exports;var i=n[e]={exports:{}};return o[e](i,i.exports,r),i.exports}t=Object.getPrototypeOf?function(e){return Object.getPrototypeOf(e)}:function(e){return e.__proto__},r.t=function(o,n){if(1&n&&(o=this(o)),8&n)return o;if("object"==typeof o&&o){if(4&n&&o.__esModule)return o;if(16&n&&"function"==typeof o.then)return o}var i=Object.create(null);r.r(i);var u={};e=e||[null,t({}),t([]),t(t)];for(var a=2&n&&o;"object"==typeof a&&!~e.indexOf(a);a=t(a))Object.getOwnPropertyNames(a).forEach((function(e){u[e]=function(){return o[e]}}));return u.default=function(){return o},r.d(i,u),i},r.d=function(e,t){for(var o in t)r.o(t,o)&&!r.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var i={};return function(){r.d(i,{component:function(){return t}});var e=coreApis.observer;const t={name:"playerAutoLight",displayName:"播放时自动关灯",urlInclude:coreApis.utils.urls.allVideoUrls,tags:[componentsTags.video],description:{"zh-CN":"在视频播放时自动关灯, 暂停或结束时再自动打开."},entry:async()=>{const{isEmbeddedPlayer:t}=await Promise.resolve().then(r.t.bind(r,109,23)),{lightOn:o,lightOff:n}=await Promise.resolve().then(r.t.bind(r,579,23));if(t())return;const i=lodash.get(JSON.parse(localStorage.getItem("bilibili_player_settings")),"video_status.autoplay",!1);(0,e.videoChange)((()=>{const e=dq("video");i&&n(),e.addEventListener("ended",(()=>o())),e.addEventListener("pause",(()=>o())),e.addEventListener("play",(()=>n()))}))}}}(),i=i.component}()}));
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["video/player/auto-light"]=t():e["video/player/auto-light"]=t()}(self,(function(){return function(){"use strict";var e,t,n={579:function(e){e.exports=coreApis.componentApis.video.playerLight},109:function(e){e.exports=coreApis.utils}},o={};function r(e){var t=o[e];if(void 0!==t)return t.exports;var i=o[e]={exports:{}};return n[e](i,i.exports,r),i.exports}t=Object.getPrototypeOf?function(e){return Object.getPrototypeOf(e)}:function(e){return e.__proto__},r.t=function(n,o){if(1&o&&(n=this(n)),8&o)return n;if("object"==typeof n&&n){if(4&o&&n.__esModule)return n;if(16&o&&"function"==typeof n.then)return n}var i=Object.create(null);r.r(i);var u={};e=e||[null,t({}),t([]),t(t)];for(var a=2&o&&n;"object"==typeof a&&!~e.indexOf(a);a=t(a))Object.getOwnPropertyNames(a).forEach((function(e){u[e]=function(){return n[e]}}));return u.default=function(){return n},r.d(i,u),i},r.d=function(e,t){for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var i={};return function(){r.d(i,{component:function(){return o}});var e=coreApis.componentApis.video.playerAgent,t=coreApis.observer;let n;const o={name:"playerAutoLight",displayName:"播放时自动关灯",urlInclude:coreApis.utils.urls.allVideoUrls,tags:[componentsTags.video],description:{"zh-CN":"在视频播放时自动关灯, 暂停或结束时再自动打开."},entry:async()=>{const{isEmbeddedPlayer:o}=await Promise.resolve().then(r.t.bind(r,109,23)),{lightOn:i,lightOff:u}=await Promise.resolve().then(r.t.bind(r,579,23));o()||(0,t.videoChange)((async()=>{if(null!=n){const e=await n.query.video.element();e.removeEventListener("ended",i),e.removeEventListener("pause",i),e.removeEventListener("play",u)}n=e.playerAgent;const{query:t,isAutoPlay:o}=n,r=await t.video.element();o()&&u(),r.addEventListener("ended",i),r.addEventListener("pause",i),r.addEventListener("play",u)}))}}}(),i=i.component}()}));

View File

@ -1 +1 @@
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["video/player/default-mode"]=t():e["video/player/default-mode"]=t()}(self,(function(){return function(){"use strict";var e={d:function(t,n){for(var o in n)e.o(n,o)&&!e.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:n[o]})},o:function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}},t={};e.d(t,{component:function(){return s}});var n=coreApis.componentApis.video.playerAgent,o=coreApis.spinQuery,l=coreApis.utils,r=coreApis.utils.urls;let a;!function(e){e.Normal="常规",e.Wide="宽屏",e.WebFullscreen="网页全屏",e.Fullscreen="全屏"}(a||(a={}));const s={name:"defaultPlayerMode",displayName:"默认播放器模式",entry:async({settings:{options:e}})=>{if((0,l.isEmbeddedPlayer)())return;await(0,l.playerReady)();const t=new Map([[a.Normal,none],[a.Wide,()=>{n.playerAgent.widescreen()}],[a.WebFullscreen,()=>{n.playerAgent.webFullscreen()}],[a.Fullscreen,async()=>{null!==await(0,o.sq)((()=>dq(n.playerAgent.query.video.element.selector)),(e=>null!==e&&4===e.readyState&&"complete"===document.readyState&&document.hasFocus()))?n.playerAgent.fullscreen():console.warn("[默认播放器模式] 未能应用全屏模式, 等待超时.")}]]),r=await n.playerAgent.query.video.element();if(!r)return;const s=lodash.get(JSON.parse(localStorage.getItem("bilibili_player_settings")),"video_status.autoplay",!1),d=t.get(e.mode),i=()=>{!dq("body[class*=player-mode-]")&&d()};e.applyOnPlay&&!s?r.addEventListener("play",i,{once:!0}):i()},tags:[componentsTags.video],description:{"zh-CN":"控制是否使用默认播放器模式, 可以为`常规`, `宽屏`, `网页全屏`或`全屏`.","en-US":"Set the default player mode. Could be `Normal`, `Widescreen`, `Web fullscreen` or `Fullscreen`.","ja-JP":"デフォルト・プレーヤー・モードが使用するかどうかを制御する、 例えば`常规`、`宽屏`、 `网页全屏`か`全屏`."},options:{mode:{defaultValue:a.Normal,displayName:"模式选择",dropdownEnum:a},applyOnPlay:{defaultValue:!1,displayName:"播放时应用"}},urlInclude:r.allVideoUrls};return t=t.component}()}));
!function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports["video/player/default-mode"]=n():e["video/player/default-mode"]=n()}(self,(function(){return function(){"use strict";var e={d:function(n,t){for(var o in t)e.o(t,o)&&!e.o(n,o)&&Object.defineProperty(n,o,{enumerable:!0,get:t[o]})},o:function(e,n){return Object.prototype.hasOwnProperty.call(e,n)}},n={};e.d(n,{component:function(){return d}});var t=coreApis.componentApis.video.playerAgent,o=coreApis.spinQuery,l=coreApis.utils,r=coreApis.utils.urls;let a;!function(e){e.Normal="常规",e.Wide="宽屏",e.WebFullscreen="网页全屏",e.Fullscreen="全屏"}(a||(a={}));const d={name:"defaultPlayerMode",displayName:"默认播放器模式",entry:async({settings:{options:e}})=>{if((0,l.isEmbeddedPlayer)())return;await(0,l.playerReady)();const n=new Map([[a.Normal,none],[a.Wide,()=>{t.playerAgent.widescreen()}],[a.WebFullscreen,()=>{t.playerAgent.webFullscreen()}],[a.Fullscreen,async()=>{null!==await(0,o.sq)((()=>dq(t.playerAgent.query.video.element.selector)),(e=>null!==e&&4===e.readyState&&"complete"===document.readyState&&document.hasFocus()))?t.playerAgent.fullscreen():console.warn("[默认播放器模式] 未能应用全屏模式, 等待超时.")}]]),r=await t.playerAgent.query.video.element();if(!r)return;const d=n.get(e.mode),s=()=>{!dq("body[class*=player-mode-]")&&d()};e.applyOnPlay&&!t.playerAgent.isAutoPlay()?r.addEventListener("play",s,{once:!0}):s()},tags:[componentsTags.video],description:{"zh-CN":"控制是否使用默认播放器模式, 可以为`常规`, `宽屏`, `网页全屏`或`全屏`.","en-US":"Set the default player mode. Could be `Normal`, `Widescreen`, `Web fullscreen` or `Fullscreen`.","ja-JP":"デフォルト・プレーヤー・モードが使用するかどうかを制御する、 例えば`常规`、`宽屏`、 `网页全屏`か`全屏`."},options:{mode:{defaultValue:a.Normal,displayName:"模式选择",dropdownEnum:a},applyOnPlay:{defaultValue:!1,displayName:"播放时应用"}},urlInclude:r.allVideoUrls};return n=n.component}()}));

View File

@ -1 +1 @@
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["video/player/intersection-actions"]=t():e["video/player/intersection-actions"]=t()}(self,(function(){return function(){"use strict";var e={d:function(t,n){for(var o in n)e.o(n,o)&&!e.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:n[o]})},o:function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}},t={};e.d(t,{component:function(){return s}});var n,o=coreApis.componentApis.video.playerAgent,i=coreApis.componentApis.video.playerLight,a=coreApis.observer,r=coreApis.settings;!function(e){e.Top="视频顶部",e.Medium="视频中间",e.Bottom="视频底部"}(n||(n={}));const s={name:"playerIntersectionActions",author:{name:"FoundTheWOUT",link:"https://github.com/FoundTheWOUT"},tags:[componentsTags.video],entry:async({settings:{options:e},metadata:t})=>{const s=e,{query:{video:p}}=o.playerAgent,u=await p.element(),d=dq(".player-wrap")||dq(".player-module");let c,l=!0;function g(e){switch(e){case n.Top:return 1;case n.Medium:return.5;case n.Bottom:return 0;default:return.5}}function m(){c.observe(d)}function y(){c.unobserve(d)}const f=e=>new IntersectionObserver((([e])=>{e.isIntersecting?l||(l=!0,s.pause&&u.paused&&u.play(),s.light&&(0,r.getComponentSettings)("playerAutoLight").enabled&&!s.pause&&!u.paused&&(0,i.lightOff)()):(u.paused||(l=!1),s.pause&&!u.paused&&u.pause(),s.light&&(0,r.getComponentSettings)("playerAutoLight").enabled&&!s.pause&&(0,i.lightOn)())}),{threshold:g(e||s.triggerLocation)});(0,r.addComponentListener)(`${t.name}.triggerLocation`,(e=>{y(),c=f(e),m()})),c=f(),function(){const e=lodash.get(JSON.parse(localStorage.getItem("bilibili_player_settings")),"video_status.autoplay",!1);(0,a.videoChange)((async()=>{e&&m(),u.addEventListener("play",m),u.addEventListener("ended",y)}))}()},displayName:"播放器位置动作",description:{"zh-CN":"设置当播放器移出视图的位置变化时执行的动作."},options:{triggerLocation:{defaultValue:n.Medium,displayName:"触发位置",dropdownEnum:n},pause:{defaultValue:!1,displayName:"自动暂停"},light:{defaultValue:!0,displayName:"自动开灯"}}};return t=t.component}()}));
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["video/player/intersection-actions"]=t():e["video/player/intersection-actions"]=t()}(self,(function(){return function(){"use strict";var e={d:function(t,n){for(var o in n)e.o(n,o)&&!e.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:n[o]})},o:function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}},t={};e.d(t,{component:function(){return s}});var n,o=coreApis.componentApis.video.playerAgent,i=coreApis.componentApis.video.playerLight,a=coreApis.observer,r=coreApis.settings;!function(e){e.Top="视频顶部",e.Medium="视频中间",e.Bottom="视频底部"}(n||(n={}));const s={name:"playerIntersectionActions",author:{name:"FoundTheWOUT",link:"https://github.com/FoundTheWOUT"},tags:[componentsTags.video],entry:async({settings:{options:e},metadata:t})=>{const s=e,{query:{video:p}}=o.playerAgent,u=await p.element(),d=document.getElementById("video-player")??(dq(".player-wrap")||dq(".player-module"));let c,l=!0;function m(e){switch(e){case n.Top:return 1;case n.Medium:return.5;case n.Bottom:return 0;default:return.5}}function y(){c.observe(d)}function g(){c.unobserve(d)}const f=e=>new IntersectionObserver((([e])=>{e.isIntersecting?l||(l=!0,s.pause&&u.paused&&u.play(),s.light&&(0,r.getComponentSettings)("playerAutoLight").enabled&&!s.pause&&!u.paused&&(0,i.lightOff)()):(u.paused||(l=!1),s.pause&&!u.paused&&u.pause(),s.light&&(0,r.getComponentSettings)("playerAutoLight").enabled&&!s.pause&&(0,i.lightOn)())}),{threshold:m(e||s.triggerLocation)});(0,r.addComponentListener)(`${t.name}.triggerLocation`,(e=>{g(),c=f(e),y()})),c=f(),(0,a.videoChange)((async()=>{o.playerAgent.isAutoPlay()&&y(),u.addEventListener("play",y),u.addEventListener("ended",g)}))},displayName:"播放器位置动作",description:{"zh-CN":"设置当播放器移出视图的位置变化时执行的动作."},options:{triggerLocation:{defaultValue:n.Medium,displayName:"触发位置",dropdownEnum:n},pause:{defaultValue:!1,displayName:"自动暂停"},light:{defaultValue:!0,displayName:"自动开灯"}}};return t=t.component}()}));

View File

@ -1,7 +1,10 @@
import { ComponentMetadata } from '@/components/types'
import { playerAgent } from '@/components/video/player-agent'
import { videoChange } from '@/core/observer'
import { allVideoUrls } from '@/core/utils/urls'
let playerAgentInstance
export const component: ComponentMetadata = {
name: 'playerAutoLight',
displayName: '播放时自动关灯',
@ -17,19 +20,26 @@ export const component: ComponentMetadata = {
if (isEmbeddedPlayer()) {
return
}
const autoPlay = lodash.get(
JSON.parse(localStorage.getItem('bilibili_player_settings')),
'video_status.autoplay',
false,
)
videoChange(() => {
const video = dq('video') as HTMLVideoElement
if (autoPlay) {
videoChange(async () => {
if (playerAgentInstance != null) {
const oldVideo = await playerAgentInstance.query.video.element()
oldVideo.removeEventListener('ended', lightOn)
oldVideo.removeEventListener('pause', lightOn)
oldVideo.removeEventListener('play', lightOff)
}
playerAgentInstance = playerAgent
const { query, isAutoPlay } = playerAgentInstance
const video = await query.video.element()
if (isAutoPlay()) {
lightOff()
}
video.addEventListener('ended', () => lightOn())
video.addEventListener('pause', () => lightOn())
video.addEventListener('play', () => lightOff())
video.addEventListener('ended', lightOn)
video.addEventListener('pause', lightOn)
video.addEventListener('play', lightOff)
})
},
}

View File

@ -40,11 +40,6 @@ const entry: ComponentEntry = async ({ settings: { options } }) => {
if (!video) {
return
}
const autoPlay = lodash.get(
JSON.parse(localStorage.getItem('bilibili_player_settings')),
'video_status.autoplay',
false,
)
const action = actions.get(options.mode)
const onplay = () => {
const isNormalMode = !dq('body[class*=player-mode-]')
@ -52,7 +47,7 @@ const entry: ComponentEntry = async ({ settings: { options } }) => {
action()
}
}
if (options.applyOnPlay && !autoPlay) {
if (options.applyOnPlay && !playerAgent.isAutoPlay()) {
video.addEventListener('play', onplay, { once: true })
} else {
onplay()

View File

@ -27,7 +27,14 @@ export const component: ComponentMetadata = {
const videoEl = await video.element() as HTMLVideoElement
// const playerWrap = await video.wrap()
const playerWrap = (dq('.player-wrap') || dq('.player-module')) as HTMLElement
// 如果有 video-player 优先的使用该盒子
// 因为在稍后再看页面medialist视频也有 player-wrap
// 选择 player-wrap 会导致闪烁。
const playerWrap = (
document.getElementById('video-player')
?? (dq('.player-wrap') || dq('.player-module'))
) as HTMLElement
let observer: IntersectionObserver
let intersectionLock = true // Lock intersection action
@ -101,13 +108,8 @@ export const component: ComponentMetadata = {
)
function mountPlayListener() {
const autoPlay = lodash.get(
JSON.parse(localStorage.getItem('bilibili_player_settings')),
'video_status.autoplay',
false,
)
videoChange(async () => {
if (autoPlay) {
if (playerAgent.isAutoPlay()) {
addPlayerOutEvent()
}
videoEl.addEventListener('play', addPlayerOutEvent)

View File

@ -61,6 +61,10 @@ interface PlayerQuery<QueryResult> extends CustomNestedQuery<QueryResult> {
webFullscreen: QueryResult
fullscreen: QueryResult
}
settings: {
wrap: QueryResult,
lightOff: QueryResult
}
}
toastWrap: QueryResult
danmakuTipLayer: QueryResult
@ -125,6 +129,22 @@ export abstract class PlayerAgent {
raiseEvent(checkbox, 'change')
return checkbox.checked
}
abstract toggleLight(on: boolean): void
// eslint-disable-next-line class-methods-use-this
getPlayerConfig(target:string) {
return lodash.get(
JSON.parse(localStorage.getItem('bilibili_player_settings')),
target,
false,
)
}
isAutoPlay() {
return this.getPlayerConfig('video_status.autoplay')
}
abstract isMute(): boolean
/** 更改音量 (%) */
abstract changeVolume(change: number): number
@ -181,6 +201,10 @@ export class VideoPlayerAgent extends PlayerAgent {
webFullscreen: '.bilibili-player-video-web-fullscreen',
fullscreen: '.bilibili-player-video-btn-fullscreen',
},
settings: {
wrap: '.bilibili-player-video-btn-setting-wrap',
lightOff: '.bilibili-player-video-btn-setting-right-others-content-lightoff .bui-checkbox-input',
},
},
toastWrap: '.bilibili-player-video-toast-wrp',
danmakuTipLayer: '.bilibili-player-dm-tip-wrap',
@ -225,6 +249,11 @@ export class VideoPlayerAgent extends PlayerAgent {
this.nativeApi.seek(video.currentTime + change, video.paused)
return this.nativeApi.getCurrentTime()
}
async toggleLight(on:boolean) {
const checkbox = await this.query.control.settings.lightOff() as HTMLInputElement
checkbox.checked = !on
raiseEvent(checkbox, 'change')
}
}
export class BwpPlayerAgent extends VideoPlayerAgent {
type: AgentType = 'bwp'
@ -277,6 +306,10 @@ export class BangumiPlayerAgent extends PlayerAgent {
webFullscreen: '.squirtle-video-pagefullscreen',
fullscreen: '.squirtle-video-fullscreen',
},
settings: {
wrap: '.squirtle-setting-wrap',
lightOff: '.squirtle-lightoff',
},
},
toastWrap: '.bpx-player-tooltip-area',
danmakuTipLayer: '.bpx-player-dialog-wrap',
@ -321,6 +354,15 @@ export class BangumiPlayerAgent extends PlayerAgent {
video.currentTime = lodash.clamp(video.currentTime + change, 0, video.duration)
return video.currentTime
}
toggleLight(on: boolean) {
const checkbox = this.query.control.settings.lightOff.sync()
const canLightOff = !checkbox.classList.contains('active') && !on
const canLightOn = checkbox.classList.contains('active') && on
if (canLightOff || canLightOn) {
checkbox.dispatchEvent(new MouseEvent('click'))
}
}
}
export const playerAgent = (() => {

View File

@ -1,52 +1,32 @@
import { select } from '@/core/spin-query'
import { matchUrlPattern, raiseEvent, none } from '@/core/utils'
import { matchUrlPattern, none } from '@/core/utils'
import { loadLazyPlayerSettingsPanel } from '@/core/utils/lazy-panel'
import { playerUrls } from '@/core/utils/urls'
import { playerAgent } from './player-agent'
let initialized = false
// let initialized = false
const setLightAdaptor = {
bangumi: (doLightOn: boolean) => async () => {
if (!initialized) {
loadLazyPlayerSettingsPanel('.squirtle-setting-wrap', '.squirtle-video-setting')
initialized = true
}
const checkbox = await select('.squirtle-lightoff') as HTMLElement
const event = new MouseEvent('click')
// 处于关灯状态,要开灯 -> 开灯
checkbox.classList.contains('active') && doLightOn ? checkbox.dispatchEvent(event) : ''
// 处于开灯状态,要关灯 -> 关灯
!checkbox.classList.contains('active') && !doLightOn ? checkbox.dispatchEvent(event) : ''
},
fallback: (on: boolean) => {
if (!playerUrls.some(url => matchUrlPattern(url))) {
return none
}
return async () => {
if (!initialized) {
loadLazyPlayerSettingsPanel(
'.bilibili-player-video-btn-setting',
'.bilibili-player-video-btn-setting-wrap',
{
style: '.bilibili-player-video-btn-setting-wrap { display: none !important }',
},
)
initialized = true
}
const checkbox = await select('.bilibili-player-video-btn-setting-right-others-content-lightoff .bui-checkbox-input') as HTMLInputElement
checkbox.checked = !on
raiseEvent(checkbox, 'change')
}
},
}
const setLight = (on: boolean) => {
if (!playerUrls.some(url => matchUrlPattern(url))) {
return none
}
return async () => {
const playerAgentInstance = playerAgent
const {
query: {
control: { settings, buttons },
},
} = playerAgentInstance
let setLight = setLightAdaptor.fallback
for (const key in setLightAdaptor) {
if (Object.prototype.hasOwnProperty.call(setLightAdaptor, key)) {
if (matchUrlPattern(key)) {
setLight = setLightAdaptor[key]
}
// if (!initialized) {
loadLazyPlayerSettingsPanel(
buttons.settings.selector,
settings.wrap.selector,
)
// initialized = true
// }
playerAgentInstance.toggleLight(on)
}
}
export const lightOn = setLight(true)
export const lightOff = setLight(false)