Skip to content

Commit

Permalink
Clear subtitle cues from the back-buffer, and remove loaded data from…
Browse files Browse the repository at this point in the history
… the fragment-tracker
  • Loading branch information
Rob Walch committed May 30, 2021
1 parent ec50dd2 commit 6b15612
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 6 deletions.
32 changes: 32 additions & 0 deletions src/controller/fragment-tracker.ts
Expand Up @@ -208,6 +208,15 @@ export class FragmentTracker implements ComponentAPI {
}
}

public subtitleBuffered(frag: Fragment) {
const fragKey = getFragmentKey(frag);
const fragmentEntity = this.fragments[fragKey];
if (fragmentEntity) {
fragmentEntity.backtrack = fragmentEntity.loaded = null;
fragmentEntity.buffered = true;
}
}

private getBufferedTimes(
fragment: Fragment,
part: Part | null,
Expand Down Expand Up @@ -412,6 +421,29 @@ export class FragmentTracker implements ComponentAPI {
return !!this.fragments[fragKey];
}

public removeFragmentsInRange(
start: number,
end: number,
playlistType: PlaylistLevelType
) {
Object.keys(this.fragments).forEach((key) => {
const fragmentEntity = this.fragments[key];
if (!fragmentEntity) {
return;
}
if (fragmentEntity.buffered) {
const frag = fragmentEntity.body;
if (
frag.type === playlistType &&
frag.start < end &&
frag.end > start
) {
this.removeFragment(frag);
}
}
});
}

public removeFragment(fragment: Fragment) {
const fragKey = getFragmentKey(fragment);
fragment.stats.loaded = 0;
Expand Down
30 changes: 29 additions & 1 deletion src/controller/subtitle-stream-controller.ts
Expand Up @@ -18,6 +18,7 @@ import type {
SubtitleTracksUpdatedData,
TrackLoadedData,
TrackSwitchedData,
BufferFlushingData,
} from '../types/events';

const TICK_INTERVAL = 500; // how often to tick in ms
Expand Down Expand Up @@ -50,6 +51,7 @@ export class SubtitleStreamController
hls.on(Events.SUBTITLE_TRACK_SWITCH, this.onSubtitleTrackSwitch, this);
hls.on(Events.SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this);
hls.on(Events.SUBTITLE_FRAG_PROCESSED, this.onSubtitleFragProcessed, this);
hls.on(Events.BUFFER_FLUSHING, this.onBufferFlushing, this);
}

private _unregisterListeners() {
Expand All @@ -61,6 +63,7 @@ export class SubtitleStreamController
hls.off(Events.SUBTITLE_TRACK_SWITCH, this.onSubtitleTrackSwitch, this);
hls.off(Events.SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this);
hls.off(Events.SUBTITLE_FRAG_PROCESSED, this.onSubtitleFragProcessed, this);
hls.off(Events.BUFFER_FLUSHING, this.onBufferFlushing, this);
}

startLoad() {
Expand Down Expand Up @@ -117,6 +120,31 @@ export class SubtitleStreamController
};
buffered.push(timeRange);
}
this.fragmentTracker.subtitleBuffered(frag);
}

onBufferFlushing(
event: Events.BUFFER_FLUSHING,
{ startOffset, endOffset }: BufferFlushingData
) {
if (startOffset === 0 && endOffset !== Number.POSITIVE_INFINITY) {
this.tracksBuffered.forEach((buffered) => {
for (let i = 0; i < buffered.length; i++) {
if (buffered[0].end <= endOffset) {
buffered.shift();
} else if (buffered[0].start < endOffset) {
buffered[0].start = endOffset;
} else {
break;
}
}
});
this.fragmentTracker.removeFragmentsInRange(
startOffset,
endOffset,
PlaylistLevelType.SUBTITLE
);
}
}

// If something goes wrong, proceed to next frag, if we were processing one.
Expand Down Expand Up @@ -331,7 +359,7 @@ export class SubtitleStreamController
super.loadFragment(frag, levelDetails, targetBufferTime);
}

get mediaBufferTimeRanges() {
get mediaBufferTimeRanges(): TimeRange[] {
return this.tracksBuffered[this.currentTrackId] || [];
}
}
19 changes: 14 additions & 5 deletions src/controller/timeline-controller.ts
Expand Up @@ -627,18 +627,27 @@ export class TimelineController implements ComponentAPI {
event: Events.BUFFER_FLUSHING,
{ startOffset, endOffset, type }: BufferFlushingData
) {
// Clear 608 CC cues from the back buffer
const { media } = this;
if (!media || media.currentTime < endOffset) {
return;
}
// Clear 608 caption cues from the captions TextTracks when the video back buffer is flushed
// Forward cues are never removed because we can loose streamed 608 content from recent fragments
if (!type || type === 'video') {
const { media } = this;
if (!media || media.currentTime < endOffset) {
return;
}
const { captionsTracks } = this;
Object.keys(captionsTracks).forEach((trackName) =>
removeCuesInRange(captionsTracks[trackName], startOffset, endOffset)
);
}
if (this.config.renderTextTracksNatively) {
// Clear VTT/IMSC1 subtitle cues from the subtitle TextTracks when the back buffer is flushed
if (startOffset === 0 && endOffset !== Number.POSITIVE_INFINITY) {
const { textTracks } = this;
Object.keys(textTracks).forEach((trackName) =>
removeCuesInRange(textTracks[trackName], startOffset, endOffset)
);
}
}
}

private extractCea608Data(byteArray: Uint8Array): number[][] {
Expand Down

0 comments on commit 6b15612

Please sign in to comment.