Skip to content

Commit

Permalink
wait for both main and audio loaders for endOfStream if main starting…
Browse files Browse the repository at this point in the history
… media unknown (#44)
  • Loading branch information
mjneil authored Feb 23, 2018
1 parent 586f317 commit 7e1c41d
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 4 deletions.
7 changes: 4 additions & 3 deletions src/master-playlist-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -623,10 +623,11 @@ export class MasterPlaylistController extends videojs.EventTarget {

if (this.mediaTypes_.AUDIO.activePlaylistLoader) {
// if the audio playlist loader exists, then alternate audio is active
if (this.mainSegmentLoader_.startingMedia_ &&
if (!this.mainSegmentLoader_.startingMedia_ ||
this.mainSegmentLoader_.startingMedia_.containsVideo) {
// if the main segment loader contains video, then we need to wait for both the
// main and audio segment loaders to call endOfStream
// if we do not know if the main segment loader contains video yet or if we
// definitively know the main segment loader contains video, then we need to wait
// for both main and audio segment loaders to call endOfStream
isEndOfStream = isEndOfStream && this.audioSegmentLoader_.ended_;
} else {
// otherwise just rely on the audio loader
Expand Down
66 changes: 65 additions & 1 deletion test/master-playlist-controller.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ function(assert) {

MPC.mediaSource.sourceBuffers[0].trigger('updateend');

assert.equal(videoEnded, 1, 'main segment loader triggered endded');
assert.equal(videoEnded, 1, 'main segment loader triggered ended');
assert.equal(audioEnded, 0, 'audio segment loader did not trigger ended');
assert.equal(MPC.mediaSource.readyState, 'open', 'Media Source not yet ended');

Expand All @@ -603,6 +603,70 @@ function(assert) {
assert.equal(MPC.mediaSource.readyState, 'ended', 'Media Source ended');
});

QUnit.test('waits for both main and audio loaders to finish before calling endOfStream' +
' if main loader starting media is unknown', function(assert) {
openMediaSource(this.player, this.clock);

const videoMedia = '#EXTM3U\n' +
'#EXT-X-VERSION:3\n' +
'#EXT-X-PLAYLIST-TYPE:VOD\n' +
'#EXT-X-MEDIA-SEQUENCE:0\n' +
'#EXT-X-TARGETDURATION:10\n' +
'#EXTINF:10,\n' +
'video-0.ts\n' +
'#EXT-X-ENDLIST\n';

const audioMedia = '#EXTM3U\n' +
'#EXT-X-VERSION:3\n' +
'#EXT-X-PLAYLIST-TYPE:VOD\n' +
'#EXT-X-MEDIA-SEQUENCE:0\n' +
'#EXT-X-TARGETDURATION:10\n' +
'#EXTINF:10,\n' +
'audio-0.ts\n' +
'#EXT-X-ENDLIST\n';

let videoEnded = 0;
let audioEnded = 0;

const MPC = this.masterPlaylistController;

MPC.mainSegmentLoader_.on('ended', () => videoEnded++);
MPC.audioSegmentLoader_.on('ended', () => audioEnded++);

MPC.audioSegmentLoader_.startingMedia_ = { containsAudio: true };

// master
this.standardXHRResponse(this.requests.shift(), manifests.demuxed);

// video media
this.standardXHRResponse(this.requests.shift(), videoMedia);

// audio media
this.standardXHRResponse(this.requests.shift(), audioMedia);

// this.requests === [videoSegment, audioSegment]

// audio segment
this.standardXHRResponse(this.requests[1]);
// audio source buffer
MPC.mediaSource.sourceBuffers[1].trigger('updateend');

assert.equal(videoEnded, 0, 'main segment loader did not trigger ended');
assert.equal(audioEnded, 1, 'audio segment loader triggered ended');
assert.equal(MPC.mediaSource.readyState, 'open', 'Media Source not yet ended');

// video segment
this.standardXHRResponse(this.requests[0]);

MPC.mainSegmentLoader_.startingMedia_ = { containsVideo: true };
// main source buffer
MPC.mediaSource.sourceBuffers[0].trigger('updateend');

assert.equal(videoEnded, 1, 'main segment loader triggered ended');
assert.equal(audioEnded, 1, 'audio segment loader did not trigger ended again');
assert.equal(MPC.mediaSource.readyState, 'ended', 'Media Source ended');
});

QUnit.test('does not wait for main loader to finish before calling endOfStream with' +
' audio only stream and alternate audio active', function(assert) {
openMediaSource(this.player, this.clock);
Expand Down

0 comments on commit 7e1c41d

Please sign in to comment.