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 807552d
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 9 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
39 changes: 35 additions & 4 deletions 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 @@ -97,7 +100,7 @@ export class SubtitleStreamController
}

// Create/update a buffered array matching the interface used by BufferHelper.bufferedInfo
// so we can re-use the logic used to detect how much have been buffered
// so we can re-use the logic used to detect how much has been buffered
let timeRange: TimeRange | undefined;
const fragStart = frag.start;
for (let i = 0; i < buffered.length; i++) {
Expand All @@ -117,6 +120,33 @@ 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; ) {
if (buffered[i].end <= endOffset) {
buffered.shift();
continue;
} else if (buffered[i].start < endOffset) {
buffered[i].start = endOffset;
} else {
break;
}
i++;
}
});
this.fragmentTracker.removeFragmentsInRange(
startOffset,
endOffset,
PlaylistLevelType.SUBTITLE
);
}
}

// If something goes wrong, proceed to next frag, if we were processing one.
Expand Down Expand Up @@ -246,7 +276,7 @@ export class SubtitleStreamController
}

if (this.state === State.IDLE) {
const { config, currentTrackId, fragmentTracker, media, levels } = this;
const { currentTrackId, levels } = this;
if (
!levels.length ||
!levels[currentTrackId] ||
Expand All @@ -255,6 +285,7 @@ export class SubtitleStreamController
return;
}

const { config, media } = this;
const bufferedInfo = BufferHelper.bufferedInfo(
this.mediaBufferTimeRanges,
media.currentTime,
Expand Down Expand Up @@ -314,7 +345,7 @@ export class SubtitleStreamController
this.hls.trigger(Events.KEY_LOADING, { frag: foundFrag });
} else if (
foundFrag &&
fragmentTracker.getState(foundFrag) === FragmentState.NOT_LOADED
this.fragmentTracker.getState(foundFrag) === FragmentState.NOT_LOADED
) {
// only load if fragment is not loaded
this.loadFragment(foundFrag, trackDetails, targetBufferTime);
Expand All @@ -331,7 +362,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 807552d

Please sign in to comment.