Skip to content

Commit

Permalink
CC and Memory fixes
Browse files Browse the repository at this point in the history
merging changes from video-dev#2309 and applying the CC fixes.
  • Loading branch information
desidiver committed Oct 9, 2019
1 parent 2ad26f0 commit 0ee8b02
Show file tree
Hide file tree
Showing 9 changed files with 2,817 additions and 2,691 deletions.
5,418 changes: 2,739 additions & 2,679 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
"lint": "./scripts/lint.sh",
"lint:fix": "./scripts/lint.sh --fix",
"lint:quiet": "./scripts/lint.sh --quiet",
"precommit": "./scripts/precommit.sh",
"pretest": "npm run lint",
"start": "npm run dev",
"test": "npm run test:unit && npm run test:func",
Expand Down
1 change: 1 addition & 0 deletions src/controller/buffer-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,7 @@ class BufferController extends EventHandler {
// time will lead to playback freezing)
// credits for level target duration - https://github.com/videojs/http-streaming/blob/3132933b6aa99ddefab29c10447624efd6fd6e52/src/segment-loader.js#L91
this.removeBufferRange(bufferType, sb, 0, targetBackBufferPosition);
this.hls.trigger(Events.LIVE_BACK_BUFFER_REACHED, { bufferEnd: targetBackBufferPosition });
}
}
}
Expand Down
25 changes: 23 additions & 2 deletions src/controller/id3-track-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
import Event from '../events';
import EventHandler from '../event-handler';
import ID3 from '../demux/id3';
import { sendAddTrackEvent, clearCurrentCues } from '../utils/texttrack-utils';
import { sendAddTrackEvent, clearCurrentCues, getClosestCue } from '../utils/texttrack-utils';

class ID3TrackController extends EventHandler {
constructor (hls) {
super(hls,
Event.MEDIA_ATTACHED,
Event.MEDIA_DETACHING,
Event.FRAG_PARSING_METADATA);
Event.FRAG_PARSING_METADATA,
Event.LIVE_BACK_BUFFER_REACHED);
this.id3Track = undefined;
this.media = undefined;
}
Expand Down Expand Up @@ -49,6 +50,26 @@ class ID3TrackController extends EventHandler {
return this.media.addTextTrack('metadata', 'id3');
}

onLiveBackBufferReached ({ bufferEnd }) {
if (!this.id3Track || !this.id3Track.cues || !this.id3Track.cues.length) {
return;
}
const foundCue = getClosestCue(this.id3Track.cues, bufferEnd);
if (!foundCue) {
return;
}

let removeCues = true;
while (removeCues) {
const cue = this.id3Track.cues[0];
if (!this.id3Track.cues.length || cue.id === foundCue.id) {
removeCues = false;
return;
}
this.id3Track.removeCue(cue);
}
}

