├── LICENSE ├── README.md └── src └── main.js /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 小淳 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Joysound视频音效增强 ![icon](https://s4.ax1x.com/2022/02/11/HNIAQH.png) 2 | > 🎵✨Joysound视频音效增强是一款基于Tampermonkey的脚本,使用wasm技术对网页中的视频音效进行增强优化,使得声音更加立体饱满 3 | 4 | ## 注意事项(Attention) 5 | 1. joysound来源于acfun 6 | 2. 若网页中没有video元素,则不起作用,常见有以下两种情况 7 | - video元素在iframe中 8 | - video元素在shadowRoot中 9 | 3. 开启和关闭状态会自动进行保存 10 | 4. **安装脚本后默认全局开启,如果遇到网页视频没有声音的情况,请手动关闭音效** 11 | 5. 脚本启动后会将全局挂载的`AudioContext`和`webkitAudioContext`置为null,此举可能会导致原生网页的音效功能失效,请注意。 12 | 13 | ## 使用(Usage) 14 | 1. 首先确保已经安装Tampermonkey 15 | 2. [安装本脚本](https://greasyfork.org/zh-CN/scripts/439845) 16 | 3. 访问网页,点击Tampermonkey图标,在弹出的菜单(Menu)中即可选择开启/关闭音效 17 | 18 | ![img](https://s4.ax1x.com/2022/02/11/HNIWtK.png) 19 | 20 | ## 接口(API) 21 | > 为了方便与其他脚本联动,本项目为用户提供了API 22 | 23 | ### hasInstalledJoysound 24 | ``` 25 | // 判断是否安装了脚本,true则为已经安装 26 | window.hasInstalledJoysound 27 | ``` 28 | 29 | ### enableJoysound 30 | ``` 31 | // 用于开启音效增强 32 | window.enableJoysound(); 33 | ``` 34 | 35 | ### disableJoysound 36 | ``` 37 | // 用于关闭音效增强 38 | window.disableJoysound(); 39 | ``` 40 | 41 | ### getJoysoundByVideoNode 42 | ``` 43 | // 对网页中自定义的video元素进行音效增强 44 | let videoNode = document.querySelector("video"); 45 | let joysound = window.getJoysoundByVideoNode(videoNode); 46 | joysound.enable(); // 开启 47 | joysound.disable(); // 关闭 48 | ``` 49 | 50 | ### 判断是否开启了Joysound 51 | ``` 52 | localStorage.getItem("Ex_isJoysound"); // 1开启 0关闭 53 | ``` -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | // ==UserScript== 3 | // @name Joysound视频音效增强 4 | // @author qianjiachun 5 | // @icon data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjJweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjIgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8dGl0bGU+am95c291bmQvc2VsZWN0ZWQ8L3RpdGxlPgogICAgPGRlZnM+CiAgICAgICAgPGxpbmVhckdyYWRpZW50IHgxPSI1MCUiIHkxPSIwJSIgeDI9IjUwJSIgeTI9IjEwMCUiIGlkPSJsaW5lYXJHcmFkaWVudC0xIj4KICAgICAgICAgICAgPHN0b3Agc3RvcC1jb2xvcj0iI0YwQ0I5NSIgb2Zmc2V0PSIwJSI+PC9zdG9wPgogICAgICAgICAgICA8c3RvcCBzdG9wLWNvbG9yPSIjRTlCRTgwIiBvZmZzZXQ9IjEwMCUiPjwvc3RvcD4KICAgICAgICA8L2xpbmVhckdyYWRpZW50PgogICAgPC9kZWZzPgogICAgPGcgaWQ9ImpveXNvdW5kL3NlbGVjdGVkIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0i57yW57uEIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyLjc4NTc1MCwgMC43MTQyMjUpIiBmaWxsPSJ1cmwoI2xpbmVhckdyYWRpZW50LTEpIiBmaWxsLXJ1bGU9Im5vbnplcm8iPgogICAgICAgICAgICA8cGF0aCBkPSJNMTYuNDI4NiwwIEwxNi40Mjg2LDkuNjQzIEMxNi40Mjg2LDE0LjEzNDU1MjcgMTIuODIzMzY2NywxNy43ODQyODggOC4zNDg5MzYxOCwxNy44NTYxNjk2IEw4LjE4NzE4MTUzLDE3Ljg1NzI1NjEgTDguMTg3MTgxNTMsMTcuODU3MjU2MSBMNy44NTcxLDE3Ljg1NzI1NjEgTDcuODU3MTM4OTYsMTcuODQ5NjQxIEMzLjQ5MjM4MDEzLDE3LjY2MjA3NDQgMCwxNC4wNTMxMzQxIDAsOS42NDMwNSBDMCw1LjExMzExNTA1IDMuNjg0NDAwMiwxLjQyODU1IDguMjE0MjUsMS40Mjg1NSBDOS43MDA3OTkxMywxLjQyODU1IDExLjA5NjI5ODUsMS44MjUzNTUwMiAxMi4zMDA0MTUxLDIuNTE4NjIzMzEgQzEyLjc0OTU2ODcsMS4wNjAxNjYwMSAxNC4xMDgyMjM2LDAgMTUuNzE0MzUsMCBMMTYuNDI4NiwwIFogTTguMjE0MjUsMi40Mjg1NSBDNC4yMzY2OTQ5NiwyLjQyODU1IDEsNS42NjUzODk3OCAxLDkuNjQzMDUgQzEsMTMuNTAwNzUwOCA0LjA0NDc3MzgsMTYuNjYxNzMzMyA3Ljg1NzA4ODk5LDE2Ljg0ODU2NjggTDcuODU3MDYyNTQsMTQuNTc1MDE3IEM2Ljc3Mjk4NjcxLDE0LjQ5NzMxMDMgNS43ODQ2MTcxOSwxNC4wNjg3NDc3IDUuMDA1MTgzMTEsMTMuNDAyNTU3OCBMNC45MjI0NzY5NywxMy4zMzAyNzYyIEw0LjgwNDkyNDY4LDEzLjIyMTc5NDEgQzMuODU5Mjk3NTksMTIuMzIwNjI4MyAzLjI2OTI1LDExLjA0OTU0OTYgMy4yNjkyNSw5LjY0MzAyNSBDMy4yNjkyNSw2LjkxNTg4MjYzIDUuNDg3MTA3NjMsNC42OTgwMjUgOC4yMTQyNSw0LjY5ODAyNSBDOS44MTQwMDc1Niw0LjY5ODAyNSAxMS4yMzg0NTI3LDUuNDYxMjEyMzMgMTIuMTQyNzY0NSw2LjY0MjcxMjE1IEwxMi4xNDI3NjQ1LDMuNTk0NjQ0OTEgQzExLjAxMTU4OTYsMi44NTczNjc2NSA5LjY2MTk5NDQ5LDIuNDI4NTUgOC4yMTQyNSwyLjQyODU1IFogTTguMjE0MjUsNS42OTgwMjUgQzYuMDM5MzkyMzcsNS42OTgwMjUgNC4yNjkyNSw3LjQ2ODE2NzM3IDQuMjY5MjUsOS42NDMwMjUgQzQuMjY5MjUsMTEuNjY5NTM3MyA1LjgwNjQ4MjY0LDEzLjM0NDc0OTggNy43NzU4ODgxNSwxMy41NjM1NjcyIEw3Ljg1NzEsMTMuNTcxNSBMOC4yMTQzNSwxMy41NzE1IEMxMC4zNDk2LDEzLjU3MTUgMTIuMDg2ODUsMTEuODY4IDEyLjE0MTYsOS43NDYgTDEyLjE0MjY0NjgsOS42NDMgTDEyLjE0MjY0NjgsOS4yODIzMzIzMyBDMTEuOTU5ODU4NSw3LjI3NTc1MDI2IDEwLjI2NzQ4MjMsNS42OTgwMjUgOC4yMTQyNSw1LjY5ODAyNSBaIE04LjIxNDI1LDcuNTAwMDI1IEM5LjM5NjE5Mjg0LDcuNTAwMDI1IDEwLjM1Nyw4LjQ2MDkzMzA5IDEwLjM1Nyw5LjY0MzAyNSBDMTAuMzU3LDEwLjgyNDkxNzQgOS4zOTYxNDIzNywxMS43ODU3NzUgOC4yMTQyNSwxMS43ODU3NzUgQzcuMDMyMTgyMTUsMTEuNzg1Nzc1IDYuMDcxNSwxMC44MjQ5OTE5IDYuMDcxNSw5LjY0MzAyNSBDNi4wNzE1LDguNDYwODU4NTUgNy4wMzIxMzE2OSw3LjUwMDAyNSA4LjIxNDI1LDcuNTAwMDI1IFogTTguMjE0MjUsOC41MDAwMjUgQzcuNTg0NDYzNDgsOC41MDAwMjUgNy4wNzE1LDkuMDEzMDk2MjcgNy4wNzE1LDkuNjQzMDI1IEM3LjA3MTUsMTAuMjcyNzMwNyA3LjU4NDQ5MDQyLDEwLjc4NTc3NSA4LjIxNDI1LDEwLjc4NTc3NSBDOC44NDM4NTc2MywxMC43ODU3NzUgOS4zNTcsMTAuMjcyNjMyNiA5LjM1Nyw5LjY0MzAyNSBDOS4zNTcsOS4wMTMxOTQzMyA4Ljg0Mzg4NDU3LDguNTAwMDI1IDguMjE0MjUsOC41MDAwMjUgWiIgaWQ9IuW9oueKtiI+PC9wYXRoPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+ 6 | // @namespace https://github.com/qianjiachun/joysound-tampermonkey 7 | // @version 2022.05.18.01 8 | // @description 🎵✨通用网页视频音效增强/优化。Enhance/Optimize video sound in web. 9 | // @match *://*/* 10 | // @include *://*/* 11 | // @connect yximgs.com 12 | // @resource asyncPlayerPlugins https://static.yximgs.com/udata/pkg/acfun-player/asyncPlayerPlugins.b678fa.js 13 | // @grant unsafeWindow 14 | // @grant GM_registerMenuCommand 15 | // @grant GM_xmlhttpRequest 16 | // @grant GM_setValue 17 | // @grant GM_getValue 18 | // @grant GM_getResourceText 19 | // @grant GM_openInTab 20 | // @license MIT 21 | // ==/UserScript== 22 | 23 | let Joysound = null; 24 | 25 | let joysoundList = []; 26 | let hasLoadedJs = false; // 是否已加载js 27 | const LOCAL_NAME = "Ex_isJoysound"; // 是否开启joysound 28 | const LOCAL_JS = "Ex_joysoundJs"; // 本地js代码 29 | const LOCAL_JS_VERSION = "Ex_joysoundJsVersion"; // 本地js版本号 30 | const JS_VERSION = "2022.03.21"; // js版本号,如有变动请修改这个值重新获取 31 | 32 | class CustomJoysound { 33 | constructor(node) { 34 | this.item = new Joysound(); 35 | this.item.init(node); 36 | } 37 | enable() { 38 | this.item.setEnabled(1); 39 | } 40 | disable() { 41 | this.item.setEnabled(0); 42 | } 43 | } 44 | 45 | async function enableJoysound() { 46 | // 开启joysound 47 | if (!hasLoadedJs) { 48 | loadJs(); 49 | } 50 | if (joysoundList.length > 0) { 51 | for (let i = 0; i < joysoundList.length; i++) { 52 | joysoundList[i].setEnabled(1); 53 | } 54 | } else { 55 | let videoNodes = document.querySelectorAll("video"); 56 | for (let i = 0; i < videoNodes.length; i++) { 57 | let item = new Joysound(); 58 | item.init(videoNodes[i]); 59 | item.setEnabled(1); 60 | joysoundList.push(item); 61 | } 62 | if (videoNodes.length <= 0) { 63 | alert("【Joysound音效增强】未找到video元素,可能是在iframe或shadowRoot下"); 64 | } else { 65 | unsafeWindow.AudioContext = null; 66 | unsafeWindow.webkitAudioContext = null; 67 | } 68 | } 69 | localStorage.setItem(LOCAL_NAME, 1); 70 | } 71 | 72 | function disableJoysound() { 73 | for (let i = 0; i < joysoundList.length; i++) { 74 | joysoundList[i].setEnabled(0); 75 | } 76 | localStorage.setItem(LOCAL_NAME, 0); 77 | } 78 | 79 | unsafeWindow.hasInstalledJoysound = true; 80 | unsafeWindow.enableJoysound = enableJoysound; 81 | unsafeWindow.disableJoysound = disableJoysound; 82 | unsafeWindow.getJoysoundByVideoNode = function (node) { 83 | return new CustomJoysound(node); 84 | }; 85 | 86 | GM_registerMenuCommand("开启", enableJoysound); 87 | GM_registerMenuCommand("关闭", disableJoysound); 88 | GM_registerMenuCommand("Github", openGithub); 89 | 90 | function init() { 91 | if (!isEnabledJoysound()) { 92 | return; 93 | } 94 | let count = 0; 95 | let timer = setInterval(() => { 96 | if (hasVideoNode()) { 97 | clearInterval(timer); 98 | enableJoysound(); 99 | } 100 | if (count >= 240) { 101 | clearInterval(timer); 102 | } 103 | count++; 104 | }, 500); 105 | } 106 | 107 | function getJs() { 108 | const STR = "b.safari"; 109 | let ret = GM_getResourceText("asyncPlayerPlugins"); 110 | let index = ret.indexOf(STR) + STR.length + 3; 111 | let js = ret.slice(0, index) + "Joysound=e;" + ret.slice(index); 112 | return js; 113 | } 114 | 115 | function loadJs() { 116 | // 判断有没有加载过js 117 | let js = GM_getValue(LOCAL_JS); 118 | let jsVersion = GM_getValue(LOCAL_JS_VERSION); 119 | if (js && jsVersion == JS_VERSION) { 120 | eval(js); 121 | } else { 122 | let js = getJs(); 123 | GM_setValue(LOCAL_JS, js); 124 | GM_setValue(LOCAL_JS_VERSION, JS_VERSION); 125 | eval(js); 126 | } 127 | hasLoadedJs = true; 128 | } 129 | 130 | function hasVideoNode() { 131 | let videoNodes = document.querySelectorAll("video"); 132 | return videoNodes.length > 0; 133 | } 134 | 135 | function isEnabledJoysound() { 136 | return localStorage.getItem(LOCAL_NAME) == 1; 137 | } 138 | 139 | function openGithub() { 140 | GM_openInTab("https://github.com/qianjiachun/joysound-tampermonkey", { 141 | active: true 142 | }); 143 | } 144 | 145 | (async function () { 146 | init(); 147 | })(); --------------------------------------------------------------------------------