Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove LHLS support #2864

Merged
merged 1 commit into from
Jul 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ export const hlsDefaultConfig: HlsConfig = {
drmSystemOptions: {}, // used by eme-controller
requestMediaKeySystemAccessFunc: requestMediaKeySystemAccess, // used by eme-controller
testBandwidth: true,
progressive: true,
progressive: false,

// Dynamic Modules
...timelineConfig(),
Expand Down
2 changes: 1 addition & 1 deletion src/controller/audio-stream-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ class AudioStreamController extends BaseStreamController implements ComponentAPI
}

// if video not attached AND
// start fragment already requested OR start frag prefetch disable
// start fragment already requested OR start frag prefetch not enabled
// exit loop
// => if media not attached but start frag prefetch is enabled and start frag not requested yet, we will not exit loop
if (!media && (this.startFragRequested || !config.startFragPrefetch)) {
Expand Down
2 changes: 1 addition & 1 deletion src/controller/level-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ export function computeReloadInterval (newDetails: LevelDetails, stats: LoaderSt

export function getProgramDateTimeAtEndOfLastEncodedFragment (levelDetails: LevelDetails): number | null {
if (levelDetails.hasProgramDateTime) {
const encodedFragments = levelDetails.fragments.filter((fragment) => !fragment.prefetch);
const encodedFragments = levelDetails.fragments;
const lastEncodedFrag = encodedFragments[encodedFragments.length - 1];
const programDateTime = lastEncodedFrag.programDateTime as number;
if (Number.isFinite(programDateTime)) {
Expand Down
2 changes: 1 addition & 1 deletion src/controller/stream-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ export default class StreamController extends BaseStreamController implements Ne
const { config, nextLoadLevel: level } = hls;

// if start level not parsed yet OR
// if video not attached AND start fragment already requested OR start frag prefetch disable
// if video not attached AND start fragment already requested OR start frag prefetch not enabled
// exit loop, as we either need more info (level not parsed) or we need media to be attached to load new fragment
if (levelLastLoaded === null || (!media && (this.startFragRequested || !config.startFragPrefetch))) {
return;
Expand Down
2 changes: 0 additions & 2 deletions src/loader/fragment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,6 @@ export default class Fragment {
public start: number = 0;
// Set when the fragment was loaded and transmuxed, but was stopped from buffering due to dropped frames.
public backtracked: boolean = false;
// LHLS prefetch flag
public prefetch?: boolean;
// Set by `updateFragPTSDTS` in level-helper
public deltaPTS?: number;
public maxStartPTS?: number;
Expand Down
28 changes: 0 additions & 28 deletions src/loader/m3u8-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ const LEVEL_PLAYLIST_REGEX_SLOW = new RegExp([
/#EXT-X-(ENDLIST)/.source,
/#EXT-X-(DISCONTINUITY-SEQ)UENCE: *(\d+)/.source,
/#EXT-X-(DIS)CONTINUITY/.source,
/#EXT-X-(PREFETCH-DIS)CONTINUITY/.source, // TODO: deprecate LHLS
/#EXT-X-(PREFETCH):(.+)/.source, // TODO: deprecate LHLS
/#EXT-X-(VERSION):(\d+)/.source,
/#EXT-X-(MAP):(.+)/.source,
/(#)([^:]*):(.*)/.source,
Expand Down Expand Up @@ -197,7 +195,6 @@ export default class M3U8Parser {
while ((result = LEVEL_PLAYLIST_REGEX_FAST.exec(string)) !== null) {
const duration = result[1];
if (duration) { // INF
frag.prefetch = false;
frag.duration = parseFloat(duration);
// avoid sliced strings https://github.com/video-dev/hls.js/issues/939
const title = (' ' + result[2]).slice(1);
Expand Down Expand Up @@ -284,31 +281,6 @@ export default class M3U8Parser {
case 'DISCONTINUITY-SEQ':
discontinuityCounter = parseInt(value1);
break;
case 'PREFETCH':
frag.prefetch = true;
frag.duration = level.targetduration;
frag.title = null;
frag.type = type;
frag.start = totalduration;
frag.levelkey = levelkey;
frag.sn = currentSN++;
frag.level = id;
frag.cc = discontinuityCounter;
frag.urlId = levelUrlId;
frag.baseurl = baseurl;
frag.relurl = value1;
assignProgramDateTime(frag, prevFrag);

level.fragments.push(frag);
prevFrag = frag;
totalduration += frag.duration;

frag = new Fragment();
break;
case 'PREFETCH-DIS':
discontinuityCounter++;
frag.tagList.push(['PREFETCH-DIS']);
break;
case 'KEY': {
// https://tools.ietf.org/html/rfc8216#section-4.3.2.4
const decryptparams = value1;
Expand Down
129 changes: 0 additions & 129 deletions tests/unit/loader/playlist-loader.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import M3U8Parser from '../../../src/loader/m3u8-parser';
import { mergeDetails } from '../../../src/controller/level-helper';
import AttrList from '../../../src/utils/attr-list';

describe('PlaylistLoader', function () {
Expand Down Expand Up @@ -966,132 +965,4 @@ http://dummy.url.com/hls/live/segment/segment_022916_164500865_719928.ts
expect(result.fragments[0].url).to.equal('http://dummy.url.com/180724_Allison VLOG v3_00001.ts');
expect(result.fragments[1].url).to.equal('http://dummy.url.com/180724_Allison VLOG v3_00002.ts');
});

describe('LHLS Parsing', function () {
const level = `#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:2
#EXT-X-MEDIA-SEQUENCE: 0
#EXT-X-DISCONTINUITY-SEQUENCE: 0
#EXT-X-PROGRAM-DATE-TIME:2018-09-05T20:59:06.531Z
#EXTINF:2.000
https://foo.com/bar/0.ts
#EXT-X-PROGRAM-DATE-TIME:2018-09-05T20:59:08.531Z
#EXTINF:2.000
https://foo.com/bar/1.ts

#EXT-X-PREFETCH:https://foo.com/bar/2.ts
`;
const levelRefreshed = `#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:2
#EXT-X-MEDIA-SEQUENCE: 1
#EXT-X-DISCONTINUITY-SEQUENCE: 0
#EXT-X-PROGRAM-DATE-TIME:2018-09-05T20:59:08.531Z
#EXTINF:2.000
https://foo.com/bar/1.ts
#EXT-X-PROGRAM-DATE-TIME:2018-09-05T20:59:10.531Z
#EXTINF:2.000
https://foo.com/bar/2.ts

#EXT-X-PREFETCH:https://foo.com/bar/3.ts
`;
const levelWithDiscontinuity = `#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:2
#EXT-X-MEDIA-SEQUENCE: 100
#EXT-X-DISCONTINUITY-SEQUENCE: 5
#EXT-X-PROGRAM-DATE-TIME:2018-09-05T20:59:06.531Z
#EXTINF:2.000
https://foo.com/bar/0.ts
#EXT-X-PROGRAM-DATE-TIME:2018-09-05T20:59:08.531Z
#EXTINF:2.000
https://foo.com/bar/1.ts

#EXT-X-PREFETCH-DISCONTINUITY
#EXT-X-PREFETCH:https://foo.com/bar/5.ts
`;

it('Adds prefetch segments to the appropriate Level object', function () {
const result = M3U8Parser.parseLevelPlaylist(level, 'http://dummy.url.com/playlist.m3u8', 2, 'main', 0);
expect(result.fragments).to.have.lengthOf(3);
expect(result.fragments[2].baseurl).to.equal('http://dummy.url.com/playlist.m3u8');
expect(result.fragments[2].level).to.equal(2);
expect(result.fragments[2].type).to.equal('main');
expect(result.fragments[2].urlId).to.equal(0);
expect(result.fragments[2].relurl).to.equal('https://foo.com/bar/2.ts');
});
it('Adds `prefetch: true` to prefetch segments', function () {
const result = M3U8Parser.parseLevelPlaylist(level, 'http://dummy.url.com/playlist.m3u8', 0);
expect(result.fragments[2]).to.have.property('prefetch').which.equals(true);
});
it('Adds `prefetch: false` to complete segments', function () {
const result = M3U8Parser.parseLevelPlaylist(level, 'http://dummy.url.com/playlist.m3u8', 0);
expect(result.fragments[0]).to.have.property('prefetch').which.equals(false);
expect(result.fragments[1]).to.have.property('prefetch').which.equals(false);
});
it('Updates `prefetch` to `false` when prefetch segments transform to complete segments', function () {
const result1 = M3U8Parser.parseLevelPlaylist(level, 'http://dummy.url.com/playlist.m3u8', 0);
const result2 = M3U8Parser.parseLevelPlaylist(levelRefreshed, 'http://dummy.url.com/playlist.m3u8', 0);

expect(result1.fragments).to.have.lengthOf(3);
expect(result1.endSN).to.equal(2);
expect(result1.fragments[0].start).to.equal(0);
expect(result1.fragments[0].sn).to.equal(0);
expect(result1.fragments[1].sn).to.equal(1);
expect(result1.fragments[2].sn).to.equal(2);
expect(result1.fragments[0].prefetch).to.equal(false);
expect(result1.fragments[1].prefetch).to.equal(false);
expect(result1.fragments[2].prefetch).to.equal(true);
expect(result1.fragments[1].relurl).to.equal('https://foo.com/bar/1.ts');
expect(result1.fragments[2].relurl).to.equal('https://foo.com/bar/2.ts');

expect(result2.fragments).to.have.lengthOf(3);
expect(result2.endSN).to.equal(3);
expect(result2.fragments[0].start).to.equal(0);
expect(result2.fragments[0].sn).to.equal(1);
expect(result2.fragments[1].sn).to.equal(2);
expect(result2.fragments[2].sn).to.equal(3);
expect(result2.fragments[0].prefetch).to.equal(false);
expect(result2.fragments[1].prefetch).to.equal(false);
expect(result2.fragments[2].prefetch).to.equal(true);
expect(result2.fragments[1].relurl).to.equal('https://foo.com/bar/2.ts');
expect(result2.fragments[2].relurl).to.equal('https://foo.com/bar/3.ts');

// Clone the new results that mergeDetails will change
const newDetails = JSON.parse(JSON.stringify(result2));
mergeDetails(result1, newDetails);

expect(newDetails.fragments[0].start).to.equal(2);
});

it('Calculates the correct start time, duration and program date time for prefetch segments', function () {
const result = M3U8Parser.parseLevelPlaylist(level, 'http://dummy.url.com/playlist.m3u8', 0);
const previousPDT = 1536181148531;
expect(result.fragments[2].duration).to.equal(2);
expect(result.fragments[2].start).to.equal(4);
expect(result.fragments[1].programDateTime).to.equal(previousPDT);
expect(result.fragments[2].programDateTime).to.equal(previousPDT + 2000);
});

it('Adds "PREFETCH-DIS" to `frag.tagList` and updates discontinuity sequence (cc) tags', function () {
const result = M3U8Parser.parseLevelPlaylist(levelWithDiscontinuity, 'http://dummy.url.com/playlist.m3u8', 0);
expect(result.fragments[0].cc).to.equal(5);
expect(result.fragments[2].cc).to.equal(6);
expect(result.fragments[2].tagList).to.have.lengthOf(1);
expect(result.fragments[2].tagList[0][0]).to.equal('PREFETCH-DIS');
});

it('Calculates the correct SN, start time and duration for prefetch segments with discontinuity', function () {
const result = M3U8Parser.parseLevelPlaylist(levelWithDiscontinuity, 'http://dummy.url.com/playlist.m3u8', 0);
const previousPDT = 1536181148531;
expect(result.fragments[0].sn).to.equal(100);
expect(result.fragments[1].sn).to.equal(101);
expect(result.fragments[2].sn).to.equal(102);
expect(result.fragments[2].duration).to.equal(2);
expect(result.fragments[2].start).to.equal(4);
expect(result.fragments[1].programDateTime).to.equal(previousPDT);
expect(result.fragments[2].programDateTime).to.equal(previousPDT + 2000);
});
});
});