onFragParsingMetadata (data) {
const fragment = data.frag;
const samples = data.samples;
Expand Down
2 changes: 1 addition & 1 deletion src/controller/timeline-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ class TimelineController extends EventHandler {
if (currentTrack.mode === 'disabled') {
hls.trigger(Event.SUBTITLE_FRAG_PROCESSED, { success: false, frag: frag });
return;
}
}
// Add cues and trigger event with success true.
cues.forEach(cue => {
// Sometimes there are cue overlaps on segmented vtts so the same
Expand Down
2 changes: 2 additions & 0 deletions src/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ const HlsEvents = {
LEVEL_UPDATED: 'hlsLevelUpdated',
// fired when a level's PTS information has been updated after parsing a fragment - data: { details : levelDetails object, level : id of updated level, drift: PTS drift observed when parsing last fragment }
LEVEL_PTS_UPDATED: 'hlsLevelPtsUpdated',
// fired when the live back buffer is reached defined by the liveBackBufferLength config option - data : { bufferEnd: number }
LIVE_BACK_BUFFER_REACHED: 'hlsLiveBackBufferReached',
// fired to notify that audio track lists has been updated - data: { audioTracks : audioTracks }
AUDIO_TRACKS_UPDATED: 'hlsAudioTracksUpdated',
// fired when an audio track switching is requested - data: { id : audio track id }
Expand Down
39 changes: 39 additions & 0 deletions src/utils/texttrack-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,42 @@ export function clearCurrentCues (track) {
}
}
}

/**
* Given a list of Cues, finds the closest cue matching the given time.
* Modified verison of binary search O(log(n)).
*
* @export
* @param {(TextTrackCueList | TextTrackCue[])} cues - List of cues.
* @param {number} time - Target time, to find closest cue to.
* @returns {TextTrackCue}
*/
export function getClosestCue (cues: TextTrackCueList | TextTrackCue[], time: number): TextTrackCue {
// If the offset is less than the first element, the first element is the closest.
if (time < cues[0].endTime) {
return cues[0];
}
// If the offset is greater than the last cue, the last is the closest.
if (time > cues[cues.length - 1].endTime) {
return cues[cues.length - 1];
}

let left = 0;
let right = cues.length - 1;

while (left <= right) {
const mid = Math.floor((right + left) / 2);

if (time < cues[mid].endTime) {
right = mid - 1;
} else if (time > cues[mid].endTime) {
left = mid + 1;
} else {
// If it's not lower or higher, it must be equal.
return cues[mid];
}
}
// At this point, left and right have swapped.
// No direct match was found, left or right element must be the closest. Check which one has the smallest diff.
return (cues[left].endTime - time) < (time - cues[right].endTime) ? cues[left] : cues[right];
}
18 changes: 11 additions & 7 deletions src/utils/webvtt-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,20 +86,22 @@ const WebVTTParser = {
if (currCC && currCC.new) {
if (localTime !== undefined) {
// When local time is provided, offset = discontinuity start time - local time
cueOffset = vttCCs.ccOffset = currCC.start;
cueOffset = vttCCs.ccOffset = currCC.start;
} else {
calculateOffset(vttCCs, cc, presentationTime);
}
}

if (presentationTime) {
// If we have MPEGTS, offset = presentation time + discontinuity offset

cueOffset = presentationTime - vttCCs.presentationOffset;
console.log('cueOFFSET IS ' + presentationTime + ' vttCCs.presentationOffset ' + vttCCs.presentationOffset);
}

// console.log(cue.startTime + ' before');
cue.startTime += cueOffset - localTime;
cue.endTime += cueOffset - localTime;

console.log(cue.startTime);
// Create a unique hash id for a cue based on start/end times and text.
// This helps timeline-controller to avoid showing repeated captions.
cue.id = hash(cue.startTime.toString()) + hash(cue.endTime.toString()) + hash(cue.text);
Expand Down Expand Up @@ -139,17 +141,19 @@ const WebVTTParser = {
}
});
try {
//
// Calculate subtitle offset in milliseconds.
if (syncPTS + ((vttCCs[cc].start * 90000) || 0) < 0) {
syncPTS += 8589934592;
}
// if (syncPTS + ((vttCCs[cc].start * 90000) || 0) < 0) {
// syncPTS += 8589934592;
// }
// Adjust MPEGTS by sync PTS.
mpegTs -= syncPTS;

// Convert cue time to seconds
localTime = cueString2millis(cueTime) / 1000;
// Convert MPEGTS to seconds from 90kHz.
presentationTime = mpegTs / 90000;

//console.log(syncPTS + " syncPTS is " + presentationTime + ' local time ' + localTime);
if (localTime === -1) {
parsingError = new Error(`Malformed X-TIMESTAMP-MAP: ${line}`);
}
Expand Down
2 changes: 1 addition & 1 deletion src/utils/xhr-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class XhrLoader {
this.callbacks.onSuccess(response, stats, context, xhr);
} else {
// if max nb of retries reached or if http status between 400 and 499 (such error cannot be recovered, retrying is useless), return error
if (stats.retry >= config.maxRetry || (status >= 400 && status < 499)) {
if (stats.retry >= config.maxRetry) {
logger.error(`${status} while loading ${context.url}`);
this.callbacks.onError({ code: status, text: xhr.statusText }, context, xhr);
} else {
Expand Down

0 comments on commit 0ee8b02

Please sign in to comment.