@@ -35,6 +35,7 @@ import Errors from '../core/errors/Errors';
3535import Settings from '../core/Settings' ;
3636import constants from './constants/Constants' ;
3737import { HTTPRequest } from './vo/metrics/HTTPRequest' ;
38+ import Events from '../core/events/Events' ;
3839
3940const APPEND_WINDOW_START_OFFSET = 0.1 ;
4041const APPEND_WINDOW_END_OFFSET = 0.01 ;
@@ -51,6 +52,7 @@ function SourceBufferSink(config) {
5152 const context = this . context ;
5253 const settings = Settings ( context ) . getInstance ( ) ;
5354 const textController = config . textController ;
55+ const eventBus = config . eventBus ;
5456
5557 let instance ,
5658 type ,
@@ -63,6 +65,7 @@ function SourceBufferSink(config) {
6365 let appendQueue = [ ] ;
6466 let isAppendingInProgress = false ;
6567 let mediaSource = config . mediaSource ;
68+ let lastRequestAppended = null ;
6669
6770 function setup ( ) {
6871 logger = Debug ( context ) . getInstance ( ) . getLogger ( instance ) ;
@@ -91,7 +94,7 @@ function SourceBufferSink(config) {
9194
9295 function changeType ( codec ) {
9396 return new Promise ( ( resolve ) => {
94- waitForUpdateEnd ( ( ) => {
97+ _waitForUpdateEnd ( ( ) => {
9598 if ( buffer . changeType ) {
9699 buffer . changeType ( codec ) ;
97100 }
@@ -149,17 +152,17 @@ function SourceBufferSink(config) {
149152 // use updateend event if possible
150153 if ( typeof buffer . addEventListener === 'function' ) {
151154 try {
152- buffer . addEventListener ( 'updateend' , updateEndHandler , false ) ;
153- buffer . addEventListener ( 'error' , errHandler , false ) ;
154- buffer . addEventListener ( 'abort' , errHandler , false ) ;
155+ buffer . addEventListener ( 'updateend' , _updateEndHandler , false ) ;
156+ buffer . addEventListener ( 'error' , _errHandler , false ) ;
157+ buffer . addEventListener ( 'abort' , _errHandler , false ) ;
155158
156159 } catch ( err ) {
157160 // use setInterval to periodically check if updating has been completed
158- intervalId = setInterval ( updateEndHandler , CHECK_INTERVAL ) ;
161+ intervalId = setInterval ( _updateEndHandler , CHECK_INTERVAL ) ;
159162 }
160163 } else {
161164 // use setInterval to periodically check if updating has been completed
162- intervalId = setInterval ( updateEndHandler , CHECK_INTERVAL ) ;
165+ intervalId = setInterval ( _updateEndHandler , CHECK_INTERVAL ) ;
163166 }
164167 }
165168
@@ -170,9 +173,9 @@ function SourceBufferSink(config) {
170173 function _removeEventListeners ( ) {
171174 try {
172175 if ( typeof buffer . removeEventListener === 'function' ) {
173- buffer . removeEventListener ( 'updateend' , updateEndHandler , false ) ;
174- buffer . removeEventListener ( 'error' , errHandler , false ) ;
175- buffer . removeEventListener ( 'abort' , errHandler , false ) ;
176+ buffer . removeEventListener ( 'updateend' , _updateEndHandler , false ) ;
177+ buffer . removeEventListener ( 'error' , _errHandler , false ) ;
178+ buffer . removeEventListener ( 'abort' , _errHandler , false ) ;
176179 }
177180 clearInterval ( intervalId ) ;
178181 } catch ( e ) {
@@ -188,7 +191,7 @@ function SourceBufferSink(config) {
188191 return ;
189192 }
190193
191- waitForUpdateEnd ( ( ) => {
194+ _waitForUpdateEnd ( ( ) => {
192195 try {
193196 if ( ! buffer ) {
194197 resolve ( ) ;
@@ -227,7 +230,7 @@ function SourceBufferSink(config) {
227230 return ;
228231 }
229232
230- waitForUpdateEnd ( ( ) => {
233+ _waitForUpdateEnd ( ( ) => {
231234 try {
232235 if ( buffer . timestampOffset !== MSETimeOffset && ! isNaN ( MSETimeOffset ) ) {
233236 buffer . timestampOffset = MSETimeOffset ;
@@ -258,6 +261,7 @@ function SourceBufferSink(config) {
258261 }
259262 buffer = null ;
260263 }
264+ lastRequestAppended = null ;
261265 }
262266
263267 function getBuffer ( ) {
@@ -273,7 +277,7 @@ function SourceBufferSink(config) {
273277 }
274278 }
275279
276- function append ( chunk ) {
280+ function append ( chunk , request = null ) {
277281 return new Promise ( ( resolve , reject ) => {
278282 if ( ! chunk ) {
279283 reject ( {
@@ -282,14 +286,14 @@ function SourceBufferSink(config) {
282286 } ) ;
283287 return ;
284288 }
285- appendQueue . push ( { data : chunk , promise : { resolve, reject } } ) ;
286- waitForUpdateEnd ( appendNextInQueue . bind ( this ) ) ;
289+ appendQueue . push ( { data : chunk , promise : { resolve, reject } , request } ) ;
290+ _waitForUpdateEnd ( _appendNextInQueue . bind ( this ) ) ;
287291 } ) ;
288292 }
289293
290294 function _abortBeforeAppend ( ) {
291295 return new Promise ( ( resolve ) => {
292- waitForUpdateEnd ( ( ) => {
296+ _waitForUpdateEnd ( ( ) => {
293297 // Save the append window, which is reset on abort().
294298 const appendWindowStart = buffer . appendWindowStart ;
295299 const appendWindowEnd = buffer . appendWindowEnd ;
@@ -313,11 +317,11 @@ function SourceBufferSink(config) {
313317 return ;
314318 }
315319
316- waitForUpdateEnd ( function ( ) {
320+ _waitForUpdateEnd ( function ( ) {
317321 try {
318322 buffer . remove ( start , end ) ;
319323 // updating is in progress, we should wait for it to complete before signaling that this operation is done
320- waitForUpdateEnd ( function ( ) {
324+ _waitForUpdateEnd ( function ( ) {
321325 resolve ( {
322326 from : start ,
323327 to : end ,
@@ -342,7 +346,7 @@ function SourceBufferSink(config) {
342346 } ) ;
343347 }
344348
345- function appendNextInQueue ( ) {
349+ function _appendNextInQueue ( ) {
346350 if ( isAppendingInProgress ) {
347351 return ;
348352 }
@@ -355,7 +359,7 @@ function SourceBufferSink(config) {
355359 const afterSuccess = function ( ) {
356360 isAppendingInProgress = false ;
357361 if ( appendQueue . length > 0 ) {
358- appendNextInQueue . call ( this ) ;
362+ _appendNextInQueue . call ( this ) ;
359363 }
360364 // Init segments are cached. In any other case we dont need the chunk bytes anymore and can free the memory
361365 if ( nextChunk && nextChunk . data && nextChunk . data . segmentType && nextChunk . data . segmentType !== HTTPRequest . INIT_SEGMENT_TYPE ) {
@@ -365,6 +369,7 @@ function SourceBufferSink(config) {
365369 } ;
366370
367371 try {
372+ lastRequestAppended = nextChunk . request ;
368373 if ( nextChunk . data . bytes . byteLength === 0 ) {
369374 afterSuccess . call ( this ) ;
370375 } else {
@@ -374,12 +379,12 @@ function SourceBufferSink(config) {
374379 buffer . append ( nextChunk . data . bytes , nextChunk . data ) ;
375380 }
376381 // updating is in progress, we should wait for it to complete before signaling that this operation is done
377- waitForUpdateEnd ( afterSuccess . bind ( this ) ) ;
382+ _waitForUpdateEnd ( afterSuccess . bind ( this ) ) ;
378383 }
379384 } catch ( err ) {
380385 logger . fatal ( 'SourceBuffer append failed "' + err + '"' ) ;
381386 if ( appendQueue . length > 0 ) {
382- appendNextInQueue ( ) ;
387+ _appendNextInQueue ( ) ;
383388 } else {
384389 isAppendingInProgress = false ;
385390 }
@@ -395,7 +400,7 @@ function SourceBufferSink(config) {
395400 try {
396401 appendQueue = [ ] ;
397402 if ( mediaSource . readyState === 'open' ) {
398- waitForUpdateEnd ( ( ) => {
403+ _waitForUpdateEnd ( ( ) => {
399404 buffer . abort ( ) ;
400405 resolve ( ) ;
401406 } ) ;
@@ -412,36 +417,42 @@ function SourceBufferSink(config) {
412417
413418 }
414419
415- function executeCallback ( ) {
420+ function _executeCallback ( ) {
416421 if ( callbacks . length > 0 ) {
417422 if ( ! buffer . updating ) {
418423 const cb = callbacks . shift ( ) ;
419424 cb ( ) ;
420425 // Try to execute next callback if still not updating
421- executeCallback ( ) ;
426+ _executeCallback ( ) ;
422427 }
423428 }
424429 }
425430
426- function updateEndHandler ( ) {
431+ function _updateEndHandler ( ) {
427432 // if updating is still in progress do nothing and wait for the next check again.
428433 if ( buffer . updating ) {
429434 return ;
430435 }
431436
432437 // updating is completed, now we can stop checking and resolve the promise
433- executeCallback ( ) ;
438+ _executeCallback ( ) ;
434439 }
435440
436- function errHandler ( ) {
437- logger . error ( 'SourceBufferSink error' ) ;
441+ function _errHandler ( e ) {
442+ const error = e . target || { } ;
443+ _triggerEvent ( Events . SOURCE_BUFFER_ERROR , { error, lastRequestAppended } )
438444 }
439445
440- function waitForUpdateEnd ( callback ) {
446+ function _triggerEvent ( eventType , data ) {
447+ let payload = data || { } ;
448+ eventBus . trigger ( eventType , payload , { streamId : mediaInfo . streamInfo . id , mediaType : type } ) ;
449+ }
450+
451+ function _waitForUpdateEnd ( callback ) {
441452 callbacks . push ( callback ) ;
442453
443454 if ( ! buffer . updating ) {
444- executeCallback ( ) ;
455+ _executeCallback ( ) ;
445456 }
446457 }
447458
@@ -454,7 +465,6 @@ function SourceBufferSink(config) {
454465 abort,
455466 reset,
456467 updateTimestampOffset,
457- waitForUpdateEnd,
458468 initializeForStreamSwitch,
459469 initializeForFirstUse,
460470 updateAppendWindow,
0 commit comments