@@ -245,7 +245,7 @@ export default class HLSHandler extends PassThrough {
245245 if ( this . stop ) return null
246246 const isRecoverable = err . message === 'aborted' || err . code === 'ECONNRESET' || err . code === 'ETIMEDOUT'
247247 if ( isRecoverable && attempt <= 3 ) {
248- const delay = Math . pow ( 2 , attempt ) * 500
248+ const delay = 2 ** attempt * 500
249249 logger ( 'warn' , 'HLSHandler' , `Segment fetch failed (attempt ${ attempt } /3): ${ err . message } . Retrying in ${ delay } ms...` )
250250 await new Promise ( r => setTimeout ( r , delay ) )
251251 return this . _fetchWithRetry ( segment , attempt + 1 )
@@ -255,6 +255,23 @@ export default class HLSHandler extends PassThrough {
255255 }
256256 }
257257
258+ async _waitForDrain ( ) {
259+ if ( this . destroyed || this . stop ) return
260+ return new Promise ( ( resolve ) => {
261+ const cleanup = ( ) => {
262+ this . removeListener ( 'drain' , onDrain )
263+ this . removeListener ( 'close' , onFinish )
264+ this . removeListener ( 'error' , onFinish )
265+ resolve ( )
266+ }
267+ const onDrain = cleanup
268+ const onFinish = cleanup
269+ this . once ( 'drain' , onDrain )
270+ this . once ( 'close' , onFinish )
271+ this . once ( 'error' , onFinish )
272+ } )
273+ }
274+
258275 async _fetchSegments ( ) {
259276 if ( this . isFetching || this . stop ) return
260277 this . isFetching = true
@@ -296,20 +313,20 @@ export default class HLSHandler extends PassThrough {
296313 if ( segment . map && segment . map . uri !== this . lastMapUri ) {
297314 const mapData = await this . fetcher . fetchMap ( segment . map , segment . key )
298315 if ( mapData && ! this . stop ) {
299- if ( ! this . write ( mapData ) ) await new Promise ( r => this . once ( 'drain' , r ) )
316+ if ( ! this . write ( mapData ) ) await this . _waitForDrain ( )
300317 this . lastMapUri = segment . map . uri
301318 }
302319 }
303320
304321 if ( this . strategy === 'segmented' ) {
305322 if ( ! this . stop && data ) {
306- if ( ! this . write ( data ) ) await new Promise ( r => this . once ( 'drain' , r ) )
323+ if ( ! this . write ( data ) ) await this . _waitForDrain ( )
307324 }
308325 } else if ( stream ) {
309326 this . activeSegmentStreams . set ( key , stream )
310327 for await ( const chunk of stream ) {
311328 if ( this . stop ) break
312- if ( ! this . write ( chunk ) ) await new Promise ( r => this . once ( 'drain' , r ) )
329+ if ( ! this . write ( chunk ) ) await this . _waitForDrain ( )
313330 }
314331 this . activeSegmentStreams . delete ( key )
315332 }
0 commit comments