From d527b076dcb07993749b76bc2c20273187beeaba Mon Sep 17 00:00:00 2001 From: imsyy Date: Fri, 21 Nov 2025 11:03:36 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9E=20fix:=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=92=AD=E6=94=BE=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 + screenshots/welcome.png | Bin 0 -> 44356 bytes src/utils/lyricManager.ts | 90 ++++++++--------- src/utils/player.ts | 199 ++++++++++++++------------------------ 4 files changed, 116 insertions(+), 177 deletions(-) create mode 100644 screenshots/welcome.png diff --git a/README.md b/README.md index fe6b6c7..3a1dd9d 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,10 @@ - 欢迎各位大佬 `Star` 😍 +## 💬 交流群 + +![交流群](/screenshots/welcome.png) + ## 👀 Demo - [SPlayer](https://music.imsyy.top/) diff --git a/screenshots/welcome.png b/screenshots/welcome.png new file mode 100644 index 0000000000000000000000000000000000000000..83a86fe687326129d2c7ac5349a14da07b77e1de GIT binary patch literal 44356 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 z z(72cj00;;{cO7-sWl3{2Rzzb#4u;kE5~Z?;4;Cc97Jrd>tc!^~N<&i*J~-tMhS&NK zJWK?G$p^V2!T1}b=-SR?v}bv2qHES!{lW_`v|8NQF8_tf7oe5db=Z%N7gl^T1*L^W zh1Qjs$wF7){gZFE&#}F@{J6TyG<|F`D6cT+TB+YxfdvtO2vH1Tyqiqdtsq1tBHAPl$l*hhl}d5S zb5f@kkRh@lT0kC!0coei$|^}NR&Yj{R|LFWU>IF?TDd9=&Evj9GQ^!=s;1~1nw&Z{7PbU4K#Pe-gA!_vn zrH>RY^ag%^>ZzAr!iG|T)kW|DMLeT4PC2i(2?kjs{q3+H3=vUTN2}pMTx!loT)C&6 z0n%nRnanJUF&Z5ungoSh%t0({&{yHP%h;e^rOTo=X=(2zRcbKex9QPq>yX-5B-zPa z4C|Iv)x@!X2dVnz=H{kb^#n+RDqH9yn;k~00ED!}>K|^!CIHF9$pS#AACLecJ_r(C zB+GS4!%H%cLRg<2a^3Ty21#8y4_!5i)8)1}Bv1u3GV$R0n~z;ChIQ02J}%2PyI)M_ z7bl3PFc){c0P5!hUhj5T$Nc<*_o^+?A+Z_h{TLH0=RAXOCm#j^)89_A`E-j!2$o8n z{cxZW9W(`{MHM}>A6~L;@ZmrH_~C~SzW?#U`!9L@^&29y-@Mj284pYq6&7I@Ol9fh z`@Zj=0w7Pl^mSnS$z@EZed9qF?yY1k@@i{tEveG$scuz%$1OmEyBLw)iVLl-Oq=5H z7h~rF(?%V~@v8A{jjx!A^ZmxCbH0^CD=|K1I5mxnhFCmK#cQ2f3bvT5ouJ`dW@|R^ zc}9a=HM-&2DPqXkluBKV^U{DiM#YYYnmIS$F=F)l`~Um5#ZlvLy$8d(EqwZW|9*E; zFu+pnUh*g?xwS@elS?3k1Co^ypA68qTcsDIHTA5F#!G3X1CKgQ9eGTr6?Ahz`jPnt zQynEI)!!sk$O$DAQv)Ye)tUgv3vx=8I+`g%&jE3B4YCCGfrtell-ex=l9jjyNs17L zJP-QZ}@)!p=`*aCPsuY3s;l@kj*`9 z2wh-gV)4(Br8@bjqfV}O)Y2$)CH9xM0`!pYGh*G&D4n-@bj@<_GNDKy58qnDchzjNd>9Az~Hd zbEPK4nY51V`aP)1ak+~cXjW3540w=r5h8q492J1vRH;p(l5Y*ghD{W<(oG|J++Dbq zi>(0U!jL=M%KC^}m2e;s>c_TXE?w>5A==Rq3ivwFNchZb2@q8o05&WA0T$+>J%}}< z$reT{OJQzcy}DkmVb$EMglk~8x}$m(m)9*^10j=H-*M7g-n=@3$e0@tbv z1e0^&g$+Y&l~tz`r*3pDdz)G6^ui+#$RdZ(!T|{e zqJM0`84C^@94Gc%6(Jk_a51J&LfuAAM%kcX@hy0~)eVidu&}}dhH%;BJ z6IUag+(u0g05Ii>Ls<~*ODbb)|16~9e^kmfGoBAerk?}HJc^3Bc*5*@z!^sKNUb! znU-2yL=aO3ygigb{O>QbOZ+XL{ptiC&SE)U?RMQ@G<~Nv~LqDho&47^l`nqOMGb%C^ zs5-m>twVlxMac)DhU6gEAW|3eF7PAhmVKz+azHG4Vs-@}ZVFr4H94g4sy~W$jVzoA zT>?N}F9DL2S294dsKaFY(HtKTfMB|z&ri7xyd}W_3A>p~(gi@|4u&uRvUHhG>ShUc zS-X_n(p5>RmCA_iA-ExxZ16LKq$(a|LIfbE{R7CNCPox;g>9juk;0|TJ&?AxHhcn{ zUuKFPN4*D8uRcdG497CyqXfvj8D|S0_T+Nr^qqHN-RYe>HeoT$lS9{Bb4_HVxa+BN z;H83+??3W(kAJc$fA5Jur|mPA-&k9liT$;%0uabwvCL{N!!T@E_OQ3|C}ScD{MF@n zh}SRqLZJ}q_vrr!2ScdHs0Xrew(9_Nm5N#n1nwsTBozvD!K0+Csua~YAhJdFh4~;7 z_d#mNDV2h)%4P;bIOy)8kO=-pxtcrcBS7j=sC(v_V=lw=OjhB5B$i-wZdO{uTTiWo zav;-691!%rGmef^lEWSe<}#MoTLoML)^qb z9$M4~;R!M(N8yfjf_R>8>*3NCp|S`Lr>BlKQq9naHUd-dAqW{a?A5FHIppGkVdiUZ zT>g4TTmIFzet3Bdk6yWE=+}{5FW!IdpA^aL+|;(b_M7c*jqKPjojzmv^7FRo=4$|i z6G8{hwjcz4>L?97)NrqqPL)DmiPBs(;ZwK=MKMcox6fPC@5aDWqgO?8G(taoC1t74 zMiv6Xq8Q8aOPbdMLeRG!ssQ8^4oEMn#q>H|=nw46WPWv|?XH_ZIam679E=7p@bI(-_k2{Czp+`Lw z@zq6KSj)Zp5X|3Z^y0<}Kwit}bF_7;sGHsB9;*F%&@cwS&BWumLgvk1-~D(O$)6v8 zZ0qSwpCx~I_0_jN18B9i(KHkYz#u?y;e>2V$1*&tGRnI^xM>l1{42bzLdZ>Y2tE#? zfy*${6s%crUtdeO!HKUFKY5k{5SW+_0)+BZmsvguh_s)n210(h)Wk#Tg99=^fZVO3 zUEMAFC4B0szM6#XQP+4ez<0^PT!VOey=Y>C5uv<%$SpB(^N2eE6N70x9-7cN=t@>0 zmJg(Cm=^+#0zkA?hvNTQ`;P+2-(-?PTqVNw<-(058PCv0|ur-gB(Ev zQ&jA)Qmhl{G0uhnq<%%@ULf)`R9izkQe@c5-PDd=GUH1uFP+i{SpdTh`uxuuh-5B0 zKcmNY+(?f!)dz>C?A+uRlV;5Rb^BHD*TZ2NZY6usiJ> z5E`1R0OYa@XMK|5^DD@$X-yPp__I(T43K_hEfFKBQj4Tw6s7}=5g-R&nIN}UwU!{z zSyS07&=8U_nme$z7YY0Bh?5fY{YzFY^O4%1PO~r`E#@JPsPHEegG7p~oodOv`Cwna zY%P6CY?(rdKZtjLA!>n7w- z_s4hqiroVb{LXwo>F)$50b=$w$-1Qr2&4HLFaik4u~7w(Pd@@D( z#po_`QM>3bfmfZ@f-Fe|ST%C;)FgLM8#TBa6%#Ohnmg#BcO5AER{eiK1R?~32y zh!K`>uK;BK5+FRbE$2a)A98Vfv&(T@PtV1U2JpcJW;>&go__j7E@lIcjRFw5G4;7a z&fh0jz%roCC!Tok(<4UlF{h(*3=PhihWoyn`0De=w%Bkfnms7tn|Ab0lwaD~26LJC zJh<;umR{G`jJh{(FXoR0a7N(ojT8QZpHZ=#GwBB2Xh>MA<4tZJh88*_l z5U^a&6bQw%WMuk$QaHliq+VYIki9b?LWcl|G9ZA3%R`HXxs|h0;sQC@;~47c8FJK> z`M`8t`r_NZ$i=9&5QMN32~13E_@dJ%jLbf}b$jmYdxztb_*d@v}wYnbA9m2xqSVR!O`Qvpbn zTI(f>m`Kpd=1aO2EzBf@mm*uMl4KSmVYjx7_z-~L=+mT7&8^K{sMl1pF}PVYiAujJ zi*+Fz1vmBm$5iOi3h)sn<^I80(T1R7iT; z*Q$z7(psryEG*029FUY0Zi-+AxAY{B6#Uc!F*9{wHyix!{(wXqf3Pe_9S;1^BhHxcc7>`ozibgwBNy8H@;a#ZS8q{7DDb$6@ zIxpINQp*ym%-==t_oWU!cAcbl4}|azdc?XIp<`#7qzY>i(y4n3!(*>PZW$5SlLfUH z2up-i>jx3P*hzS*&h{1X^*J9@rkm2u$#g9D>+ka-fGJ(J>KU_eJ`mW0%`r6}K94UD z3jg>uf{`yqr%ZGB%ZaI+QQSIq_#yk`fBb2tVN2R>8`m>wbBk*-o`aPUkuFX`e%Kz@ z^|+ZsCFl!BLrqzQEbLte4e&Zjh#XBmDiH!Y@FE=oK)Pi`Qzd^Z7A2$e)C#GpggT0n z=u9eZ2);;__D5ZaHZfGr;ezlHsj%dxF?+?W&_uS-AlMb8`V={J%)u!YZx2Wif8t91 z>=*H{{ewHR7LzQlcyh(2o8kv$BLi?qo^>LnQtbV&A?jTP4v)*Ja3} zVk{TmO7<-kdr&zYbbl#I%W|?0(d}M%RB09BgfJY+8U*7o^qZ7P{jbTo%K2O-%&Bt0 z1tA}`nYELdhF*B`mmkX!E<4Ygxk-e-8GUlk=;ZL!RKc9Uy2Bs;@Xm~7;<+5E!McGX zmo^Jys}I@p!?ufVn=rR7f7gf`P%dAj@#1qD5HD4%&`ka*_v2OWiSz%|thJ8?%!NPDtQi&w? zbR_$cWd|Ar2)(iiY>i6M?y>A_e*!X_%7P5O!%z@{)52|r2V)@wmp<% zs)P|b5{Y7}>P@xvE(zg(?)12K=FXIV@7$U1`?~lRznpXKnS0NaUsT~9?wD`if*iZ-JX-6(L7j4`PypHW>2nOR;KCIYN3NE5NJ4yAfRpA73*r{3 zLx?IgdgDgmp_IWz*Et~JR~HnqoIM-9M0RQbEBJ+{oF&~SO`@6G@4KO?ES@Z&(4`f( z?15{T7_5LAbpjJUf2)gAAl?*NOFo(rhZ=+6cdlAl5H(ZQ3{-{iFmozx3rS|3we6;V zy-9Qc4c2eNDH*AgXrG$2GU;^9wn_kG{e~Aio|&2RGtWpPoEAZ?P9Wxl&!r_>=`-ob|t+5f~9z7KL4_) z_mt?sBim-+dsA(G9EImN*1ISmDFwO*6Y`wJ^_rctUGNfyPhlBR$KPLp6cyQdzLJz zReEgz2kT$FDCSOgT`=$T%1e{yb==l|RqRRXmH5m0?qhB=s)G~JM2~9TYBNq;%OuU8 z>|fa1y#Cy^T^y08XMYe&cQKqi1s{k$I=NMHeTB4f_elqY;b04*dYEuZLRyRYix=YK z2V_|YAZ$Rw`4Ag}GzIK3#3wuk>FK_yLj;03coiex#mG2B0R$R5ErO%YQEU*!Jqj&^ z)}fZc^Q5);(5Q5+Vj9@ljIBX)_wKpZm<|kxgJ-5QXifl*Z6Z;1ovQh^h|G1Mp@z*GQ`uOSN$B(aHe?8l7D&F^p#UC7y@*93pm0tjY z8Fyc$b*<1kh8GSDue4?j5{_}=(g9Jcu8RwUCI&>aAhNruu7B7M9gU_mKp+VRI~fLq z_+Y7-RPEptyBS5jh!1fs8jJPJJY>tfa@rc$N{HQJZAHo#AEOs@`O0-rAUX$SOlMK_ z+@+m6FAj-LePmfrs1!3v{HXfL0 zZV8C*bwBd~BNF6do$3Jx%mHfT*`vyuxkY?@KwD*Z14d>8XjW)no0Tr^fF*nnkCwvuIm+B8p8ttL9@z`?lTp zG?xou!K8E8WIl$v4{Se_uoH`SpI| zh7G+wd>}|R+r@a-i};_x_DbV>W#pW8k-3>tx9nrxLTL}&i9*}ooi+k$~8JLlDsE{njn4rGRWj;cKRC(4x z6Ue||Pva$oAfcdSO{GyAwI-L$M3|7f2oZKS-~*Ei2!`%rhK2&t$B%~$ zPRIG;4w|IAfM~|U7l1%~*Q8gt#1w8qWRi?VhymdcL|f*LfO}E59P*0Rvx>ndm=8$Y zL`uYOM1~BSw+dw;(v?cSX3~3CQskCn8TONiI5YX+>DmaLn5RRwPjAJi(k}~HBU{@# z2jAR!drq`qCBIi1mGoN5>%*V$kxCs8DV-1!X5z!=VZcH_vpL@yri+BeT{mTDK~SwePg~_=-3?89};z^?Xs)!O0pp%xxqMtA69b z+W0K|Bdc{Tv~8#%287)V;PBkn@{IrqmN2Xx$Zn!+pI?%Ux50ii~`?0&mr5BU5QYY z+sp-<5V|HZ97DO^oSpy?-CkJIxA+rdJ`{f0JqBy>NrQ{A%uDLttGvMs-w>9I7@U5y8me#}9#I8@l$IOd)h&F5vKwNM3#S(hPdWuEp0Wpm4O$b9y87@OBCZ?Wi(!oc6p>^QnwP1uM%_n5IK~T*zQ*6r zMfvu2{E|>|0|YHn0{`$*@$Fl;Ivmgr{zY>*tqv#lIvVoqeq*kUkz=KtwPS@F)-&;$i1x z+n!%iJ{%DE@NEowZAEGa5It`nCxni?=Fl14l&cR{;9_I@XiW7TKzMWO`&)c0izpo$ zNx*@Z@A$=aeMxbog@~a+Z=Zj(`4BAjI3S~6lYF4!qmM`2y{HY~5FZlqVWKsvUN>|= z248-+fzyH@1Dh!wg;wJdL&W64(A&~tUa2-U0L1V>V-@OIkF<@^ zC5B@%ASn;Z5NwpXB3PuZaz2Q53aQ{wDIW-rcu2>Ej{u0cQBfj7v{bAxFD;4q9)=R6 ztU)pg$_Zashek09T)7$@T;DtL?o(h_W7omaWC zg|T=1W&Sv*d{}`B8R3L%6c9iDkcaUCgeXf?gbg>gUZjTYElw0?AW&i@>e0nSSD1VN z;=33-2qCuI)nD}5mYwc7h>jhtB0PhFzKz8SlkwT1$DZ~Q$AnGnLY+r}SKNFwzra|=BBMQS)m9UivVf(tul5AR~Y zf}Rzw7t)qLAB%*<3f1yQq(fD+L398iOwUv7Y07)Z9eEVAB(Mam8{AjhKXGvyvuoNhmd4A8UsWkNvS9fQp5hmCd;Z*e+*7h z_jiv_iAphjTrBAj+12>EPk?7B%~`_Vvf!;AKT{qAYpi*i9^7I z&Q>>TFbg&aMLRA$Y8e&L&91tuPAPxvt0J1*eT0t@EyjNu2*A3Q@#Vp3G6=z`(#f?&uu)?XwgGzjppypczQ zrLH>{hDZl^s5i4lCSje>R+h5EJ(`UcXCv_>g{% zfr)nF*XpUnQx%hCw3fPAn!J5Vd%O1b?NbIuerSzp)*9hcn^gKpd{-mCWIh*@Avd+3 z({sY6sc95VBtIWCpQ|wh&C!R&eSeG24mSuuf_Cw>4!=*^r0FdDOjni?wadkKZcc@fBjp!KTn_C9|5_2d&}*3yYSq~e?#$T%s&$qsGI@Cu1Sx1Kq z1q4t;hv_b!33}41#OhSqbSg815vtjAx}G8Z=!^#*MR=vn2y-1XSMAu5M~SRMNjvDO zy&9D+*UvqjP1e)Bp{@j-KTiyG=KPs6^l@Ei>4xeK4JVil^&sj*vJ(svEuB7nI!|0D zla9L}gFXfb`eJDWVM}VdYy0+HQyfjF#5ZlA8zedtJZ3{UAY-PJ5g8uXp&j4?7euYS z-_y;#H*ellAQ*^(5L!t^GHr!wJd$-(F+s~-abaW_AZRHzdPopGopd=NBQ;21ghY~- zm~m|fjND{4+dlK>?EoXFY+q$MEd(GX9?FP%9}EN*7$SRY?!(cigAf@P6(I_RQ{r$C z&IS>s2}I1fpc6r`5mN?M@gWTrc+gdh#s@5j*J^{&MZ*`FSc7y`5yBf7Oy^2OrUWG> zX4{n&EG;ffqSh0&lnzY1$B2dWLqycx4kJ*ZLtb(&LrBnB?NtIHXbi{+iFl|D=x8r7 z7c7AUMj{?<)0%S{Fs?xL^DM}B6VVc=s#-k21dzx*q zWa8Q|LO`d) z4H`o!f#S2l;R2EVs$zJUI~m#{Aboua>&&WgGNsS*i01_d-zC1m0O1$mu66%j9 zay1aLLkStlB6M5{!D0r96^Jwx=pY;px zEc%B!F-}}OltIP_LLeFt3#mp&brQmw9R^4KLYrA-kZSjb2pL8f zv{5^-PACXfWRD+0VrPMHY`_C^3wnOQWP(r#kcj-j9zev1tA`7SL}VnyQ%I(d;zT?g zIteiQV?vfe}N7F UfOtq=KL7v#07*qoM6N<$f=Vw%l>h($ literal 0 HcmV?d00001 diff --git a/src/utils/lyricManager.ts b/src/utils/lyricManager.ts index 819dbcd..bbf511d 100644 --- a/src/utils/lyricManager.ts +++ b/src/utils/lyricManager.ts @@ -105,59 +105,51 @@ class LyricManager { const isStale = () => this.activeLyricReq !== req || musicStore.playSong?.id !== id; // 处理 TTML 歌词 const adoptTTML = async () => { - try { - if (!settingStore.enableTTMLLyric) return; - const ttmlContent = await songLyricTTML(id); - if (isStale()) return; - if (!ttmlContent || typeof ttmlContent !== "string") return; - const parsed = parseTTML(ttmlContent); - const lines = parsed?.lines || []; - if (!lines.length) return; - result.yrcData = lines; - ttmlAdopted = true; - } catch (err) { - throw err; - } + if (!settingStore.enableTTMLLyric) return; + const ttmlContent = await songLyricTTML(id); + if (isStale()) return; + if (!ttmlContent || typeof ttmlContent !== "string") return; + const parsed = parseTTML(ttmlContent); + const lines = parsed?.lines || []; + if (!lines.length) return; + result.yrcData = lines; + ttmlAdopted = true; }; // 处理 LRC 歌词 const adoptLRC = async () => { - try { - const data = await songLyric(id); - if (isStale()) return; - if (!data || data.code !== 200) return; - let lrcLines: LyricLine[] = []; - let yrcLines: LyricLine[] = []; - // 普通歌词 - if (data?.lrc?.lyric) { - lrcLines = parseLrc(data.lrc.lyric) || []; - // 普通歌词翻译 - if (data?.tlyric?.lyric) - lrcLines = this.alignLyrics(lrcLines, parseLrc(data.tlyric.lyric), "translatedLyric"); - // 普通歌词音译 - if (data?.romalrc?.lyric) - lrcLines = this.alignLyrics(lrcLines, parseLrc(data.romalrc.lyric), "romanLyric"); - } - // 逐字歌词 - if (data?.yrc?.lyric) { - yrcLines = parseYrc(data.yrc.lyric) || []; - // 逐字歌词翻译 - if (data?.ytlrc?.lyric) - yrcLines = this.alignLyrics(yrcLines, parseLrc(data.ytlrc.lyric), "translatedLyric"); - // 逐字歌词音译 - if (data?.yromalrc?.lyric) - yrcLines = this.alignLyrics(yrcLines, parseLrc(data.yromalrc.lyric), "romanLyric"); - } - if (lrcLines.length) result.lrcData = lrcLines; - // 如果没有 TTML,则采用 网易云 YRC - if (!result.yrcData.length && yrcLines.length) { - result.yrcData = yrcLines; - } - // 先返回一次,避免 TTML 请求过慢 - const lyricData = this.handleLyricExclude(result); - this.setFinalLyric(lyricData, req); - } catch (err) { - throw err; + const data = await songLyric(id); + if (isStale()) return; + if (!data || data.code !== 200) return; + let lrcLines: LyricLine[] = []; + let yrcLines: LyricLine[] = []; + // 普通歌词 + if (data?.lrc?.lyric) { + lrcLines = parseLrc(data.lrc.lyric) || []; + // 普通歌词翻译 + if (data?.tlyric?.lyric) + lrcLines = this.alignLyrics(lrcLines, parseLrc(data.tlyric.lyric), "translatedLyric"); + // 普通歌词音译 + if (data?.romalrc?.lyric) + lrcLines = this.alignLyrics(lrcLines, parseLrc(data.romalrc.lyric), "romanLyric"); } + // 逐字歌词 + if (data?.yrc?.lyric) { + yrcLines = parseYrc(data.yrc.lyric) || []; + // 逐字歌词翻译 + if (data?.ytlrc?.lyric) + yrcLines = this.alignLyrics(yrcLines, parseLrc(data.ytlrc.lyric), "translatedLyric"); + // 逐字歌词音译 + if (data?.yromalrc?.lyric) + yrcLines = this.alignLyrics(yrcLines, parseLrc(data.yromalrc.lyric), "romanLyric"); + } + if (lrcLines.length) result.lrcData = lrcLines; + // 如果没有 TTML,则采用 网易云 YRC + if (!result.yrcData.length && yrcLines.length) { + result.yrcData = yrcLines; + } + // 先返回一次,避免 TTML 请求过慢 + const lyricData = this.handleLyricExclude(result); + this.setFinalLyric(lyricData, req); }; // 设置 TTML await Promise.allSettled([adoptTTML(), adoptLRC()]); diff --git a/src/utils/player.ts b/src/utils/player.ts index 93c3a09..eb0a566 100644 --- a/src/utils/player.ts +++ b/src/utils/player.ts @@ -3,6 +3,7 @@ import type { MessageReactive } from "naive-ui"; import { Howl, Howler } from "howler"; import { cloneDeep } from "lodash-es"; import { useMusicStore, useStatusStore, useDataStore, useSettingStore } from "@/stores"; +import { useIntervalFn } from "@vueuse/core"; import { calculateProgress } from "./time"; import { shuffleArray, runIdle } from "./helper"; import { heartRateList } from "@/api/playlist"; @@ -23,8 +24,11 @@ import audioContextManager from "@/utils/player-utils/context"; import lyricManager from "./lyricManager"; import blob from "./blob"; -// 播放器核心 -// Howler.js +/** + * 播放器核心 + * Howler.js 音频库 + */ +let _player: Player | null = null; /* *允许播放格式 */ const allowPlayFormat = ["mp3", "flac", "webm", "ogg", "wav"]; @@ -33,78 +37,12 @@ class Player { /** 播放器 */ private player: Howl; /** 定时器 */ - private playerInterval: ReturnType | undefined; - /** 自动关闭定时器 */ - private autoCloseInterval: ReturnType | undefined; - /** 频谱数据 */ - private audioContext: AudioContext | null = null; - private analyser: AnalyserNode | null = null; - private dataArray: Uint8Array | null = null; - /** 其他数据 */ - private message: MessageReactive | null = null; - /** 预载下一首歌曲播放地址缓存(仅存 URL,不创建 Howl) */ - private nextPrefetch: { id: number; url: string | null; ublock: boolean } | null = null; - /** 并发控制:当前播放会话与初始化/切曲状态 */ - private playSessionId: number = 0; - /** 是否正在切换歌曲 */ - private switching: boolean = false; - /** 当前曲目重试信息(按歌曲维度计数) */ - private retryInfo: { songId: number; count: number } = { songId: 0, count: 0 }; - constructor() { - // 创建播放器实例 - this.player = new Howl({ src: [""], format: allowPlayFormat, autoplay: false }); - // 初始化媒体会话 - this.initMediaSession(); - // 挂载全局 - window.$player = this; - } - /** - * 新建会话并返回会话 id - */ - private newSession(): number { - this.playSessionId += 1; - return this.playSessionId; - } - /** - * 检查传入会话是否过期 - */ - private isStale(sessionId: number): boolean { - return sessionId !== this.playSessionId; - } - /** - * 重置底层播放器与定时器(幂等) - */ - private resetPlayerCore() { - try { - // 仅卸载当前播放器实例 - if (this.player) { - this.player.stop(); - this.player.off(); - this.player.unload(); - } - } catch { - /* empty */ - } - this.cleanupAllTimers(); - } - /** - * 处理播放状态 - */ - private handlePlayStatus() { - const musicStore = useMusicStore(); - const statusStore = useStatusStore(); - const settingStore = useSettingStore(); - const currentSessionId = this.playSessionId; - // 清理定时器 - clearInterval(this.playerInterval); - // 更新播放状态 - this.playerInterval = setInterval(() => { - // 检查会话是否过期 - if (currentSessionId !== this.playSessionId) { - clearInterval(this.playerInterval); - return; - } - if (!this.player.playing()) return; + private readonly playerInterval = useIntervalFn( + () => { + if (!this.player?.playing()) return; + const musicStore = useMusicStore(); + const statusStore = useStatusStore(); + const settingStore = useSettingStore(); const currentTime = this.getSeek(); const duration = this.getDuration(); // 计算进度条距离 @@ -130,7 +68,47 @@ class Player { window.electron.ipcRenderer.send("set-bar", progress); } } - }, 250); + }, + 250, + { immediate: false }, + ); + + /** 自动关闭定时器 */ + private autoCloseInterval: ReturnType | undefined; + /** 频谱数据 */ + private audioContext: AudioContext | null = null; + private analyser: AnalyserNode | null = null; + private dataArray: Uint8Array | null = null; + /** 其他数据 */ + private message: MessageReactive | null = null; + /** 预载下一首歌曲播放地址缓存(仅存 URL,不创建 Howl) */ + private nextPrefetch: { id: number; url: string | null; ublock: boolean } | null = null; + /** 当前曲目重试信息(按歌曲维度计数) */ + private retryInfo: { songId: number; count: number } = { songId: 0, count: 0 }; + constructor() { + // 创建播放器实例 + this.player = new Howl({ src: [""], format: allowPlayFormat, autoplay: false }); + // 初始化媒体会话 + this.initMediaSession(); + // 挂载全局 + window.$player = this; + } + /** + * 重置底层播放器与定时器(幂等) + */ + private resetPlayerCore() { + try { + // 仅卸载当前播放器实例 + if (this.player) { + this.player.stop(); + this.player.off(); + this.player.unload(); + } + Howler.unload(); + } catch { + /* empty */ + } + this.cleanupAllTimers(); } /** * 预载下一首歌曲的播放地址(优先官方,失败则并发尝试解灰) @@ -215,19 +193,10 @@ class Player { const settingStore = useSettingStore(); // 播放信息 const { id, path, type } = musicStore.playSong; - const currentSessionId = this.playSessionId; - // 检查会话是否过期 - if (currentSessionId !== this.playSessionId) { - console.log("🚫 Session expired, skipping player creation"); - return; - } + // 统一重置底层播放器 this.resetPlayerCore(); - // 二次检查会话 - if (currentSessionId !== this.playSessionId) { - console.log("🚫 Session expired after cleanup, aborting"); - return; - } + // 创建播放器 this.player = new Howl({ src, @@ -250,8 +219,7 @@ class Player { // else resetSongLyric(); // 获取歌词数据 lyricManager.handleLyric(id, path); - // 定时获取状态 - if (!this.playerInterval) this.handlePlayStatus(); + // 新增播放历史 if (type !== "radio") dataStore.setHistory(musicStore.playSong); // 获取歌曲封面主色 @@ -279,10 +247,8 @@ class Player { const playSongData = getPlaySongData(); // 获取配置 const { seek } = options; - const currentSessionId = this.playSessionId; // 初次加载 this.player.once("load", () => { - if (currentSessionId !== this.playSessionId) return; // 允许跨域 if (settingStore.showSpectrums) { const audioDom = this.getAudioDom(); @@ -325,8 +291,8 @@ class Player { }); // 播放 this.player.on("play", () => { - if (currentSessionId !== this.playSessionId) return; window.document.title = getPlayerInfo() || "SPlayer"; + this.playerInterval.resume(); // 重置重试计数 try { const current = getPlaySongData(); @@ -344,8 +310,8 @@ class Player { }); // 暂停 this.player.on("pause", () => { - if (currentSessionId !== this.playSessionId) return; if (!isElectron) window.document.title = "SPlayer"; + this.playerInterval.pause(); // ipc if (isElectron) { window.electron.ipcRenderer.send("play-status-change", false); @@ -354,7 +320,7 @@ class Player { }); // 结束 this.player.on("end", () => { - if (currentSessionId !== this.playSessionId) return; + this.playerInterval.pause(); // statusStore.playStatus = false; console.log("⏹️ song end:", playSongData); @@ -374,13 +340,11 @@ class Player { }); // 错误 this.player.on("loaderror", (sourceid, err: unknown) => { - if (currentSessionId !== this.playSessionId) return; const code = typeof err === "number" ? err : undefined; this.handlePlaybackError(code); console.error("❌ song error:", sourceid, playSongData, err); }); this.player.on("playerror", (sourceid, err: unknown) => { - if (currentSessionId !== this.playSessionId) return; const code = typeof err === "number" ? err : undefined; this.handlePlaybackError(code); console.error("❌ song play error:", sourceid, playSongData, err); @@ -507,7 +471,6 @@ class Player { } // 超过次数:切到下一首或清空 this.retryInfo.count = 0; - this.switching = false; if (dataStore.playList.length > 1) { window.$message.error("当前歌曲播放失败,已跳至下一首"); await this.nextOrPrev("next"); @@ -589,7 +552,6 @@ class Player { const musicStore = useMusicStore(); const statusStore = useStatusStore(); const settingStore = useSettingStore(); - const sessionId = this.newSession(); try { // 获取播放数据 @@ -609,7 +571,6 @@ class Player { // 本地歌曲 if (path) { - if (this.isStale(sessionId)) return; try { await this.createPlayer(`file://${path}`, autoPlay, seek); await this.parseLocalMusicInfo(path); @@ -658,20 +619,18 @@ class Player { if (!playerUrl) { window.$message.error("该歌曲暂无音源,跳至下一首"); - this.switching = false; await this.nextOrPrev("next"); return; } } catch (err) { console.error("❌ 获取歌曲地址出错:", err); window.$message.error("获取歌曲地址失败,跳至下一首"); - this.switching = false; await this.nextOrPrev("next"); return; } // 有有效 URL 才创建播放器 - if (playerUrl && !this.isStale(sessionId)) { + if (playerUrl) { try { await this.createPlayer(playerUrl, autoPlay, seek); } catch (err) { @@ -682,10 +641,7 @@ class Player { } catch (err) { console.error("❌ 初始化音乐播放器出错:", err); window.$message.error("播放遇到错误,尝试下一首"); - this.switching = false; await this.nextOrPrev("next"); - } finally { - this.switching = false; } } /** @@ -758,12 +714,6 @@ class Player { const dataStore = useDataStore(); const musicStore = useMusicStore(); try { - if (this.switching) { - console.log("🔄 Already switching, ignoring request"); - return; - } - this.switching = true; - // 立即更新UI状态,防止用户重复点击 statusStore.playLoading = true; statusStore.playStatus = false; @@ -818,16 +768,12 @@ class Player { // 重置播放进度(切换歌曲时必须重置) statusStore.currentTime = 0; statusStore.progress = 0; - // 暂停当前播放 - await this.pause(false); // 初始化播放器(不传入seek参数,确保从头开始播放) await this.initPlayer(play, 0); } catch (error) { console.error("Error in nextOrPrev:", error); statusStore.playLoading = false; throw error; - } finally { - this.switching = false; } } /** @@ -1046,7 +992,6 @@ class Player { // 查找索引(在处理后的列表中查找) statusStore.playIndex = processedData.findIndex((item) => item.id === song.id); // 播放 - await this.pause(false); await this.initPlayer(); } } else { @@ -1055,7 +1000,6 @@ class Player { ? Math.floor(Math.random() * processedData.length) : 0; // 播放 - await this.pause(false); await this.initPlayer(); } // 更改播放歌单 @@ -1095,11 +1039,6 @@ class Player { const dataStore = useDataStore(); const statusStore = useStatusStore(); try { - if (this.switching) { - console.log("🔄 Already switching, ignoring request"); - return; - } - this.switching = true; // 立即更新UI状态,防止用户重复点击 statusStore.playLoading = true; statusStore.playStatus = false; @@ -1118,8 +1057,6 @@ class Player { statusStore.currentTime = 0; statusStore.progress = 0; statusStore.lyricIndex = -1; - // 暂停当前播放 - await this.pause(false); // 清理定时器,防止旧定时器继续运行 this.cleanupAllTimers(); // 清理并播放(不传入seek参数,确保从头开始播放) @@ -1128,8 +1065,6 @@ class Player { console.error("Error in togglePlayIndex:", error); statusStore.playLoading = false; throw error; - } finally { - this.switching = false; } } /** @@ -1469,9 +1404,8 @@ class Player { */ private cleanupAllTimers() { // 清理播放状态定时器 - if (this.playerInterval) { - clearInterval(this.playerInterval); - this.playerInterval = undefined; + if (this.playerInterval.isActive.value) { + this.playerInterval.pause(); } // 清理自动关闭定时器 if (this.autoCloseInterval) { @@ -1495,3 +1429,12 @@ class Player { } export default new Player(); + +/** + * 获取播放器实例 + * @returns Player + */ +export const usePlayer = (): Player => { + if (!_player) _player = new Player(); + return _player; +};