@@ -17,6 +17,10 @@ import {
17
17
import { getMessageID } from "./utils.js" ;
18
18
import { ERROR_TERMINATED , ERROR_NOT_LOADED } from "./errors.js" ;
19
19
20
+ type FFMessageOptions = {
21
+ signal ?: AbortSignal ;
22
+ } ;
23
+
20
24
/**
21
25
* Provides APIs to interact with ffmpeg web worker.
22
26
*
@@ -85,7 +89,8 @@ export class FFmpeg {
85
89
*/
86
90
#send = (
87
91
{ type, data } : Message ,
88
- trans : Transferable [ ] = [ ]
92
+ trans : Transferable [ ] = [ ] ,
93
+ signal ?: AbortSignal
89
94
) : Promise < CallbackData > => {
90
95
if ( ! this . #worker) {
91
96
return Promise . reject ( ERROR_NOT_LOADED ) ;
@@ -96,6 +101,14 @@ export class FFmpeg {
96
101
this . #worker && this . #worker. postMessage ( { id, type, data } , trans ) ;
97
102
this . #resolves[ id ] = resolve ;
98
103
this . #rejects[ id ] = reject ;
104
+
105
+ signal ?. addEventListener (
106
+ "abort" ,
107
+ ( ) => {
108
+ reject ( new DOMException ( `Message # ${ id } was aborted` , "AbortError" ) ) ;
109
+ } ,
110
+ { once : true }
111
+ ) ;
99
112
} ) ;
100
113
} ;
101
114
@@ -148,9 +161,13 @@ export class FFmpeg {
148
161
callback : LogEventCallback | ProgressEventCallback
149
162
) {
150
163
if ( event === "log" ) {
151
- this . #logEventCallbacks = this . #logEventCallbacks. filter ( ( f ) => f !== callback ) ;
164
+ this . #logEventCallbacks = this . #logEventCallbacks. filter (
165
+ ( f ) => f !== callback
166
+ ) ;
152
167
} else if ( event === "progress" ) {
153
- this . #progressEventCallbacks = this . #progressEventCallbacks. filter ( ( f ) => f !== callback ) ;
168
+ this . #progressEventCallbacks = this . #progressEventCallbacks. filter (
169
+ ( f ) => f !== callback
170
+ ) ;
154
171
}
155
172
}
156
173
@@ -161,17 +178,24 @@ export class FFmpeg {
161
178
* @category FFmpeg
162
179
* @returns `true` if ffmpeg core is loaded for the first time.
163
180
*/
164
- public load = ( config : FFMessageLoadConfig = { } ) : Promise < IsFirst > => {
181
+ public load = (
182
+ config : FFMessageLoadConfig = { } ,
183
+ { signal } : FFMessageOptions = { }
184
+ ) : Promise < IsFirst > => {
165
185
if ( ! this . #worker) {
166
186
this . #worker = new Worker ( new URL ( "./worker.js" , import . meta. url ) , {
167
187
type : "module" ,
168
188
} ) ;
169
189
this . #registerHandlers( ) ;
170
190
}
171
- return this . #send( {
172
- type : FFMessageType . LOAD ,
173
- data : config ,
174
- } ) as Promise < IsFirst > ;
191
+ return this . #send(
192
+ {
193
+ type : FFMessageType . LOAD ,
194
+ data : config ,
195
+ } ,
196
+ undefined ,
197
+ signal
198
+ ) as Promise < IsFirst > ;
175
199
} ;
176
200
177
201
/**
@@ -202,12 +226,17 @@ export class FFmpeg {
202
226
*
203
227
* @defaultValue -1
204
228
*/
205
- timeout = - 1
229
+ timeout = - 1 ,
230
+ { signal } : FFMessageOptions = { }
206
231
) : Promise < number > =>
207
- this . #send( {
208
- type : FFMessageType . EXEC ,
209
- data : { args, timeout } ,
210
- } ) as Promise < number > ;
232
+ this . #send(
233
+ {
234
+ type : FFMessageType . EXEC ,
235
+ data : { args, timeout } ,
236
+ } ,
237
+ undefined ,
238
+ signal
239
+ ) as Promise < number > ;
211
240
212
241
/**
213
242
* Terminate all ongoing API calls and terminate web worker.
@@ -244,7 +273,11 @@ export class FFmpeg {
244
273
*
245
274
* @category File System
246
275
*/
247
- public writeFile = ( path : string , data : FileData ) : Promise < OK > => {
276
+ public writeFile = (
277
+ path : string ,
278
+ data : FileData ,
279
+ { signal } : FFMessageOptions = { }
280
+ ) : Promise < OK > => {
248
281
const trans : Transferable [ ] = [ ] ;
249
282
if ( data instanceof Uint8Array ) {
250
283
trans . push ( data . buffer ) ;
@@ -254,7 +287,8 @@ export class FFmpeg {
254
287
type : FFMessageType . WRITE_FILE ,
255
288
data : { path, data } ,
256
289
} ,
257
- trans
290
+ trans ,
291
+ signal
258
292
) as Promise < OK > ;
259
293
} ;
260
294
@@ -279,65 +313,106 @@ export class FFmpeg {
279
313
*
280
314
* @defaultValue binary
281
315
*/
282
- encoding = "binary"
316
+ encoding = "binary" ,
317
+ { signal } : FFMessageOptions = { }
283
318
) : Promise < FileData > =>
284
- this . #send( {
285
- type : FFMessageType . READ_FILE ,
286
- data : { path, encoding } ,
287
- } ) as Promise < FileData > ;
319
+ this . #send(
320
+ {
321
+ type : FFMessageType . READ_FILE ,
322
+ data : { path, encoding } ,
323
+ } ,
324
+ undefined ,
325
+ signal
326
+ ) as Promise < FileData > ;
288
327
289
328
/**
290
329
* Delete a file.
291
330
*
292
331
* @category File System
293
332
*/
294
- public deleteFile = ( path : string ) : Promise < OK > =>
295
- this . #send( {
296
- type : FFMessageType . DELETE_FILE ,
297
- data : { path } ,
298
- } ) as Promise < OK > ;
333
+ public deleteFile = (
334
+ path : string ,
335
+ { signal } : FFMessageOptions = { }
336
+ ) : Promise < OK > =>
337
+ this . #send(
338
+ {
339
+ type : FFMessageType . DELETE_FILE ,
340
+ data : { path } ,
341
+ } ,
342
+ undefined ,
343
+ signal
344
+ ) as Promise < OK > ;
299
345
300
346
/**
301
347
* Rename a file or directory.
302
348
*
303
349
* @category File System
304
350
*/
305
- public rename = ( oldPath : string , newPath : string ) : Promise < OK > =>
306
- this . #send( {
307
- type : FFMessageType . RENAME ,
308
- data : { oldPath, newPath } ,
309
- } ) as Promise < OK > ;
351
+ public rename = (
352
+ oldPath : string ,
353
+ newPath : string ,
354
+ { signal } : FFMessageOptions = { }
355
+ ) : Promise < OK > =>
356
+ this . #send(
357
+ {
358
+ type : FFMessageType . RENAME ,
359
+ data : { oldPath, newPath } ,
360
+ } ,
361
+ undefined ,
362
+ signal
363
+ ) as Promise < OK > ;
310
364
311
365
/**
312
366
* Create a directory.
313
367
*
314
368
* @category File System
315
369
*/
316
- public createDir = ( path : string ) : Promise < OK > =>
317
- this . #send( {
318
- type : FFMessageType . CREATE_DIR ,
319
- data : { path } ,
320
- } ) as Promise < OK > ;
370
+ public createDir = (
371
+ path : string ,
372
+ { signal } : FFMessageOptions = { }
373
+ ) : Promise < OK > =>
374
+ this . #send(
375
+ {
376
+ type : FFMessageType . CREATE_DIR ,
377
+ data : { path } ,
378
+ } ,
379
+ undefined ,
380
+ signal
381
+ ) as Promise < OK > ;
321
382
322
383
/**
323
384
* List directory contents.
324
385
*
325
386
* @category File System
326
387
*/
327
- public listDir = ( path : string ) : Promise < FSNode [ ] > =>
328
- this . #send( {
329
- type : FFMessageType . LIST_DIR ,
330
- data : { path } ,
331
- } ) as Promise < FSNode [ ] > ;
388
+ public listDir = (
389
+ path : string ,
390
+ { signal } : FFMessageOptions = { }
391
+ ) : Promise < FSNode [ ] > =>
392
+ this . #send(
393
+ {
394
+ type : FFMessageType . LIST_DIR ,
395
+ data : { path } ,
396
+ } ,
397
+ undefined ,
398
+ signal
399
+ ) as Promise < FSNode [ ] > ;
332
400
333
401
/**
334
402
* Delete an empty directory.
335
403
*
336
404
* @category File System
337
405
*/
338
- public deleteDir = ( path : string ) : Promise < OK > =>
339
- this . #send( {
340
- type : FFMessageType . DELETE_DIR ,
341
- data : { path } ,
342
- } ) as Promise < OK > ;
406
+ public deleteDir = (
407
+ path : string ,
408
+ { signal } : FFMessageOptions = { }
409
+ ) : Promise < OK > =>
410
+ this . #send(
411
+ {
412
+ type : FFMessageType . DELETE_DIR ,
413
+ data : { path } ,
414
+ } ,
415
+ undefined ,
416
+ signal
417
+ ) as Promise < OK > ;
343
418
}
0 commit comments