1+ // ==UserScript==
2+ // @name HTML5 视频音频默认音量
3+ // @version 1.0.0
4+ // @author X.I.U
5+ // @description 避免被一些默认 100% 音量的视频/音频吓一跳(或社死)!且支持各网站分别记住音量...
6+ // @match *://*/*
7+ // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAALfElEQVRYhX2Xe3Bd1XXGf3vvc859X+nq6nUlW5Yly7JlI2xsYzAwtnk4ATpAxkNTHm0mnaTT/gHTTvrIBDLTpp1JUoZppqHQls5AKTR2INOWJJQSXF4x2BhsJCRZ8kuWZckPSVf3/Trn7N3RVTFpQrNn1l97n7O/vda31reWMKMPcmUJA9U8vrwHGdqCHn4HPzePaIxhVSoYbYRXrn7BeMVbCUduF6kVUXHwvQP+6amDaqDnoIompmQytaBnTmB8H5lowrjgFss48SBeI/hUEEZeudLi1ywhJEIJdL6Q8rzal/1a5SGC4XZrYBvWwEZobMdLdH6RH+z/Io1taEeh52fe8tOZbysl/ouWFvANYP7fSz4DgAEBBIL4xiS8ubmnVcTZK68aRK29Dtm8dgnZJydRW+/E2nrnp19nz+7U77+60zt0qMz07J/KxuQTwrIw4rMBCDP6wC+FIIcO34eudDdXf/7jD52Opi772lugY3AZr++hp06gz48j+waRqTWYmVHcS+chEMFeuw1hBzBzY7g/fQE9fmqBYPzBQKrpVa/R4OkCAnXlSvXnX9sIllk220BE4Z8OdHoj54YCK6Od1i2/iUmuRyDRk6NUn3+M0pv/hnf0AE40jEjEqP3oe6Rf/CGOWUTNjFKby2MP7EBtugURFWFxfOhB4+o4yfhrGAdZsxHaqZt6dNce9KXYFSPfGWS68JFqTXSqO7+MCaTqETGTwxSeeoRCOoPT2YUIhFC2jbQF/uwUatU6rPbVUM5T+OfHUO3dWKv6kSsGUIOD6PEPr+fswnanpecFZYVQhFAyjPS9Tj4xw2rcU+pJApEutWsvRjaBW8NUShilkE1JIqlUPfi6VMLNFTBVr+7KYKqJ8uEjlM+dJrR5K0L7eB+9hTd2CFrWYt33h0jH3O5Nj37TBGtgZUBkUN/6q4dQ7UmsnlW450//gU5PPRq460uQXAu+j//i99A/+UdUMoXqbMNkz2OnUkixlF4u9spe/HMTULyEaA7jXkoT2fEbQIXi838DJ4cRDXHkEjc2b0MPHdptZubGpBUbM0UfKQpBRDmKWRSD3tTMk87gddA2WGe4+dkzMD0CyQ5qP/4XVDCAvfkaLMvHamzEClpQzGDF46iuJOH1CaKr2tDZRfzhQ0Ru24NYsYrCM4/jDb+FiHdi3XU/0s3vr7WsGKxcfyPSy+bxi0UqJ8f/IriiE2vrnuWsLefQk8NoO4AMBBB9/XjDI6hQCjdTxq9WCaQ6ULaDFrIeKr3oIlv70Olz2K1xlAVaSUQojD786nKi9e5A3LBHMHn0W+LUUaS1FI9q+iZZWLhHdq/FxFbWSSfsIDIQwVw4g/GK2OuuhloNMzaCaF+DNBJtQfX8LFYigElX0OkQtZKHVy3jqwDlqWncCzPI3nU4t+2FWrH+OLHzHpRl3109memTOhqDi9NfkefHEKvWLTO+VKD68Qf4G27CueFWhJ/Df+0lVFcXJOJYnobm1ZjsJUxuFjyDjK/GNK2gND4ESuDPXcCOSaI7thPqX0ft8OtUn/oTKOQgkET39KJU4RbpZXOtNRW717p+FyRSdYT+v36H4u/fQXbfc3iRDkT3FsTGjWAWEU0OZKfAU9CyEdXVD2lQPduplmo4jkBEbMzK1VgDu5EVTe3gm1RHx6Bcxpz6YLkEO0lMYeFGi6z7eVMqhkT/ZrCb0LNT+NMTRH/nt/BLRdy3X8Nv68Lu6cZEHURjE6K3hirYeLRhDWyA4jxzH40RXJwkeuM29MpN+JcziEsz+Avz6GgcW1pYbUlEQCyHwYpSyxS7rGo+v8man4ZMATrAHf+QSt7FTkWR4QbsjlbIX8IMH0VuuAqj4piGAbhmEPPzI/injnNxMUPuwOtseOIxKKTJ7/8BTBxDdXcjO9sJdTeg01VqH4wg3CDB9bshHMKORbGolVOmeRW09dVdUxkbp3ruNM7GXnS1hK5OYSoSbBDZBcxCBtF3DcUzk6hkhGA0RmtHKx1rOkE04lbzWC1tqMRt1CZHUafPIs8H6/JsNTcgN+9YFq1qgbBUFUvnK9qrVghXCvWN8MBmivueJDtylqaeBKWJaXR4JZEtNyBWrkGt6AJboCZO4J49Rc64xGIhcgtZgm6egKhgtUQQto17WeHOLqCNj5Vowbr7q4j+Lcs1JhhEphcXLTebd0jPwpkx6Lwa++bbCR95ALecp5a6BrvrJoLdHajmMOTnKb3+BrVMntjARpzeFbz8jcfpa22gGm+kMJlm95Zu9M9+iI5G0G3d6EgIUSnjzs/gv/Icgd6rqcvz0IeYWnXc8pEtYnEe8gtXNL7xz74LehHSE3DqNP7EIdx3p5DSh7JNJePiBE/gN3Uz8NWHae5sRJYXqKQvU+raQPg7L6L3/QNMHcfp6EREGjC5LDp9GaOs5VQ/NQI93YctOxFPlwniDh/C3n47JHvrQPTBl3DHjiIDQUQ4jGhOYcqaQFuE0Nl53OnLRHfsZV33KsTxd6GlHeaP477zMl5uAWv7dkyLg6kZREsb+vgCcvPOuoaYuWNQWERs3jAuQ6nooXK6TH566cXnrjQK7uwFaoseWA3oJf2WEhEJUjm/gMgXCfdvQlFFv/R3uCND6FIRv7MfMnOIiaPoI/8NEb2kWAhfoLbdjLr2jmUv/8f+pVbkHRGNnZHum2/udxxtCn4j/vgEIjNTD4O9upfIprUYoxBKo9Z14jumTq7YYD9WayvuR++hs1lkshmha4iuNeDYiIAFMoCevIi+cJHaa29gmvsRTUn0R29g9u1D7bxxv+jrRnpD56cCkdjfV9NzpA+8A5VlLojWAczlGVTAYKXimIU8MlsjtKEXgiF0aRGdm8cEYnXm+O+/gdAGuWsP3shhTHoOEYqCCEF2DsrF5f+e/xiikUldrT6l3z+GevSaTahaZdRY6uFqxRXR1sRyzU/21Gu6OTOMfzmPd6kI8TgiX8B4imouj1QCKmVUNITJ59AnR1F77kH4ZaRnQFroMyeRW3egdt6DwIX391Gshv+4LK2jtcuLqK9t7ALjZXzH1uVM/mb/7BTRnjZEex+idQ2EAnjjR/BdF1PIoV2Bae/F/fh9dL5IYE0XUmpMNo+ev4AINSJWb0UPHa63Z7SvRN3/CHJpFHj2G4iZzAuBbTu+GWpIEGxrQ/3RnlvxG5M4kYa3Lc2u4uyFblnIE+xfAbF2RMtqZGsn/uTYUgHH+dz9eFMnqYx8gO+CEwkjhcDPF/DLHurSaeTm3RiWMsDHeuDrSFvBv3+bi08+N1Vwuj/vZWtu+dwclZlFrESoeZmZysJXoTsCjnVk8dDQBuN+n8RDD9fbcdG7leBX1iOkQjhBOHmQfKGAHW3CS6fR+QClmYuYMyPY265DtPVgtfctiw4V/GcfYfGNQzj3/u4DqlormUoZEQwuc0I//eSnY4G0wPJjmdGhw+mh0fWxNZ0037cXccPd1MXgk+GjNE/tR3+Le+YEyg5TnT6LXlwgcu1u7C99HZlsv3K2+vjvkTs2RvDe3747tm7Dy1SKvzSYPP/MLwxFAkIKEzEye2zswOXX395lJyK0fOFzRHfuglQfqPin59Nn0RNDuJk09vprkd0brmx5H7xCbfgQbrZ83OkfvN1pj0+ZmkBYNhjzCwCeffr/AsBDJyU6kqBwbPzRuTcP/GXV82lYlaJpfQ+BjVdhXX0tNKTAjvzKqKXPTeC++1NKY0c9kVz1SGzb9X8tjIdfzSFCDfUw/noA0scPuxBrwcvmmH3rQIvMm3/y0XdJS4JfIpiIUG9g+wcg6KDnZpGZNDQ0Ii5cSAtlPRHYct13axWvJNwadiiAli4iEP8VAJ89HQtR129TLiG1nos0Nt8dSOi12qi9lRq3utVqT/lirql24hW3vLBQi3d3XUqu73+PZOonBNR/WnbYSMeGTO5/Xf6ZtwDwPwtFRezQVs+sAAAAAElFTkSuQmCC
8+ // @grant GM_registerMenuCommand
9+ // @grant GM_unregisterMenuCommand
10+ // @grant GM_openInTab
11+ // @grant GM_getValue
12+ // @grant GM_setValue
13+ // @grant GM_notification
14+ // @license GPL-3.0 License
15+ // @run -at document-start
16+ // @namespace https://github.com/XIU2/UserScript
17+ // ==/UserScript==
18+
19+ ( function ( ) {
20+ 'use strict' ;
21+ var menu_ID = [ ] ;
22+ registerMenuCommand ( ) ; // 注册脚本菜单
23+ function registerMenuCommand ( ) {
24+ if ( self != top ) return
25+ // 如果菜单ID数组多于菜单数组,说明不是首次添加菜单,需要卸载所有脚本菜单
26+ if ( menu_ID . length > 0 ) { for ( let i = 0 ; i < menu_ID . length ; i ++ ) { GM_unregisterMenuCommand ( menu_ID [ i ] ) ; } }
27+ menu_ID [ 0 ] = GM_registerMenuCommand ( '#️⃣ 修改全局默认音量 [ ' + GM_getValue ( 'menu_defaultVolume' , 30 ) + '% ]' , function ( ) { customDefaultVolume ( ) } ) ;
28+ menu_ID [ 1 ] = GM_registerMenuCommand ( '🔁 忘记当前网站音量 (即跟随全局)' , function ( ) { resetCurrentVolume ( ) } ) ;
29+ // 记得修改反馈 URL
30+ menu_ID [ 2 ] = GM_registerMenuCommand ( '💬 反馈 & 建议' , function ( ) { GM_openInTab ( 'https://github.com/XIU2/UserScript#xiu2userscript' , { active : true , insert : true , setParent : true } ) ; GM_openInTab ( 'https://greasyfork.org/zh-CN/scripts/XXXXXXXXXXXXXX/feedback' , { active : true , insert : true , setParent : true } ) ; } ) ;
31+ }
32+
33+ insPage ( ) ;
34+ currentPage ( ) ;
35+
36+
37+ // 网页本身的 Video Audio 标签
38+ function currentPage ( event = true ) {
39+ document . querySelectorAll ( 'video, audio' ) . forEach ( function ( _this ) {
40+ //console.log('网页本身:', _this)
41+ modifyVolume ( _this ) ;
42+ if ( event ) _this . addEventListener ( 'volumechange' , volumeChangeEvent ) ;
43+ } )
44+ }
45+
46+
47+ // 后续动态插入的 Video Audio 标签(插入事件)
48+ function insPage ( ) {
49+ const callback = ( mutationsList , observer ) => {
50+ for ( const mutation of mutationsList ) {
51+ for ( const target of mutation . addedNodes ) {
52+ if ( target . nodeType != 1 ) break
53+ if ( target . tagName === 'VIDEO' || target . tagName === 'AUDIO' ) {
54+ //console.log('后续插入:', target)
55+ modifyVolume ( target ) ;
56+ target . addEventListener ( 'volumechange' , volumeChangeEvent ) ;
57+ }
58+ }
59+ }
60+ } ;
61+ const observer = new MutationObserver ( callback ) ;
62+ observer . observe ( document , { childList : true , subtree : true } ) ;
63+ }
64+
65+
66+ // 音量变化事件(记住音量)
67+ function volumeChangeEvent ( event ) {
68+ if ( localStorage . getItem ( 'html5_xiu_currentVolume' ) || ( ( event . target . volume * 100 ) !== GM_getValue ( 'menu_defaultVolume' , 30 ) ) ) localStorage . setItem ( 'html5_xiu_currentVolume' , event . target . volume * 100 )
69+ }
70+
71+
72+ // 修改视频音量
73+ function modifyVolume ( _this ) {
74+ if ( ! _this . controls ) return ; // 如果视频/音频没有默认控件,则代表是
75+ let nowVolume = parseFloat ( localStorage . getItem ( 'html5_xiu_currentVolume' ) ) ; // 先看看 localStorage 有没有(即用户是否手动调整过音量)
76+ if ( ! nowVolume ) nowVolume = GM_getValue ( 'menu_defaultVolume' , 30 ) ; // 如果 localStorage 没有,那就从脚本配置中获取
77+ if ( ! ( ( typeof nowVolume === 'number' ) && nowVolume <= 100 ) ) nowVolume = 30 ; // 如果获取到的音量数值不是数字,或大于 100,则重置为 30
78+ _this . volume = nowVolume / 100 ; // 设置音量为 0~1 范围
79+ }
80+
81+
82+ // 修改全局默认音量
83+ function customDefaultVolume ( ) {
84+ let newValue = parseFloat ( prompt ( '修改全局默认音量,不影响各网站记住的音量,当前网页需刷新后生效~\n范围:0~100 (即 0%~100%,不需要加 % 百分号)\n默认:30' , GM_getValue ( 'menu_defaultVolume' , 30 ) ) ) ;
85+ if ( ! Number . isNaN ( newValue ) && newValue >= 0 && newValue <= 100 ) { GM_setValue ( 'menu_defaultVolume' , newValue ) ; }
86+ registerMenuCommand ( ) ; // 重新注册菜单(刷新菜单上的音量值)
87+ }
88+
89+
90+ // 忘记当前网站音量
91+ function resetCurrentVolume ( ) {
92+ if ( localStorage . getItem ( 'html5_xiu_currentVolume' ) ) localStorage . removeItem ( 'html5_xiu_currentVolume' ) // 清理 localStorage
93+ currentPage ( false ) ; // 重置当前网页的音量
94+ }
95+ } ) ( ) ;
0 commit comments