@@ -57,6 +57,8 @@ export class FFmpegAudioPlayer extends BaseAudioPlayer {
5757
5858 /** 当前音频源地址 */
5959 private _src : string = "" ;
60+ /** 用于取消正在进行的 fetch 请求 */
61+ private abortController : AbortController | null = null ;
6062
6163 constructor ( ) {
6264 super ( ) ;
@@ -125,6 +127,13 @@ export class FFmpegAudioPlayer extends BaseAudioPlayer {
125127 this . playerState = "loading" ;
126128 this . emit ( AUDIO_EVENTS . LOAD_START ) ;
127129
130+ // 唯一的加载 ID
131+ const loadId = ++ FFmpegAudioPlayer . messageIdCounter ;
132+ this . currentMessageId = loadId ;
133+
134+ // 取消 fetch
135+ this . abortController = new AbortController ( ) ;
136+
128137 return new Promise < void > ( ( resolve , reject ) => {
129138 this . metadataResolve = resolve ;
130139 this . metadataReject = reject ;
@@ -135,15 +144,19 @@ export class FFmpegAudioPlayer extends BaseAudioPlayer {
135144 this . init ( ) ;
136145 }
137146
138- const response = await fetch ( url ) ;
147+ const response = await fetch ( url , { signal : this . abortController ?. signal } ) ;
148+ // 检查是否被新的 load 调用覆盖
149+ if ( this . currentMessageId !== loadId ) return ;
139150 if ( ! response . ok ) throw new Error ( `Failed to fetch ${ url } ` ) ;
140151 const blob = await response . blob ( ) ;
152+ // 再次检查
153+ if ( this . currentMessageId !== loadId ) return ;
154+
141155 const file = new File ( [ blob ] , "und" , { type : blob . type } ) ;
142156
143157 this . worker = new AudioWorker ( ) ;
144158 this . setupWorkerListeners ( ) ;
145159
146- this . currentMessageId = ++ FFmpegAudioPlayer . messageIdCounter ;
147160 if ( this . worker ) {
148161 this . worker . postMessage ( {
149162 type : "INIT" ,
@@ -153,6 +166,8 @@ export class FFmpegAudioPlayer extends BaseAudioPlayer {
153166 } ) ;
154167 }
155168 } catch ( e ) {
169+ // 被新的 load 取消了,不需要处理
170+ if ( ( e as Error ) . name === "AbortError" ) return ;
156171 this . cleanupLoadPromise ( ) ;
157172 this . handleError ( ( e as Error ) . message , AudioErrorCode . NETWORK ) ;
158173 reject ( e ) ;
@@ -283,6 +298,13 @@ export class FFmpegAudioPlayer extends BaseAudioPlayer {
283298 */
284299 private reset ( ) {
285300 this . _errorCode = 0 ;
301+
302+ // 取消正在进行的 fetch 请求
303+ if ( this . abortController ) {
304+ this . abortController . abort ( ) ;
305+ this . abortController = null ;
306+ }
307+
286308 if ( this . metadataReject ) {
287309 this . metadataReject ( new Error ( "Aborted by reset" ) ) ;
288310 this . cleanupLoadPromise ( ) ;
0 commit comments