mirror of
https://github.com/the1812/Bilibili-Evolved.git
synced 2025-11-04 21:22:45 +08:00
Add volume overdrive
This commit is contained in:
parent
1f3bfb458d
commit
1bc1407df5
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
File diff suppressed because one or more lines are too long
@ -198,8 +198,8 @@
|
||||
"settings-tooltip.min.css": "0C138D5CF16B9068E73D173D229B2B458C15F50272DA73D6A580921C5A848845",
|
||||
"settings-tooltip.min.js": "E9ABA72B3C29CA850342109E57B055B193F3356DD59876B202E8E908AE6247C9",
|
||||
"settings-tooltip.zh-CN.min.js": "C237FB86DE05C28C1EB8A11EAE85D4F79D942937C6DD8BD2D4D900FCC99B930B",
|
||||
"show-cover-before-play.min.css": "E963B5E47F0FF5F283CE2C2621DF7AD13A97C619386F2807021E57544233B08F",
|
||||
"show-cover-before-play.min.js": "7CB9F6D6F4F0C6DF2D5D251306314D055C53FF9992C4DDB6E5A6A2B2F22A641A",
|
||||
"show-cover-before-play.min.css": "E4050D66F8014029270CB5A4DEFDE2F847B095BA9ED4274BFED3E131B737B06D",
|
||||
"show-cover-before-play.min.js": "1460F247A0DCE097C0F7B4977D6D060D4644862D9F2AE774F3F6F1E41469D12A",
|
||||
"show-dead-video-title.min.js": "8D591930421EBA43A1BDF50DC8B645C1BD1A17E109FB1CFBCD6B78E6C74E1D68",
|
||||
"simple-home.vue.min.js": "1F5CF46DEE65549A30C5F0790578EED0C6B3AD6C5F20D9B88CD745C4B7664ABB",
|
||||
"simple-home-bangumi-category.vue.min.js": "87DCA2C8295CAD66C9FA01D65437EC2F9DD5E7F4A565B4384ABAB1746A6787EE",
|
||||
@ -242,6 +242,7 @@
|
||||
"video-list.vue.min.js": "90C4CCAB3C9C3FB0CFE39C9A9482C3A964EE7FAC17F7FBF682CCC2FEFB6632F2",
|
||||
"video-story.min.js": "F9D4D2D80997DF5F11BF0CFA4D389B77BDBF1566EA6002E47174B68B440F3C0D",
|
||||
"view-cover.min.js": "895AA8A393D5EBA787ABCAE12EAF4D47E5A68E6B998E4FE839F81FB491F92ED5",
|
||||
"volume-overdrive.min.js": "442428F9918086D86AD90966071E37298F4C726883232F627C6B6E15AAB4F6D0",
|
||||
"watchlater.min.js": "940646B8DEAC0B2C47BACD360A259DFCF9F67F78E4B9D38ACE9E8D7322E88016",
|
||||
"watchlater-api.min.js": "0A341429EFB4489594C6670A1FEEF99E7EC2564FF18BCE3A679E98101BA0F2F4",
|
||||
"watchlater-expire-warnings.min.js": "99282802EF8EB87F199BDE88240E1F196CD85C77516E8D5466EB6F1939B908DD"
|
||||
|
||||
BIN
min/bundle.zip
BIN
min/bundle.zip
Binary file not shown.
1
min/volume-overdrive.min.js
vendored
Normal file
1
min/volume-overdrive.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
(()=>{return(e,t)=>{const n=new Map;const i=e=>{console.log("create new context");const t=new AudioContext;const i=t.createMediaElementSource(e);const o=t.createGain();i.connect(o);o.connect(t.destination);n.set(e,o.gain);return o.gain};const o=e=>{if(n.has(e)){const t=n.get(e);t.value=1}};const r=(e,t)=>{if(n.has(e)){const i=n.get(e);let o=i.value+t;if(o<0){o=0}i.value=o;return o}else{const n=i(e);const o=n.value+t;n.value=o;return o}};const s=async()=>{const e=["https://www.bilibili.com/bangumi/","https://www.bilibili.com/video/","https://www.bilibili.com/watchlater/","https://www.bilibili.com/medialist/play/"];if(e.every(e=>!document.URL.startsWith(e))){return}let i;const o=e=>{let n=dq(".volume-overdrive-tip");if(!n){const e=dq(".bilibili-player-video-wrap");if(!e){return}e.insertAdjacentHTML("afterbegin",`\n<div class="volume-overdrive-tip-container">\n<i class="mdi mdi-volume-high"></i>\n<div class="volume-overdrive-tip"></div>\n</div>\n`);t.applyStyleFromText(`\n .volume-overdrive-tip-container {\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n padding: 8px 16px;\n background-color: #000A;\n color: white;\n pointer-events: none;\n opacity: 0;\n z-index: 100;\n display: flex;\n align-items: center;\n font-size: 14pt;\n border-radius: 4px;\n transition: .2s ease-out;\n }\n .volume-overdrive-tip-container.show {\n opacity: 1;\n }\n .volume-overdrive-tip-container i {\n line-height: 1;\n margin-right: 8px;\n font-size: 18pt;\n }\n`,"volumeOverdriveStyle");n=dq(".volume-overdrive-tip")}const o=dq("video");n.innerHTML=`音量${Math.round(o.volume*100)}% x 增幅${Math.round(e*100)}% = ${Math.round(o.volume*e*100)}%`;if(i){clearTimeout(i)}dq(".volume-overdrive-tip-container").classList.add("show");i=setTimeout(()=>{dq(".volume-overdrive-tip-container").classList.remove("show")},2e3)};Observer.videoChange(async()=>{n.clear();document.body.addEventListener("keydown",e=>{const t=!e.shiftKey&&e.ctrlKey&&!e.altKey&&!e.metaKey;if(t&&(e.key==="ArrowDown"||e.key==="ArrowUp")){const t=dq("video");if(!t){return}const n=e.key==="ArrowDown"?-.1:.1;const i=r(t,n);o(i);e.preventDefault();e.stopImmediatePropagation()}},{capture:true})})};s();return{export:{setVolume:r}}}})();
|
||||
@ -922,5 +922,11 @@ Resource.manifest = {
|
||||
showCoverBeforePlay: '播放前显示封面',
|
||||
},
|
||||
},
|
||||
volumeOverdrive: {
|
||||
path: 'volume-overdrive.min.js',
|
||||
displayNames: {
|
||||
volumeOverdrive: '音量增幅',
|
||||
},
|
||||
},
|
||||
}
|
||||
export const resourceManifest = Resource.manifest
|
||||
|
||||
@ -240,6 +240,7 @@ export const settings = {
|
||||
watchLaterRedirectNavbar: true,
|
||||
watchLaterRedirectPage: true,
|
||||
showCoverBeforePlay: false,
|
||||
volumeOverdrive: false,
|
||||
cache: {},
|
||||
}
|
||||
const fixedSettings = {
|
||||
|
||||
127
src/video/volume-overdrive.ts
Normal file
127
src/video/volume-overdrive.ts
Normal file
@ -0,0 +1,127 @@
|
||||
|
||||
const gainMap = new Map<HTMLVideoElement, AudioParam>()
|
||||
export const getGain = (video: HTMLVideoElement) => {
|
||||
console.log('create new context')
|
||||
const context = new AudioContext()
|
||||
const source = context.createMediaElementSource(video)
|
||||
const gainNode = context.createGain()
|
||||
source.connect(gainNode)
|
||||
gainNode.connect(context.destination)
|
||||
gainMap.set(video, gainNode.gain)
|
||||
return gainNode.gain
|
||||
}
|
||||
export const resetGain = (video: HTMLVideoElement) => {
|
||||
if (gainMap.has(video)) {
|
||||
const gain = gainMap.get(video)!
|
||||
gain.value = 1
|
||||
}
|
||||
}
|
||||
export const setVolume = (video: HTMLVideoElement, volumeChange: number): number => {
|
||||
if (gainMap.has(video)) {
|
||||
const gain = gainMap.get(video)!
|
||||
let volume = gain.value + volumeChange
|
||||
if (volume < 0) {
|
||||
volume = 0
|
||||
}
|
||||
gain.value = volume
|
||||
return volume
|
||||
} else {
|
||||
const gain = getGain(video)
|
||||
const volume = gain.value + volumeChange
|
||||
gain.value = volume
|
||||
return volume
|
||||
}
|
||||
}
|
||||
const entry = async () => {
|
||||
const supportedUrls = [
|
||||
'https://www.bilibili.com/bangumi/',
|
||||
'https://www.bilibili.com/video/',
|
||||
'https://www.bilibili.com/watchlater/',
|
||||
'https://www.bilibili.com/medialist/play/',
|
||||
]
|
||||
if (supportedUrls.every(url => !document.URL.startsWith(url))) {
|
||||
return
|
||||
}
|
||||
/** 音量增幅提示框用的`setTimeout`句柄 */
|
||||
let showVolumeTipOldTimeout: number
|
||||
/**
|
||||
* 显示音量增幅提示框
|
||||
* @param volume 音量
|
||||
*/
|
||||
const showVolumeTip = (volume: number) => {
|
||||
let tip = dq('.volume-overdrive-tip') as HTMLDivElement
|
||||
if (!tip) {
|
||||
const player = dq('.bilibili-player-video-wrap')
|
||||
if (!player) {
|
||||
return
|
||||
}
|
||||
player.insertAdjacentHTML('afterbegin', /*html*/`
|
||||
<div class="volume-overdrive-tip-container">
|
||||
<i class="mdi mdi-volume-high"></i>
|
||||
<div class="volume-overdrive-tip"></div>
|
||||
</div>
|
||||
`)
|
||||
resources.applyStyleFromText(`
|
||||
.volume-overdrive-tip-container {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
padding: 8px 16px;
|
||||
background-color: #000A;
|
||||
color: white;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14pt;
|
||||
border-radius: 4px;
|
||||
transition: .2s ease-out;
|
||||
}
|
||||
.volume-overdrive-tip-container.show {
|
||||
opacity: 1;
|
||||
}
|
||||
.volume-overdrive-tip-container i {
|
||||
line-height: 1;
|
||||
margin-right: 8px;
|
||||
font-size: 18pt;
|
||||
}
|
||||
`, 'volumeOverdriveStyle')
|
||||
tip = dq('.volume-overdrive-tip') as HTMLDivElement
|
||||
}
|
||||
const video = dq('video') as HTMLVideoElement
|
||||
tip.innerHTML = `音量${Math.round(video.volume * 100)}% x 增幅${Math.round(volume * 100)}% = ${Math.round(video.volume * volume * 100)}%`
|
||||
if (showVolumeTipOldTimeout) {
|
||||
clearTimeout(showVolumeTipOldTimeout)
|
||||
}
|
||||
(dq('.volume-overdrive-tip-container') as HTMLDivElement).classList.add('show')
|
||||
showVolumeTipOldTimeout = setTimeout(() => {
|
||||
(dq('.volume-overdrive-tip-container') as HTMLDivElement).classList.remove('show')
|
||||
}, 2000)
|
||||
}
|
||||
Observer.videoChange(async () => {
|
||||
gainMap.clear()
|
||||
document.body.addEventListener('keydown', e => {
|
||||
const ctrlKey = !e.shiftKey && e.ctrlKey && !e.altKey && !e.metaKey
|
||||
if (ctrlKey && (e.key === 'ArrowDown' || e.key === 'ArrowUp')) {
|
||||
const video = dq('video') as HTMLVideoElement
|
||||
if (!video) {
|
||||
return
|
||||
}
|
||||
const volumeChange = e.key === 'ArrowDown' ? -0.1 : 0.1
|
||||
const volume = setVolume(video, volumeChange)
|
||||
showVolumeTip(volume)
|
||||
e.preventDefault()
|
||||
e.stopImmediatePropagation()
|
||||
}
|
||||
}, { capture: true })
|
||||
})
|
||||
}
|
||||
entry()
|
||||
|
||||
export default {
|
||||
export: {
|
||||
setVolume,
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user