Skip to content

Commit

Permalink
Remove SIDX playlist MAP patching (video-dev#5139)
Browse files Browse the repository at this point in the history
Resolves video-dev#4274

Co-authored-by: Rob Walch <[email protected]>
  • Loading branch information
robwalch and Rob Walch authored Jan 6, 2023
1 parent 7f8ffc6 commit 166bed1
Show file tree
Hide file tree
Showing 5 changed files with 2 additions and 102 deletions.
4 changes: 0 additions & 4 deletions api-extractor/report/hls.js.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1471,8 +1471,6 @@ export class LevelDetails {
// (undocumented)
misses: number;
// (undocumented)
needSidxRanges: boolean;
// (undocumented)
get partEnd(): number;
// (undocumented)
partHoldBack: number;
Expand Down Expand Up @@ -2100,8 +2098,6 @@ export interface PlaylistLoaderContext extends LoaderContext {
// (undocumented)
id: number | null;
// (undocumented)
isSidxRequest?: boolean;
// (undocumented)
level: number | null;
// (undocumented)
levelDetails?: LevelDetails;
Expand Down
1 change: 0 additions & 1 deletion src/loader/level-details.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export class LevelDetails {
public advanced: boolean = true;
public availabilityDelay?: number; // Manifest reload synchronization
public misses: number = 0;
public needSidxRanges: boolean = false;
public startCC: number = 0;
public startSN: number = 0;
public startTimeOffset: number | null = null;
Expand Down
31 changes: 2 additions & 29 deletions src/loader/m3u8-parser.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as URLToolkit from 'url-toolkit';

import { buildAbsoluteURL } from 'url-toolkit';
import { DateRange } from './date-range';
import { Fragment, Part } from './fragment';
import { LevelDetails } from './level-details';
Expand Down Expand Up @@ -53,12 +52,6 @@ const LEVEL_PLAYLIST_REGEX_SLOW = new RegExp(
].join('|')
);

const MP4_REGEX_SUFFIX = /\.(mp4|m4s|m4v|m4a)$/i;

function isMP4Url(url: string): boolean {
return MP4_REGEX_SUFFIX.test(URLToolkit.parseURL(url)?.path ?? '');
}

export default class M3U8Parser {
static findGroup(
groups: Array<AudioGroup>,
Expand All @@ -85,7 +78,7 @@ export default class M3U8Parser {
}

static resolve(url, baseUrl) {
return URLToolkit.buildAbsoluteURL(baseUrl, url, { alwaysNormalize: true });
return buildAbsoluteURL(baseUrl, url, { alwaysNormalize: true });
}

static parseMasterPlaylist(
Expand Down Expand Up @@ -533,26 +526,6 @@ export default class M3U8Parser {
}
if (firstFragment) {
level.startCC = firstFragment.cc;
if (!firstFragment.initSegment) {
// this is a bit lurky but HLS really has no other way to tell us
// if the fragments are TS or MP4, except if we download them :/
// but this is to be able to handle SIDX.
if (
level.fragments.every(
(frag) => frag.relurl && isMP4Url(frag.relurl)
)
) {
logger.warn(
'MP4 fragments found but no init segment (probably no MAP, incomplete M3U8), trying to fetch SIDX'
);
frag = new Fragment(type, baseurl);
frag.relurl = lastFragment.relurl;
frag.level = id;
frag.sn = 'initSegment';
firstFragment.initSegment = frag;
level.needSidxRanges = true;
}
}
}
} else {
level.endSN = 0;
Expand Down
66 changes: 0 additions & 66 deletions src/loader/playlist-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import { Events } from '../events';
import { ErrorDetails, ErrorTypes } from '../errors';
import { logger } from '../utils/logger';
import { parseSegmentIndex, findBox } from '../utils/mp4-tools';
import M3U8Parser from './m3u8-parser';
import type { LevelParsed } from '../types/level';
import type {
Expand Down Expand Up @@ -316,12 +315,6 @@ class PlaylistLoader implements NetworkComponentAPI {
context: PlaylistLoaderContext,
networkDetails: any = null
): void {
if (context.isSidxRequest) {
this.handleSidxRequest(response, context);
this.handlePlaylistLoaded(response, stats, context, networkDetails);
return;
}

this.resetInternalLoader(context.type);

const string = response.data as string;
Expand Down Expand Up @@ -524,71 +517,12 @@ class PlaylistLoader implements NetworkComponentAPI {
// save parsing time
stats.parsing.end = performance.now();

// in case we need SIDX ranges
// return early after calling load for
// the SIDX box.
if (levelDetails.needSidxRanges) {
const sidxUrl = levelDetails.fragments[0].initSegment?.url as string;
this.load({
url: sidxUrl,
isSidxRequest: true,
type,
level,
levelDetails,
id,
groupId: null,
rangeStart: 0,
rangeEnd: 2048,
responseType: 'arraybuffer',
deliveryDirectives: null,
});
return;
}

// extend the context with the new levelDetails property
context.levelDetails = levelDetails;

this.handlePlaylistLoaded(response, stats, context, networkDetails);
}

private handleSidxRequest(
response: LoaderResponse,
context: PlaylistLoaderContext
): void {
const data = new Uint8Array(response.data as ArrayBuffer);
const sidxBox = findBox(data, ['sidx'])[0];
// if provided fragment does not contain sidx, early return
if (!sidxBox) {
return;
}
const sidxInfo = parseSegmentIndex(sidxBox);
if (!sidxInfo) {
return;
}
const sidxReferences = sidxInfo.references;
const levelDetails = context.levelDetails as LevelDetails;
sidxReferences.forEach((segmentRef, index) => {
const segRefInfo = segmentRef.info;
const frag = levelDetails.fragments[index];
if (!frag) {
logger.error(`no fragment for sidx index ${index}`);
return;
}
if (frag.byteRange.length === 0) {
frag.setByteRange(
String(1 + segRefInfo.end - segRefInfo.start) +
'@' +
String(segRefInfo.start)
);
}
if (frag.initSegment) {
const moovBox = findBox(data, ['moov'])[0];
const moovEndOffset = moovBox ? moovBox.length : null;
frag.initSegment.setByteRange(String(moovEndOffset) + '@0');
}
});
}

private handleManifestParsingError(
response: LoaderResponse,
context: PlaylistLoaderContext,
Expand Down
2 changes: 0 additions & 2 deletions src/types/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,6 @@ export interface PlaylistLoaderContext extends LoaderContext {
id: number | null;
// track group id
groupId: string | null;
// defines if the loader is handling a sidx request for the playlist
isSidxRequest?: boolean;
// internal representation of a parsed m3u8 level playlist
levelDetails?: LevelDetails;
// Blocking playlist request delivery directives (or null id none were added to playlist url
Expand Down

0 comments on commit 166bed1

Please sign in to comment.