@@ -186,6 +186,9 @@ class NeteaseMiniPlayer {
186186 const embedValue = element . getAttribute ( 'data-embed' ) || element . dataset . embed ;
187187 const isEmbed = embedValue === 'true' || embedValue === true ;
188188
189+ const autoPauseAttr = element . getAttribute ( 'data-auto-pause' ) ?? element . dataset . autoPause ;
190+ const autoPauseDisabled = autoPauseAttr === 'true' || autoPauseAttr === true ;
191+
189192 return {
190193 embed : isEmbed ,
191194 autoplay : element . dataset . autoplay === 'true' ,
@@ -195,7 +198,8 @@ class NeteaseMiniPlayer {
195198 lyric : element . dataset . lyric !== 'false' ,
196199 theme : element . dataset . theme || 'auto' ,
197200 size : element . dataset . size || 'compact' ,
198- defaultMinimized : defaultMinimized
201+ defaultMinimized : defaultMinimized ,
202+ autoPauseDisabled : autoPauseDisabled
199203 } ;
200204 }
201205 /**
@@ -237,7 +241,76 @@ class NeteaseMiniPlayer {
237241 if ( this . playlist . length > 0 ) {
238242 await this . loadCurrentSong ( ) ;
239243 if ( this . config . autoplay && ! this . config . embed ) {
240- this . play ( ) ;
244+ // 静音自动播放策略(Silent Warm-up)
245+ // 1. 先静音启动
246+ this . audio . muted = true ;
247+ // 双重保险:音量先设为0
248+ const originalVolume = this . volume ;
249+ this . audio . volume = 0 ;
250+
251+ try {
252+ await this . play ( ) ;
253+ } catch ( e ) {
254+ console . log ( '静音自动播放被拦截,转为交互后播放' ) ;
255+ }
256+
257+ // 2. 监听所有可能的用户交互事件来恢复音量
258+ const interactionEvents = [ 'click' , 'touchstart' , 'keydown' , 'wheel' , 'scroll' ] ;
259+
260+ const enableAudio = ( ) => {
261+ // 移除所有监听器
262+ interactionEvents . forEach ( event => {
263+ document . removeEventListener ( event , enableAudio ) ;
264+ } ) ;
265+
266+ // 恢复音量设置(淡入效果)
267+ this . audio . muted = false ;
268+
269+ // 如果之前播放失败了(不在播放状态),则尝试再次播放
270+ if ( ! this . isPlaying ) {
271+ this . play ( ) . then ( ( ) => {
272+ // 播放成功后开始淡入
273+ this . audio . volume = 0 ;
274+ fadeIn ( ) ;
275+ } ) . catch ( e => console . error ( '交互后播放失败:' , e ) ) ;
276+ } else {
277+ // 已经在静音播放中,直接淡入
278+ this . audio . volume = 0 ;
279+ fadeIn ( ) ;
280+ }
281+
282+ // 淡入动画函数
283+ const fadeIn = ( ) => {
284+ let currentVol = 0 ;
285+ const targetVol = originalVolume ;
286+ const step = targetVol / 10 ; // 分10步完成
287+ const interval = 50 ; // 每50ms一步,共500ms
288+
289+ const fadeTimer = setInterval ( ( ) => {
290+ currentVol += step ;
291+ if ( currentVol >= targetVol ) {
292+ currentVol = targetVol ;
293+ clearInterval ( fadeTimer ) ;
294+ }
295+ this . audio . volume = currentVol ;
296+ this . volume = currentVol ; // 同步内部状态
297+ } , interval ) ;
298+ } ;
299+ } ;
300+
301+ if ( this . isPlaying ) {
302+ // 如果静音播放成功,只需要等待交互恢复音量
303+ interactionEvents . forEach ( event => {
304+ document . addEventListener ( event , enableAudio , { once : true , passive : true } ) ;
305+ } ) ;
306+ } else {
307+ // 如果静音播放也失败了,说明策略严格,必须等待交互才能开始播放
308+ this . audio . muted = false ; // 恢复状态,等待交互
309+ this . audio . volume = originalVolume ;
310+ interactionEvents . forEach ( event => {
311+ document . addEventListener ( event , enableAudio , { once : true , passive : true } ) ;
312+ } ) ;
313+ }
241314 }
242315 }
243316 if ( this . config . defaultMinimized && ! this . config . embed && this . config . position !== 'static' ) {
@@ -1186,6 +1259,12 @@ class NeteaseMiniPlayer {
11861259 this . elements . albumCover . classList . add ( 'playing' ) ;
11871260 this . element . classList . add ( 'player-playing' ) ;
11881261 } catch ( error ) {
1262+ // 如果是自动播放受阻,不显示错误提示,交给外部处理(如静音自动播放策略)
1263+ if ( error . name === 'NotAllowedError' ) {
1264+ console . warn ( '自动播放被拦截 (NotAllowedError)' ) ;
1265+ this . isPlaying = false ;
1266+ throw error ;
1267+ }
11891268 console . error ( '播放失败:' , error ) ;
11901269 this . showError ( '播放失败' ) ;
11911270 }
@@ -2289,4 +2368,4 @@ if (typeof module !== 'undefined' && module.exports) {
22892368 } ;
22902369}
22912370
2292- console . log ( [ "版本号 v2.1.0" , "NeteaseMiniPlayer V2 [NMPv2]" , "BHCN STUDIO & 北海的佰川(ImBHCN[numakkiyu])" , "GitHub地址:https://github.com/numakkiyu/NeteaseMiniPlayer" , "基于 Apache 2.0 开源协议发布" ] . join ( "\n" ) ) ;
2371+ console . log ( [ "版本号 v2.1.0.2 " , "NeteaseMiniPlayer V2 [NMPv2]" , "BHCN STUDIO & 北海的佰川(ImBHCN[numakkiyu])" , "GitHub地址:https://github.com/numakkiyu/NeteaseMiniPlayer" , "基于 Apache 2.0 开源协议发布" ] . join ( "\n" ) ) ;
0 commit comments