Skip to content

Commit

Permalink
Add detection of open-ended byterange requests and ignore them for no…
Browse files Browse the repository at this point in the history
…w. Add skeleton for fetch loader support of these requests.
  • Loading branch information
iamboorrito committed Jun 28, 2024
1 parent e215504 commit deac50e
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 11 deletions.
51 changes: 44 additions & 7 deletions src/loader/fragment-preloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from '../types/events';
import { HlsConfig } from '../hls';
import { logger } from '../utils/logger';
import FetchLoader from '../utils/fetch-loader';

export const enum FragRequestState {
IDLE,
Expand All @@ -32,6 +33,7 @@ export default class FragmentPreloader extends FragmentLoader {
state: FragRequestState.IDLE,
};
protected log: (msg: any) => void;
private fetchLoader?: FetchLoader | undefined;

constructor(config: HlsConfig, logPrefix: string) {
super(config);
Expand All @@ -49,10 +51,38 @@ export default class FragmentPreloader extends FragmentLoader {

public has(frag: Fragment, part: Part | undefined): boolean {
const { request } = this.storage;

if (request === undefined || request.frag.sn !== frag.sn) {
return false;
}

const requestPart = request.part;
// frag preload hint only
if (requestPart === undefined && part === undefined) {
return true;
}

// mismatched part / frag
if (requestPart === undefined || part === undefined) {
return false;
}

if (requestPart.index === part.index) {
return true;
}

// Return true if byterange into requested part AND fetch loader exists
return (
request !== undefined &&
request.frag.sn === frag.sn &&
request.part?.index === part?.index
this.fetchLoader !== undefined &&
// request is byterange
requestPart.byteRangeStartOffset !== undefined &&
requestPart.byteRangeEndOffset !== undefined &&
// part is byterange
part.byteRangeStartOffset !== undefined &&
part.byteRangeEndOffset !== undefined &&
// part byterange contained within request range
requestPart.byteRangeStartOffset <= part.byteRangeStartOffset &&
requestPart.byteRangeEndOffset >= part.byteRangeEndOffset
);
}

Expand All @@ -74,10 +104,17 @@ export default class FragmentPreloader extends FragmentLoader {
}:${part?.index}`,
);

const loadPromise =
part !== undefined
? this.loadPart(frag, part, noop)
: this.load(frag, noop);
let loadPromise;
if (part !== undefined) {
// TODO: Use fetch loader to progressively load open-ended byterange requests
if (part.byteRangeEndOffset === 2 ** 53 - 1) {
return;
} else {
loadPromise = this.loadPart(frag, part, noop);
}
} else {
loadPromise = this.load(frag, noop);
}

const request = {
frag,
Expand Down
12 changes: 8 additions & 4 deletions src/loader/m3u8-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -755,10 +755,14 @@ export default class M3U8Parser {
preloadHintAttrs['BYTERANGE-START'] ||
preloadHintAttrs['BYTERANGE-LENGTH']
) {
const byteRangeStartOffset = preloadHintAttrs['BYTERANGE-START'] | 0;
const byteRangeLength =
preloadHintAttrs['BYTERANGE-LENGTH'] | (2 ** 53 - 1);
byteRange = `${byteRangeLength}@${byteRangeStartOffset}`;
const byteRangeStartOffset = preloadHintAttrs['BYTERANGE-START'];
let byteRangeLength = preloadHintAttrs['BYTERANGE-LENGTH'];
if (byteRangeLength <= 0) {
byteRangeLength = 2 ** 53 - 1;
}
if (isFinite(byteRangeLength) && isFinite(byteRangeStartOffset)) {
byteRange = `${byteRangeLength}@${byteRangeStartOffset}`;
}
}
const preloadType = preloadHintAttrs.TYPE;
if (preloadType === 'PART' && level.partList) {
Expand Down

0 comments on commit deac50e

Please sign in to comment.