Skip to content

Commit

Permalink
merge changes from #371 and master
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonocasey committed May 2, 2019
1 parent 9eedb25 commit 29c1d32
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 17 deletions.
67 changes: 54 additions & 13 deletions src/segment-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -533,9 +533,17 @@ export default class SegmentLoader extends videojs.EventTarget {
};
}

const oldId = oldPlaylist ? oldPlaylist.id : null;
let oldId = null;

this.logger_(`playlist update [${oldId} => ${newPlaylist.id}]`);
if (oldPlaylist) {
if (oldPlaylist.id) {
oldId = oldPlaylist.id;
} else if (oldPlaylist.uri) {
oldId = oldPlaylist.uri;
}
}

this.logger_(`playlist update [${oldId} => ${newPlaylist.id || newPlaylist.uri}]`);

// in VOD, this is always a rendition switch (or we updated our syncInfo above)
// in LIVE, we always want to update with new playlists (including refreshes)
Expand Down Expand Up @@ -776,11 +784,7 @@ export default class SegmentLoader extends videojs.EventTarget {
return;
}

let isEndOfStream = detectEndOfStream(this.playlist_,
this.mediaSource_,
segmentInfo.mediaIndex);

if (isEndOfStream) {
if (this.isEndOfStream_(segmentInfo.mediaIndex)) {
this.endOfStream();
return;
}
Expand Down Expand Up @@ -826,6 +830,21 @@ export default class SegmentLoader extends videojs.EventTarget {
return segmentInfo.startOfSegment < this.sourceUpdater_.audioTimestampOffset();
}

/**
* Determines if this segment loader is at the end of it's stream.
*
* @param {Number} mediaIndex the index of segment we last appended
* @param {Object} [playlist=this.playlist_] a media playlist object
* @returns {Boolean} true if at end of stream, false otherwise.
*/
isEndOfStream_(mediaIndex, playlist = this.playlist_) {
return detectEndOfStream(
playlist,
this.mediaSource_,
mediaIndex
) && !this.sourceUpdater_.updating();
}

/**
* Determines what segment request should be made, given current playback
* state.
Expand Down Expand Up @@ -1466,7 +1485,10 @@ export default class SegmentLoader extends videojs.EventTarget {
segments
});

this.sourceUpdater_.appendBuffer(type, bytes, (error) => {
const videoSegmentTimingInfoCallback =
this.handleVideoSegmentTimingInfo_.bind(this, initSegment.requestId)

this.sourceUpdater_.appendBuffer({type, bytes, videoSegmentTimingInfoCallback}, (error) => {
if (error) {
this.error(error);
// If an append errors, we can't recover.
Expand All @@ -1478,6 +1500,28 @@ export default class SegmentLoader extends videojs.EventTarget {
});
}

handleVideoSegmentTimingInfo_(requestId, event) {
if (!this.pendingSegment_ || requestId !== this.pendingSegment_.requestId) {
return;
}

const segment = this.pendingSegment_.segment;

if (!segment.videoTimingInfo) {
segment.videoTimingInfo = {};
}

segment.videoTimingInfo.transmuxerPrependedSeconds =
event.videoSegmentTimingInfo.prependedContentDuration || 0;
segment.videoTimingInfo.transmuxedPresentationStart =
event.videoSegmentTimingInfo.start.presentation;
segment.videoTimingInfo.transmuxedPresentationEnd =
event.videoSegmentTimingInfo.end.presentation;
// mainly used as a reference for debugging
segment.videoTimingInfo.baseMediaDecodeTime =
event.videoSegmentTimingInfo.baseMediaDecodeTime;
}

appendData_(segmentInfo, result) {
const {
type,
Expand Down Expand Up @@ -2016,11 +2060,7 @@ export default class SegmentLoader extends videojs.EventTarget {
// any time an update finishes and the last segment is in the
// buffer, end the stream. this ensures the "ended" event will
// fire if playback reaches that point.
const isEndOfStream = detectEndOfStream(segmentInfo.playlist,
this.mediaSource_,
segmentInfo.mediaIndex + 1);

if (isEndOfStream) {
if (this.isEndOfStream_(segmentInfo.mediaIndex + 1, segmentInfo.playlist)) {
this.endOfStream();
}

Expand Down Expand Up @@ -2081,6 +2121,7 @@ export default class SegmentLoader extends videojs.EventTarget {

const Cue = window.WebKitDataCue || window.VTTCue;
const value = {
custom: segment.custom,
dateTimeObject: segment.dateTimeObject,
dateTimeString: segment.dateTimeString,
bandwidth: segmentInfo.playlist.attributes.BANDWIDTH,
Expand Down
66 changes: 62 additions & 4 deletions src/source-updater.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ const actions = {
callback();
},
duration: (duration) => (sourceUpdater) => {
sourceUpdater.mediaSource.duration = duration;
try {
sourceUpdater.mediaSource.duration = duration;
} catch (e) {
videojs.log.warn('Failed to set media source duration', e);
}
}
};

Expand Down Expand Up @@ -245,17 +249,64 @@ export default class SourceUpdater extends videojs.EventTarget {
* @param {Function} done the function to call when done
* @see http://www.w3.org/TR/media-source/#widl-SourceBuffer-appendBuffer-void-ArrayBuffer-data
*/
appendBuffer(type, bytes, doneFn) {
appendBuffer({type, bytes, videoSegmentTimingInfoCallback}, doneFn) {
this.processedAppend_ = true;
let originalAction = action = actions.appendBuffer(bytes);
let originalDoneFn = doneFn;

if (videoSegmentTimingInfoCallback) {
action = (type, sourceUpdater) => {
if (type === 'video' && this.videoBuffer) {
this.videoBuffer.addEventListener('videoSegmentTimingInfo', videoSegmentTimingInfoCallback);
}
originalAction(type, sourceUpdater);
};

doneFn = (err) => {
if (this.videoBuffer) {
this.videoBuffer.removeEventListener('videoSegmentTimingInfo', videoSegmentTimingInfoCallback);
}
originalDoneFn(err);
};
}


pushQueue({
type,
sourceUpdater: this,
action: actions.appendBuffer(bytes),
action,
doneFn,
name: 'appendBuffer'
});
}

/********
-------
This chunk is related to https://github.com/videojs/http-streaming/pull/371
The interface here is different from the one above, as well
as how things are appended (pushqueue vs doing things on the sourcebuffer)
sall related calls will need to be modified as well.
-------
*
*
appendBuffer(config, done) {
this.processedAppend_ = true;
this.queueCallback_(() => {
if (config.videoSegmentTimingInfoCallback) {
this.sourceBuffer_.addEventListener(
'videoSegmentTimingInfo', config.videoSegmentTimingInfoCallback);
}
this.sourceBuffer_.appendBuffer(config.bytes);
}, () => {
if (config.videoSegmentTimingInfoCallback) {
this.sourceBuffer_.removeEventListener(
'videoSegmentTimingInfo', config.videoSegmentTimingInfoCallback);
}
done();
});
}
*/

audioBuffered() {
return this.audioBuffer && this.audioBuffer.buffered ? this.audioBuffer.buffered :
videojs.createTimeRange();
Expand Down Expand Up @@ -338,15 +389,22 @@ export default class SourceUpdater extends videojs.EventTarget {
* @return {Boolean} the updating status of the SourceBuffer
*/
updating() {
// we are updating if:
// the audio source buffer is updating
if (this.audioBuffer && this.audioBuffer.updating) {
return true;
}

// the video source buffer is updating
if (this.videoBuffer && this.videoBuffer.updating) {
return true;
}
if (this.pendingCallback_) {

// or we have a pending callback that is not our internal noop
if (this.pendingCallback_ && this.pendingCallback_ !== noop) {
return true;
}

return false;
}

Expand Down

0 comments on commit 29c1d32

Please sign in to comment.