chore(deps): update dependency prettier to v3 (#5646)

* chore(deps): update dependency prettier to v3

* run prettier

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Tom Jenkinson <tom@tjenkinson.me>
This commit is contained in:
renovate[bot]
2023-08-22 11:24:59 +01:00
committed by GitHub
parent 07db3b9d46
commit 359197f20b
146 changed files with 1914 additions and 1897 deletions
+11 -11
View File
@@ -10,7 +10,7 @@ const istanbul = require('rollup-plugin-istanbul');
const fs = require('fs');
const pkgJson = JSON.parse(
fs.readFileSync('./package.json', { encoding: 'utf-8' })
fs.readFileSync('./package.json', { encoding: 'utf-8' }),
);
const BUILD_TYPE = {
@@ -53,24 +53,24 @@ const buildConstants = (type, additional = {}) => ({
values: {
__VERSION__: JSON.stringify(pkgJson.version),
__USE_SUBTITLES__: JSON.stringify(
type === BUILD_TYPE.full || addSubtitleSupport
type === BUILD_TYPE.full || addSubtitleSupport,
),
__USE_ALT_AUDIO__: JSON.stringify(
type === BUILD_TYPE.full || addAltAudioSupport
type === BUILD_TYPE.full || addAltAudioSupport,
),
__USE_EME_DRM__: JSON.stringify(type === BUILD_TYPE.full || addEMESupport),
__USE_CMCD__: JSON.stringify(type === BUILD_TYPE.full || addCMCDSupport),
__USE_CONTENT_STEERING__: JSON.stringify(
type === BUILD_TYPE.full || addContentSteeringSupport
type === BUILD_TYPE.full || addContentSteeringSupport,
),
__USE_VARIABLE_SUBSTITUTION__: JSON.stringify(
type === BUILD_TYPE.full || addVariableSubstitutionSupport
type === BUILD_TYPE.full || addVariableSubstitutionSupport,
),
__USE_M2TS_ADVANCED_CODECS__: JSON.stringify(
type === BUILD_TYPE.full || addM2TSAdvancedCodecSupport
type === BUILD_TYPE.full || addM2TSAdvancedCodecSupport,
),
__USE_MEDIA_CAPABILITIES__: JSON.stringify(
type === BUILD_TYPE.full || addMediaCapabilitiesSupport
type === BUILD_TYPE.full || addMediaCapabilitiesSupport,
),
...additional,
@@ -132,7 +132,7 @@ const babelTsWithPresetEnvTargets = ({ targets, stripConsole }) =>
espath.node.callee = importHelper.addNamed(
espath,
'isFiniteNumber',
path.resolve('src/polyfills/number')
path.resolve('src/polyfills/number'),
);
} else if (
espath.get('callee').matchesPattern('Number.MAX_SAFE_INTEGER')
@@ -140,7 +140,7 @@ const babelTsWithPresetEnvTargets = ({ targets, stripConsole }) =>
espath.node.callee = importHelper.addNamed(
espath,
'MAX_SAFE_INTEGER',
path.resolve('src/polyfills/number')
path.resolve('src/polyfills/number'),
);
}
},
@@ -344,7 +344,7 @@ const configs = Object.entries({
replace(
buildConstants(BUILD_TYPE.full, {
__IN_WORKER__: JSON.stringify(true),
})
}),
),
buildBabelLegacyBrowsers({ stripConsole: true }),
terser(),
@@ -377,7 +377,7 @@ const configs = Object.entries({
branch: env.CF_PAGES_BRANCH,
commitRef: env.CF_PAGES_COMMIT_SHA,
}
: null
: null,
),
},
}),
+1 -1
View File
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
+1 -1
View File
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
+1 -1
View File
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
+1 -1
View File
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<head>
<title>hls.js metrics page</title>
+1 -1
View File
@@ -235,7 +235,7 @@ You need to provide manifest URL as below:
});
hls.on(Hls.Events.MANIFEST_PARSED, function (event, data) {
console.log(
'manifest loaded, found ' + data.levels.length + ' quality level'
'manifest loaded, found ' + data.levels.length + ' quality level',
);
});
hls.loadSource('http://my.streamURL.com/playlist.m3u8');
+8 -6
View File
@@ -1,17 +1,19 @@
const micromatch = require('micromatch');
const prettier = require('prettier');
const prettierSupportedExtensions = prettier
.getSupportInfo()
.languages.map(({ extensions }) => extensions)
.flat();
const addQuotes = (a) => `"${a}"`;
module.exports = (allStagedFiles) => {
module.exports = async (allStagedFiles) => {
const prettierSupportedExtensions = (
await prettier.getSupportInfo()
).languages
.map(({ extensions }) => extensions)
.flat();
const eslintFiles = micromatch(allStagedFiles, '**/*.{js,ts}');
const prettierFiles = micromatch(
allStagedFiles,
prettierSupportedExtensions.map((extension) => `**/*${extension}`)
prettierSupportedExtensions.map((extension) => `**/*${extension}`),
);
return [
+9 -9
View File
@@ -62,7 +62,7 @@
"mocha": "10.2.0",
"node-fetch": "3.3.2",
"npm-run-all": "4.1.5",
"prettier": "2.8.8",
"prettier": "3.0.1",
"promise-polyfill": "8.3.0",
"rollup": "3.28.0",
"rollup-plugin-istanbul": "4.0.0",
@@ -10275,15 +10275,15 @@
}
},
"node_modules/prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.1.tgz",
"integrity": "sha512-fcOWSnnpCrovBsmFZIGIy9UqK2FaI7Hqax+DIO0A9UxeVoY4iweyaFjS5TavZN97Hfehph0nhsZnjlVKzEQSrQ==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=10.13.0"
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
@@ -20680,9 +20680,9 @@
"dev": true
},
"prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.1.tgz",
"integrity": "sha512-fcOWSnnpCrovBsmFZIGIy9UqK2FaI7Hqax+DIO0A9UxeVoY4iweyaFjS5TavZN97Hfehph0nhsZnjlVKzEQSrQ==",
"dev": true
},
"printable-characters": {
+1 -1
View File
@@ -116,7 +116,7 @@
"mocha": "10.2.0",
"node-fetch": "3.3.2",
"npm-run-all": "4.1.5",
"prettier": "2.8.8",
"prettier": "3.0.1",
"promise-polyfill": "8.3.0",
"rollup": "3.28.0",
"rollup-plugin-istanbul": "4.0.0",
+4 -4
View File
@@ -13,20 +13,20 @@ module.exports = ({ configType = [] }) => {
} else {
// Filter out enabled configs
const enabledEntries = configs.filter(([name]) =>
requestedConfigs.includes(name)
requestedConfigs.includes(name),
);
if (!enabledEntries.length) {
throw new Error(
`Couldn't find a valid config with the names ${JSON.stringify(
requestedConfigs
)}. Known configs are: ${configs.map(([name]) => name).join(', ')}`
requestedConfigs,
)}. Known configs are: ${configs.map(([name]) => name).join(', ')}`,
);
}
configEntries = enabledEntries;
}
console.log(
`Building configs: ${configEntries.map(([name]) => name).join(', ')}.\n`
`Building configs: ${configEntries.map(([name]) => name).join(', ')}.\n`,
);
return configEntries.map(([, config]) => config);
};
+2 -2
View File
@@ -24,8 +24,8 @@ async function versionPublished() {
//https://github.com/npm/registry/blob/master/docs/REGISTRY-API.md
const response = await fetch(
`https://registry.npmjs.org/${encodeURIComponent(
packageJson.name
)}/${encodeURIComponent(packageJson.version)}`
packageJson.name,
)}/${encodeURIComponent(packageJson.version)}`,
);
if (response.status === 200) {
return true;
+5 -5
View File
@@ -23,7 +23,7 @@ try {
// 1.2.3-0.caaanary.custom => bad
// 1.2.3-0.caaanary.custom.0.canary.503 => now lower than 1.2.3-0.canary.501
throw new Error(
`It's possible that "${newVersion}" has a lower precedense than an existing canary version which is not allowed.`
`It's possible that "${newVersion}" has a lower precedense than an existing canary version which is not allowed.`,
);
}
} else {
@@ -44,7 +44,7 @@ try {
const suffix = process.env.CF_PAGES
? `pr.${process.env.CF_PAGES_BRANCH.replace(
/[^a-zA-Z-]/g,
'-'
'-',
)}.${getCommitHash().slice(0, 8)}`
: `0.canary.${getCommitNum()}`;
@@ -53,18 +53,18 @@ try {
if (!versionParser.isGreaterOrEqual(newVersion, latestVersion)) {
throw new Error(
`New version "${newVersion}" is not >= latest version "${latestVersion}" on this branch.`
`New version "${newVersion}" is not >= latest version "${latestVersion}" on this branch.`,
);
}
const foundPreviousVersion = versionParser
.getPotentialPreviousStableVersions(`v${newVersion}`)
.every((potentialPreviousVersion) =>
hasTag(`v${potentialPreviousVersion}`)
hasTag(`v${potentialPreviousVersion}`),
);
if (!foundPreviousVersion) {
throw new Error(
'Could not find a previous version. The tag must follow a previous stable version number.'
'Could not find a previous version. The tag must follow a previous stable version number.',
);
}
+11 -11
View File
@@ -84,7 +84,7 @@ export type DRMSystemConfiguration = {
this: Hls,
initDataType: string,
initData: ArrayBuffer | null,
keyContext: MediaKeySessionContext
keyContext: MediaKeySessionContext,
) =>
| { initDataType: string; initData: ArrayBuffer | null }
| undefined
@@ -101,13 +101,13 @@ export type EMEControllerConfig = {
xhr: XMLHttpRequest,
url: string,
keyContext: MediaKeySessionContext,
licenseChallenge: Uint8Array
licenseChallenge: Uint8Array,
) => void | Uint8Array | Promise<Uint8Array | void>;
licenseResponseCallback?: (
this: Hls,
xhr: XMLHttpRequest,
url: string,
keyContext: MediaKeySessionContext
keyContext: MediaKeySessionContext,
) => ArrayBuffer;
emeEnabled: boolean;
widevineLicenseUrl?: string;
@@ -532,7 +532,7 @@ function timelineConfig(): TimelineControllerConfig {
*/
export function mergeConfig(
defaultConfig: HlsConfig,
userConfig: Partial<HlsConfig>
userConfig: Partial<HlsConfig>,
): HlsConfig {
if (
(userConfig.liveSyncDurationCount ||
@@ -540,7 +540,7 @@ export function mergeConfig(
(userConfig.liveSyncDuration || userConfig.liveMaxLatencyDuration)
) {
throw new Error(
"Illegal hls.js config: don't mix up liveSyncDurationCount/liveMaxLatencyDurationCount and liveSyncDuration/liveMaxLatencyDuration"
"Illegal hls.js config: don't mix up liveSyncDurationCount/liveMaxLatencyDurationCount and liveSyncDuration/liveMaxLatencyDuration",
);
}
@@ -551,7 +551,7 @@ export function mergeConfig(
userConfig.liveSyncDurationCount)
) {
throw new Error(
'Illegal hls.js config: "liveMaxLatencyDurationCount" must be greater than "liveSyncDurationCount"'
'Illegal hls.js config: "liveMaxLatencyDurationCount" must be greater than "liveSyncDurationCount"',
);
}
@@ -561,7 +561,7 @@ export function mergeConfig(
userConfig.liveMaxLatencyDuration <= userConfig.liveSyncDuration)
) {
throw new Error(
'Illegal hls.js config: "liveMaxLatencyDuration" must be greater than "liveSyncDuration"'
'Illegal hls.js config: "liveMaxLatencyDuration" must be greater than "liveSyncDuration"',
);
}
@@ -609,10 +609,10 @@ export function mergeConfig(
if (report.length) {
logger.warn(
`hls.js config: "${report.join(
'", "'
'", "',
)}" setting(s) are deprecated, use "${policyName}": ${JSON.stringify(
userConfig[policyName]
)}`
userConfig[policyName],
)}`,
);
}
});
@@ -644,7 +644,7 @@ export function enableStreamingMode(config) {
if (currentLoader !== FetchLoader && currentLoader !== XhrLoader) {
// If a developer has configured their own loader, respect that choice
logger.log(
'[config]: Custom loader detected, cannot enable progressive streaming'
'[config]: Custom loader detected, cannot enable progressive streaming',
);
config.progressive = false;
} else {
+35 -35
View File
@@ -65,7 +65,7 @@ class AbrController implements AbrComponentAPI {
return new EwmaBandWidthEstimator(
config.abrEwmaSlowVoD,
config.abrEwmaFastVoD,
config.abrEwmaDefaultEstimate
config.abrEwmaDefaultEstimate,
);
}
@@ -106,7 +106,7 @@ class AbrController implements AbrComponentAPI {
protected onManifestLoading(
event: Events.MANIFEST_LOADING,
data: ManifestLoadingData
data: ManifestLoadingData,
) {
this.lastLoadedFragLevel = -1;
this.lastLevelLoadSec = 0;
@@ -140,7 +140,7 @@ class AbrController implements AbrComponentAPI {
protected onLevelSwitching(
event: Events.LEVEL_SWITCHING,
data: LevelSwitchingData
data: LevelSwitchingData,
): void {
this.clearTimer();
}
@@ -161,7 +161,7 @@ class AbrController implements AbrComponentAPI {
timeToFirstByteSec: number,
bandwidth: number,
fragSizeBits: number,
isSwitch: boolean
isSwitch: boolean,
): number {
const fragLoadSec = timeToFirstByteSec + fragSizeBits / bandwidth;
const playlistLoadSec = isSwitch ? this.lastLevelLoadSec : 0;
@@ -284,7 +284,7 @@ class AbrController implements AbrComponentAPI {
ttfbEstimate / 1000,
bwe,
duration * levelNextBitrate,
!levels[nextLoadLevel].details
!levels[nextLoadLevel].details,
);
if (fragLevelNextLoadedDelay < bufferStarvationDelay) {
break;
@@ -305,7 +305,7 @@ class AbrController implements AbrComponentAPI {
// If there has been loading progress, sample bandwidth using loading time offset by minimum TTFB time
this.bwEstimator.sample(
timeLoading - Math.min(ttfbEstimate, ttfb),
stats.loaded
stats.loaded,
);
} else {
// If there has been no loading progress, sample TTFB
@@ -319,7 +319,7 @@ class AbrController implements AbrComponentAPI {
Time to underbuffer: ${bufferStarvationDelay.toFixed(3)} s
Estimated load time for current fragment: ${fragLoadedDelay.toFixed(3)} s
Estimated load time for down switch fragment: ${fragLevelNextLoadedDelay.toFixed(
3
3,
)} s
TTFB estimate: ${ttfb}
Current BW estimate: ${
@@ -336,7 +336,7 @@ class AbrController implements AbrComponentAPI {
protected onFragLoaded(
event: Events.FRAG_LOADED,
{ frag, part }: FragLoadedData
{ frag, part }: FragLoadedData,
) {
const stats = part ? part.stats : frag.stats;
if (frag.type === PlaylistLevelType.MAIN) {
@@ -378,7 +378,7 @@ class AbrController implements AbrComponentAPI {
protected onFragBuffered(
event: Events.FRAG_BUFFERED,
data: FragBufferedData
data: FragBufferedData,
) {
const { frag, part } = data;
const stats = part?.stats.loaded ? part.stats : frag.stats;
@@ -397,7 +397,7 @@ class AbrController implements AbrComponentAPI {
stats.loading.start -
Math.min(
stats.loading.first - stats.loading.start,
this.bwEstimator.getEstimateTTFB()
this.bwEstimator.getEstimateTTFB(),
);
this.bwEstimator.sample(processingMs, stats.loaded);
stats.bwEstimate = this.getBwEstimate();
@@ -430,7 +430,7 @@ class AbrController implements AbrComponentAPI {
0,
maxStartDelay,
1,
1
1,
);
if (abrAutoLevel > -1) {
return abrAutoLevel;
@@ -438,7 +438,7 @@ class AbrController implements AbrComponentAPI {
const firstLevel = this.hls.firstLevel;
const clamped = Math.min(Math.max(firstLevel, minAutoLevel), maxAutoLevel);
logger.warn(
`[abr] Could not find best starting auto level. Defaulting to first in playlist ${firstLevel} clamped to ${clamped}`
`[abr] Could not find best starting auto level. Defaulting to first in playlist ${firstLevel} clamped to ${clamped}`,
);
return clamped;
}
@@ -529,7 +529,7 @@ class AbrController implements AbrComponentAPI {
bufferStarvationDelay,
0,
bwFactor,
bwUpFactor
bwUpFactor,
);
if (bestLevel >= 0) {
return bestLevel;
@@ -555,10 +555,10 @@ class AbrController implements AbrComponentAPI {
maxStarvationDelay = maxLoadingDelay - bitrateTestDelay;
logger.info(
`[abr] bitrate test took ${Math.round(
1000 * bitrateTestDelay
1000 * bitrateTestDelay,
)}ms, set first fragment max fetchDuration to ${Math.round(
1000 * maxStarvationDelay
)} ms`
1000 * maxStarvationDelay,
)} ms`,
);
// don't use conservative factor on bitrate test
bwFactor = bwUpFactor = 1;
@@ -571,12 +571,12 @@ class AbrController implements AbrComponentAPI {
bufferStarvationDelay,
maxStarvationDelay,
bwFactor,
bwUpFactor
bwUpFactor,
);
logger.info(
`[abr] ${
bufferStarvationDelay ? 'rebuffering expected' : 'buffer is empty'
}, optimal quality level ${bestLevel}`
}, optimal quality level ${bestLevel}`,
);
if (bestLevel > -1) {
return bestLevel;
@@ -604,7 +604,7 @@ class AbrController implements AbrComponentAPI {
bufferStarvationDelay: number,
maxStarvationDelay: number,
bwFactor: number,
bwUpFactor: number
bwUpFactor: number,
): number {
const maxFetchDuration: number = bufferStarvationDelay + maxStarvationDelay;
const lastLoadedFragLevel = this.lastLoadedFragLevel;
@@ -628,7 +628,7 @@ class AbrController implements AbrComponentAPI {
levels,
audioTracksByGroup,
minAutoLevel,
maxAutoLevel
maxAutoLevel,
));
const { codecSet, videoRange, minFramerate, minBitrate } =
getStartCodecTier(codecTiers, currentVideoRange, currentBw);
@@ -669,13 +669,13 @@ class AbrController implements AbrComponentAPI {
mediaCapabilities,
currentVideoRange,
currentFrameRate,
currentBw
currentBw,
)
) {
levelInfo.supportedPromise = getMediaDecodingInfoPromise(
levelInfo,
audioTracksByGroup,
mediaCapabilities
mediaCapabilities,
);
levelInfo.supportedPromise.then((decodingInfo) => {
levelInfo.supportedResult = decodingInfo;
@@ -683,13 +683,13 @@ class AbrController implements AbrComponentAPI {
logger.warn(
`[abr] MediaCapabilities decodingInfo error: "${
decodingInfo.error
}" for level ${i} ${JSON.stringify(decodingInfo)}`
}" for level ${i} ${JSON.stringify(decodingInfo)}`,
);
} else if (!decodingInfo.supported) {
logger.warn(
`[abr] Removing unsupported level ${i} after MediaCapabilities decodingInfo check failed ${JSON.stringify(
decodingInfo
)}`
decodingInfo,
)}`,
);
if (i > 0) {
this.hls.removeLevel(i);
@@ -746,7 +746,7 @@ class AbrController implements AbrComponentAPI {
ttfbEstimateSec,
adjustedbw,
bitrate * avgDuration,
levelDetails === undefined
levelDetails === undefined,
);
const canSwitchWithinTolerance =
@@ -767,28 +767,28 @@ class AbrController implements AbrComponentAPI {
if (levelsSkipped.length) {
logger.trace(
`[abr] Skipped level(s) ${levelsSkipped.join(
','
',',
)} of ${maxAutoLevel} max with CODECS and VIDEO-RANGE:"${
levels[levelsSkipped[0]].codecs
}" ${levels[levelsSkipped[0]].videoRange}; not compatible with "${
level.codecs
}" ${currentVideoRange}`
}" ${currentVideoRange}`,
);
}
logger.info(
`[abr] switch candidate:${selectionBaseLevel}->${i} adjustedbw(${Math.round(
adjustedbw
adjustedbw,
)})-bitrate=${Math.round(
adjustedbw - bitrate
adjustedbw - bitrate,
)} ttfb:${ttfbEstimateSec.toFixed(
1
1,
)} avgDuration:${avgDuration.toFixed(
1
1,
)} maxFetchDuration:${maxFetchDuration.toFixed(
1
1,
)} fetchDuration:${fetchDuration.toFixed(
1
)} firstSelection:${firstSelection} codecSet:${currentCodecSet} videoRange:${currentVideoRange} hls.loadLevel:${loadLevel}`
1,
)} firstSelection:${firstSelection} codecSet:${currentCodecSet} videoRange:${currentVideoRange} hls.loadLevel:${loadLevel}`,
);
}
// as we are looping from highest to lowest, this will return the best achievable quality level
+33 -33
View File
@@ -62,14 +62,14 @@ class AudioStreamController
constructor(
hls: Hls,
fragmentTracker: FragmentTracker,
keyLoader: KeyLoader
keyLoader: KeyLoader,
) {
super(
hls,
fragmentTracker,
keyLoader,
'[audio-stream-controller]',
PlaylistLevelType.AUDIO
PlaylistLevelType.AUDIO,
);
this._registerListeners();
}
@@ -118,7 +118,7 @@ class AudioStreamController
// INIT_PTS_FOUND is triggered when the video track parsed in the stream-controller has a new PTS value
onInitPtsFound(
event: Events.INIT_PTS_FOUND,
{ frag, id, initPTS, timescale }: InitPTSFoundData
{ frag, id, initPTS, timescale }: InitPTSFoundData,
) {
// Always update the new INIT PTS
// Can change due level switch
@@ -146,8 +146,8 @@ class AudioStreamController
if (lastCurrentTime > 0 && startPosition === -1) {
this.log(
`Override startPosition with lastCurrentTime @${lastCurrentTime.toFixed(
3
)}`
3,
)}`,
);
startPosition = lastCurrentTime;
this.state = State.IDLE;
@@ -213,7 +213,7 @@ class AudioStreamController
} else if (this.videoTrackCC !== this.waitingVideoCC) {
// Drop waiting fragment if videoTrackCC has changed since waitingFragment was set and initPTS was not found
this.log(
`Waiting fragment cc (${frag.cc}) cancelled because video is at cc ${this.videoTrackCC}`
`Waiting fragment cc (${frag.cc}) cancelled because video is at cc ${this.videoTrackCC}`,
);
this.clearWaitingFragment();
} else {
@@ -222,16 +222,16 @@ class AudioStreamController
const bufferInfo = BufferHelper.bufferInfo(
this.mediaBuffer,
pos,
this.config.maxBufferHole
this.config.maxBufferHole,
);
const waitingFragmentAtPosition = fragmentWithinToleranceTest(
bufferInfo.end,
this.config.maxFragLookUpTolerance,
frag
frag,
);
if (waitingFragmentAtPosition < 0) {
this.log(
`Waiting fragment cc (${frag.cc}) @ ${frag.start} cancelled because another fragment at ${bufferInfo.end} is needed`
`Waiting fragment cc (${frag.cc}) @ ${frag.start} cancelled because another fragment at ${bufferInfo.end} is needed`,
);
this.clearWaitingFragment();
}
@@ -304,13 +304,13 @@ class AudioStreamController
this.afterBufferFlushed(
bufferable,
ElementaryStreamTypes.AUDIO,
PlaylistLevelType.AUDIO
PlaylistLevelType.AUDIO,
);
}
const bufferInfo = this.getFwdBufferInfo(
bufferable,
PlaylistLevelType.AUDIO
PlaylistLevelType.AUDIO,
);
if (bufferInfo === null) {
return;
@@ -325,7 +325,7 @@ class AudioStreamController
const mainBufferInfo = this.getFwdBufferInfo(
this.videoBuffer ? this.videoBuffer : this.media,
PlaylistLevelType.MAIN
PlaylistLevelType.MAIN,
);
const bufferLen = bufferInfo.len;
const maxBufLen = this.getMaxBufferLength(mainBufferInfo?.len);
@@ -344,7 +344,7 @@ class AudioStreamController
// if everything is buffered from pos to start or if audio buffer upfront, let's seek to start
if (bufferInfo.end > start || bufferInfo.nextStart) {
this.log(
'Alt audio track ahead of main track, seek to start of alt audio track'
'Alt audio track ahead of main track, seek to start of alt audio track',
);
media.currentTime = start + 0.05;
}
@@ -370,7 +370,7 @@ class AudioStreamController
trackDetails,
bufferInfo,
PlaylistLevelType.MAIN,
maxBufLen
maxBufLen,
);
}
if (!frag) {
@@ -413,7 +413,7 @@ class AudioStreamController
}
return Math.min(
Math.max(maxConfigBuffer, mainBufferLength),
this.config.maxMaxBufferLength
this.config.maxMaxBufferLength,
);
}
@@ -424,7 +424,7 @@ class AudioStreamController
onAudioTracksUpdated(
event: Events.AUDIO_TRACKS_UPDATED,
{ audioTracks }: AudioTracksUpdatedData
{ audioTracks }: AudioTracksUpdatedData,
) {
this.resetTransmuxer();
this.levels = audioTracks.map((mediaPlaylist) => new Level(mediaPlaylist));
@@ -432,7 +432,7 @@ class AudioStreamController
onAudioTrackSwitching(
event: Events.AUDIO_TRACK_SWITCHING,
data: AudioTrackSwitchingData
data: AudioTrackSwitchingData,
) {
// if any URL found on new audio track, it is an alternate audio track
const altAudio = !!data.url;
@@ -505,7 +505,7 @@ class AudioStreamController
newDetails.lastPartSn
? `[part-${newDetails.lastPartSn}-${newDetails.lastPartIndex}]`
: ''
},duration:${newDetails.totalduration}`
},duration:${newDetails.totalduration}`,
);
const track = levels[trackId];
@@ -555,7 +555,7 @@ class AudioStreamController
const { config, trackId, levels } = this;
if (!levels) {
this.warn(
`Audio tracks were reset while fragment load was in progress. Fragment ${frag.sn} of level ${frag.level} will not be buffered`
`Audio tracks were reset while fragment load was in progress. Fragment ${frag.sn} of level ${frag.level} will not be buffered`,
);
return;
}
@@ -580,7 +580,7 @@ class AudioStreamController
this.hls,
PlaylistLevelType.AUDIO,
this._handleTransmuxComplete.bind(this),
this._handleTransmuxerFlush.bind(this)
this._handleTransmuxerFlush.bind(this),
);
}
@@ -600,7 +600,7 @@ class AudioStreamController
frag.stats.chunkCount,
payload.byteLength,
partIndex,
partial
partial,
);
transmuxer.push(
payload,
@@ -612,11 +612,11 @@ class AudioStreamController
details.totalduration,
accurateTimeOffset,
chunkMeta,
initPTS
initPTS,
);
} else {
this.log(
`Unknown video PTS for cc ${frag.cc}, waiting for video PTS before demuxing audio frag ${frag.sn} of [${details.startSN} ,${details.endSN}],track ${trackId}`
`Unknown video PTS for cc ${frag.cc}, waiting for video PTS before demuxing audio frag ${frag.sn} of [${details.startSN} ,${details.endSN}],track ${trackId}`,
);
const { cache } = (this.waitingData = this.waitingData || {
frag,
@@ -678,7 +678,7 @@ class AudioStreamController
this.state
}, audioSwitch: ${
this.switchingTrack ? this.switchingTrack.name : 'false'
}`
}`,
);
return;
}
@@ -745,7 +745,7 @@ class AudioStreamController
private onBufferFlushed(
event: Events.BUFFER_FLUSHED,
{ type }: BufferFlushedData
{ type }: BufferFlushedData,
) {
if (type === ElementaryStreamTypes.AUDIO) {
this.bufferFlushed = true;
@@ -792,7 +792,7 @@ class AudioStreamController
level,
initSegment.tracks,
mapFragment,
chunkMeta
chunkMeta,
);
hls.trigger(Events.FRAG_PARSING_INIT_SEGMENT, {
frag: mapFragment,
@@ -816,7 +816,7 @@ class AudioStreamController
startPTS,
endPTS,
startDTS,
endDTS
endDTS,
);
this.bufferFragmentData(audio, frag, part, chunkMeta);
}
@@ -828,7 +828,7 @@ class AudioStreamController
frag,
details,
},
id3
id3,
);
hls.trigger(Events.FRAG_PARSING_METADATA, emittedID3);
}
@@ -839,7 +839,7 @@ class AudioStreamController
frag,
details,
},
text
text,
);
hls.trigger(Events.FRAG_PARSING_USERDATA, emittedText);
}
@@ -849,7 +849,7 @@ class AudioStreamController
currentLevel: Level,
tracks: TrackSet,
frag: Fragment,
chunkMeta: ChunkMetadata
chunkMeta: ChunkMetadata,
) {
if (this.state !== State.PARSING) {
return;
@@ -869,7 +869,7 @@ class AudioStreamController
const variantAudioCodecs = currentLevel.audioCodec;
this.log(
`Init audio buffer, container:${track.container}, codecs[level/parsed]=[${variantAudioCodecs}/${track.codec}]`
`Init audio buffer, container:${track.container}, codecs[level/parsed]=[${variantAudioCodecs}/${track.codec}]`,
);
// SourceBuffer will use track.levelCodec if defined
if (variantAudioCodecs && variantAudioCodecs.split(',').length === 1) {
@@ -895,7 +895,7 @@ class AudioStreamController
protected loadFragment(
frag: Fragment,
track: Level,
targetBufferTime: number
targetBufferTime: number,
) {
// only load if fragment is not loaded or if in audio switch
const fragState = this.fragmentTracker.getState(frag);
@@ -911,7 +911,7 @@ class AudioStreamController
this._loadInitSegment(frag, track);
} else if (track.details?.live && !this.initPTS[frag.cc]) {
this.log(
`Waiting for video PTS in continuity counter ${frag.cc} of live stream before loading audio fragment ${frag.sn} of level ${this.trackId}`
`Waiting for video PTS in continuity counter ${frag.cc} of live stream before loading audio fragment ${frag.sn} of level ${this.trackId}`,
);
this.state = State.WAITING_INIT_PTS;
const mainDetails = this.mainDetails;
+12 -12
View File
@@ -66,21 +66,21 @@ class AudioTrackController extends BasePlaylistController {
protected onManifestParsed(
event: Events.MANIFEST_PARSED,
data: ManifestParsedData
data: ManifestParsedData,
): void {
this.tracks = data.audioTracks || [];
}
protected onAudioTrackLoaded(
event: Events.AUDIO_TRACK_LOADED,
data: AudioTrackLoadedData
data: AudioTrackLoadedData,
): void {
const { id, groupId, details } = data;
const trackInActiveGroup = this.tracksInGroup[id];
if (!trackInActiveGroup || trackInActiveGroup.groupId !== groupId) {
this.warn(
`Track with id:${id} and group:${groupId} not found in active group ${trackInActiveGroup.groupId}`
`Track with id:${id} and group:${groupId} not found in active group ${trackInActiveGroup.groupId}`,
);
return;
}
@@ -88,7 +88,7 @@ class AudioTrackController extends BasePlaylistController {
const curDetails = trackInActiveGroup.details;
trackInActiveGroup.details = data.details;
this.log(
`audio-track ${id} "${trackInActiveGroup.name}" lang:${trackInActiveGroup.lang} group:${groupId} loaded [${details.startSN}-${details.endSN}]`
`audio-track ${id} "${trackInActiveGroup.name}" lang:${trackInActiveGroup.lang} group:${groupId} loaded [${details.startSN}-${details.endSN}]`,
);
if (id === this.trackId) {
@@ -98,14 +98,14 @@ class AudioTrackController extends BasePlaylistController {
protected onLevelLoading(
event: Events.LEVEL_LOADING,
data: LevelLoadingData
data: LevelLoadingData,
): void {
this.switchLevel(data.level);
}
protected onLevelSwitching(
event: Events.LEVEL_SWITCHING,
data: LevelSwitchingData
data: LevelSwitchingData,
): void {
this.switchLevel(data.level);
}
@@ -122,7 +122,7 @@ class AudioTrackController extends BasePlaylistController {
this.groupId = audioGroupId || null;
const audioTracks = this.tracks.filter(
(track): boolean => !audioGroupId || track.groupId === audioGroupId
(track): boolean => !audioGroupId || track.groupId === audioGroupId,
);
// Disable selectDefaultTrack if there are no default tracks
@@ -136,7 +136,7 @@ class AudioTrackController extends BasePlaylistController {
this.tracksInGroup = audioTracks;
const audioTracksUpdated: AudioTracksUpdatedData = { audioTracks };
this.log(
`Updating audio tracks, ${audioTracks.length} track(s) found in group:${audioGroupId}`
`Updating audio tracks, ${audioTracks.length} track(s) found in group:${audioGroupId}`,
);
this.hls.trigger(Events.AUDIO_TRACKS_UPDATED, audioTracksUpdated);
@@ -197,7 +197,7 @@ class AudioTrackController extends BasePlaylistController {
const track = tracks[newId];
const { groupId, name } = track;
this.log(
`Switching to audio-track ${newId} "${name}" lang:${track.lang} group:${groupId}`
`Switching to audio-track ${newId} "${name}" lang:${track.lang} group:${groupId}`,
);
this.trackId = newId;
this.currentTrack = track;
@@ -222,7 +222,7 @@ class AudioTrackController extends BasePlaylistController {
this.setAudioTrack(trackId);
} else {
const error = new Error(
`No track found for running audio group-ID: ${this.groupId} track count: ${audioTracks.length}`
`No track found for running audio group-ID: ${this.groupId} track count: ${audioTracks.length}`,
);
this.warn(error.message);
@@ -271,13 +271,13 @@ class AudioTrackController extends BasePlaylistController {
url = hlsUrlParameters.addDirectives(url);
} catch (error) {
this.warn(
`Could not construct new URL with HLS Delivery Directives: ${error}`
`Could not construct new URL with HLS Delivery Directives: ${error}`,
);
}
}
// track not retrieved yet, or live playlist we need to (re)load it
this.log(
`loading audio-track playlist ${id} "${audioTrack.name}" lang:${audioTrack.lang} group:${groupId}`
`loading audio-track playlist ${id} "${audioTrack.name}" lang:${audioTrack.lang} group:${groupId}`,
);
this.clearTimer();
this.hls.trigger(Events.AUDIO_TRACK_LOADING, {
+22 -22
View File
@@ -54,7 +54,7 @@ export default class BasePlaylistController implements NetworkComponentAPI {
protected switchParams(
playlistUri: string,
previous: LevelDetails | undefined
previous: LevelDetails | undefined,
): HlsUrlParameters | undefined {
const renditionReports = previous?.renditionReports;
if (renditionReports) {
@@ -66,7 +66,7 @@ export default class BasePlaylistController implements NetworkComponentAPI {
uri = new self.URL(attr.URI, previous.url).href;
} catch (error) {
logger.warn(
`Could not construct new URL for Rendition Report: ${error}`
`Could not construct new URL for Rendition Report: ${error}`,
);
uri = attr.URI || '';
}
@@ -86,7 +86,7 @@ export default class BasePlaylistController implements NetworkComponentAPI {
if (this.hls.config.lowLatencyMode) {
const currentGoal = Math.min(
previous.age - previous.partTarget,
previous.targetduration
previous.targetduration,
);
if (part >= 0 && currentGoal > previous.partTarget) {
part += 1;
@@ -95,7 +95,7 @@ export default class BasePlaylistController implements NetworkComponentAPI {
return new HlsUrlParameters(
msn,
part >= 0 ? part : undefined,
HlsSkip.No
HlsSkip.No,
);
}
}
@@ -109,7 +109,7 @@ export default class BasePlaylistController implements NetworkComponentAPI {
}
protected shouldLoadPlaylist(
playlist: Level | MediaPlaylist | null | undefined
playlist: Level | MediaPlaylist | null | undefined,
): boolean {
return (
this.canLoad &&
@@ -120,7 +120,7 @@ export default class BasePlaylistController implements NetworkComponentAPI {
}
protected shouldReloadPlaylist(
playlist: Level | MediaPlaylist | null | undefined
playlist: Level | MediaPlaylist | null | undefined,
): boolean {
return (
this.timer === -1 &&
@@ -132,7 +132,7 @@ export default class BasePlaylistController implements NetworkComponentAPI {
protected playlistLoaded(
index: number,
data: LevelLoadedData | AudioTrackLoadedData | TrackLoadedData,
previousDetails?: LevelDetails
previousDetails?: LevelDetails,
) {
const { details, stats } = data;
@@ -152,7 +152,7 @@ export default class BasePlaylistController implements NetworkComponentAPI {
details.advanced
? 'REFRESHED ' + details.lastPartSn + '-' + details.lastPartIndex
: 'MISSED'
}`
}`,
);
}
// Merge live playlists to adjust fragment starts and fill in delta playlist skipped segments
@@ -187,14 +187,14 @@ export default class BasePlaylistController implements NetworkComponentAPI {
const cdnAge = lastAdvanced + details.ageHeader;
let currentGoal = Math.min(
cdnAge - details.partTarget,
details.targetduration * 1.5
details.targetduration * 1.5,
);
if (currentGoal > 0) {
if (previousDetails && currentGoal > previousDetails.tuneInGoal) {
// If we attempted to get the next or latest playlist update, but currentGoal increased,
// then we either can't catchup, or the "age" header cannot be trusted.
this.warn(
`CDN Tune-in goal increased from: ${previousDetails.tuneInGoal} to: ${currentGoal} with playlist age: ${details.age}`
`CDN Tune-in goal increased from: ${previousDetails.tuneInGoal} to: ${currentGoal} with playlist age: ${details.age}`,
);
currentGoal = 0;
} else {
@@ -202,7 +202,7 @@ export default class BasePlaylistController implements NetworkComponentAPI {
msn += segments;
if (part !== undefined) {
const parts = Math.round(
(currentGoal % details.targetduration) / details.partTarget
(currentGoal % details.targetduration) / details.partTarget,
);
part += parts;
}
@@ -210,8 +210,8 @@ export default class BasePlaylistController implements NetworkComponentAPI {
`CDN Tune-in age: ${
details.ageHeader
}s last advanced ${lastAdvanced.toFixed(
2
)}s goal: ${currentGoal} skip sn ${segments} to part ${part}`
2,
)}s goal: ${currentGoal} skip sn ${segments} to part ${part}`,
);
}
details.tuneInGoal = currentGoal;
@@ -220,7 +220,7 @@ export default class BasePlaylistController implements NetworkComponentAPI {
details,
data.deliveryDirectives,
msn,
part
part,
);
if (lowLatencyMode || !lastPart) {
this.loadPlaylist(deliveryDirectives);
@@ -231,7 +231,7 @@ export default class BasePlaylistController implements NetworkComponentAPI {
details,
data.deliveryDirectives,
msn,
part
part,
);
}
const bufferInfo = this.hls.mainForwardBufferInfo;
@@ -239,7 +239,7 @@ export default class BasePlaylistController implements NetworkComponentAPI {
const distanceToLiveEdgeMs = (details.edge - position) * 1000;
const reloadInterval = computeReloadInterval(
details,
distanceToLiveEdgeMs
distanceToLiveEdgeMs,
);
if (details.updated && now > this.requestScheduled + reloadInterval) {
this.requestScheduled = stats.loading.start;
@@ -262,8 +262,8 @@ export default class BasePlaylistController implements NetworkComponentAPI {
estimatedTimeUntilUpdate = Math.max(0, estimatedTimeUntilUpdate);
this.log(
`reload live playlist ${index} in ${Math.round(
estimatedTimeUntilUpdate
)} ms`
estimatedTimeUntilUpdate,
)} ms`,
);
// this.log(
// `live reload ${details.updated ? 'REFRESHED' : 'MISSED'}
@@ -283,7 +283,7 @@ export default class BasePlaylistController implements NetworkComponentAPI {
this.timer = self.setTimeout(
() => this.loadPlaylist(deliveryDirectives),
estimatedTimeUntilUpdate
estimatedTimeUntilUpdate,
);
} else {
this.clearTimer();
@@ -294,7 +294,7 @@ export default class BasePlaylistController implements NetworkComponentAPI {
details: LevelDetails,
previousDeliveryDirectives: HlsUrlParameters | null,
msn?: number,
part?: number
part?: number,
): HlsUrlParameters {
let skip = getSkipValue(details, msn);
if (previousDeliveryDirectives?.skip && details.deltaUpdateFailed) {
@@ -326,7 +326,7 @@ export default class BasePlaylistController implements NetworkComponentAPI {
this.warn(
`Retrying playlist loading ${retryCount + 1}/${
retryConfig.maxNumRetry
} after "${errorDetails}" without delivery-directives`
} after "${errorDetails}" without delivery-directives`,
);
this.loadPlaylist();
} else {
@@ -336,7 +336,7 @@ export default class BasePlaylistController implements NetworkComponentAPI {
this.warn(
`Retrying playlist loading ${retryCount + 1}/${
retryConfig.maxNumRetry
} after "${errorDetails}" in ${delay}ms`
} after "${errorDetails}" in ${delay}ms`,
);
}
// `levelRetry = true` used to inform other controllers that a retry is happening
+87 -87
View File
@@ -109,7 +109,7 @@ export default class BaseStreamController
fragmentTracker: FragmentTracker,
keyLoader: KeyLoader,
logPrefix: string,
playlistType: PlaylistLevelType
playlistType: PlaylistLevelType,
) {
super();
this.playlistType = playlistType;
@@ -152,7 +152,7 @@ export default class BaseStreamController
protected _streamEnded(
bufferInfo: BufferInfo,
levelDetails: LevelDetails
levelDetails: LevelDetails,
): boolean {
// If playlist is live, there is another buffered range after the current range, nothing buffered, media is detached,
// of nothing loading/loaded return false
@@ -176,7 +176,7 @@ export default class BaseStreamController
// part mismatches for independent audio and video playlists/segments.
const lastPartBuffered = BufferHelper.isBuffered(
this.media,
lastPart.start + lastPart.duration / 2
lastPart.start + lastPart.duration / 2,
);
return lastPartBuffered;
}
@@ -194,7 +194,7 @@ export default class BaseStreamController
protected onMediaAttached(
event: Events.MEDIA_ATTACHED,
data: MediaAttachedData
data: MediaAttachedData,
) {
const media = (this.media = this.mediaBuffer = data.media);
this.onvseeking = this.onMediaSeeking.bind(this) as EventListener;
@@ -235,13 +235,13 @@ export default class BaseStreamController
const bufferInfo = BufferHelper.bufferInfo(
mediaBuffer ? mediaBuffer : media,
currentTime,
config.maxBufferHole
config.maxBufferHole,
);
this.log(
`media seeking to ${
Number.isFinite(currentTime) ? currentTime.toFixed(3) : currentTime
}, state: ${state}`
}, state: ${state}`,
);
if (this.state === State.ENDED) {
@@ -263,7 +263,7 @@ export default class BaseStreamController
if (currentTime < fragStartOffset || pastFragment) {
if (pastFragment && fragCurrent.loader) {
this.log(
'seeking outside of buffer while fragment load in progress, cancel fragment load'
'seeking outside of buffer while fragment load in progress, cancel fragment load',
);
fragCurrent.abortRequests();
this.resetLoadingState();
@@ -279,7 +279,7 @@ export default class BaseStreamController
currentTime,
Infinity,
this.playlistType,
true
true,
);
this.lastCurrentTime = currentTime;
@@ -301,7 +301,7 @@ export default class BaseStreamController
protected onManifestLoaded(
event: Events.MANIFEST_LOADED,
data: ManifestLoadedData
data: ManifestLoadedData,
): void {
this.startTimeOffset = data.startTimeOffset;
this.initPTS = [];
@@ -338,7 +338,7 @@ export default class BaseStreamController
protected loadFragment(
frag: Fragment,
level: Level,
targetBufferTime: number
targetBufferTime: number,
) {
this._loadFragForPlayback(frag, level, targetBufferTime);
}
@@ -346,16 +346,16 @@ export default class BaseStreamController
private _loadFragForPlayback(
frag: Fragment,
level: Level,
targetBufferTime: number
targetBufferTime: number,
) {
const progressCallback: FragmentLoadProgressCallback = (
data: FragLoadedData
data: FragLoadedData,
) => {
if (this.fragContextChanged(frag)) {
this.warn(
`Fragment ${frag.sn}${
data.part ? ' p: ' + data.part.index : ''
} of level ${frag.level} was dropped during download.`
} of level ${frag.level} was dropped during download.`,
);
this.fragmentTracker.removeFragment(frag);
return;
@@ -407,11 +407,11 @@ export default class BaseStreamController
const playlistType = frag.type as PlaylistLevelType;
const bufferedInfo = this.getFwdBufferInfo(
this.mediaBuffer,
playlistType
playlistType,
);
const minForwardBufferLength = Math.max(
frag.duration,
bufferedInfo ? bufferedInfo.len : this.config.maxBufferLength
bufferedInfo ? bufferedInfo.len : this.config.maxBufferLength,
);
if (this.reduceMaxBufferLength(minForwardBufferLength)) {
fragmentTracker.removeFragment(frag);
@@ -436,7 +436,7 @@ export default class BaseStreamController
protected flushMainBuffer(
startOffset: number,
endOffset: number,
type: SourceBufferName | null = null
type: SourceBufferName | null = null,
) {
if (!(startOffset - endOffset)) {
return;
@@ -476,7 +476,7 @@ export default class BaseStreamController
.decrypt(
new Uint8Array(payload),
decryptData.key.buffer,
decryptData.iv.buffer
decryptData.iv.buffer,
)
.catch((err) => {
hls.trigger(Events.ERROR, {
@@ -551,7 +551,7 @@ export default class BaseStreamController
media
? TimeRanges.toString(BufferHelper.getBuffered(media))
: '(detached)'
})`
})`,
);
if (frag.sn !== 'initSegment') {
if (frag.type !== PlaylistLevelType.SUBTITLE) {
@@ -565,7 +565,7 @@ export default class BaseStreamController
const level = this.levels?.[frag.level];
if (level?.fragmentError) {
this.log(
`Resetting level fragment error count of ${level.fragmentError} on frag buffered`
`Resetting level fragment error count of ${level.fragmentError} on frag buffered`,
);
level.fragmentError = 0;
}
@@ -605,26 +605,26 @@ export default class BaseStreamController
frag.stats.chunkCount + 1,
0,
part ? part.index : -1,
!complete
!complete,
);
transmuxer.flush(chunkMeta);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
protected _handleFragmentLoadProgress(
frag: PartsLoadedData | FragLoadedData
frag: PartsLoadedData | FragLoadedData,
) {}
protected _doFragLoad(
frag: Fragment,
level: Level,
targetBufferTime: number | null = null,
progressCallback?: FragmentLoadProgressCallback
progressCallback?: FragmentLoadProgressCallback,
): Promise<PartsLoadedData | FragLoadedData | null> {
const details = level?.details;
if (!this.levels || !details) {
throw new Error(
`frag load aborted, missing level${details ? '' : ' detail'}s`
`frag load aborted, missing level${details ? '' : ' detail'}s`,
);
}
@@ -633,7 +633,7 @@ export default class BaseStreamController
this.log(
`Loading key for ${frag.sn} of [${details.startSN}-${details.endSN}], ${
this.logPrefix === '[stream-controller]' ? 'level' : 'track'
} ${frag.level}`
} ${frag.level}`,
);
this.state = State.KEY_LOADING;
this.fragCurrent = frag;
@@ -649,7 +649,7 @@ export default class BaseStreamController
this.hls.trigger(Events.KEY_LOADING, { frag });
if (this.fragCurrent === null) {
keyLoadingPromise = Promise.reject(
new Error(`frag load aborted, context changed in KEY_LOADING`)
new Error(`frag load aborted, context changed in KEY_LOADING`),
);
}
} else if (!frag.encrypted && details.encryptedFragments.length) {
@@ -674,8 +674,8 @@ export default class BaseStreamController
}] parts [0-${partIndex}-${partList.length - 1}] ${
this.logPrefix === '[stream-controller]' ? 'level' : 'track'
}: ${frag.level}, target: ${parseFloat(
targetBufferTime.toFixed(3)
)}`
targetBufferTime.toFixed(3),
)}`,
);
this.nextLoadPosition = part.start + part.duration;
this.state = State.FRAG_LOADING;
@@ -693,7 +693,7 @@ export default class BaseStreamController
frag,
part,
level,
progressCallback
progressCallback,
);
})
.catch((error) => this.handleFragLoadError(error));
@@ -702,7 +702,7 @@ export default class BaseStreamController
frag,
part,
level,
progressCallback
progressCallback,
).catch((error: LoadError) => this.handleFragLoadError(error));
}
this.hls.trigger(Events.FRAG_LOADING, {
@@ -713,8 +713,8 @@ export default class BaseStreamController
if (this.fragCurrent === null) {
return Promise.reject(
new Error(
`frag load aborted, context changed in FRAG_LOADING parts`
)
`frag load aborted, context changed in FRAG_LOADING parts`,
),
);
}
return result;
@@ -733,7 +733,7 @@ export default class BaseStreamController
details ? 'of [' + details.startSN + '-' + details.endSN + '] ' : ''
}${this.logPrefix === '[stream-controller]' ? 'level' : 'track'}: ${
frag.level
}, target: ${parseFloat(targetBufferTime.toFixed(3))}`
}, target: ${parseFloat(targetBufferTime.toFixed(3))}`,
);
// Don't update nextLoadPosition for fragments which are not buffered
if (Number.isFinite(frag.sn as number) && !this.bitrateTest) {
@@ -759,7 +759,7 @@ export default class BaseStreamController
result = Promise.all([
this.fragmentLoader.load(
frag,
dataOnProgress ? progressCallback : undefined
dataOnProgress ? progressCallback : undefined,
),
keyLoadingPromise,
])
@@ -774,7 +774,7 @@ export default class BaseStreamController
this.hls.trigger(Events.FRAG_LOADING, { frag, targetBufferTime });
if (this.fragCurrent === null) {
return Promise.reject(
new Error(`frag load aborted, context changed in FRAG_LOADING`)
new Error(`frag load aborted, context changed in FRAG_LOADING`),
);
}
return result;
@@ -784,7 +784,7 @@ export default class BaseStreamController
frag: Fragment,
fromPart: Part,
level: Level,
progressCallback: FragmentLoadProgressCallback
progressCallback: FragmentLoadProgressCallback,
): Promise<PartsLoadedData | null> {
return new Promise(
(resolve: ResolveFragLoaded, reject: RejectFragLoaded) => {
@@ -813,7 +813,7 @@ export default class BaseStreamController
.catch(reject);
};
loadPart(fromPart);
}
},
);
}
@@ -859,13 +859,13 @@ export default class BaseStreamController
}
protected getCurrentContext(
chunkMeta: ChunkMetadata
chunkMeta: ChunkMetadata,
): { frag: Fragment; part: Part | null; level: Level } | null {
const { levels, fragCurrent } = this;
const { level: levelIndex, sn, part: partIndex } = chunkMeta;
if (!levels?.[levelIndex]) {
this.warn(
`Levels object was unset while buffering fragment ${sn} of level ${levelIndex}. The current chunk will not be buffered.`
`Levels object was unset while buffering fragment ${sn} of level ${levelIndex}. The current chunk will not be buffered.`,
);
return null;
}
@@ -888,7 +888,7 @@ export default class BaseStreamController
frag: Fragment,
part: Part | null,
chunkMeta: ChunkMetadata,
noBacktracking?: boolean
noBacktracking?: boolean,
) {
if (!data || this.state !== State.PARSING) {
return;
@@ -940,11 +940,11 @@ export default class BaseStreamController
const fragDuration = frag.duration;
const segmentFraction = Math.min(
this.config.maxFragLookUpTolerance * 2,
fragDuration * 0.25
fragDuration * 0.25,
);
const start = Math.max(
Math.min(frag.start - segmentFraction, bufferInfo.end - segmentFraction),
currentTime + segmentFraction
currentTime + segmentFraction,
);
if (frag.start - start > segmentFraction) {
this.flushMainBuffer(start, frag.start);
@@ -953,7 +953,7 @@ export default class BaseStreamController
protected getFwdBufferInfo(
bufferable: Bufferable | null,
type: PlaylistLevelType
type: PlaylistLevelType,
): BufferInfo | null {
const pos = this.getLoadPosition();
if (!Number.isFinite(pos)) {
@@ -965,7 +965,7 @@ export default class BaseStreamController
protected getFwdBufferInfoAtPos(
bufferable: Bufferable | null,
pos: number,
type: PlaylistLevelType
type: PlaylistLevelType,
): BufferInfo | null {
const {
config: { maxBufferHole },
@@ -978,7 +978,7 @@ export default class BaseStreamController
return BufferHelper.bufferInfo(
bufferable,
pos,
Math.max(bufferInfo.nextStart, maxBufferHole)
Math.max(bufferInfo.nextStart, maxBufferHole),
);
}
}
@@ -991,7 +991,7 @@ export default class BaseStreamController
if (levelBitrate) {
maxBufLen = Math.max(
(8 * config.maxBufferSize) / levelBitrate,
config.maxBufferLength
config.maxBufferLength,
);
} else {
maxBufLen = config.maxBufferLength;
@@ -1013,11 +1013,11 @@ export default class BaseStreamController
protected getAppendedFrag(
position: number,
playlistType: PlaylistLevelType = PlaylistLevelType.MAIN
playlistType: PlaylistLevelType = PlaylistLevelType.MAIN,
): Fragment | null {
const fragOrPart = this.fragmentTracker.getAppendedFrag(
position,
PlaylistLevelType.MAIN
PlaylistLevelType.MAIN,
);
if (fragOrPart && 'fragment' in fragOrPart) {
return fragOrPart.fragment;
@@ -1027,7 +1027,7 @@ export default class BaseStreamController
protected getNextFragment(
pos: number,
levelDetails: LevelDetails
levelDetails: LevelDetails,
): Fragment | null {
const fragments = levelDetails.fragments;
const fragLen = fragments.length;
@@ -1045,7 +1045,7 @@ export default class BaseStreamController
const initialLiveManifestSize = config.initialLiveManifestSize;
if (fragLen < initialLiveManifestSize) {
this.warn(
`Not enough fragments to start playback (have: ${fragLen}, need: ${initialLiveManifestSize})`
`Not enough fragments to start playback (have: ${fragLen}, need: ${initialLiveManifestSize})`,
);
return null;
}
@@ -1094,12 +1094,12 @@ export default class BaseStreamController
levelDetails: LevelDetails,
bufferInfo: BufferInfo,
playlistType: PlaylistLevelType,
maxBufLen: number
maxBufLen: number,
): Fragment | null {
const gapStart = frag.gap;
const nextFragment = this.getNextFragment(
this.nextLoadPosition,
levelDetails
levelDetails,
);
if (nextFragment === null) {
return nextFragment;
@@ -1110,7 +1110,7 @@ export default class BaseStreamController
const nextbufferInfo = this.getFwdBufferInfoAtPos(
this.mediaBuffer ? this.mediaBuffer : this.media,
bufferInfo.nextStart,
playlistType
playlistType,
);
if (
nextbufferInfo !== null &&
@@ -1118,7 +1118,7 @@ export default class BaseStreamController
) {
// Returning here might result in not finding an audio and video candiate to skip to
this.log(
`buffer full after gaps in "${playlistType}" playlist starting at sn: ${frag.sn}`
`buffer full after gaps in "${playlistType}" playlist starting at sn: ${frag.sn}`,
);
return null;
}
@@ -1138,7 +1138,7 @@ export default class BaseStreamController
getNextPart(
partList: Part[],
frag: Fragment,
targetBufferTime: number
targetBufferTime: number,
): number {
let nextPart = -1;
let contiguous = false;
@@ -1165,7 +1165,7 @@ export default class BaseStreamController
private loadedEndOfParts(
partList: Part[],
targetBufferTime: number
targetBufferTime: number,
): boolean {
const lastPart = partList[partList.length - 1];
return lastPart && targetBufferTime > lastPart.start && lastPart.loaded;
@@ -1178,7 +1178,7 @@ export default class BaseStreamController
*/
protected getInitialLiveFragment(
levelDetails: LevelDetails,
fragments: Array<Fragment>
fragments: Array<Fragment>,
): Fragment | null {
const fragPrevious = this.fragPrevious;
let frag: Fragment | null = null;
@@ -1186,12 +1186,12 @@ export default class BaseStreamController
if (levelDetails.hasProgramDateTime) {
// Prefer using PDT, because it can be accurate enough to choose the correct fragment without knowing the level sliding
this.log(
`Live playlist, switching playlist, load frag with same PDT: ${fragPrevious.programDateTime}`
`Live playlist, switching playlist, load frag with same PDT: ${fragPrevious.programDateTime}`,
);
frag = findFragmentByPDT(
fragments,
fragPrevious.endProgramDateTime,
this.config.maxFragLookUpTolerance
this.config.maxFragLookUpTolerance,
);
}
if (!frag) {
@@ -1208,7 +1208,7 @@ export default class BaseStreamController
this.log(
`Live playlist, switching playlist, load frag with next SN: ${
frag!.sn
}`
}`,
);
}
}
@@ -1218,7 +1218,7 @@ export default class BaseStreamController
frag = findFragWithCC(fragments, fragPrevious.cc);
if (frag) {
this.log(
`Live playlist, switching playlist, load frag with same CC: ${frag.sn}`
`Live playlist, switching playlist, load frag with same CC: ${frag.sn}`,
);
}
}
@@ -1230,7 +1230,7 @@ export default class BaseStreamController
frag = this.getFragmentAtPosition(
liveStart,
this.bitrateTest ? levelDetails.fragmentEnd : levelDetails.edge,
levelDetails
levelDetails,
);
}
}
@@ -1244,7 +1244,7 @@ export default class BaseStreamController
protected getFragmentAtPosition(
bufferEnd: number,
end: number,
levelDetails: LevelDetails
levelDetails: LevelDetails,
): Fragment | null {
const { config } = this;
let { fragPrevious } = this;
@@ -1273,7 +1273,7 @@ export default class BaseStreamController
fragPrevious,
fragments,
bufferEnd,
lookupTolerance
lookupTolerance,
);
} else {
// reach end of playlist
@@ -1349,10 +1349,10 @@ export default class BaseStreamController
if (media.readyState) {
this.warn(
`Playback: ${currentTime.toFixed(
3
3,
)} is located too far from the end of live sliding playlist: ${end}, reset currentTime to : ${liveSyncPosition.toFixed(
3
)}`
3,
)}`,
);
media.currentTime = liveSyncPosition;
}
@@ -1362,7 +1362,7 @@ export default class BaseStreamController
protected alignPlaylists(
details: LevelDetails,
previousDetails?: LevelDetails
previousDetails?: LevelDetails,
): number {
const { levels, levelLastLoaded, fragPrevious } = this;
const lastLevel: Level | null =
@@ -1386,7 +1386,7 @@ export default class BaseStreamController
previousDetails ? previousDetails.startSN : 'na'
}->${details.startSN} prev-sn: ${
fragPrevious ? fragPrevious.sn : 'na'
} fragments: ${length}`
} fragments: ${length}`,
);
return alignedSlidingStart;
}
@@ -1425,12 +1425,12 @@ export default class BaseStreamController
}
startPosition = Math.min(
Math.max(sliding, startPosition),
sliding + details.totalduration
sliding + details.totalduration,
);
this.log(
`Start time offset ${startTimeOffset} found in ${
offsetInMultivariantPlaylist ? 'multivariant' : 'media'
} playlist, adjust startPosition to ${startPosition}`
} playlist, adjust startPosition to ${startPosition}`,
);
this.startPosition = startPosition;
} else if (details.live) {
@@ -1463,7 +1463,7 @@ export default class BaseStreamController
this.warn(
`Fragment ${frag.sn}${part ? ' part ' + part.index : ''} of level ${
frag.level
} was aborted`
} was aborted`,
);
this.resetFragmentLoading(frag);
}
@@ -1481,7 +1481,7 @@ export default class BaseStreamController
protected onFragmentOrKeyLoadError(
filterType: PlaylistLevelType,
data: ErrorData
data: ErrorData,
) {
if (data.chunkMeta && !data.frag) {
const context = this.getCurrentContext(data.chunkMeta);
@@ -1496,7 +1496,7 @@ export default class BaseStreamController
}
if (this.fragContextChanged(frag)) {
this.warn(
`Frag load error must match current frag to retry ${frag.url} > ${this.fragCurrent?.url}`
`Frag load error must match current frag to retry ${frag.url} > ${this.fragCurrent?.url}`,
);
return;
}
@@ -1519,7 +1519,7 @@ export default class BaseStreamController
data.details
}, retrying loading ${retryCount + 1}/${
retryConfig.maxNumRetry
} in ${delay}ms`
} in ${delay}ms`,
);
errorAction.resolved = true;
this.retryDate = self.performance.now() + delay;
@@ -1536,7 +1536,7 @@ export default class BaseStreamController
}
} else {
logger.warn(
`${data.details} reached or exceeded max retry (${retryCount})`
`${data.details} reached or exceeded max retry (${retryCount})`,
);
return;
}
@@ -1557,7 +1557,7 @@ export default class BaseStreamController
const playlistType = data.parent as PlaylistLevelType;
const bufferedInfo = this.getFwdBufferInfo(
this.mediaBuffer,
playlistType
playlistType,
);
// 0.5 : tolerance needed as some browsers stalls playback before reaching buffered end
// reduce max buf len if current position is buffered
@@ -1571,7 +1571,7 @@ export default class BaseStreamController
// this happens on IE/Edge, refer to https://github.com/video-dev/hls.js/pull/708
// in that case flush the whole audio buffer to recover
this.warn(
`Buffer full error while media.currentTime is not buffered, flush ${playlistType} buffer`
`Buffer full error while media.currentTime is not buffered, flush ${playlistType} buffer`,
);
}
if (data.frag) {
@@ -1602,7 +1602,7 @@ export default class BaseStreamController
protected afterBufferFlushed(
media: Bufferable,
bufferType: SourceBufferName,
playlistType: PlaylistLevelType
playlistType: PlaylistLevelType,
) {
if (!media) {
return;
@@ -1613,7 +1613,7 @@ export default class BaseStreamController
this.fragmentTracker.detectEvictedFragments(
bufferType,
bufferedTimeRanges,
playlistType
playlistType,
);
if (this.state === State.ENDED) {
this.resetLoadingState();
@@ -1646,7 +1646,7 @@ export default class BaseStreamController
protected resetWhenMissingContext(chunkMeta: ChunkMetadata) {
this.warn(
`The loading context changed while buffering fragment ${chunkMeta.sn} of level ${chunkMeta.level}. This chunk will not be buffered.`
`The loading context changed while buffering fragment ${chunkMeta.sn} of level ${chunkMeta.level}. This chunk will not be buffered.`,
);
this.removeUnbufferedFrags();
this.resetStartWhenNotLoaded(this.levelLastLoaded ?? chunkMeta.level);
@@ -1659,7 +1659,7 @@ export default class BaseStreamController
Infinity,
this.playlistType,
false,
true
true,
);
}
@@ -1667,7 +1667,7 @@ export default class BaseStreamController
frag: Fragment,
part: Part | null,
level: Level,
partial: boolean
partial: boolean,
) {
const details = level.details as LevelDetails;
if (!details) {
@@ -1684,7 +1684,7 @@ export default class BaseStreamController
// The new transmuxer will be configured with a time offset matching the next fragment start,
// preventing the timeline from shifting.
this.warn(
`Could not parse fragment ${frag.sn} ${type} duration reliably (${parsedDuration})`
`Could not parse fragment ${frag.sn} ${type} duration reliably (${parsedDuration})`,
);
return result || false;
}
@@ -1696,7 +1696,7 @@ export default class BaseStreamController
info.startPTS,
info.endPTS,
info.startDTS,
info.endDTS
info.endDTS,
);
this.hls.trigger(Events.LEVEL_PTS_UPDATED, {
details,
@@ -1711,11 +1711,11 @@ export default class BaseStreamController
}
return result;
},
false
false,
);
if (!parsed && this.transmuxer?.error === null) {
const error = new Error(
`Found no media in fragment ${frag.sn} of level ${frag.level} resetting transmuxer to fallback to playlist timing`
`Found no media in fragment ${frag.sn} of level ${frag.level} resetting transmuxer to fallback to playlist timing`,
);
if (level.fragmentError === 0) {
// Mark and track the odd empty segment as a gap to avoid reloading
@@ -1755,7 +1755,7 @@ export default class BaseStreamController
this.fragmentTracker.removeAllFragments();
this.resetTransmuxer();
this.resetStartWhenNotLoaded(
this.levelLastLoaded ?? this.fragCurrent?.level ?? 0
this.levelLastLoaded ?? this.fragCurrent?.level ?? 0,
);
this.resetLoadingState();
}
+28 -28
View File
@@ -157,7 +157,7 @@ export default class BufferController implements ComponentAPI {
protected onManifestParsed(
event: Events.MANIFEST_PARSED,
data: ManifestParsedData
data: ManifestParsedData,
) {
// in case of alt audio 2 BUFFER_CODECS events will be triggered, one per stream controller
// sourcebuffers will be created all at once when the expected nb of tracks will be reached
@@ -173,7 +173,7 @@ export default class BufferController implements ComponentAPI {
protected onMediaAttaching(
event: Events.MEDIA_ATTACHING,
data: MediaAttachingData
data: MediaAttachingData,
) {
const media = (this.media = data.media);
if (media && MediaSource) {
@@ -203,7 +203,7 @@ export default class BufferController implements ComponentAPI {
mediaSource.endOfStream();
} catch (err) {
this.warn(
`onMediaDetaching: ${err.message} while calling endOfStream`
`onMediaDetaching: ${err.message} while calling endOfStream`,
);
}
}
@@ -268,7 +268,7 @@ export default class BufferController implements ComponentAPI {
protected onBufferCodecs(
event: Events.BUFFER_CODECS,
data: BufferCodecsData
data: BufferCodecsData,
) {
const sourceBufferCount = this.getSourceBufferTypes().length;
@@ -281,16 +281,16 @@ export default class BufferController implements ComponentAPI {
data[trackName];
const currentCodedFull = pickMostCompleteCodecName(
track.codec,
track.levelCodec
track.levelCodec,
);
const currentCodec = currentCodedFull.replace(
VIDEO_CODEC_PROFILE_REPLACE,
'$1'
'$1',
);
let trackCodec = pickMostCompleteCodecName(codec, levelCodec);
const nextCodec = trackCodec.replace(
VIDEO_CODEC_PROFILE_REPLACE,
'$1'
'$1',
);
if (currentCodec !== nextCodec) {
if (trackName.slice(0, 5) === 'audio') {
@@ -322,7 +322,7 @@ export default class BufferController implements ComponentAPI {
this.bufferCodecEventsExpected = Math.max(
this.bufferCodecEventsExpected - 1,
0
0,
);
if (this.mediaSource && this.mediaSource.readyState === 'open') {
this.checkPendingTracks();
@@ -352,7 +352,7 @@ export default class BufferController implements ComponentAPI {
protected onBufferAppending(
event: Events.BUFFER_APPENDING,
eventData: BufferAppendingData
eventData: BufferAppendingData,
) {
const { hls, operationQueue, tracks } = this;
const { data, type, frag, part, chunkMeta } = eventData;
@@ -394,7 +394,7 @@ export default class BufferController implements ComponentAPI {
const delta = fragStart - sb.timestampOffset;
if (Math.abs(delta) >= 0.1) {
this.log(
`Updating audio SourceBuffer timestampOffset to ${fragStart} (delta: ${delta}) sn: ${frag.sn})`
`Updating audio SourceBuffer timestampOffset to ${fragStart} (delta: ${delta}) sn: ${frag.sn})`,
);
sb.timestampOffset = fragStart;
}
@@ -463,7 +463,7 @@ export default class BufferController implements ComponentAPI {
browser is able to evict some data from sourcebuffer. Retrying can help recover.
*/
this.warn(
`Failed ${appendErrorCount}/${hls.config.appendErrorMaxRetry} times to append segment in "${type}" sourceBuffer`
`Failed ${appendErrorCount}/${hls.config.appendErrorMaxRetry} times to append segment in "${type}" sourceBuffer`,
);
if (appendErrorCount >= hls.config.appendErrorMaxRetry) {
event.fatal = true;
@@ -477,7 +477,7 @@ export default class BufferController implements ComponentAPI {
protected onBufferFlushing(
event: Events.BUFFER_FLUSHING,
data: BufferFlushingData
data: BufferFlushingData,
) {
const { operationQueue } = this;
const flushOperation = (type: SourceBufferName): BufferOperation => ({
@@ -485,7 +485,7 @@ export default class BufferController implements ComponentAPI {
this,
type,
data.startOffset,
data.endOffset
data.endOffset,
),
onStart: () => {
// logger.debug(`[buffer-controller]: Started flushing ${data.startOffset} -> ${data.endOffset} for ${type} Source Buffer`);
@@ -542,7 +542,7 @@ export default class BufferController implements ComponentAPI {
if (buffersAppendedTo.length === 0) {
this.warn(
`Fragments must have at least one ElementaryStreamType set. type: ${frag.type} level: ${frag.level} sn: ${frag.sn}`
`Fragments must have at least one ElementaryStreamType set. type: ${frag.type} level: ${frag.level} sn: ${frag.sn}`,
);
}
@@ -581,7 +581,7 @@ export default class BufferController implements ComponentAPI {
if (!mediaSource || mediaSource.readyState !== 'open') {
if (mediaSource) {
this.log(
`Could not call mediaSource.endOfStream(). mediaSource.readyState: ${mediaSource.readyState}`
`Could not call mediaSource.endOfStream(). mediaSource.readyState: ${mediaSource.readyState}`,
);
}
return;
@@ -595,7 +595,7 @@ export default class BufferController implements ComponentAPI {
protected onLevelUpdated(
event: Events.LEVEL_UPDATED,
{ details }: LevelUpdatedData
{ details }: LevelUpdatedData,
) {
if (!details.fragments.length) {
return;
@@ -659,7 +659,7 @@ export default class BufferController implements ComponentAPI {
buffered.end(buffered.length - 1) - currentTime < targetDuration * 2
) {
this.log(
`Cannot flush ${type} back buffer while SourceBuffer is in ended state`
`Cannot flush ${type} back buffer while SourceBuffer is in ended state`,
);
return;
}
@@ -720,7 +720,7 @@ export default class BufferController implements ComponentAPI {
const start = Math.max(0, fragments[0].start);
const end = Math.max(start, start + levelDetails.totalduration);
this.log(
`Media Source duration is set to ${mediaSource.duration}. Setting seekable range to ${start}-${end}.`
`Media Source duration is set to ${mediaSource.duration}. Setting seekable range to ${start}-${end}.`,
);
mediaSource.setLiveSeekableRange(start, end);
}
@@ -750,7 +750,7 @@ export default class BufferController implements ComponentAPI {
});
} else {
const error = new Error(
'could not create source buffer for media codec(s)'
'could not create source buffer for media codec(s)',
);
this.hls.trigger(Events.ERROR, {
type: ErrorTypes.MEDIA_ERROR,
@@ -773,7 +773,7 @@ export default class BufferController implements ComponentAPI {
const track = tracks[trackName as keyof TrackSet];
if (!track) {
throw Error(
`source buffer exists for track ${trackName}, however track does not`
`source buffer exists for track ${trackName}, however track does not`,
);
}
// use levelCodec as first priority
@@ -844,7 +844,7 @@ export default class BufferController implements ComponentAPI {
const { media, _objectUrl } = this;
if (media && media.src !== _objectUrl) {
this.error(
`Media element src was set while attaching MediaSource (${_objectUrl} > ${media.src})`
`Media element src was set while attaching MediaSource (${_objectUrl} > ${media.src})`,
);
}
};
@@ -889,13 +889,13 @@ export default class BufferController implements ComponentAPI {
private removeExecutor(
type: SourceBufferName,
startOffset: number,
endOffset: number
endOffset: number,
) {
const { media, mediaSource, operationQueue, sourceBuffer } = this;
const sb = sourceBuffer[type];
if (!media || !mediaSource || !sb) {
this.warn(
`Attempting to remove from the ${type} SourceBuffer, but it does not exist`
`Attempting to remove from the ${type} SourceBuffer, but it does not exist`,
);
operationQueue.shiftAndExecuteNext(type);
return;
@@ -911,7 +911,7 @@ export default class BufferController implements ComponentAPI {
if (removeEnd > removeStart && (!sb.ending || sb.ended)) {
sb.ended = false;
this.log(
`Removing [${removeStart},${removeEnd}] from the ${type} SourceBuffer`
`Removing [${removeStart},${removeEnd}] from the ${type} SourceBuffer`,
);
sb.remove(removeStart, removeEnd);
} else {
@@ -926,7 +926,7 @@ export default class BufferController implements ComponentAPI {
if (!sb) {
if (!this.pendingTracks[type]) {
throw new Error(
`Attempting to append to the ${type} SourceBuffer, but it does not exist`
`Attempting to append to the ${type} SourceBuffer, but it does not exist`,
);
}
return;
@@ -941,7 +941,7 @@ export default class BufferController implements ComponentAPI {
// upon completion, since we already do it here
private blockBuffers(
onUnblocked: () => void,
buffers: Array<SourceBufferName> = this.getSourceBufferTypes()
buffers: Array<SourceBufferName> = this.getSourceBufferTypes(),
) {
if (!buffers.length) {
this.log('Blocking operation requested, but no SourceBuffers exist');
@@ -952,7 +952,7 @@ export default class BufferController implements ComponentAPI {
// logger.debug(`[buffer-controller]: Blocking ${buffers} SourceBuffer`);
const blockingOperations = buffers.map((type) =>
operationQueue.appendBlocker(type as SourceBufferName)
operationQueue.appendBlocker(type as SourceBufferName),
);
Promise.all(blockingOperations).then(() => {
// logger.debug(`[buffer-controller]: Blocking operation resolved; unblocking ${buffers} SourceBuffer`);
@@ -976,7 +976,7 @@ export default class BufferController implements ComponentAPI {
private addBufferListener(
type: SourceBufferName,
event: string,
fn: Function
fn: Function,
) {
const buffer = this.sourceBuffer[type];
if (!buffer) {
+2 -2
View File
@@ -21,7 +21,7 @@ export default class BufferOperationQueue {
public append(
operation: BufferOperation,
type: SourceBufferName,
pending?: boolean
pending?: boolean,
) {
const queue = this.queues[type];
queue.push(operation);
@@ -62,7 +62,7 @@ export default class BufferOperationQueue {
operation.execute();
} catch (error) {
logger.warn(
`[buffer-operation-queue]: Exception executing "${type}" SourceBuffer operation: ${error}`
`[buffer-operation-queue]: Exception executing "${type}" SourceBuffer operation: ${error}`,
);
operation.onError(error);
+10 -10
View File
@@ -78,7 +78,7 @@ class CapLevelController implements ComponentAPI {
protected onFpsDropLevelCapping(
event: Events.FPS_DROP_LEVEL_CAPPING,
data: FPSDropLevelCappingData
data: FPSDropLevelCappingData,
) {
// Don't add a restricted level more than once
const level = this.hls.levels[data.droppedLevel];
@@ -93,7 +93,7 @@ class CapLevelController implements ComponentAPI {
protected onMediaAttaching(
event: Events.MEDIA_ATTACHING,
data: MediaAttachingData
data: MediaAttachingData,
) {
this.media = data.media instanceof HTMLVideoElement ? data.media : null;
this.clientRect = null;
@@ -104,7 +104,7 @@ class CapLevelController implements ComponentAPI {
protected onManifestParsed(
event: Events.MANIFEST_PARSED,
data: ManifestParsedData
data: ManifestParsedData,
) {
const hls = this.hls;
this.restrictedLevels = [];
@@ -117,7 +117,7 @@ class CapLevelController implements ComponentAPI {
private onLevelsUpdated(
event: Events.LEVELS_UPDATED,
data: LevelsUpdatedData
data: LevelsUpdatedData,
) {
if (this.timer && Number.isFinite(this.autoLevelCapping)) {
this.detectPlayerSize();
@@ -128,7 +128,7 @@ class CapLevelController implements ComponentAPI {
// to the first level
protected onBufferCodecs(
event: Events.BUFFER_CODECS,
data: BufferCodecsData
data: BufferCodecsData,
) {
const hls = this.hls;
if (hls.config.capLevelToPlayerSize && data.video) {
@@ -153,7 +153,7 @@ class CapLevelController implements ComponentAPI {
const maxLevel = this.getMaxLevel(levels.length - 1);
if (maxLevel !== this.autoLevelCapping) {
logger.log(
`Setting autoLevelCapping to ${maxLevel}: ${levels[maxLevel].height}p@${levels[maxLevel].bitrate} for media ${this.mediaWidth}x${this.mediaHeight}`
`Setting autoLevelCapping to ${maxLevel}: ${levels[maxLevel].height}p@${levels[maxLevel].bitrate} for media ${this.mediaWidth}x${this.mediaHeight}`,
);
}
hls.autoLevelCapping = maxLevel;
@@ -180,14 +180,14 @@ class CapLevelController implements ComponentAPI {
}
const validLevels = levels.filter(
(level, index) => this.isLevelAllowed(level) && index <= capLevelIndex
(level, index) => this.isLevelAllowed(level) && index <= capLevelIndex,
);
this.clientRect = null;
return CapLevelController.getMaxLevelByMediaSize(
validLevels,
this.mediaWidth,
this.mediaHeight
this.mediaHeight,
);
}
@@ -274,7 +274,7 @@ class CapLevelController implements ComponentAPI {
static getMaxLevelByMediaSize(
levels: Array<Level>,
width: number,
height: number
height: number,
): number {
if (!levels?.length) {
return -1;
@@ -284,7 +284,7 @@ class CapLevelController implements ComponentAPI {
// to determine whether we've chosen the greatest bandwidth for the media's dimensions
const atGreatestBandwidth = (
curLevel: Level,
nextLevel: Level | undefined
nextLevel: Level | undefined,
) => {
if (!nextLevel) {
return true;
+5 -5
View File
@@ -83,7 +83,7 @@ export default class CMCDController implements ComponentAPI {
private onMediaAttached(
event: Events.MEDIA_ATTACHED,
data: MediaAttachedData
data: MediaAttachedData,
) {
this.media = data.media;
this.media.addEventListener('waiting', this.onWaiting);
@@ -104,7 +104,7 @@ export default class CMCDController implements ComponentAPI {
private onBufferCreated(
event: Events.BUFFER_CREATED,
data: BufferCreatedData
data: BufferCreatedData,
) {
this.audioBuffer = data.tracks.audio?.buffer;
this.videoBuffer = data.tracks.video?.buffer;
@@ -297,7 +297,7 @@ export default class CMCDController implements ComponentAPI {
const info = BufferHelper.bufferInfo(
buffer,
media.currentTime,
this.config.maxBufferHole
this.config.maxBufferHole,
);
return info.len * 1000;
@@ -337,7 +337,7 @@ export default class CMCDController implements ComponentAPI {
load(
context: PlaylistLoaderContext,
config: LoaderConfiguration,
callbacks: LoaderCallbacks<PlaylistLoaderContext>
callbacks: LoaderCallbacks<PlaylistLoaderContext>,
) {
apply(context);
this.loader.load(context, config, callbacks);
@@ -379,7 +379,7 @@ export default class CMCDController implements ComponentAPI {
load(
context: FragmentLoaderContext,
config: LoaderConfiguration,
callbacks: LoaderCallbacks<FragmentLoaderContext>
callbacks: LoaderCallbacks<FragmentLoaderContext>,
) {
apply(context);
this.loader.load(context, config, callbacks);
+18 -18
View File
@@ -96,7 +96,7 @@ export default class ContentSteeringController implements NetworkComponentAPI {
if (this.updated) {
const ttl = Math.max(
this.timeToLoad * 1000 - (performance.now() - this.updated),
0
0,
);
this.scheduleRefresh(this.uri, ttl);
} else {
@@ -148,7 +148,7 @@ export default class ContentSteeringController implements NetworkComponentAPI {
private onManifestLoaded(
event: Events.MANIFEST_LOADED,
data: ManifestLoadedData
data: ManifestLoadedData,
) {
const { contentSteering } = data;
if (contentSteering === null) {
@@ -163,7 +163,7 @@ export default class ContentSteeringController implements NetworkComponentAPI {
private onManifestParsed(
event: Events.MANIFEST_PARSED,
data: ManifestParsedData
data: ManifestParsedData,
) {
this.audioTracks = data.audioTracks;
this.subtitleTracks = data.subtitleTracks;
@@ -203,14 +203,14 @@ export default class ContentSteeringController implements NetworkComponentAPI {
if (pathwayLevels.length === 0) {
const pathwayId = levels[0].pathwayId;
this.log(
`No levels found in Pathway ${this.pathwayId}. Setting initial Pathway to "${pathwayId}"`
`No levels found in Pathway ${this.pathwayId}. Setting initial Pathway to "${pathwayId}"`,
);
pathwayLevels = this.getLevelsForPathway(pathwayId);
this.pathwayId = pathwayId;
}
if (pathwayLevels.length !== levels.length) {
this.log(
`Found ${pathwayLevels.length}/${levels.length} levels in Pathway "${this.pathwayId}"`
`Found ${pathwayLevels.length}/${levels.length} levels in Pathway "${this.pathwayId}"`,
);
return pathwayLevels;
}
@@ -261,7 +261,7 @@ export default class ContentSteeringController implements NetworkComponentAPI {
levelAfterChange.bitrate !== selectedLevel.bitrate
) {
this.log(
`Unstable Pathways change from bitrate ${selectedLevel.bitrate} to ${levelAfterChange.bitrate}`
`Unstable Pathways change from bitrate ${selectedLevel.bitrate} to ${levelAfterChange.bitrate}`,
);
}
this.hls.nextLoadLevel = selectedIndex;
@@ -295,7 +295,7 @@ export default class ContentSteeringController implements NetworkComponentAPI {
baseLevel.uri,
baseLevel.attrs['STABLE-VARIANT-ID'],
'PER-VARIANT-URIS',
uriReplacement
uriReplacement,
);
const attributes = new AttrList(baseLevel.attrs);
attributes['PATHWAY-ID'] = cloneId;
@@ -316,20 +316,20 @@ export default class ContentSteeringController implements NetworkComponentAPI {
addGroupId(clonedLevel, 'audio', clonedAudioGroupId);
addGroupId(clonedLevel, 'text', clonedSubtitleGroupId);
return clonedLevel;
}
},
);
levels.push(...clonedVariants);
cloneRenditionGroups(
this.audioTracks,
audioGroupCloneMap,
uriReplacement,
cloneId
cloneId,
);
cloneRenditionGroups(
this.subtitleTracks,
subtitleGroupCloneMap,
uriReplacement,
cloneId
cloneId,
);
});
}
@@ -377,7 +377,7 @@ export default class ContentSteeringController implements NetworkComponentAPI {
response: LoaderResponse,
stats: LoaderStats,
context: LoaderContext,
networkDetails: any
networkDetails: any,
) => {
this.log(`Loaded steering manifest: "${url}"`);
const steeringData = response.data as SteeringManifest;
@@ -398,7 +398,7 @@ export default class ContentSteeringController implements NetworkComponentAPI {
} catch (error) {
this.enabled = false;
this.log(
`Failed to parse Steering Manifest RELOAD-URI: ${reloadUri}`
`Failed to parse Steering Manifest RELOAD-URI: ${reloadUri}`,
);
return;
}
@@ -423,10 +423,10 @@ export default class ContentSteeringController implements NetworkComponentAPI {
error: { code: number; text: string },
context: LoaderContext,
networkDetails: any,
stats: LoaderStats
stats: LoaderStats,
) => {
this.log(
`Error loading steering manifest: ${error.code} ${error.text} (${context.url})`
`Error loading steering manifest: ${error.code} ${error.text} (${context.url})`,
);
this.stopLoad();
if (error.code === 410) {
@@ -452,7 +452,7 @@ export default class ContentSteeringController implements NetworkComponentAPI {
onTimeout: (
stats: LoaderStats,
context: LoaderContext,
networkDetails: any
networkDetails: any,
) => {
this.log(`Timeout loading steering manifest (${context.url})`);
this.scheduleRefresh(this.uri || context.url);
@@ -475,7 +475,7 @@ function cloneRenditionGroups(
tracks: MediaPlaylist[] | null,
groupCloneMap: Record<string, string>,
uriReplacement: UriReplacement,
cloneId: string
cloneId: string,
) {
if (!tracks) {
return;
@@ -491,7 +491,7 @@ function cloneRenditionGroups(
track.url,
track.attrs['STABLE-RENDITION-ID'],
'PER-RENDITION-URIS',
uriReplacement
uriReplacement,
);
clonedTrack.groupId = clonedTrack.attrs['GROUP-ID'] =
groupCloneMap[audioGroupId];
@@ -506,7 +506,7 @@ function performUriReplacement(
uri: string,
stableId: string | undefined,
perOptionKey: 'PER-VARIANT-URIS' | 'PER-RENDITION-URIS',
uriReplacement: UriReplacement
uriReplacement: UriReplacement,
): string {
const {
HOST: host,
+98 -98
View File
@@ -148,7 +148,7 @@ class EMEController implements ComponentAPI {
}
throw new Error(
`no license server URL configured for key-system "${keySystem}"`
`no license server URL configured for key-system "${keySystem}"`,
);
}
@@ -164,7 +164,7 @@ class EMEController implements ComponentAPI {
}
private attemptKeySystemAccess(
keySystemsToAttempt: KeySystems[]
keySystemsToAttempt: KeySystems[],
): Promise<{ keySystem: KeySystems; mediaKeys: MediaKeys }> {
const levels = this.hls.levels;
const uniqueCodec = (value: string | undefined, i, a): value is string =>
@@ -185,7 +185,7 @@ class EMEController implements ComponentAPI {
keySystem: KeySystems;
mediaKeys: MediaKeys;
}) => void,
reject: (Error) => void
reject: (Error) => void,
) => {
const attempt = (keySystems) => {
const keySystem = keySystems.shift();
@@ -205,20 +205,20 @@ class EMEController implements ComponentAPI {
error,
fatal: true,
},
error.message
)
error.message,
),
);
}
});
};
attempt(keySystemsToAttempt);
}
},
);
}
private requestMediaKeySystemAccess(
keySystem: KeySystems,
supportedConfigurations: MediaKeySystemConfiguration[]
supportedConfigurations: MediaKeySystemConfiguration[],
): Promise<MediaKeySystemAccess> {
const { requestMediaKeySystemAccessFunc } = this.config;
if (!(typeof requestMediaKeySystemAccessFunc === 'function')) {
@@ -238,14 +238,14 @@ class EMEController implements ComponentAPI {
private getMediaKeysPromise(
keySystem: KeySystems,
audioCodecs: string[],
videoCodecs: string[]
videoCodecs: string[],
): Promise<MediaKeys> {
// This can throw, but is caught in event handler callpath
const mediaKeySystemConfigs = getSupportedMediaKeySystemConfigurations(
keySystem,
audioCodecs,
videoCodecs,
this.config.drmSystemOptions
this.config.drmSystemOptions,
);
const keySystemAccessPromises: KeySystemAccessPromises =
this.keySystemAccessPromises[keySystem];
@@ -253,12 +253,12 @@ class EMEController implements ComponentAPI {
if (!keySystemAccess) {
this.log(
`Requesting encrypted media "${keySystem}" key-system access with config: ${JSON.stringify(
mediaKeySystemConfigs
)}`
mediaKeySystemConfigs,
)}`,
);
keySystemAccess = this.requestMediaKeySystemAccess(
keySystem,
mediaKeySystemConfigs
mediaKeySystemConfigs,
);
const keySystemAccessPromises: KeySystemAccessPromises =
(this.keySystemAccessPromises[keySystem] = {
@@ -266,12 +266,12 @@ class EMEController implements ComponentAPI {
});
keySystemAccess.catch((error) => {
this.log(
`Failed to obtain access to key-system "${keySystem}": ${error}`
`Failed to obtain access to key-system "${keySystem}": ${error}`,
);
});
return keySystemAccess.then((mediaKeySystemAccess) => {
this.log(
`Access for key-system "${mediaKeySystemAccess.keySystem}" obtained`
`Access for key-system "${mediaKeySystemAccess.keySystem}" obtained`,
);
const certificateRequest = this.fetchServerCertificate(keySystem);
@@ -286,7 +286,7 @@ class EMEController implements ComponentAPI {
return this.setMediaKeysServerCertificate(
mediaKeys,
keySystem,
certificate
certificate,
);
}
return mediaKeys;
@@ -295,7 +295,7 @@ class EMEController implements ComponentAPI {
keySystemAccessPromises.mediaKeys.catch((error) => {
this.error(
`Failed to create media-keys for "${keySystem}"}: ${error}`
`Failed to create media-keys for "${keySystem}"}: ${error}`,
);
});
@@ -316,8 +316,8 @@ class EMEController implements ComponentAPI {
}): MediaKeySessionContext {
this.log(
`Creating key-system session "${keySystem}" keyId: ${Hex.hexDump(
decryptdata.keyId! || []
)}`
decryptdata.keyId! || [],
)}`,
);
const mediaKeysSession = mediaKeys.createSession();
@@ -339,7 +339,7 @@ class EMEController implements ComponentAPI {
const decryptdata = mediaKeySessionContext.decryptdata;
if (decryptdata.pssh) {
const keySessionContext = this.createMediaKeySessionContext(
mediaKeySessionContext
mediaKeySessionContext,
);
const keyId = this.getKeyIdString(decryptdata);
const scheme = 'cenc';
@@ -348,7 +348,7 @@ class EMEController implements ComponentAPI {
keySessionContext,
scheme,
decryptdata.pssh,
'expired'
'expired',
);
} else {
this.warn(`Could not renew expired session. Missing pssh initData.`);
@@ -368,14 +368,14 @@ class EMEController implements ComponentAPI {
private updateKeySession(
mediaKeySessionContext: MediaKeySessionContext,
data: Uint8Array
data: Uint8Array,
): Promise<void> {
const keySession = mediaKeySessionContext.mediaKeysSession;
this.log(
`Updating key-session "${keySession.sessionId}" for keyID ${Hex.hexDump(
mediaKeySessionContext.decryptdata?.keyId! || []
mediaKeySessionContext.decryptdata?.keyId! || [],
)}
} (data length: ${data ? data.byteLength : data})`
} (data length: ${data ? data.byteLength : data})`,
);
return keySession.update(data);
}
@@ -386,7 +386,7 @@ class EMEController implements ComponentAPI {
this.log(
`Selecting key-system from fragment (sn: ${frag.sn} ${frag.type}: ${
frag.level
}) key formats ${keyFormats.join(', ')}`
}) key formats ${keyFormats.join(', ')}`,
);
this.keyFormatPromise = this.getKeyFormatPromise(keyFormats);
}
@@ -394,14 +394,14 @@ class EMEController implements ComponentAPI {
}
private getKeyFormatPromise(
keyFormats: KeySystemFormats[]
keyFormats: KeySystemFormats[],
): Promise<KeySystemFormats> {
return new Promise((resolve, reject) => {
const keySystemsInConfig = getKeySystemsForConfig(this.config);
const keySystemsToAttempt = keyFormats
.map(keySystemFormatToKeySystemDomain)
.filter(
(value) => !!value && keySystemsInConfig.indexOf(value) !== -1
(value) => !!value && keySystemsInConfig.indexOf(value) !== -1,
) as any as KeySystems[];
return this.getKeySystemSelectionPromise(keySystemsToAttempt)
.then(({ keySystem }) => {
@@ -410,7 +410,7 @@ class EMEController implements ComponentAPI {
resolve(keySystemFormat);
} else {
reject(
new Error(`Unable to find format for key-system "${keySystem}"`)
new Error(`Unable to find format for key-system "${keySystem}"`),
);
}
})
@@ -433,7 +433,7 @@ class EMEController implements ComponentAPI {
({ keySystem, mediaKeys }) => {
this.throwIfDestroyed();
this.log(
`Handle encrypted media sn: ${data.frag.sn} ${data.frag.type}: ${data.frag.level} using key ${keyDetails}`
`Handle encrypted media sn: ${data.frag.sn} ${data.frag.type}: ${data.frag.level} using key ${keyDetails}`,
);
return this.attemptSetMediaKeys(keySystem, mediaKeys).then(() => {
@@ -448,10 +448,10 @@ class EMEController implements ComponentAPI {
keySessionContext,
scheme,
decryptdata.pssh,
'playlist-key'
'playlist-key',
);
});
}
},
);
keySessionContextPromise.catch((error) => this.handleError(error));
@@ -484,13 +484,13 @@ class EMEController implements ComponentAPI {
}
private getKeySystemForKeyPromise(
decryptdata: LevelKey
decryptdata: LevelKey,
): Promise<{ keySystem: KeySystems; mediaKeys: MediaKeys }> {
const keyId = this.getKeyIdString(decryptdata);
const mediaKeySessionContext = this.keyIdToKeySessionPromise[keyId];
if (!mediaKeySessionContext) {
const keySystem = keySystemFormatToKeySystemDomain(
decryptdata.keyFormat as KeySystemFormats
decryptdata.keyFormat as KeySystemFormats,
);
const keySystemsToAttempt = keySystem
? [keySystem]
@@ -501,7 +501,7 @@ class EMEController implements ComponentAPI {
}
private getKeySystemSelectionPromise(
keySystemsToAttempt: KeySystems[]
keySystemsToAttempt: KeySystems[],
): Promise<{ keySystem: KeySystems; mediaKeys: MediaKeys }> | never {
if (!keySystemsToAttempt.length) {
keySystemsToAttempt = getKeySystemsForConfig(this.config);
@@ -515,7 +515,7 @@ class EMEController implements ComponentAPI {
},
`Missing key-system license configuration options ${JSON.stringify({
drmSystems: this.config.drmSystems,
})}`
})}`,
);
}
return this.attemptKeySystemAccess(keySystemsToAttempt);
@@ -565,7 +565,7 @@ class EMEController implements ComponentAPI {
keyId = psshInfo.data.subarray(8, 24);
}
keySystemDomain = keySystemIdToKeySystemDomain(
psshInfo.systemId as KeySystemIds
psshInfo.systemId as KeySystemIds,
);
}
@@ -599,7 +599,7 @@ class EMEController implements ComponentAPI {
keyContext,
initDataType,
initData,
'encrypted-event-key-match'
'encrypted-event-key-match',
);
});
break;
@@ -615,7 +615,7 @@ class EMEController implements ComponentAPI {
const decryptdata = new LevelKey(
'ISO-23001-7',
keyIdHex,
keySystemToKeySystemFormat(keySystem) ?? ''
keySystemToKeySystemFormat(keySystem) ?? '',
);
decryptdata.pssh = new Uint8Array(initData);
decryptdata.keyId = keyId as Uint8Array;
@@ -630,10 +630,10 @@ class EMEController implements ComponentAPI {
keySessionContext,
initDataType,
initData,
'encrypted-event-no-match'
'encrypted-event-no-match',
);
});
}
},
);
}
keySessionContextPromise.catch((error) => this.handleError(error));
@@ -645,7 +645,7 @@ class EMEController implements ComponentAPI {
private attemptSetMediaKeys(
keySystem: KeySystems,
mediaKeys: MediaKeys
mediaKeys: MediaKeys,
): Promise<void> {
const queue = this.setMediaKeysQueue.slice();
@@ -655,7 +655,7 @@ class EMEController implements ComponentAPI {
const setMediaKeysPromise = Promise.all(queue).then(() => {
if (!this.media) {
throw new Error(
'Attempted to set mediaKeys without media element attached'
'Attempted to set mediaKeys without media element attached',
);
}
return this.media.setMediaKeys(mediaKeys);
@@ -665,7 +665,7 @@ class EMEController implements ComponentAPI {
this.log(`Media-keys set for "${keySystem}"`);
queue.push(setMediaKeysPromise!);
this.setMediaKeysQueue = this.setMediaKeysQueue.filter(
(p) => queue.indexOf(p) === -1
(p) => queue.indexOf(p) === -1,
);
});
}
@@ -678,7 +678,7 @@ class EMEController implements ComponentAPI {
| 'playlist-key'
| 'encrypted-event-key-match'
| 'encrypted-event-no-match'
| 'expired'
| 'expired',
): Promise<MediaKeySessionContext> | never {
const generateRequestFilter =
this.config.drmSystems?.[context.keySystem]?.generateRequest;
@@ -688,7 +688,7 @@ class EMEController implements ComponentAPI {
generateRequestFilter.call(this.hls, initDataType, initData, context);
if (!mappedInitData) {
throw new Error(
'Invalid response from configured generateRequest filter'
'Invalid response from configured generateRequest filter',
);
}
initDataType = mappedInitData.initDataType;
@@ -712,7 +712,7 @@ class EMEController implements ComponentAPI {
this.log(
`Generating key-session request for "${reason}": ${keyId} (init data type: ${initDataType} length: ${
initData ? initData.byteLength : null
})`
})`,
);
const licenseStatus = new EventEmitter();
@@ -725,7 +725,7 @@ class EMEController implements ComponentAPI {
}
const { messageType, message } = event;
this.log(
`"${messageType}" message event for session "${keySession.sessionId}" message size: ${message.byteLength}`
`"${messageType}" message event for session "${keySession.sessionId}" message size: ${message.byteLength}`,
);
if (
messageType === 'license-request' ||
@@ -746,7 +746,7 @@ class EMEController implements ComponentAPI {
};
context.mediaKeysSession.onkeystatuseschange = (
event: MediaKeyMessageEvent
event: MediaKeyMessageEvent,
) => {
const keySession = context.mediaKeysSession;
if (!keySession) {
@@ -777,8 +777,8 @@ class EMEController implements ComponentAPI {
details: ErrorDetails.KEY_SYSTEM_STATUS_OUTPUT_RESTRICTED,
fatal: false,
},
'HDCP level output restricted'
)
'HDCP level output restricted',
),
);
} else if (keyStatus === 'internal-error') {
reject(
@@ -788,8 +788,8 @@ class EMEController implements ComponentAPI {
details: ErrorDetails.KEY_SYSTEM_STATUS_INTERNAL_ERROR,
fatal: true,
},
`key status changed to "${keyStatus}"`
)
`key status changed to "${keyStatus}"`,
),
);
} else if (keyStatus === 'expired') {
reject(new Error('key expired while generating request'));
@@ -797,14 +797,14 @@ class EMEController implements ComponentAPI {
this.warn(`unhandled key status change "${keyStatus}"`);
}
});
}
},
);
return context.mediaKeysSession
.generateRequest(initDataType, initData)
.then(() => {
this.log(
`Request generated for key-session "${context.mediaKeysSession?.sessionId}" keyId: ${keyId}`
`Request generated for key-session "${context.mediaKeysSession?.sessionId}" keyId: ${keyId}`,
);
})
.catch((error) => {
@@ -815,7 +815,7 @@ class EMEController implements ComponentAPI {
error,
fatal: false,
},
`Error generating key-session request: ${error}`
`Error generating key-session request: ${error}`,
);
})
.then(() => keyUsablePromise)
@@ -837,18 +837,18 @@ class EMEController implements ComponentAPI {
`key status change "${status}" for keyStatuses keyId: ${Hex.hexDump(
'buffer' in keyId
? new Uint8Array(keyId.buffer, keyId.byteOffset, keyId.byteLength)
: new Uint8Array(keyId)
: new Uint8Array(keyId),
)} session keyId: ${Hex.hexDump(
new Uint8Array(mediaKeySessionContext.decryptdata.keyId || [])
)} uri: ${mediaKeySessionContext.decryptdata.uri}`
new Uint8Array(mediaKeySessionContext.decryptdata.keyId || []),
)} uri: ${mediaKeySessionContext.decryptdata.uri}`,
);
mediaKeySessionContext.keyStatus = status;
}
},
);
}
private fetchServerCertificate(
keySystem: KeySystems
keySystem: KeySystems,
): Promise<BufferSource | void> {
const config = this.config;
const Loader = config.loader;
@@ -890,8 +890,8 @@ class EMEController implements ComponentAPI {
...response,
},
},
`"${keySystem}" certificate request failed (${url}). Status: ${response.code} (${response.text})`
)
`"${keySystem}" certificate request failed (${url}). Status: ${response.code} (${response.text})`,
),
);
},
onTimeout: (stats, context, networkDetails) => {
@@ -908,8 +908,8 @@ class EMEController implements ComponentAPI {
data: undefined,
},
},
`"${keySystem}" certificate request timed out (${url})`
)
`"${keySystem}" certificate request timed out (${url})`,
),
);
},
onAbort: (stats, context, networkDetails) => {
@@ -923,7 +923,7 @@ class EMEController implements ComponentAPI {
private setMediaKeysServerCertificate(
mediaKeys: MediaKeys,
keySystem: KeySystems,
cert: BufferSource
cert: BufferSource,
): Promise<MediaKeys> {
return new Promise((resolve, reject) => {
mediaKeys
@@ -932,7 +932,7 @@ class EMEController implements ComponentAPI {
this.log(
`setServerCertificate ${
success ? 'success' : 'not supported by CDM'
} (${cert?.byteLength}) on "${keySystem}"`
} (${cert?.byteLength}) on "${keySystem}"`,
);
resolve(mediaKeys);
})
@@ -946,8 +946,8 @@ class EMEController implements ComponentAPI {
error,
fatal: true,
},
error.message
)
error.message,
),
);
});
});
@@ -955,7 +955,7 @@ class EMEController implements ComponentAPI {
private renewLicense(
context: MediaKeySessionContext,
keyMessage: ArrayBuffer
keyMessage: ArrayBuffer,
): Promise<void> {
return this.requestLicense(context, new Uint8Array(keyMessage)).then(
(data: ArrayBuffer) => {
@@ -968,17 +968,17 @@ class EMEController implements ComponentAPI {
error,
fatal: true,
},
error.message
error.message,
);
}
},
);
}
},
);
}
private unpackPlayReadyKeyMessage(
xhr: XMLHttpRequest,
licenseChallenge: Uint8Array
licenseChallenge: Uint8Array,
): Uint8Array {
// On Edge, the raw license message is UTF-16-encoded XML. We need
// to unpack the Challenge element (base64-encoded string containing the
@@ -987,7 +987,7 @@ class EMEController implements ComponentAPI {
// For PlayReady CDMs, we need to dig the Challenge out of the XML.
const xmlString = String.fromCharCode.apply(
null,
new Uint16Array(licenseChallenge.buffer)
new Uint16Array(licenseChallenge.buffer),
);
if (!xmlString.includes('PlayReadyKeyMessage')) {
// This does not appear to be a wrapped message as on Edge. Some
@@ -999,7 +999,7 @@ class EMEController implements ComponentAPI {
}
const keyMessageXml = new DOMParser().parseFromString(
xmlString,
'application/xml'
'application/xml',
);
// Set request headers.
const headers = keyMessageXml.querySelectorAll('HttpHeader');
@@ -1026,7 +1026,7 @@ class EMEController implements ComponentAPI {
xhr: XMLHttpRequest,
url: string,
keysListItem: MediaKeySessionContext,
licenseChallenge: Uint8Array
licenseChallenge: Uint8Array,
): Promise<{ xhr: XMLHttpRequest; licenseChallenge: Uint8Array }> {
const licenseXhrSetup = this.config.licenseXhrSetup;
@@ -1046,7 +1046,7 @@ class EMEController implements ComponentAPI {
xhr,
url,
keysListItem,
licenseChallenge
licenseChallenge,
);
})
.catch((error: Error) => {
@@ -1062,7 +1062,7 @@ class EMEController implements ComponentAPI {
xhr,
url,
keysListItem,
licenseChallenge
licenseChallenge,
);
})
.then((licenseXhrSetupResult) => {
@@ -1079,7 +1079,7 @@ class EMEController implements ComponentAPI {
private requestLicense(
keySessionContext: MediaKeySessionContext,
licenseChallenge: Uint8Array
licenseChallenge: Uint8Array,
): Promise<ArrayBuffer> {
const keyLoadPolicy = this.config.keyLoadPolicy.default;
return new Promise((resolve, reject) => {
@@ -1098,7 +1098,7 @@ class EMEController implements ComponentAPI {
this.log(
`License received ${
data instanceof ArrayBuffer ? data.byteLength : data
}`
}`,
);
const licenseResponseCallback = this.config.licenseResponseCallback;
if (licenseResponseCallback) {
@@ -1107,7 +1107,7 @@ class EMEController implements ComponentAPI {
this.hls,
xhr,
url,
keySessionContext
keySessionContext,
);
} catch (error) {
this.error(error);
@@ -1136,18 +1136,18 @@ class EMEController implements ComponentAPI {
text: xhr.statusText,
},
},
`License Request XHR failed (${url}). Status: ${xhr.status} (${xhr.statusText})`
)
`License Request XHR failed (${url}). Status: ${xhr.status} (${xhr.statusText})`,
),
);
} else {
const attemptsLeft =
maxNumRetry - this._requestLicenseFailureCount + 1;
this.warn(
`Retrying license request, ${attemptsLeft} attempts left`
`Retrying license request, ${attemptsLeft} attempts left`,
);
this.requestLicense(keySessionContext, licenseChallenge).then(
resolve,
reject
reject,
);
}
}
@@ -1166,18 +1166,18 @@ class EMEController implements ComponentAPI {
if (keySessionContext.keySystem == KeySystems.PLAYREADY) {
licenseChallenge = this.unpackPlayReadyKeyMessage(
xhr,
licenseChallenge
licenseChallenge,
);
}
xhr.send(licenseChallenge);
}
},
);
});
}
private onMediaAttached(
event: Events.MEDIA_ATTACHED,
data: MediaAttachedData
data: MediaAttachedData,
) {
if (!this.config.emeEnabled) {
return;
@@ -1212,15 +1212,15 @@ class EMEController implements ComponentAPI {
EMEController.CDMCleanupPromise = Promise.all(
mediaKeysList
.map((mediaKeySessionContext) =>
this.removeSession(mediaKeySessionContext)
this.removeSession(mediaKeySessionContext),
)
.concat(
media?.setMediaKeys(null).catch((error) => {
this.log(
`Could not clear media keys: ${error}. media.src: ${media?.src}`
`Could not clear media keys: ${error}. media.src: ${media?.src}`,
);
})
)
}),
),
)
.then(() => {
if (keySessionCount) {
@@ -1230,7 +1230,7 @@ class EMEController implements ComponentAPI {
})
.catch((error) => {
this.log(
`Could not close sessions and clear media keys: ${error}. media.src: ${media?.src}`
`Could not close sessions and clear media keys: ${error}. media.src: ${media?.src}`,
);
});
}
@@ -1241,7 +1241,7 @@ class EMEController implements ComponentAPI {
private onManifestLoaded(
event: Events.MANIFEST_LOADED,
{ sessionKeys }: ManifestLoadedData
{ sessionKeys }: ManifestLoadedData,
) {
if (!sessionKeys || !this.config.emeEnabled) {
return;
@@ -1256,22 +1256,22 @@ class EMEController implements ComponentAPI {
}
return formats;
},
[]
[],
);
this.log(
`Selecting key-system from session-keys ${keyFormats.join(', ')}`
`Selecting key-system from session-keys ${keyFormats.join(', ')}`,
);
this.keyFormatPromise = this.getKeyFormatPromise(keyFormats);
}
}
private removeSession(
mediaKeySessionContext: MediaKeySessionContext
mediaKeySessionContext: MediaKeySessionContext,
): Promise<void> | void {
const { mediaKeysSession, licenseXhr } = mediaKeySessionContext;
if (mediaKeysSession) {
this.log(
`Remove licenses and keys and close session ${mediaKeysSession.sessionId}`
`Remove licenses and keys and close session ${mediaKeysSession.sessionId}`,
);
mediaKeysSession.onmessage = null;
mediaKeysSession.onkeystatuseschange = null;
@@ -1305,7 +1305,7 @@ class EMEKeyError extends Error {
public readonly data: ErrorData;
constructor(
data: Omit<ErrorData, 'error'> & { error?: Error },
message: string
message: string,
) {
super(message);
data.error ||= new Error(message);
+16 -16
View File
@@ -159,7 +159,7 @@ export default class ErrorController implements NetworkComponentAPI {
) {
data.errorAction = this.getPlaylistRetryOrSwitchAction(
data,
levelIndex
levelIndex,
);
} else {
// Escalate to fatal if not retrying or switching
@@ -173,7 +173,7 @@ export default class ErrorController implements NetworkComponentAPI {
if (typeof context?.level === 'number') {
data.errorAction = this.getPlaylistRetryOrSwitchAction(
data,
context.level
context.level,
);
}
return;
@@ -194,7 +194,7 @@ export default class ErrorController implements NetworkComponentAPI {
// otherwise allow playlist retry count to reach max error retries
data.errorAction = this.getPlaylistRetryOrSwitchAction(
data,
hls.loadLevel
hls.loadLevel,
);
data.errorAction.action =
NetworkErrorAction.SendAlternateToPenaltyBox;
@@ -224,7 +224,7 @@ export default class ErrorController implements NetworkComponentAPI {
case ErrorDetails.BUFFER_APPEND_ERROR:
data.errorAction = this.getLevelSwitchAction(
data,
data.level ?? hls.loadLevel
data.level ?? hls.loadLevel,
);
return;
case ErrorDetails.INTERNAL_EXCEPTION:
@@ -255,7 +255,7 @@ export default class ErrorController implements NetworkComponentAPI {
private getPlaylistRetryOrSwitchAction(
data: ErrorData,
levelIndex: number | null | undefined
levelIndex: number | null | undefined,
): IErrorAction {
const hls = this.hls;
const retryConfig = getRetryConfig(hls.config.playlistLoadPolicy, data);
@@ -265,7 +265,7 @@ export default class ErrorController implements NetworkComponentAPI {
retryConfig,
retryCount,
isTimeoutError(data),
httpStatus
httpStatus,
);
if (retry) {
return {
@@ -292,11 +292,11 @@ export default class ErrorController implements NetworkComponentAPI {
const { fragLoadPolicy, keyLoadPolicy } = hls.config;
const retryConfig = getRetryConfig(
data.details.startsWith('key') ? keyLoadPolicy : fragLoadPolicy,
data
data,
);
const fragmentErrors = hls.levels.reduce(
(acc, level) => acc + level.fragmentError,
0
0,
);
// Switch levels when out of retried or level index out of bounds
if (level) {
@@ -308,7 +308,7 @@ export default class ErrorController implements NetworkComponentAPI {
retryConfig,
fragmentErrors,
isTimeoutError(data),
httpStatus
httpStatus,
);
if (retry) {
return {
@@ -332,7 +332,7 @@ export default class ErrorController implements NetworkComponentAPI {
private getLevelSwitchAction(
data: ErrorData,
levelIndex: number | null | undefined
levelIndex: number | null | undefined,
): IErrorAction {
const hls = this.hls;
if (levelIndex === null || levelIndex === undefined) {
@@ -371,7 +371,7 @@ export default class ErrorController implements NetworkComponentAPI {
isVideoCodecError &&
levels.some(
({ codecSet, audioCodec }) =>
level.codecSet !== codecSet && level.audioCodec === audioCodec
level.codecSet !== codecSet && level.audioCodec === audioCodec,
);
const { type: playlistErrorType, groupId: playlistErrorGroupId } =
data.context ?? {};
@@ -391,7 +391,7 @@ export default class ErrorController implements NetworkComponentAPI {
const fragCandidate = findFragmentByPTS(
data.frag,
levelDetails.fragments,
data.frag.start
data.frag.start,
);
if (fragCandidate?.gap) {
continue;
@@ -491,7 +491,7 @@ export default class ErrorController implements NetworkComponentAPI {
errorAction.resolved = true;
}
this.warn(
`Restricting playback to HDCP-LEVEL of "${hls.maxHdcpLevel}" or lower`
`Restricting playback to HDCP-LEVEL of "${hls.maxHdcpLevel}" or lower`,
);
break;
}
@@ -536,7 +536,7 @@ export default class ErrorController implements NetworkComponentAPI {
this.warn(
`Switching to Redundant Stream ${newUrlId + 1}/${redundantLevels}: "${
level.url[newUrlId]
}" after ${data.details}`
}" after ${data.details}`,
);
this.playlistError = 0;
hls.levels.forEach((lv) => {
@@ -566,7 +566,7 @@ export default class ErrorController implements NetworkComponentAPI {
function checkExpired(
penalizedRendition: PenalizedRendition,
data: ErrorData,
currentPenaltyState: PenalizedRendition | undefined
currentPenaltyState: PenalizedRendition | undefined,
): boolean {
// Expire penalty for switching back to rendition after RENDITION_PENALTY_DURATION_MS
if (
@@ -582,7 +582,7 @@ function checkExpired(
const candidateFrag = findFragmentByPTS(
null,
lastErrorDetails.fragments,
position
position,
);
if (candidateFrag && !candidateFrag.gap) {
return true;
+6 -6
View File
@@ -46,7 +46,7 @@ class FPSController implements ComponentAPI {
protected onMediaAttaching(
event: Events.MEDIA_ATTACHING,
data: MediaAttachingData
data: MediaAttachingData,
) {
const config = this.hls.config;
if (config.capLevelOnFPSDrop) {
@@ -60,7 +60,7 @@ class FPSController implements ComponentAPI {
self.clearInterval(this.timer);
this.timer = self.setInterval(
this.checkFPSInterval.bind(this),
config.fpsDroppedMonitoringPeriod
config.fpsDroppedMonitoringPeriod,
);
}
}
@@ -68,7 +68,7 @@ class FPSController implements ComponentAPI {
checkFPS(
video: HTMLVideoElement,
decodedFrames: number,
droppedFrames: number
droppedFrames: number,
) {
const currentTime = performance.now();
if (decodedFrames) {
@@ -92,7 +92,7 @@ class FPSController implements ComponentAPI {
let currentLevel = hls.currentLevel;
logger.warn(
'drop FPS ratio greater than max allowed value for currentLevel: ' +
currentLevel
currentLevel,
);
if (
currentLevel > 0 &&
@@ -124,14 +124,14 @@ class FPSController implements ComponentAPI {
this.checkFPS(
video,
videoPlaybackQuality.totalVideoFrames,
videoPlaybackQuality.droppedVideoFrames
videoPlaybackQuality.droppedVideoFrames,
);
} else {
// HTMLVideoElement doesn't include the webkit types
this.checkFPS(
video,
(video as any).webkitDecodedFrameCount as number,
(video as any).webkitDroppedFrameCount as number
(video as any).webkitDroppedFrameCount as number,
);
}
}
+8 -8
View File
@@ -10,7 +10,7 @@ import { Fragment } from '../loader/fragment';
export function findFragmentByPDT(
fragments: Array<Fragment>,
PDTValue: number | null,
maxFragLookUpTolerance: number
maxFragLookUpTolerance: number,
): Fragment | null {
if (
PDTValue === null ||
@@ -57,7 +57,7 @@ export function findFragmentByPTS(
fragPrevious: Fragment | null,
fragments: Array<Fragment>,
bufferEnd: number = 0,
maxFragLookUpTolerance: number = 0
maxFragLookUpTolerance: number = 0,
): Fragment | null {
let fragNext: Fragment | null = null;
if (fragPrevious) {
@@ -79,7 +79,7 @@ export function findFragmentByPTS(
// We might be seeking past the tolerance so find the best match
const foundFragment = BinarySearch.search(
fragments,
fragmentWithinToleranceTest.bind(null, bufferEnd, maxFragLookUpTolerance)
fragmentWithinToleranceTest.bind(null, bufferEnd, maxFragLookUpTolerance),
);
if (foundFragment && (foundFragment !== fragPrevious || !fragNext)) {
return foundFragment;
@@ -98,7 +98,7 @@ export function findFragmentByPTS(
export function fragmentWithinToleranceTest(
bufferEnd = 0,
maxFragLookUpTolerance = 0,
candidate: Fragment
candidate: Fragment,
) {
// eagerly accept an accurate match (no tolerance)
if (
@@ -123,7 +123,7 @@ export function fragmentWithinToleranceTest(
// Set the lookup tolerance to be small enough to detect the current segment - ensures we don't skip over very small segments
const candidateLookupTolerance = Math.min(
maxFragLookUpTolerance,
candidate.duration + (candidate.deltaPTS ? candidate.deltaPTS : 0)
candidate.duration + (candidate.deltaPTS ? candidate.deltaPTS : 0),
);
if (
candidate.start + candidate.duration - candidateLookupTolerance <=
@@ -152,12 +152,12 @@ export function fragmentWithinToleranceTest(
export function pdtWithinToleranceTest(
pdtBufferEnd: number,
maxFragLookUpTolerance: number,
candidate: Fragment
candidate: Fragment,
): boolean {
const candidateLookupTolerance =
Math.min(
maxFragLookUpTolerance,
candidate.duration + (candidate.deltaPTS ? candidate.deltaPTS : 0)
candidate.duration + (candidate.deltaPTS ? candidate.deltaPTS : 0),
) * 1000;
// endProgramDateTime can be null, default to zero
@@ -167,7 +167,7 @@ export function pdtWithinToleranceTest(
export function findFragWithCC(
fragments: Fragment[],
cc: number
cc: number,
): Fragment | null {
return BinarySearch.search(fragments, (candidate) => {
if (candidate.cc < cc) {
+12 -12
View File
@@ -77,7 +77,7 @@ export class FragmentTracker implements ComponentAPI {
*/
public getAppendedFrag(
position: number,
levelType: PlaylistLevelType
levelType: PlaylistLevelType,
): Fragment | Part | null {
const activeParts = this.activePartLists[levelType];
if (activeParts) {
@@ -106,7 +106,7 @@ export class FragmentTracker implements ComponentAPI {
*/
public getBufferedFrag(
position: number,
levelType: PlaylistLevelType
levelType: PlaylistLevelType,
): Fragment | null {
const { fragments } = this;
const keys = Object.keys(fragments);
@@ -131,7 +131,7 @@ export class FragmentTracker implements ComponentAPI {
elementaryStream: SourceBufferName,
timeRange: TimeRanges,
playlistType: PlaylistLevelType,
appendedPart?: Part | null
appendedPart?: Part | null,
) {
if (this.timeRanges) {
this.timeRanges[elementaryStream] = timeRange;
@@ -161,7 +161,7 @@ export class FragmentTracker implements ComponentAPI {
const isNotBuffered = !this.isTimeBuffered(
time.startPTS,
time.endPTS,
timeRange
timeRange,
);
if (isNotBuffered) {
// Unregister partial fragment as it needs to load again to be reused
@@ -200,7 +200,7 @@ export class FragmentTracker implements ComponentAPI {
frag,
part,
partial,
timeRange
timeRange,
);
});
fragmentEntity.loaded = null;
@@ -225,7 +225,7 @@ export class FragmentTracker implements ComponentAPI {
return;
}
this.activePartLists[levelType] = activeParts.filter(
(part) => (part.fragment.sn as number) >= snToKeep
(part) => (part.fragment.sn as number) >= snToKeep,
);
}
@@ -254,7 +254,7 @@ export class FragmentTracker implements ComponentAPI {
fragment: Fragment,
part: Part | null,
partial: boolean,
timeRange: TimeRanges
timeRange: TimeRanges,
): FragmentBufferedRange {
const buffered: FragmentBufferedRange = {
time: [],
@@ -354,7 +354,7 @@ export class FragmentTracker implements ComponentAPI {
private isTimeBuffered(
startPTS: number,
endPTS: number,
timeRange: TimeRanges
timeRange: TimeRanges,
): boolean {
let startTime;
let endTime;
@@ -397,7 +397,7 @@ export class FragmentTracker implements ComponentAPI {
private onBufferAppended(
event: Events.BUFFER_APPENDED,
data: BufferAppendedData
data: BufferAppendedData,
) {
const { frag, part, timeRanges } = data;
if (frag.sn === 'initSegment') {
@@ -419,7 +419,7 @@ export class FragmentTracker implements ComponentAPI {
elementaryStream,
timeRange,
playlistType,
part
part,
);
});
}
@@ -442,7 +442,7 @@ export class FragmentTracker implements ComponentAPI {
end: number,
playlistType: PlaylistLevelType,
withGapOnly?: boolean,
unbufferedOnly?: boolean
unbufferedOnly?: boolean,
) {
if (withGapOnly && !this.hasGaps) {
return;
@@ -474,7 +474,7 @@ export class FragmentTracker implements ComponentAPI {
if (activeParts) {
const snToRemove = fragment.sn;
this.activePartLists[fragment.type] = activeParts.filter(
(part) => part.fragment.sn !== snToRemove
(part) => part.fragment.sn !== snToRemove,
);
}
delete this.fragments[fragKey];
+12 -12
View File
@@ -64,8 +64,8 @@ export default class GapController {
const stalledDuration = self.performance.now() - stalled;
logger.warn(
`playback not stuck anymore @${currentTime}, after ${Math.round(
stalledDuration
)}ms`
stalledDuration,
)}ms`,
);
this.stallReported = false;
}
@@ -161,7 +161,7 @@ export default class GapController {
const bufferedWithHoles = BufferHelper.bufferInfo(
media,
currentTime,
config.maxBufferHole
config.maxBufferHole,
);
this._tryFixBufferStall(bufferedWithHoles, stalledDuration);
}
@@ -174,7 +174,7 @@ export default class GapController {
*/
private _tryFixBufferStall(
bufferInfo: BufferInfo,
stalledDurationMs: number
stalledDurationMs: number,
) {
const { config, fragmentTracker, media } = this;
if (media === null) {
@@ -226,7 +226,7 @@ export default class GapController {
const error = new Error(
`Playback stalling at @${
media.currentTime
} due to low buffer (${JSON.stringify(bufferInfo)})`
} due to low buffer (${JSON.stringify(bufferInfo)})`,
);
logger.warn(error.message);
hls.trigger(Events.ERROR, {
@@ -268,7 +268,7 @@ export default class GapController {
if (currentTime === 0) {
const startFrag = fragmentTracker.getAppendedFrag(
0,
PlaylistLevelType.MAIN
PlaylistLevelType.MAIN,
);
if (startFrag && startTime < startFrag.end) {
startGap = true;
@@ -279,7 +279,7 @@ export default class GapController {
partial ||
fragmentTracker.getAppendedFrag(
currentTime,
PlaylistLevelType.MAIN
PlaylistLevelType.MAIN,
);
if (startProvisioned) {
let moreToLoad = false;
@@ -301,17 +301,17 @@ export default class GapController {
}
const targetTime = Math.max(
startTime + SKIP_BUFFER_RANGE_START,
currentTime + SKIP_BUFFER_HOLE_STEP_SECONDS
currentTime + SKIP_BUFFER_HOLE_STEP_SECONDS,
);
logger.warn(
`skipping hole, adjusting currentTime from ${currentTime} to ${targetTime}`
`skipping hole, adjusting currentTime from ${currentTime} to ${targetTime}`,
);
this.moved = true;
this.stalled = null;
media.currentTime = targetTime;
if (partial && !partial.gap) {
const error = new Error(
`fragment loaded with buffer holes, seeking from ${currentTime} to ${targetTime}`
`fragment loaded with buffer holes, seeking from ${currentTime} to ${targetTime}`,
);
hls.trigger(Events.ERROR, {
type: ErrorTypes.MEDIA_ERROR,
@@ -344,7 +344,7 @@ export default class GapController {
const targetTime = currentTime + (nudgeRetry + 1) * config.nudgeOffset;
// playback stalled in buffered area ... let's nudge currentTime to try to overcome this
const error = new Error(
`Nudging 'currentTime' from ${currentTime} to ${targetTime}`
`Nudging 'currentTime' from ${currentTime} to ${targetTime}`,
);
logger.warn(error.message);
media.currentTime = targetTime;
@@ -356,7 +356,7 @@ export default class GapController {
});
} else {
const error = new Error(
`Playhead still not moving while enough data buffered @${currentTime} after ${config.nudgeMaxRetry} nudges`
`Playhead still not moving while enough data buffered @${currentTime} after ${config.nudgeMaxRetry} nudges`,
);
logger.error(error.message);
hls.trigger(Events.ERROR, {
+7 -7
View File
@@ -61,7 +61,7 @@ function hexToArrayBuffer(str): ArrayBuffer {
.replace(/^0x/, '')
.replace(/([\da-fA-F]{2}) ?/g, '0x$1 ')
.replace(/ +$/, '')
.split(' ')
.split(' '),
).buffer;
}
class ID3TrackController implements ComponentAPI {
@@ -110,7 +110,7 @@ class ID3TrackController implements ComponentAPI {
// Add ID3 metatadata text track.
protected onMediaAttached(
event: Events.MEDIA_ATTACHED,
data: MediaAttachedData
data: MediaAttachedData,
): void {
this.media = data.media;
}
@@ -154,7 +154,7 @@ class ID3TrackController implements ComponentAPI {
onFragParsingMetadata(
event: Events.FRAG_PARSING_METADATA,
data: FragParsingMetadataData
data: FragParsingMetadataData,
) {
if (!this.media) {
return;
@@ -238,7 +238,7 @@ class ID3TrackController implements ComponentAPI {
onBufferFlushing(
event: Events.BUFFER_FLUSHING,
{ startOffset, endOffset, type }: BufferFlushingData
{ startOffset, endOffset, type }: BufferFlushingData,
) {
const { id3Track, hls } = this;
if (!hls) {
@@ -282,7 +282,7 @@ class ID3TrackController implements ComponentAPI {
// Remove cues from track not found in details.dateRanges
if (id3Track) {
const idsToRemove = Object.keys(dateRangeCuesAppended).filter(
(id) => !ids.includes(id)
(id) => !ids.includes(id),
);
for (let i = idsToRemove.length; i--; ) {
const id = idsToRemove[i];
@@ -314,7 +314,7 @@ class ID3TrackController implements ComponentAPI {
let durationKnown = appendedDateRangeCues?.durationKnown || false;
const startTime = dateRangeDateToTimelineSeconds(
dateRange.startDate,
dateTimeOffset
dateTimeOffset,
);
let endTime = MAX_CUE_ENDTIME;
const endDate = dateRange.endDate;
@@ -338,7 +338,7 @@ class ID3TrackController implements ComponentAPI {
if (nextDateRangeWithSameClass) {
endTime = dateRangeDateToTimelineSeconds(
nextDateRangeWithSameClass.startDate,
dateTimeOffset
dateTimeOffset,
);
durationKnown = true;
}
+6 -6
View File
@@ -67,7 +67,7 @@ export default class LatencyController implements ComponentAPI {
targetLatency +
Math.min(
this.stallCount * liveSyncOnStallIncrease,
maxLiveSyncOnStallIncrease
maxLiveSyncOnStallIncrease,
)
);
}
@@ -147,7 +147,7 @@ export default class LatencyController implements ComponentAPI {
private onMediaAttached(
event: Events.MEDIA_ATTACHED,
data: MediaAttachingData
data: MediaAttachingData,
) {
this.media = data.media;
this.media.addEventListener('timeupdate', this.timeupdateHandler);
@@ -168,7 +168,7 @@ export default class LatencyController implements ComponentAPI {
private onLevelUpdated(
event: Events.LEVEL_UPDATED,
{ details }: LevelUpdatedData
{ details }: LevelUpdatedData,
) {
this.levelDetails = details;
if (details.advanced) {
@@ -186,7 +186,7 @@ export default class LatencyController implements ComponentAPI {
this.stallCount++;
if (this.levelDetails?.live) {
logger.warn(
'[playback-rate-controller]: Stall detected, adjusting target latency'
'[playback-rate-controller]: Stall detected, adjusting target latency',
);
}
}
@@ -219,7 +219,7 @@ export default class LatencyController implements ComponentAPI {
// Playback further than one target duration from target can be considered DVR playback.
const liveMinLatencyDuration = Math.min(
this.maxLatency,
targetLatency + levelDetails.targetduration
targetLatency + levelDetails.targetduration,
);
const inLiveRange = distanceFromTarget < liveMinLatencyDuration;
if (
@@ -232,7 +232,7 @@ export default class LatencyController implements ComponentAPI {
const rate =
Math.round(
(2 / (1 + Math.exp(-0.75 * distanceFromTarget - this.edgeStalled))) *
20
20,
) / 20;
media.playbackRate = Math.min(max, Math.max(1, rate));
} else if (media.playbackRate !== 1 && media.playbackRate !== 0) {
+21 -21
View File
@@ -50,7 +50,7 @@ export default class LevelController extends BasePlaylistController {
constructor(
hls: Hls,
contentSteeringController: ContentSteeringController | null
contentSteeringController: ContentSteeringController | null,
) {
super(hls, '[level-controller]');
this.steering = contentSteeringController;
@@ -108,14 +108,14 @@ export default class LevelController extends BasePlaylistController {
private onManifestLoading(
event: Events.MANIFEST_LOADING,
data: ManifestLoadingData
data: ManifestLoadingData,
) {
this.resetLevels();
}
protected onManifestLoaded(
event: Events.MANIFEST_LOADED,
data: ManifestLoadedData
data: ManifestLoadedData,
) {
const levels: Level[] = [];
const levelSet: { [key: string]: Level } = {};
@@ -169,7 +169,7 @@ export default class LevelController extends BasePlaylistController {
private filterAndSortMediaOptions(
unfilteredLevels: Level[],
data: ManifestLoadedData
data: ManifestLoadedData,
) {
let audioTracks: MediaPlaylist[] = [];
let subtitleTracks: MediaPlaylist[] = [];
@@ -189,14 +189,14 @@ export default class LevelController extends BasePlaylistController {
(!audioCodec || areCodecsMediaSourceSupported(audioCodec, 'audio')) &&
(!videoCodec || areCodecsMediaSourceSupported(videoCodec, 'video'))
);
}
},
);
// remove audio-only and invalid video-range levels if we also have levels with video codecs or RESOLUTION signalled
if ((resolutionFound || videoCodecFound) && audioCodecFound) {
levels = levels.filter(
({ videoCodec, videoRange, width, height }) =>
(!!videoCodec || !!(width && height)) && isVideoRange(videoRange)
(!!videoCodec || !!(width && height)) && isVideoRange(videoRange),
);
}
@@ -207,12 +207,12 @@ export default class LevelController extends BasePlaylistController {
if (unfilteredLevels.length) {
this.warn(
`One or more CODECS in variant not supported: ${JSON.stringify(
unfilteredLevels[0].attrs
)}`
unfilteredLevels[0].attrs,
)}`,
);
}
const error = new Error(
'no level with compatible codecs found in manifest'
'no level with compatible codecs found in manifest',
);
this.hls.trigger(Events.ERROR, {
type: ErrorTypes.MEDIA_ERROR,
@@ -231,7 +231,7 @@ export default class LevelController extends BasePlaylistController {
audioTracks = data.audioTracks.filter(
(track) =>
!track.audioCodec ||
areCodecsMediaSourceSupported(track.audioCodec, 'audio')
areCodecsMediaSourceSupported(track.audioCodec, 'audio'),
);
// Assign ids after filtering as array indices by group-id
assignTrackIdsByGroup(audioTracks);
@@ -298,13 +298,13 @@ export default class LevelController extends BasePlaylistController {
const firstLevelBitrate = firstLevelInPlaylist.bitrate;
const bandwidthEstimate = this.hls.bandwidthEstimate;
this.log(
`manifest loaded, ${levels.length} level(s) found, first bitrate: ${firstLevelBitrate}`
`manifest loaded, ${levels.length} level(s) found, first bitrate: ${firstLevelBitrate}`,
);
// Update default bwe to first variant bitrate as long it has not been configured or set
if (this.hls.userConfig?.abrEwmaDefaultEstimate === undefined) {
const startingBwEstimate = Math.min(
firstLevelBitrate,
this.hls.config.abrEwmaDefaultEstimateMax
this.hls.config.abrEwmaDefaultEstimateMax,
);
if (
startingBwEstimate > bandwidthEstimate &&
@@ -401,7 +401,7 @@ export default class LevelController extends BasePlaylistController {
pathwayId ? ' with Pathway ' + pathwayId : ''
} from level ${lastLevelIndex}${
lastPathwayId ? ' with Pathway ' + lastPathwayId : ''
}`
}`,
);
const levelSwitchingData: LevelSwitchingData = Object.assign({}, level, {
@@ -482,7 +482,7 @@ export default class LevelController extends BasePlaylistController {
// reset errors on the successful load of a fragment
protected onFragBuffered(
event: Events.FRAG_BUFFERED,
{ frag }: FragBufferedData
{ frag }: FragBufferedData,
) {
if (frag !== undefined && frag.type === PlaylistLevelType.MAIN) {
const el = frag.elementaryStreams;
@@ -492,7 +492,7 @@ export default class LevelController extends BasePlaylistController {
const level = this._levels[frag.level];
if (level?.loadError) {
this.log(
`Resetting level error count of ${level.loadError} on frag buffered`
`Resetting level error count of ${level.loadError} on frag buffered`,
);
level.loadError = 0;
}
@@ -526,7 +526,7 @@ export default class LevelController extends BasePlaylistController {
protected onAudioTrackSwitched(
event: Events.AUDIO_TRACK_SWITCHED,
data: TrackSwitchedData
data: TrackSwitchedData,
) {
const currentLevel = this.currentLevel;
if (!currentLevel) {
@@ -568,7 +568,7 @@ export default class LevelController extends BasePlaylistController {
url = hlsUrlParameters.addDirectives(url);
} catch (error) {
this.warn(
`Could not construct new URL with HLS Delivery Directives: ${error}`
`Could not construct new URL with HLS Delivery Directives: ${error}`,
);
}
}
@@ -584,7 +584,7 @@ export default class LevelController extends BasePlaylistController {
: ''
} with${pathwayId ? ' Pathway ' + pathwayId : ''} URI ${id + 1}/${
currentLevel.url.length
} ${url}`
} ${url}`,
);
// console.log('Current audio track group ID:', this.hls.audioTracks[this.hls.audioTrack].groupId);
@@ -625,12 +625,12 @@ export default class LevelController extends BasePlaylistController {
level.url = level.url.filter(filterLevelAndGroupByIdIndex);
if (level.audioGroupIds) {
level.audioGroupIds = level.audioGroupIds.filter(
filterLevelAndGroupByIdIndex
filterLevelAndGroupByIdIndex,
);
}
if (level.textGroupIds) {
level.textGroupIds = level.textGroupIds.filter(
filterLevelAndGroupByIdIndex
filterLevelAndGroupByIdIndex,
);
}
level.urlId = 0;
@@ -658,7 +658,7 @@ export default class LevelController extends BasePlaylistController {
private onLevelsUpdated(
event: Events.LEVELS_UPDATED,
{ levels }: LevelsUpdatedData
{ levels }: LevelsUpdatedData,
) {
this._levels = levels;
}
+48 -48
View File
@@ -60,14 +60,14 @@ export default class StreamController
constructor(
hls: Hls,
fragmentTracker: FragmentTracker,
keyLoader: KeyLoader
keyLoader: KeyLoader,
) {
super(
hls,
fragmentTracker,
keyLoader,
'[stream-controller]',
PlaylistLevelType.MAIN
PlaylistLevelType.MAIN,
);
this._registerListeners();
}
@@ -83,7 +83,7 @@ export default class StreamController
hls.on(
Events.FRAG_LOAD_EMERGENCY_ABORTED,
this.onFragLoadEmergencyAborted,
this
this,
);
hls.on(Events.ERROR, this.onError, this);
hls.on(Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
@@ -104,7 +104,7 @@ export default class StreamController
hls.off(
Events.FRAG_LOAD_EMERGENCY_ABORTED,
this.onFragLoadEmergencyAborted,
this
this,
);
hls.off(Events.ERROR, this.onError, this);
hls.off(Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
@@ -147,8 +147,8 @@ export default class StreamController
if (lastCurrentTime > 0 && startPosition === -1) {
this.log(
`Override startPosition with lastCurrentTime @${lastCurrentTime.toFixed(
3
)}`
3,
)}`,
);
startPosition = lastCurrentTime;
}
@@ -336,7 +336,7 @@ export default class StreamController
levelDetails,
bufferInfo,
PlaylistLevelType.MAIN,
maxBufLen
maxBufLen,
);
}
if (!frag) {
@@ -352,7 +352,7 @@ export default class StreamController
protected loadFragment(
frag: Fragment,
level: Level,
targetBufferTime: number
targetBufferTime: number,
) {
// Check if fragment is not loaded
const fragState = this.fragmentTracker.getState(frag);
@@ -365,7 +365,7 @@ export default class StreamController
this._loadInitSegment(frag, level);
} else if (this.bitrateTest) {
this.log(
`Fragment ${frag.sn} of level ${frag.level} is being downloaded to test bitrate and will not be buffered`
`Fragment ${frag.sn} of level ${frag.level} is being downloaded to test bitrate and will not be buffered`,
);
this._loadBitrateTestFrag(frag, level);
} else {
@@ -380,7 +380,7 @@ export default class StreamController
private getBufferedFrag(position) {
return this.fragmentTracker.getBufferedFrag(
position,
PlaylistLevelType.MAIN
PlaylistLevelType.MAIN,
);
}
@@ -464,10 +464,10 @@ export default class StreamController
Math.min(
Math.max(
fragDuration - this.config.maxFragLookUpTolerance,
fragDuration * 0.5
fragDuration * 0.5,
),
fragDuration * 0.75
)
fragDuration * 0.75,
),
);
this.flushMainBuffer(startPts, Number.POSITIVE_INFINITY);
}
@@ -499,13 +499,13 @@ export default class StreamController
super.flushMainBuffer(
startOffset,
endOffset,
this.altAudio ? 'video' : null
this.altAudio ? 'video' : null,
);
}
protected onMediaAttached(
event: Events.MEDIA_ATTACHED,
data: MediaAttachedData
data: MediaAttachedData,
) {
super.onMediaAttached(event, data);
const media = data.media;
@@ -517,7 +517,7 @@ export default class StreamController
this.config,
media,
this.fragmentTracker,
this.hls
this.hls,
);
}
@@ -555,7 +555,7 @@ export default class StreamController
this.warn(
`Main forward buffer length on "seeked" event ${
bufferInfo ? bufferInfo.len : 'empty'
})`
})`,
);
return;
}
@@ -577,7 +577,7 @@ export default class StreamController
private onManifestParsed(
event: Events.MANIFEST_PARSED,
data: ManifestParsedData
data: ManifestParsedData,
) {
let aac = false;
let heaac = false;
@@ -598,7 +598,7 @@ export default class StreamController
this.audioCodecSwitch = aac && heaac && !changeTypeSupported();
if (this.audioCodecSwitch) {
this.log(
'Both AAC/HE-AAC audio found in levels; declaring level codec as HE-AAC'
'Both AAC/HE-AAC audio found in levels; declaring level codec as HE-AAC',
);
}
@@ -636,7 +636,7 @@ export default class StreamController
newDetails.lastPartSn
? `[part-${newDetails.lastPartSn}-${newDetails.lastPartIndex}]`
: ''
}, cc [${newDetails.startCC}, ${newDetails.endCC}] duration:${duration}`
}, cc [${newDetails.startCC}, ${newDetails.endCC}] duration:${duration}`,
);
const curLevel = levels[newLevelId];
@@ -698,7 +698,7 @@ export default class StreamController
const { levels } = this;
if (!levels) {
this.warn(
`Levels were reset while fragment load was in progress. Fragment ${frag.sn} of level ${frag.level} will not be buffered`
`Levels were reset while fragment load was in progress. Fragment ${frag.sn} of level ${frag.level} will not be buffered`,
);
return;
}
@@ -706,7 +706,7 @@ export default class StreamController
const details = currentLevel.details as LevelDetails;
if (!details) {
this.warn(
`Dropping fragment ${frag.sn} of level ${frag.level} after level details were reset`
`Dropping fragment ${frag.sn} of level ${frag.level} after level details were reset`,
);
this.fragmentTracker.removeFragment(frag);
return;
@@ -726,7 +726,7 @@ export default class StreamController
this.hls,
PlaylistLevelType.MAIN,
this._handleTransmuxComplete.bind(this),
this._handleTransmuxerFlush.bind(this)
this._handleTransmuxerFlush.bind(this),
));
const partIndex = part ? part.index : -1;
const partial = partIndex !== -1;
@@ -736,7 +736,7 @@ export default class StreamController
frag.stats.chunkCount,
payload.byteLength,
partIndex,
partial
partial,
);
const initPTS = this.initPTS[frag.cc];
@@ -750,13 +750,13 @@ export default class StreamController
details.totalduration,
accurateTimeOffset,
chunkMeta,
initPTS
initPTS,
);
}
private onAudioTrackSwitching(
event: Events.AUDIO_TRACK_SWITCHING,
data: AudioTrackSwitchingData
data: AudioTrackSwitchingData,
) {
// if any URL found on new audio track, it is an alternate audio track
const fromAltAudio = this.altAudio;
@@ -767,7 +767,7 @@ export default class StreamController
if (!altAudio) {
if (this.mediaBuffer !== this.media) {
this.log(
'Switching on main audio, use media.buffered to schedule main fragment loading'
'Switching on main audio, use media.buffered to schedule main fragment loading',
);
this.mediaBuffer = this.media;
const fragCurrent = this.fragCurrent;
@@ -801,7 +801,7 @@ export default class StreamController
private onAudioTrackSwitched(
event: Events.AUDIO_TRACK_SWITCHED,
data: AudioTrackSwitchedData
data: AudioTrackSwitchedData,
) {
const trackId = data.id;
const altAudio = !!this.hls.audioTracks[trackId].url;
@@ -810,7 +810,7 @@ export default class StreamController
// if we switched on alternate audio, ensure that main fragment scheduling is synced with video sourcebuffer buffered
if (videoBuffer && this.mediaBuffer !== videoBuffer) {
this.log(
'Switching on alternate audio, use video.buffered to schedule main fragment loading'
'Switching on alternate audio, use video.buffered to schedule main fragment loading',
);
this.mediaBuffer = videoBuffer;
}
@@ -821,7 +821,7 @@ export default class StreamController
private onBufferCreated(
event: Events.BUFFER_CREATED,
data: BufferCreatedData
data: BufferCreatedData,
) {
const tracks = data.tracks;
let mediaTrack;
@@ -845,7 +845,7 @@ export default class StreamController
}
if (alternate && mediaTrack) {
this.log(
`Alternate track found, use ${name}.buffered to schedule main fragment loading`
`Alternate track found, use ${name}.buffered to schedule main fragment loading`,
);
this.mediaBuffer = mediaTrack.buffer;
} else {
@@ -864,7 +864,7 @@ export default class StreamController
this.warn(
`Fragment ${frag.sn}${part ? ' p: ' + part.index : ''} of level ${
frag.level
} finished buffering, but was aborted. state: ${this.state}`
} finished buffering, but was aborted. state: ${this.state}`,
);
if (this.state === State.PARSED) {
this.state = State.IDLE;
@@ -873,7 +873,7 @@ export default class StreamController
}
const stats = part ? part.stats : frag.stats;
this.fragLastKbps = Math.round(
(8 * stats.total) / (stats.buffering.end - stats.loading.first)
(8 * stats.total) / (stats.buffering.end - stats.loading.first),
);
if (frag.sn !== 'initSegment') {
this.fragPrevious = frag;
@@ -959,7 +959,7 @@ export default class StreamController
private onBufferFlushed(
event: Events.BUFFER_FLUSHED,
{ type }: BufferFlushedData
{ type }: BufferFlushedData,
) {
if (
type !== ElementaryStreamTypes.AUDIO ||
@@ -976,7 +976,7 @@ export default class StreamController
private onLevelsUpdated(
event: Events.LEVELS_UPDATED,
data: LevelsUpdatedData
data: LevelsUpdatedData,
) {
if (this.level > -1 && this.fragCurrent) {
this.level = this.fragCurrent.level;
@@ -1003,7 +1003,7 @@ export default class StreamController
if (startPosition >= 0 && currentTime < startPosition) {
if (media.seeking) {
this.log(
`could not seek to ${startPosition}, already seeking at ${currentTime}`
`could not seek to ${startPosition}, already seeking at ${currentTime}`,
);
return;
}
@@ -1020,7 +1020,7 @@ export default class StreamController
this.startPosition = startPosition;
}
this.log(
`seek to target start position ${startPosition} from current time ${currentTime}`
`seek to target start position ${startPosition} from current time ${currentTime}`,
);
media.currentTime = startPosition;
}
@@ -1095,7 +1095,7 @@ export default class StreamController
level,
initSegment.tracks,
mapFragment,
chunkMeta
chunkMeta,
);
hls.trigger(Events.FRAG_PARSING_INIT_SEGMENT, {
frag: mapFragment,
@@ -1164,7 +1164,7 @@ export default class StreamController
endPTS,
frag.start,
endDTS,
true
true,
);
}
}
@@ -1173,7 +1173,7 @@ export default class StreamController
startPTS,
endPTS,
startDTS,
endDTS
endDTS,
);
if (this.backtrackFragment) {
this.backtrackFragment = frag;
@@ -1183,7 +1183,7 @@ export default class StreamController
frag,
part,
chunkMeta,
isFirstFragment || isFirstInDiscontinuity
isFirstFragment || isFirstInDiscontinuity,
);
} else if (isFirstFragment || isFirstInDiscontinuity) {
// Mark segment with a gap to avoid loop loading
@@ -1209,7 +1209,7 @@ export default class StreamController
startPTS,
endPTS,
startDTS,
endDTS
endDTS,
);
this.bufferFragmentData(audio, frag, part, chunkMeta);
}
@@ -1238,7 +1238,7 @@ export default class StreamController
currentLevel: Level,
tracks: TrackSet,
frag: Fragment,
chunkMeta: ChunkMetadata
chunkMeta: ChunkMetadata,
) {
if (this.state !== State.PARSING) {
return;
@@ -1283,7 +1283,7 @@ export default class StreamController
}
if (currentLevel.audioCodec && currentLevel.audioCodec !== audioCodec) {
this.log(
`Swapping manifest audio codec "${currentLevel.audioCodec}" for "${audioCodec}"`
`Swapping manifest audio codec "${currentLevel.audioCodec}" for "${audioCodec}"`,
);
}
audio.levelCodec = audioCodec;
@@ -1293,7 +1293,7 @@ export default class StreamController
audio.container
}, codecs[selected/level/parsed]=[${audioCodec || ''}/${
currentLevel.audioCodec || ''
}/${audio.codec}]`
}/${audio.codec}]`,
);
}
if (video) {
@@ -1304,12 +1304,12 @@ export default class StreamController
video.container
}, codecs[level/parsed]=[${currentLevel.videoCodec || ''}/${
video.codec
}]`
}]`,
);
}
if (audiovideo) {
this.log(
`Init audiovideo buffer, container:${audiovideo.container}, codecs[level/parsed]=[${currentLevel.codecs}/${audiovideo.codec}]`
`Init audiovideo buffer, container:${audiovideo.container}, codecs[level/parsed]=[${currentLevel.codecs}/${audiovideo.codec}]`,
);
}
this.hls.trigger(Events.BUFFER_CODECS, tracks);
@@ -1335,7 +1335,7 @@ export default class StreamController
public getMainFwdBufferInfo(): BufferInfo | null {
return this.getFwdBufferInfo(
this.mediaBuffer ? this.mediaBuffer : this.media,
PlaylistLevelType.MAIN
PlaylistLevelType.MAIN,
);
}
+18 -18
View File
@@ -47,14 +47,14 @@ export class SubtitleStreamController
constructor(
hls: Hls,
fragmentTracker: FragmentTracker,
keyLoader: KeyLoader
keyLoader: KeyLoader,
) {
super(
hls,
fragmentTracker,
keyLoader,
'[subtitle-stream-controller]',
PlaylistLevelType.SUBTITLE
PlaylistLevelType.SUBTITLE,
);
this._registerListeners();
}
@@ -124,7 +124,7 @@ export class SubtitleStreamController
onSubtitleFragProcessed(
event: Events.SUBTITLE_FRAG_PROCESSED,
data: SubtitleFragProcessed
data: SubtitleFragProcessed,
) {
const { frag, success } = data;
this.fragPrevious = frag;
@@ -187,7 +187,7 @@ export class SubtitleStreamController
this.fragmentTracker.removeFragmentsInRange(
startOffset,
endOffsetSubtitles,
PlaylistLevelType.SUBTITLE
PlaylistLevelType.SUBTITLE,
);
}
}
@@ -217,11 +217,11 @@ export class SubtitleStreamController
// Got all new subtitle levels.
onSubtitleTracksUpdated(
event: Events.SUBTITLE_TRACKS_UPDATED,
{ subtitleTracks }: SubtitleTracksUpdatedData
{ subtitleTracks }: SubtitleTracksUpdatedData,
) {
if (subtitleOptionsIdentical(this.levels, subtitleTracks)) {
this.levels = subtitleTracks.map(
(mediaPlaylist) => new Level(mediaPlaylist)
(mediaPlaylist) => new Level(mediaPlaylist),
);
return;
}
@@ -234,7 +234,7 @@ export class SubtitleStreamController
this.fragmentTracker.removeFragmentsInRange(
0,
Number.POSITIVE_INFINITY,
PlaylistLevelType.SUBTITLE
PlaylistLevelType.SUBTITLE,
);
this.fragPrevious = null;
this.mediaBuffer = null;
@@ -242,7 +242,7 @@ export class SubtitleStreamController
onSubtitleTrackSwitch(
event: Events.SUBTITLE_TRACK_SWITCH,
data: TrackSwitchedData
data: TrackSwitchedData,
) {
this.currentTrackId = data.id;
@@ -266,7 +266,7 @@ export class SubtitleStreamController
// Got a new set of subtitle fragments.
onSubtitleTrackLoaded(
event: Events.SUBTITLE_TRACK_LOADED,
data: TrackLoadedData
data: TrackLoadedData,
) {
const { details: newDetails, id: trackId } = data;
const { currentTrackId, levels } = this;
@@ -324,7 +324,7 @@ export class SubtitleStreamController
null,
newDetails.fragments,
this.media.currentTime,
0
0,
);
if (!foundFrag) {
this.warn('Subtitle playlist not aligned with playback');
@@ -356,7 +356,7 @@ export class SubtitleStreamController
.decrypt(
new Uint8Array(payload),
decryptData.key.buffer,
decryptData.iv.buffer
decryptData.iv.buffer,
)
.catch((err) => {
hls.trigger(Events.ERROR, {
@@ -404,13 +404,13 @@ export class SubtitleStreamController
const bufferedInfo = BufferHelper.bufferedInfo(
this.tracksBuffered[this.currentTrackId] || [],
currentTime,
config.maxBufferHole
config.maxBufferHole,
);
const { end: targetBufferTime, len: bufferLen } = bufferedInfo;
const mainBufferInfo = this.getFwdBufferInfo(
this.media,
PlaylistLevelType.MAIN
PlaylistLevelType.MAIN,
);
const trackDetails = track.details as LevelDetails;
const maxBufLen =
@@ -434,7 +434,7 @@ export class SubtitleStreamController
fragPrevious,
fragments,
Math.max(fragments[0].start, targetBufferTime),
lookupTolerance
lookupTolerance,
);
if (
!foundFrag &&
@@ -482,7 +482,7 @@ export class SubtitleStreamController
protected loadFragment(
frag: Fragment,
level: Level,
targetBufferTime: number
targetBufferTime: number,
) {
this.fragCurrent = frag;
if (frag.sn === 'initSegment') {
@@ -495,7 +495,7 @@ export class SubtitleStreamController
get mediaBufferTimeRanges(): Bufferable {
return new BufferableInstance(
this.tracksBuffered[this.currentTrackId] || []
this.tracksBuffered[this.currentTrackId] || [],
);
}
}
@@ -507,12 +507,12 @@ class BufferableInstance implements Bufferable {
const getRange = (
name: 'start' | 'end',
index: number,
length: number
length: number,
): number => {
index = index >>> 0;
if (index > length - 1) {
throw new DOMException(
`Failed to execute '${name}' on 'TimeRanges': The index provided (${index}) is greater than the maximum bound (${length})`
`Failed to execute '${name}' on 'TimeRanges': The index provided (${index}) is greater than the maximum bound (${length})`,
);
}
return timeranges[index][name];
+15 -15
View File
@@ -79,7 +79,7 @@ class SubtitleTrackController extends BasePlaylistController {
// Listen for subtitle track change, then extract the current track ID.
protected onMediaAttached(
event: Events.MEDIA_ATTACHED,
data: MediaAttachedData
data: MediaAttachedData,
): void {
this.media = data.media;
if (!this.media) {
@@ -99,7 +99,7 @@ class SubtitleTrackController extends BasePlaylistController {
} else {
this.media.textTracks.addEventListener(
'change',
this.asyncPollTrackChange
this.asyncPollTrackChange,
);
}
}
@@ -108,7 +108,7 @@ class SubtitleTrackController extends BasePlaylistController {
self.clearInterval(this.subtitlePollingInterval);
this.subtitlePollingInterval = self.setInterval(
this.trackChangeListener,
timeout
timeout,
);
}
@@ -121,7 +121,7 @@ class SubtitleTrackController extends BasePlaylistController {
if (!this.useTextTrackPolling) {
this.media.textTracks.removeEventListener(
'change',
this.asyncPollTrackChange
this.asyncPollTrackChange,
);
}
@@ -150,14 +150,14 @@ class SubtitleTrackController extends BasePlaylistController {
// Fired whenever a new manifest is loaded.
protected onManifestParsed(
event: Events.MANIFEST_PARSED,
data: ManifestParsedData
data: ManifestParsedData,
): void {
this.tracks = data.subtitleTracks;
}
protected onSubtitleTrackLoaded(
event: Events.SUBTITLE_TRACK_LOADED,
data: TrackLoadedData
data: TrackLoadedData,
): void {
const { id, details } = data;
const { trackId } = this;
@@ -171,7 +171,7 @@ class SubtitleTrackController extends BasePlaylistController {
const curDetails = currentTrack.details;
currentTrack.details = data.details;
this.log(
`subtitle track ${id} loaded [${details.startSN}-${details.endSN}]`
`subtitle track ${id} loaded [${details.startSN}-${details.endSN}]`,
);
if (id === this.trackId) {
@@ -181,14 +181,14 @@ class SubtitleTrackController extends BasePlaylistController {
protected onLevelLoading(
event: Events.LEVEL_LOADING,
data: LevelLoadingData
data: LevelLoadingData,
): void {
this.switchLevel(data.level);
}
protected onLevelSwitching(
event: Events.LEVEL_SWITCHING,
data: LevelSwitchingData
data: LevelSwitchingData,
): void {
this.switchLevel(data.level);
}
@@ -204,7 +204,7 @@ class SubtitleTrackController extends BasePlaylistController {
: undefined;
if (this.groupId !== textGroupId) {
const subtitleTracks = this.tracks.filter(
(track): boolean => !textGroupId || track.groupId === textGroupId
(track): boolean => !textGroupId || track.groupId === textGroupId,
);
this.tracksInGroup = subtitleTracks;
const initialTrackId =
@@ -215,7 +215,7 @@ class SubtitleTrackController extends BasePlaylistController {
subtitleTracks,
};
this.log(
`Updating subtitle tracks, ${subtitleTracks.length} track(s) found in "${textGroupId}" group-id`
`Updating subtitle tracks, ${subtitleTracks.length} track(s) found in "${textGroupId}" group-id`,
);
this.hls.trigger(Events.SUBTITLE_TRACKS_UPDATED, subtitleTracksUpdated);
@@ -289,7 +289,7 @@ class SubtitleTrackController extends BasePlaylistController {
url = hlsUrlParameters.addDirectives(url);
} catch (error) {
this.warn(
`Could not construct new URL with HLS Delivery Directives: ${error}`
`Could not construct new URL with HLS Delivery Directives: ${error}`,
);
}
}
@@ -316,7 +316,7 @@ class SubtitleTrackController extends BasePlaylistController {
const textTracks = filterSubtitleTracks(media.textTracks);
const groupTracks = textTracks.filter(
(track) => (track as any).groupId === this.groupId
(track) => (track as any).groupId === this.groupId,
);
if (newId === -1) {
[].slice.call(textTracks).forEach((track) => {
@@ -341,7 +341,7 @@ class SubtitleTrackController extends BasePlaylistController {
*/
private setSubtitleTrack(
newId: number,
lastTrack: MediaPlaylist | undefined
lastTrack: MediaPlaylist | undefined,
): void {
const tracks = this.tracksInGroup;
@@ -376,7 +376,7 @@ class SubtitleTrackController extends BasePlaylistController {
`Switching to subtitle-track ${newId}` +
(track
? ` "${track.name}" lang:${track.lang} group:${track.groupId}`
: '')
: ''),
);
this.trackId = newId;
if (track) {
+21 -21
View File
@@ -149,7 +149,7 @@ export class TimelineController implements ComponentAPI {
startTime: number,
endTime: number,
screen: CaptionScreen,
cueRanges: Array<[number, number]>
cueRanges: Array<[number, number]>,
) {
// skip cues which overlap more than 50% with previously parsed time ranges
let merged = false;
@@ -159,7 +159,7 @@ export class TimelineController implements ComponentAPI {
cueRange[0],
cueRange[1],
startTime,
endTime
endTime,
);
if (overlap >= 0) {
cueRange[0] = Math.min(cueRange[0], startTime);
@@ -190,7 +190,7 @@ export class TimelineController implements ComponentAPI {
// Triggered when an initial PTS is found; used for synchronisation of WebVTT.
private onInitPtsFound(
event: Events.INIT_PTS_FOUND,
{ frag, id, initPTS, timescale }: InitPTSFoundData
{ frag, id, initPTS, timescale }: InitPTSFoundData,
) {
const { unparsedVttFrags } = this;
if (id === 'main') {
@@ -274,7 +274,7 @@ export class TimelineController implements ComponentAPI {
private createTextTrack(
kind: TextTrackKind,
label: string,
lang?: string
lang?: string,
): TextTrack | undefined {
const media = this.media;
if (!media) {
@@ -285,7 +285,7 @@ export class TimelineController implements ComponentAPI {
private onMediaAttaching(
event: Events.MEDIA_ATTACHING,
data: MediaAttachingData
data: MediaAttachingData,
) {
this.media = data.media;
this._cleanTracks();
@@ -338,7 +338,7 @@ export class TimelineController implements ComponentAPI {
private onSubtitleTracksUpdated(
event: Events.SUBTITLE_TRACKS_UPDATED,
data: SubtitleTracksUpdatedData
data: SubtitleTracksUpdatedData,
) {
const tracks: Array<MediaPlaylist> = data.subtitleTracks || [];
const hasIMSC1 = tracks.some((track) => track.textCodec === IMSC1_CODEC);
@@ -379,7 +379,7 @@ export class TimelineController implements ComponentAPI {
textTrack = this.createTextTrack(
textTrackKind,
track.name,
track.lang
track.lang,
);
if (textTrack) {
textTrack.mode = 'disabled';
@@ -408,7 +408,7 @@ export class TimelineController implements ComponentAPI {
}
private _captionsOrSubtitlesFromCharacteristics(
track: MediaPlaylist
track: MediaPlaylist,
): TextTrackKind {
if (track.attrs.CHARACTERISTICS) {
if (
@@ -424,12 +424,12 @@ export class TimelineController implements ComponentAPI {
private onManifestLoaded(
event: Events.MANIFEST_LOADED,
data: ManifestLoadedData
data: ManifestLoadedData,
) {
if (this.config.enableCEA708Captions && data.captions) {
data.captions.forEach((captionsTrack) => {
const instreamIdMatch = /(?:CC|SERVICE)([1-4])/.exec(
captionsTrack.instreamId as string
captionsTrack.instreamId as string,
);
if (!instreamIdMatch) {
return;
@@ -483,7 +483,7 @@ export class TimelineController implements ComponentAPI {
private onFragLoaded(
event: Events.FRAG_LOADED,
data: FragDecryptedData | FragLoadedData
data: FragDecryptedData | FragLoadedData,
) {
const { frag, payload } = data;
if (frag.type === PlaylistLevelType.SUBTITLE) {
@@ -543,7 +543,7 @@ export class TimelineController implements ComponentAPI {
frag: frag,
error,
});
}
},
);
}
@@ -593,7 +593,7 @@ export class TimelineController implements ComponentAPI {
frag: frag,
error,
});
}
},
);
}
@@ -610,7 +610,7 @@ export class TimelineController implements ComponentAPI {
},
() => {
trackPlaylistMedia.textCodec = 'wvtt';
}
},
);
}
}
@@ -639,7 +639,7 @@ export class TimelineController implements ComponentAPI {
private onFragDecrypted(
event: Events.FRAG_DECRYPTED,
data: FragDecryptedData
data: FragDecryptedData,
) {
const { frag } = data;
if (frag.type === PlaylistLevelType.SUBTITLE) {
@@ -654,7 +654,7 @@ export class TimelineController implements ComponentAPI {
private onFragParsingUserdata(
event: Events.FRAG_PARSING_USERDATA,
data: FragParsingUserdataData
data: FragParsingUserdataData,
) {
if (!this.enabled) {
return;
@@ -685,7 +685,7 @@ export class TimelineController implements ComponentAPI {
onBufferFlushing(
event: Events.BUFFER_FLUSHING,
{ startOffset, endOffset, endOffsetSubtitles, type }: BufferFlushingData
{ startOffset, endOffset, endOffsetSubtitles, type }: BufferFlushingData,
) {
const { media } = this;
if (!media || media.currentTime < endOffset) {
@@ -696,7 +696,7 @@ export class TimelineController implements ComponentAPI {
if (!type || type === 'video') {
const { captionsTracks } = this;
Object.keys(captionsTracks).forEach((trackName) =>
removeCuesInRange(captionsTracks[trackName], startOffset, endOffset)
removeCuesInRange(captionsTracks[trackName], startOffset, endOffset),
);
}
if (this.config.renderTextTracksNatively) {
@@ -707,8 +707,8 @@ export class TimelineController implements ComponentAPI {
removeCuesInRange(
textTracks[trackName],
startOffset,
endOffsetSubtitles
)
endOffsetSubtitles,
),
);
}
}
@@ -745,7 +745,7 @@ export class TimelineController implements ComponentAPI {
function canReuseVttTextTrack(
inUseTrack: (TextTrack & { textTrack1?; textTrack2? }) | null,
manifestTrack: MediaPlaylist
manifestTrack: MediaPlaylist,
): boolean {
return (
!!inUseTrack &&
+4 -4
View File
@@ -81,7 +81,7 @@ export default class Decrypter {
public decrypt(
data: Uint8Array | ArrayBuffer,
key: ArrayBuffer,
iv: ArrayBuffer
iv: ArrayBuffer,
): Promise<ArrayBuffer> {
if (this.useSoftware) {
return new Promise((resolve, reject) => {
@@ -102,7 +102,7 @@ export default class Decrypter {
public softwareDecrypt(
data: Uint8Array,
key: ArrayBuffer,
iv: ArrayBuffer
iv: ArrayBuffer,
): ArrayBuffer | null {
const { currentIV, currentResult, remainderData } = this;
this.logOnce('JS AES decrypt');
@@ -146,7 +146,7 @@ export default class Decrypter {
public webCryptoDecrypt(
data: Uint8Array,
key: ArrayBuffer,
iv: ArrayBuffer
iv: ArrayBuffer,
): Promise<ArrayBuffer> {
const subtle = this.subtle;
if (this.key !== key || !this.fastAesKey) {
@@ -166,7 +166,7 @@ export default class Decrypter {
})
.catch((err) => {
logger.warn(
`[decrypter]: WebCrypto Error, disable WebCrypto API, ${err.name}: ${err.message}`
`[decrypter]: WebCrypto Error, disable WebCrypto API, ${err.name}: ${err.message}`,
);
return this.onWebCryptoError(data, key, iv);
+3 -3
View File
@@ -22,7 +22,7 @@ class AACDemuxer extends BaseAudioDemuxer {
initSegment: Uint8Array | undefined,
audioCodec: string | undefined,
videoCodec: string | undefined,
trackDuration: number
trackDuration: number,
) {
super.resetInitSegment(initSegment, audioCodec, videoCodec, trackDuration);
this._audioTrack = {
@@ -72,14 +72,14 @@ class AACDemuxer extends BaseAudioDemuxer {
this.observer,
data,
offset,
track.manifestCodec
track.manifestCodec,
);
const frame = ADTS.appendFrame(
track,
data,
offset,
this.basePTS as number,
this.frameIndex
this.frameIndex,
);
if (frame && frame.missing === 0) {
return frame;
+4 -4
View File
@@ -16,7 +16,7 @@ export class AC3Demuxer extends BaseAudioDemuxer {
initSegment: Uint8Array | undefined,
audioCodec: string | undefined,
videoCodec: string | undefined,
trackDuration: number
trackDuration: number,
) {
super.resetInitSegment(initSegment, audioCodec, videoCodec, trackDuration);
this._audioTrack = {
@@ -41,14 +41,14 @@ export class AC3Demuxer extends BaseAudioDemuxer {
appendFrame(
track: DemuxedAudioTrack,
data: Uint8Array,
offset: number
offset: number,
): AudioFrame | void {
const frameLength = appendFrame(
track,
data,
offset,
this.basePTS as number,
this.frameIndex
this.frameIndex,
);
if (frameLength !== -1) {
const sample = track.samples[track.samples.length - 1];
@@ -86,7 +86,7 @@ export function appendFrame(
data: Uint8Array,
start: number,
pts: number,
frameIndex: number
frameIndex: number,
): number {
if (start + 8 > data.length) {
return -1; // not enough bytes left
+6 -6
View File
@@ -29,7 +29,7 @@ export function getAudioConfig(
observer,
data: Uint8Array,
offset: number,
audioCodec: string
audioCodec: string,
): AudioConfig | void {
let adtsObjectType: number;
let adtsExtensionSamplingIndex: number;
@@ -57,7 +57,7 @@ export function getAudioConfig(
// byte 3
adtsChannelConfig |= (data[offset + 3] & 0xc0) >>> 6;
logger.log(
`manifest codec:${audioCodec}, ADTS type:${adtsObjectType}, samplingIndex:${adtsSamplingIndex}`
`manifest codec:${audioCodec}, ADTS type:${adtsObjectType}, samplingIndex:${adtsSamplingIndex}`,
);
// firefox: freq less than 24kHz = AAC SBR (HE-AAC)
if (/firefox/i.test(userAgent)) {
@@ -230,7 +230,7 @@ export function initTrackConfig(
observer: HlsEventEmitter,
data: Uint8Array,
offset: number,
audioCodec: string
audioCodec: string,
) {
if (!track.samplerate) {
const config = getAudioConfig(observer, data, offset, audioCodec);
@@ -243,7 +243,7 @@ export function initTrackConfig(
track.codec = config.codec;
track.manifestCodec = config.manifestCodec;
logger.log(
`parsed codec:${track.codec}, rate:${config.samplerate}, channels:${config.channelCount}`
`parsed codec:${track.codec}, rate:${config.samplerate}, channels:${config.channelCount}`,
);
}
}
@@ -254,7 +254,7 @@ export function getFrameDuration(samplerate: number): number {
export function parseFrameHeader(
data: Uint8Array,
offset: number
offset: number,
): FrameHeader | void {
// The protection skip bit tells us if we have 2 bytes of CRC data at the end of the ADTS header
const headerLength = getHeaderLength(data, offset);
@@ -273,7 +273,7 @@ export function appendFrame(
data: Uint8Array,
offset: number,
pts: number,
frameIndex: number
frameIndex: number,
): AudioFrame {
const frameDuration = getFrameDuration(track.samplerate as number);
const stamp = pts + frameIndex * frameDuration;
+7 -5
View File
@@ -28,7 +28,7 @@ class BaseAudioDemuxer implements Demuxer {
initSegment: Uint8Array | undefined,
audioCodec: string | undefined,
videoCodec: string | undefined,
trackDuration: number
trackDuration: number,
) {
this._id3Track = {
type: 'id3',
@@ -59,7 +59,7 @@ class BaseAudioDemuxer implements Demuxer {
appendFrame(
track: DemuxedAudioTrack,
data: Uint8Array,
offset: number
offset: number,
): AudioFrame | void {}
// feed incoming data to the front of the parsing pipeline
@@ -147,10 +147,12 @@ class BaseAudioDemuxer implements Demuxer {
demuxSampleAes(
data: Uint8Array,
keyData: KeyData,
timeOffset: number
timeOffset: number,
): Promise<DemuxerResult> {
return Promise.reject(
new Error(`[${this}] This demuxer does not support Sample-AES decryption`)
new Error(
`[${this}] This demuxer does not support Sample-AES decryption`,
),
);
}
@@ -182,7 +184,7 @@ class BaseAudioDemuxer implements Demuxer {
export const initPTSFn = (
timestamp: number | undefined,
timeOffset: number,
initPTS: RationalTimestamp | null
initPTS: RationalTimestamp | null,
): number => {
if (Number.isFinite(timestamp as number)) {
return timestamp! * 90;
+2 -2
View File
@@ -12,7 +12,7 @@ class MP3Demuxer extends BaseAudioDemuxer {
initSegment: Uint8Array | undefined,
audioCodec: string | undefined,
videoCodec: string | undefined,
trackDuration: number
trackDuration: number,
) {
super.resetInitSegment(initSegment, audioCodec, videoCodec, trackDuration);
this._audioTrack = {
@@ -76,7 +76,7 @@ class MP3Demuxer extends BaseAudioDemuxer {
data,
offset,
this.basePTS,
this.frameIndex
this.frameIndex,
);
}
}
+1 -1
View File
@@ -60,7 +60,7 @@ export function appendFrame(
data: Uint8Array,
offset: number,
pts: number,
frameIndex: number
frameIndex: number,
) {
// Using http://www.datavoyage.com/mpgscript/mpeghdr.htm as a reference
if (offset + 24 > data.length) {
+1 -1
View File
@@ -29,7 +29,7 @@ export default class ChunkCache {
function concatUint8Arrays(
chunks: Array<Uint8Array>,
dataLength: number
dataLength: number,
): Uint8Array {
const result = new Uint8Array(dataLength);
let offset = 0;
+6 -6
View File
@@ -91,7 +91,7 @@ export const isFooter = (data: Uint8Array, offset: number): boolean => {
*/
export const getID3Data = (
data: Uint8Array,
offset: number
offset: number,
): Uint8Array | undefined => {
const front = offset;
let length = 0;
@@ -222,7 +222,7 @@ export const decodeFrame = (frame: RawFrame): Frame | undefined => {
};
const decodePrivFrame = (
frame: RawFrame
frame: RawFrame,
): DecodedFrame<ArrayBuffer> | undefined => {
/*
Format: <text string>\0<binary data>
@@ -279,7 +279,7 @@ const decodeURLFrame = (frame: RawFrame): DecodedFrame<string> | undefined => {
let index = 1;
const description: string = utf8ArrayToStr(
frame.data.subarray(index),
true
true,
);
index += description.length + 1;
@@ -296,7 +296,7 @@ const decodeURLFrame = (frame: RawFrame): DecodedFrame<string> | undefined => {
};
const readTimeStamp = (
timeStampFrame: DecodedFrame<ArrayBuffer>
timeStampFrame: DecodedFrame<ArrayBuffer>,
): number | undefined => {
if (timeStampFrame.data.byteLength === 8) {
const data = new Uint8Array(timeStampFrame.data);
@@ -328,7 +328,7 @@ const readTimeStamp = (
*/
export const utf8ArrayToStr = (
array: Uint8Array,
exitOnNull: boolean = false
exitOnNull: boolean = false,
): string => {
const decoder = getTextDecoder();
if (decoder) {
@@ -381,7 +381,7 @@ export const utf8ArrayToStr = (
char2 = array[i++];
char3 = array[i++];
out += String.fromCharCode(
((c & 0x0f) << 12) | ((char2 & 0x3f) << 6) | ((char3 & 0x3f) << 0)
((c & 0x0f) << 12) | ((char2 & 0x3f) << 6) | ((char3 & 0x3f) << 0),
);
break;
default:
+1 -1
View File
@@ -19,7 +19,7 @@ export function injectWorker(): WorkerContext {
],
{
type: 'text/javascript',
}
},
);
const objectURL = self.URL.createObjectURL(blob);
const worker = new self.Worker(objectURL);
+7 -7
View File
@@ -45,19 +45,19 @@ class MP4Demuxer implements Demuxer {
initSegment: Uint8Array | undefined,
audioCodec: string | undefined,
videoCodec: string | undefined,
trackDuration: number
trackDuration: number,
) {
const videoTrack = (this.videoTrack = dummyTrack(
'video',
1
1,
) as PassthroughTrack);
const audioTrack = (this.audioTrack = dummyTrack(
'audio',
1
1,
) as DemuxedAudioTrack);
const captionTrack = (this.txtTrack = dummyTrack(
'text',
1
1,
) as DemuxedUserdataTrack);
this.id3Track = dummyTrack('id3', 1) as DemuxedMetadataTrack;
@@ -148,7 +148,7 @@ class MP4Demuxer implements Demuxer {
private extractID3Track(
videoTrack: PassthroughTrack,
timeOffset: number
timeOffset: number,
): DemuxedMetadataTrack {
const id3Track = this.id3Track as DemuxedMetadataTrack;
if (videoTrack.samples.length) {
@@ -188,10 +188,10 @@ class MP4Demuxer implements Demuxer {
demuxSampleAes(
data: Uint8Array,
keyData: KeyData,
timeOffset: number
timeOffset: number,
): Promise<DemuxerResult> {
return Promise.reject(
new Error('The MP4 demuxer does not support SAMPLE-AES decryption')
new Error('The MP4 demuxer does not support SAMPLE-AES decryption'),
);
}
+12 -12
View File
@@ -29,7 +29,7 @@ class SampleAesDecrypter {
return this.decrypter.decrypt(
encryptedData,
this.keyData.key.buffer,
this.keyData.iv.buffer
this.keyData.iv.buffer,
);
}
@@ -37,7 +37,7 @@ class SampleAesDecrypter {
private decryptAacSample(
samples: AudioSample[],
sampleIndex: number,
callback: () => void
callback: () => void,
) {
const curUnit = samples[sampleIndex].unit;
if (curUnit.length <= 16) {
@@ -47,11 +47,11 @@ class SampleAesDecrypter {
}
const encryptedData = curUnit.subarray(
16,
curUnit.length - (curUnit.length % 16)
curUnit.length - (curUnit.length % 16),
);
const encryptedBuffer = encryptedData.buffer.slice(
encryptedData.byteOffset,
encryptedData.byteOffset + encryptedData.length
encryptedData.byteOffset + encryptedData.length,
);
this.decryptBuffer(encryptedBuffer).then((decryptedBuffer: ArrayBuffer) => {
@@ -67,7 +67,7 @@ class SampleAesDecrypter {
decryptAacSamples(
samples: AudioSample[],
sampleIndex: number,
callback: () => void
callback: () => void,
) {
for (; ; sampleIndex++) {
if (sampleIndex >= samples.length) {
@@ -100,7 +100,7 @@ class SampleAesDecrypter {
) {
encryptedData.set(
decodedData.subarray(inputPos, inputPos + 16),
outputPos
outputPos,
);
}
@@ -109,7 +109,7 @@ class SampleAesDecrypter {
getAvcDecryptedUnit(
decodedData: Uint8Array,
decryptedData: ArrayLike<number> | ArrayBuffer | SharedArrayBuffer
decryptedData: ArrayLike<number> | ArrayBuffer | SharedArrayBuffer,
) {
const uint8DecryptedData = new Uint8Array(decryptedData);
let inputPos = 0;
@@ -120,7 +120,7 @@ class SampleAesDecrypter {
) {
decodedData.set(
uint8DecryptedData.subarray(inputPos, inputPos + 16),
outputPos
outputPos,
);
}
@@ -132,7 +132,7 @@ class SampleAesDecrypter {
sampleIndex: number,
unitIndex: number,
callback: () => void,
curUnit: VideoSampleUnit
curUnit: VideoSampleUnit,
) {
const decodedData = discardEPB(curUnit.data);
const encryptedData = this.getAvcEncryptedData(decodedData);
@@ -144,7 +144,7 @@ class SampleAesDecrypter {
if (!this.decrypter.isSync()) {
this.decryptAvcSamples(samples, sampleIndex, unitIndex + 1, callback);
}
}
},
);
}
@@ -152,7 +152,7 @@ class SampleAesDecrypter {
samples: DemuxedVideoTrackBase['samples'],
sampleIndex: number,
unitIndex: number,
callback: () => void
callback: () => void,
) {
if (samples instanceof Uint8Array) {
throw new Error('Cannot decrypt samples of type Uint8Array');
@@ -183,7 +183,7 @@ class SampleAesDecrypter {
sampleIndex,
unitIndex,
callback,
curUnit
curUnit,
);
if (!this.decrypter.isSync()) {
+15 -15
View File
@@ -42,7 +42,7 @@ export default class TransmuxerInterface {
hls: Hls,
id: PlaylistLevelType,
onTransmuxComplete: (transmuxResult: TransmuxerResult) => void,
onFlush: (chunkMeta: ChunkMetadata) => void
onFlush: (chunkMeta: ChunkMetadata) => void,
) {
const config = hls.config;
this.hls = hls;
@@ -93,7 +93,7 @@ export default class TransmuxerInterface {
worker.addEventListener('message', this.onwmsg as any);
worker.onerror = (event) => {
const error = new Error(
`${event.message} (${event.filename}:${event.lineno})`
`${event.message} (${event.filename}:${event.lineno})`,
);
config.enableWorker = false;
logger.warn(`Error in "${id}" Web Worker, fallback to inline`);
@@ -115,7 +115,7 @@ export default class TransmuxerInterface {
} catch (err) {
logger.warn(
`Error setting up "${id}" Web Worker, fallback to inline`,
err
err,
);
this.resetWorker();
this.error = null;
@@ -124,7 +124,7 @@ export default class TransmuxerInterface {
m2tsTypeSupported,
config,
vendor,
id
id,
);
}
return;
@@ -136,7 +136,7 @@ export default class TransmuxerInterface {
m2tsTypeSupported,
config,
vendor,
id
id,
);
}
@@ -186,7 +186,7 @@ export default class TransmuxerInterface {
duration: number,
accurateTimeOffset: boolean,
chunkMeta: ChunkMetadata,
defaultInitPTS?: RationalTimestamp
defaultInitPTS?: RationalTimestamp,
): void {
chunkMeta.transmuxing.start = self.performance.now();
const { transmuxer } = this;
@@ -224,7 +224,7 @@ export default class TransmuxerInterface {
accurateTimeOffset,
trackSwitch,
timeOffset,
initSegmentChange
initSegmentChange,
);
if (!contiguous || discontinuity || initSegmentChange) {
logger.log(`[transmuxer-interface, ${frag.type}]: Starting new transmux session for sn: ${chunkMeta.sn} p: ${chunkMeta.part} level: ${chunkMeta.level} id: ${chunkMeta.id}
@@ -239,7 +239,7 @@ export default class TransmuxerInterface {
videoCodec,
initSegmentData,
duration,
defaultInitPTS
defaultInitPTS,
);
this.configureTransmuxer(config);
}
@@ -258,14 +258,14 @@ export default class TransmuxerInterface {
chunkMeta,
state,
},
data instanceof ArrayBuffer ? [data] : []
data instanceof ArrayBuffer ? [data] : [],
);
} else if (transmuxer) {
const transmuxResult = transmuxer.push(
data,
decryptdata,
chunkMeta,
state
state,
);
if (isPromise(transmuxResult)) {
transmuxer.async = true;
@@ -277,7 +277,7 @@ export default class TransmuxerInterface {
this.transmuxerError(
error,
chunkMeta,
'transmuxer-interface push error'
'transmuxer-interface push error',
);
});
} else {
@@ -311,13 +311,13 @@ export default class TransmuxerInterface {
this.transmuxerError(
error,
chunkMeta,
'transmuxer-interface flush error'
'transmuxer-interface flush error',
);
});
} else {
this.handleFlushResult(
transmuxResult as Array<TransmuxerResult>,
chunkMeta
chunkMeta,
);
}
}
@@ -326,7 +326,7 @@ export default class TransmuxerInterface {
private transmuxerError(
error: Error,
chunkMeta: ChunkMetadata,
reason: string
reason: string,
) {
if (!this.hls) {
return;
@@ -345,7 +345,7 @@ export default class TransmuxerInterface {
private handleFlushResult(
results: Array<TransmuxerResult>,
chunkMeta: ChunkMetadata
chunkMeta: ChunkMetadata,
) {
results.forEach((result) => {
this.handleTransmuxComplete(result);
+8 -8
View File
@@ -44,7 +44,7 @@ function startWorker(self) {
data.typeSupported,
config,
data.vendor,
data.id
data.id,
);
enableLogs(config.debug, data.id);
forwardWorkerLogs();
@@ -61,7 +61,7 @@ function startWorker(self) {
data.data,
data.decryptdata,
data.chunkMeta,
data.state
data.state,
);
if (isPromise(transmuxResult)) {
self.transmuxer.async = true;
@@ -113,7 +113,7 @@ function startWorker(self) {
handleFlushResult(
self,
transmuxResult as Array<TransmuxerResult>,
id
id,
);
}
break;
@@ -126,7 +126,7 @@ function startWorker(self) {
function emitTransmuxComplete(
self: any,
transmuxResult: TransmuxerResult
transmuxResult: TransmuxerResult,
): boolean {
if (isEmptyResult(transmuxResult.remuxResult)) {
return false;
@@ -141,7 +141,7 @@ function emitTransmuxComplete(
}
self.postMessage(
{ event: 'transmuxComplete', data: transmuxResult },
transferable
transferable,
);
return true;
}
@@ -150,7 +150,7 @@ function emitTransmuxComplete(
// in order to minimize message passing overhead
function addToTransferable(
transferable: Array<ArrayBuffer>,
track: RemuxedTrack
track: RemuxedTrack,
) {
if (track.data1) {
transferable.push(track.data1.buffer);
@@ -163,11 +163,11 @@ function addToTransferable(
function handleFlushResult(
self: any,
results: Array<TransmuxerResult>,
chunkMeta: ChunkMetadata
chunkMeta: ChunkMetadata,
) {
const parsed = results.reduce(
(parsed, result) => emitTransmuxComplete(self, result) || parsed,
false
false,
);
if (!parsed) {
// Emit at least one "transmuxComplete" message even if media is not found to update stream-controller state to PARSING
+24 -24
View File
@@ -65,7 +65,7 @@ export default class Transmuxer {
typeSupported: TypeSupported,
config: HlsConfig,
vendor: string,
id: PlaylistLevelType
id: PlaylistLevelType,
) {
this.observer = observer;
this.typeSupported = typeSupported;
@@ -85,7 +85,7 @@ export default class Transmuxer {
data: ArrayBuffer,
decryptdata: DecryptData | null,
chunkMeta: ChunkMetadata,
state?: TransmuxState
state?: TransmuxState,
): TransmuxerResult | Promise<TransmuxerResult> {
const stats = chunkMeta.transmuxing;
stats.executeStart = now();
@@ -122,7 +122,7 @@ export default class Transmuxer {
let decryptedData = decrypter.softwareDecrypt(
uintData,
keyData.key.buffer,
keyData.iv.buffer
keyData.iv.buffer,
);
// For Low-Latency HLS Parts, decrypt in place, since part parsing is expected on push progress
const loadingParts = chunkMeta.part > -1;
@@ -143,7 +143,7 @@ export default class Transmuxer {
const result = this.push(
decryptedData,
null,
chunkMeta
chunkMeta,
) as TransmuxerResult;
this.decryptionPromise = null;
return result;
@@ -175,7 +175,7 @@ export default class Transmuxer {
audioCodec,
videoCodec,
duration,
decryptdata
decryptdata,
);
}
@@ -192,7 +192,7 @@ export default class Transmuxer {
keyData,
timeOffset,
accurateTimeOffset,
chunkMeta
chunkMeta,
);
const currentState = this.currentTransmuxState;
@@ -206,7 +206,7 @@ export default class Transmuxer {
// Due to data caching, flush calls can produce more than one TransmuxerResult (hence the Array type)
flush(
chunkMeta: ChunkMetadata
chunkMeta: ChunkMetadata,
): TransmuxerResult[] | Promise<TransmuxerResult[]> {
const stats = chunkMeta.transmuxing;
stats.executeStart = now();
@@ -231,7 +231,7 @@ export default class Transmuxer {
if (decryptedData) {
// Push always returns a TransmuxerResult if decryptdata is null
transmuxResults.push(
this.push(decryptedData, null, chunkMeta) as TransmuxerResult
this.push(decryptedData, null, chunkMeta) as TransmuxerResult,
);
}
}
@@ -259,14 +259,14 @@ export default class Transmuxer {
private flushRemux(
transmuxResults: TransmuxerResult[],
demuxResult: DemuxerResult,
chunkMeta: ChunkMetadata
chunkMeta: ChunkMetadata,
) {
const { audioTrack, videoTrack, id3Track, textTrack } = demuxResult;
const { accurateTimeOffset, timeOffset } = this.currentTransmuxState;
logger.log(
`[transmuxer.ts]: Flushed fragment ${chunkMeta.sn}${
chunkMeta.part > -1 ? ' p: ' + chunkMeta.part : ''
} of level ${chunkMeta.level}`
} of level ${chunkMeta.level}`,
);
const remuxResult = this.remuxer!.remux(
audioTrack,
@@ -276,7 +276,7 @@ export default class Transmuxer {
timeOffset,
accurateTimeOffset,
true,
this.id
this.id,
);
transmuxResults.push({
remuxResult,
@@ -309,7 +309,7 @@ export default class Transmuxer {
audioCodec: string | undefined,
videoCodec: string | undefined,
trackDuration: number,
decryptdata: DecryptData | null
decryptdata: DecryptData | null,
) {
const { demuxer, remuxer } = this;
if (!demuxer || !remuxer) {
@@ -319,13 +319,13 @@ export default class Transmuxer {
initSegmentData,
audioCodec,
videoCodec,
trackDuration
trackDuration,
);
remuxer.resetInitSegment(
initSegmentData,
audioCodec,
videoCodec,
decryptdata
decryptdata,
);
}
@@ -345,7 +345,7 @@ export default class Transmuxer {
keyData: KeyData | null,
timeOffset: number,
accurateTimeOffset: boolean,
chunkMeta: ChunkMetadata
chunkMeta: ChunkMetadata,
): TransmuxerResult | Promise<TransmuxerResult> {
let result: TransmuxerResult | Promise<TransmuxerResult>;
if (keyData && keyData.method === 'SAMPLE-AES') {
@@ -354,14 +354,14 @@ export default class Transmuxer {
keyData,
timeOffset,
accurateTimeOffset,
chunkMeta
chunkMeta,
);
} else {
result = this.transmuxUnencrypted(
data,
timeOffset,
accurateTimeOffset,
chunkMeta
chunkMeta,
);
}
return result;
@@ -371,7 +371,7 @@ export default class Transmuxer {
data: Uint8Array,
timeOffset: number,
accurateTimeOffset: boolean,
chunkMeta: ChunkMetadata
chunkMeta: ChunkMetadata,
): TransmuxerResult {
const { audioTrack, videoTrack, id3Track, textTrack } = (
this.demuxer as Demuxer
@@ -384,7 +384,7 @@ export default class Transmuxer {
timeOffset,
accurateTimeOffset,
false,
this.id
this.id,
);
return {
remuxResult,
@@ -397,7 +397,7 @@ export default class Transmuxer {
decryptData: KeyData,
timeOffset: number,
accurateTimeOffset: boolean,
chunkMeta: ChunkMetadata
chunkMeta: ChunkMetadata,
): Promise<TransmuxerResult> {
return (this.demuxer as Demuxer)
.demuxSampleAes(data, decryptData, timeOffset)
@@ -410,7 +410,7 @@ export default class Transmuxer {
timeOffset,
accurateTimeOffset,
false,
this.id
this.id,
);
return {
remuxResult,
@@ -463,7 +463,7 @@ export default class Transmuxer {
function getEncryptionType(
data: Uint8Array,
decryptData: DecryptData | null
decryptData: DecryptData | null,
): KeyData | null {
let encryptionType: KeyData | null = null;
if (
@@ -499,7 +499,7 @@ export class TransmuxConfig {
videoCodec: string | undefined,
initSegmentData: Uint8Array | undefined,
duration: number,
defaultInitPts?: RationalTimestamp
defaultInitPts?: RationalTimestamp,
) {
this.audioCodec = audioCodec;
this.videoCodec = videoCodec;
@@ -523,7 +523,7 @@ export class TransmuxState {
accurateTimeOffset: boolean,
trackSwitch: boolean,
timeOffset: number,
initSegmentChange: boolean
initSegmentChange: boolean,
) {
this.discontinuity = discontinuity;
this.contiguous = contiguous;
+25 -25
View File
@@ -79,7 +79,7 @@ class TSDemuxer implements Demuxer {
constructor(
observer: HlsEventEmitter,
config: HlsConfig,
typeSupported: TypeSupported
typeSupported: TypeSupported,
) {
this.observer = observer;
this.config = config;
@@ -91,7 +91,7 @@ class TSDemuxer implements Demuxer {
const syncOffset = TSDemuxer.syncOffset(data);
if (syncOffset > 0) {
logger.warn(
`MPEG2-TS detected but first sync word found @ offset ${syncOffset}`
`MPEG2-TS detected but first sync word found @ offset ${syncOffset}`,
);
}
return syncOffset !== -1;
@@ -117,7 +117,7 @@ class TSDemuxer implements Demuxer {
scanwindow =
Math.min(
packetStart + PACKET_LENGTH * 99,
data.length - PACKET_LENGTH
data.length - PACKET_LENGTH,
) + 1;
}
}
@@ -150,7 +150,7 @@ class TSDemuxer implements Demuxer {
*/
static createTrack(
type: 'audio' | 'video' | 'id3' | 'text',
duration?: number
duration?: number,
): DemuxedTrack {
return {
container:
@@ -174,7 +174,7 @@ class TSDemuxer implements Demuxer {
initSegment: Uint8Array | undefined,
audioCodec: string,
videoCodec: string,
trackDuration: number
trackDuration: number,
) {
this.pmtParsed = false;
this._pmtId = -1;
@@ -182,7 +182,7 @@ class TSDemuxer implements Demuxer {
this._videoTrack = TSDemuxer.createTrack('video') as DemuxedVideoTrack;
this._audioTrack = TSDemuxer.createTrack(
'audio',
trackDuration
trackDuration,
) as DemuxedAudioTrack;
this._id3Track = TSDemuxer.createTrack('id3') as DemuxedMetadataTrack;
this._txtTrack = TSDemuxer.createTrack('text') as DemuxedUserdataTrack;
@@ -217,7 +217,7 @@ class TSDemuxer implements Demuxer {
data: Uint8Array,
timeOffset: number,
isSampleAes = false,
flush = false
flush = false,
): DemuxerResult {
if (!isSampleAes) {
this.sampleAes = null;
@@ -263,7 +263,7 @@ class TSDemuxer implements Demuxer {
this.remainderData = new Uint8Array(
data.buffer,
len,
data.buffer.byteLength - len
data.buffer.byteLength - len,
);
}
@@ -295,7 +295,7 @@ class TSDemuxer implements Demuxer {
textTrack,
pes,
false,
this._duration
this._duration,
);
}
@@ -360,7 +360,7 @@ class TSDemuxer implements Demuxer {
data,
offset,
this.typeSupported,
isSampleAes
isSampleAes,
);
// only update track id if track PID found while parsing PMT
@@ -387,7 +387,7 @@ class TSDemuxer implements Demuxer {
if (unknownPID !== null && !pmtParsed) {
logger.warn(
`MPEG-TS PMT found at ${start} after unknown PID '${unknownPID}'. Backtracking to sync byte @${syncOffset} to parse all TS packets.`
`MPEG-TS PMT found at ${start} after unknown PID '${unknownPID}'. Backtracking to sync byte @${syncOffset} to parse all TS packets.`,
);
unknownPID = null;
// we set it to -188, the += 188 in the for loop will reset start to 0
@@ -410,7 +410,7 @@ class TSDemuxer implements Demuxer {
if (tsPacketErrors > 0) {
const error = new Error(
`Found ${tsPacketErrors} TS packet/s that do not start with 0x47`
`Found ${tsPacketErrors} TS packet/s that do not start with 0x47`,
);
this.observer.emit(Events.ERROR, Events.ERROR, {
type: ErrorTypes.MEDIA_ERROR,
@@ -473,7 +473,7 @@ class TSDemuxer implements Demuxer {
textTrack as DemuxedUserdataTrack,
pes,
true,
this._duration
this._duration,
);
videoTrack.pesData = null;
} else {
@@ -499,7 +499,7 @@ class TSDemuxer implements Demuxer {
} else {
if (audioData?.size) {
logger.log(
'last AAC PES packet truncated,might overlap between fragments'
'last AAC PES packet truncated,might overlap between fragments',
);
}
@@ -519,25 +519,25 @@ class TSDemuxer implements Demuxer {
public demuxSampleAes(
data: Uint8Array,
keyData: KeyData,
timeOffset: number
timeOffset: number,
): Promise<DemuxerResult> {
const demuxResult = this.demux(
data,
timeOffset,
true,
!this.config.progressive
!this.config.progressive,
);
const sampleAes = (this.sampleAes = new SampleAesDecrypter(
this.observer,
this.config,
keyData
keyData,
));
return this.decrypt(demuxResult, sampleAes);
}
private decrypt(
demuxResult: DemuxerResult,
sampleAes: SampleAesDecrypter
sampleAes: SampleAesDecrypter,
): Promise<DemuxerResult> {
return new Promise((resolve) => {
const { audioTrack, videoTrack } = demuxResult;
@@ -578,7 +578,7 @@ class TSDemuxer implements Demuxer {
const frameOverflowBytes = sampleLength - frameMissingBytes;
aacOverFlow.sample.unit.set(
data.subarray(0, frameMissingBytes),
frameOverflowBytes
frameOverflowBytes,
);
track.samples.push(aacOverFlow.sample);
startOffset = aacOverFlow.missing;
@@ -621,7 +621,7 @@ class TSDemuxer implements Demuxer {
this.observer,
data,
offset,
this.audioCodec as string
this.audioCodec as string,
);
let pts: number;
@@ -675,7 +675,7 @@ class TSDemuxer implements Demuxer {
data,
offset,
pts,
frameIndex
frameIndex,
);
if (frame) {
offset += frame.length;
@@ -740,7 +740,7 @@ function parsePMT(
data: Uint8Array,
offset: number,
typeSupported: TypeSupported,
isSampleAes: boolean
isSampleAes: boolean,
) {
const result = {
audioPid: -1,
@@ -848,7 +848,7 @@ function parsePMT(
if (__USE_M2TS_ADVANCED_CODECS__) {
if (typeSupported.ac3 !== true) {
logger.log(
'AC-3 audio found, not supported in this browser for now'
'AC-3 audio found, not supported in this browser for now',
);
} else {
result.audioPid = pid;
@@ -945,8 +945,8 @@ function parsePES(stream: ElementaryStreamData): PES | null {
if (pesPts - pesDts > 60 * 90000) {
logger.warn(
`${Math.round(
(pesPts - pesDts) / 90000
)}s delta between PTS and DTS, align them`
(pesPts - pesDts) / 90000,
)}s delta between PTS and DTS, align them`,
);
pesPts = pesDts;
}
+9 -9
View File
@@ -19,7 +19,7 @@ class AvcVideoParser extends BaseVideoParser {
textTrack: DemuxedUserdataTrack,
pes: PES,
last: boolean,
duration: number
duration: number,
) {
const units = this.parseAVCNALu(track, pes.data);
const debug = false;
@@ -37,7 +37,7 @@ class AvcVideoParser extends BaseVideoParser {
false,
pes.pts,
pes.dts,
''
'',
);
}
@@ -80,7 +80,7 @@ class AvcVideoParser extends BaseVideoParser {
true,
pes.pts,
pes.dts,
''
'',
);
}
@@ -107,7 +107,7 @@ class AvcVideoParser extends BaseVideoParser {
true,
pes.pts,
pes.dts,
''
'',
);
}
@@ -128,7 +128,7 @@ class AvcVideoParser extends BaseVideoParser {
unit.data,
1,
pes.pts as number,
textTrack.samples
textTrack.samples,
);
break;
// SPS
@@ -186,7 +186,7 @@ class AvcVideoParser extends BaseVideoParser {
false,
pes.pts,
pes.dts,
debug ? 'AUD ' : ''
debug ? 'AUD ' : '',
);
break;
// Filler Data
@@ -215,7 +215,7 @@ class AvcVideoParser extends BaseVideoParser {
private parseAVCNALu(
track: DemuxedVideoTrack,
array: Uint8Array
array: Uint8Array,
): Array<{
data: Uint8Array;
type: number;
@@ -280,7 +280,7 @@ class AvcVideoParser extends BaseVideoParser {
// strip last bytes
lastUnit.data = lastUnit.data.subarray(
0,
lastUnit.data.byteLength - lastState
lastUnit.data.byteLength - lastState,
);
}
}
@@ -290,7 +290,7 @@ class AvcVideoParser extends BaseVideoParser {
// logger.log('first NALU found with overflow:' + overflow);
lastUnit.data = appendUint8Array(
lastUnit.data,
array.subarray(0, overflow)
array.subarray(0, overflow),
);
lastUnit.state = 0;
}
+4 -4
View File
@@ -13,7 +13,7 @@ class BaseVideoParser {
key: boolean,
pts: number | undefined,
dts: number | undefined,
debug: string
debug: string,
): ParsedVideoSample {
return {
key,
@@ -27,7 +27,7 @@ class BaseVideoParser {
}
protected getLastNalUnit(
samples: VideoSample[]
samples: VideoSample[],
): VideoSampleUnit | undefined {
let VideoSample = this.VideoSample;
let lastUnit: VideoSampleUnit | undefined;
@@ -44,7 +44,7 @@ class BaseVideoParser {
protected pushAccessUnit(
VideoSample: ParsedVideoSample,
videoTrack: DemuxedVideoTrack
videoTrack: DemuxedVideoTrack,
) {
if (VideoSample.units.length && VideoSample.frame) {
// if sample does not have PTS/DTS, patch with last sample PTS/DTS
@@ -65,7 +65,7 @@ class BaseVideoParser {
}
if (VideoSample.debug.length) {
logger.log(
VideoSample.pts + '/' + VideoSample.dts + ':' + VideoSample.debug
VideoSample.pts + '/' + VideoSample.dts + ':' + VideoSample.debug,
);
}
}
+1 -1
View File
@@ -338,7 +338,7 @@ class ExpGolomb {
width: Math.ceil(
(picWidthInMbsMinus1 + 1) * 16 -
frameCropLeftOffset * 2 -
frameCropRightOffset * 2
frameCropRightOffset * 2,
),
height:
(2 - frameMbsOnlyFlag) * (picHeightInMapUnitsMinus1 + 1) * 16 -
+51 -51
View File
@@ -173,212 +173,212 @@ export enum Events {
export interface HlsListeners {
[Events.MEDIA_ATTACHING]: (
event: Events.MEDIA_ATTACHING,
data: MediaAttachingData
data: MediaAttachingData,
) => void;
[Events.MEDIA_ATTACHED]: (
event: Events.MEDIA_ATTACHED,
data: MediaAttachedData
data: MediaAttachedData,
) => void;
[Events.MEDIA_DETACHING]: (event: Events.MEDIA_DETACHING) => void;
[Events.MEDIA_DETACHED]: (event: Events.MEDIA_DETACHED) => void;
[Events.BUFFER_RESET]: (event: Events.BUFFER_RESET) => void;
[Events.BUFFER_CODECS]: (
event: Events.BUFFER_CODECS,
data: BufferCodecsData
data: BufferCodecsData,
) => void;
[Events.BUFFER_CREATED]: (
event: Events.BUFFER_CREATED,
data: BufferCreatedData
data: BufferCreatedData,
) => void;
[Events.BUFFER_APPENDING]: (
event: Events.BUFFER_APPENDING,
data: BufferAppendingData
data: BufferAppendingData,
) => void;
[Events.BUFFER_APPENDED]: (
event: Events.BUFFER_APPENDED,
data: BufferAppendedData
data: BufferAppendedData,
) => void;
[Events.BUFFER_EOS]: (event: Events.BUFFER_EOS, data: BufferEOSData) => void;
[Events.BUFFER_FLUSHING]: (
event: Events.BUFFER_FLUSHING,
data: BufferFlushingData
data: BufferFlushingData,
) => void;
[Events.BUFFER_FLUSHED]: (
event: Events.BUFFER_FLUSHED,
data: BufferFlushedData
data: BufferFlushedData,
) => void;
[Events.MANIFEST_LOADING]: (
event: Events.MANIFEST_LOADING,
data: ManifestLoadingData
data: ManifestLoadingData,
) => void;
[Events.MANIFEST_LOADED]: (
event: Events.MANIFEST_LOADED,
data: ManifestLoadedData
data: ManifestLoadedData,
) => void;
[Events.MANIFEST_PARSED]: (
event: Events.MANIFEST_PARSED,
data: ManifestParsedData
data: ManifestParsedData,
) => void;
[Events.LEVEL_SWITCHING]: (
event: Events.LEVEL_SWITCHING,
data: LevelSwitchingData
data: LevelSwitchingData,
) => void;
[Events.LEVEL_SWITCHED]: (
event: Events.LEVEL_SWITCHED,
data: LevelSwitchedData
data: LevelSwitchedData,
) => void;
[Events.LEVEL_LOADING]: (
event: Events.LEVEL_LOADING,
data: LevelLoadingData
data: LevelLoadingData,
) => void;
[Events.LEVEL_LOADED]: (
event: Events.LEVEL_LOADED,
data: LevelLoadedData
data: LevelLoadedData,
) => void;
[Events.LEVEL_UPDATED]: (
event: Events.LEVEL_UPDATED,
data: LevelUpdatedData
data: LevelUpdatedData,
) => void;
[Events.LEVEL_PTS_UPDATED]: (
event: Events.LEVEL_PTS_UPDATED,
data: LevelPTSUpdatedData
data: LevelPTSUpdatedData,
) => void;
[Events.LEVELS_UPDATED]: (
event: Events.LEVELS_UPDATED,
data: LevelsUpdatedData
data: LevelsUpdatedData,
) => void;
[Events.AUDIO_TRACKS_UPDATED]: (
event: Events.AUDIO_TRACKS_UPDATED,
data: AudioTracksUpdatedData
data: AudioTracksUpdatedData,
) => void;
[Events.AUDIO_TRACK_SWITCHING]: (
event: Events.AUDIO_TRACK_SWITCHING,
data: AudioTrackSwitchingData
data: AudioTrackSwitchingData,
) => void;
[Events.AUDIO_TRACK_SWITCHED]: (
event: Events.AUDIO_TRACK_SWITCHED,
data: AudioTrackSwitchedData
data: AudioTrackSwitchedData,
) => void;
[Events.AUDIO_TRACK_LOADING]: (
event: Events.AUDIO_TRACK_LOADING,
data: TrackLoadingData
data: TrackLoadingData,
) => void;
[Events.AUDIO_TRACK_LOADED]: (
event: Events.AUDIO_TRACK_LOADED,
data: AudioTrackLoadedData
data: AudioTrackLoadedData,
) => void;
[Events.SUBTITLE_TRACKS_UPDATED]: (
event: Events.SUBTITLE_TRACKS_UPDATED,
data: SubtitleTracksUpdatedData
data: SubtitleTracksUpdatedData,
) => void;
[Events.SUBTITLE_TRACKS_CLEARED]: (
event: Events.SUBTITLE_TRACKS_CLEARED
event: Events.SUBTITLE_TRACKS_CLEARED,
) => void;
[Events.SUBTITLE_TRACK_SWITCH]: (
event: Events.SUBTITLE_TRACK_SWITCH,
data: SubtitleTrackSwitchData
data: SubtitleTrackSwitchData,
) => void;
[Events.SUBTITLE_TRACK_LOADING]: (
event: Events.SUBTITLE_TRACK_LOADING,
data: TrackLoadingData
data: TrackLoadingData,
) => void;
[Events.SUBTITLE_TRACK_LOADED]: (
event: Events.SUBTITLE_TRACK_LOADED,
data: SubtitleTrackLoadedData
data: SubtitleTrackLoadedData,
) => void;
[Events.SUBTITLE_FRAG_PROCESSED]: (
event: Events.SUBTITLE_FRAG_PROCESSED,
data: SubtitleFragProcessedData
data: SubtitleFragProcessedData,
) => void;
[Events.CUES_PARSED]: (
event: Events.CUES_PARSED,
data: CuesParsedData
data: CuesParsedData,
) => void;
[Events.NON_NATIVE_TEXT_TRACKS_FOUND]: (
event: Events.NON_NATIVE_TEXT_TRACKS_FOUND,
data: NonNativeTextTracksData
data: NonNativeTextTracksData,
) => void;
[Events.INIT_PTS_FOUND]: (
event: Events.INIT_PTS_FOUND,
data: InitPTSFoundData
data: InitPTSFoundData,
) => void;
[Events.FRAG_LOADING]: (
event: Events.FRAG_LOADING,
data: FragLoadingData
data: FragLoadingData,
) => void;
// [Events.FRAG_LOAD_PROGRESS]: TodoEventType
[Events.FRAG_LOAD_EMERGENCY_ABORTED]: (
event: Events.FRAG_LOAD_EMERGENCY_ABORTED,
data: FragLoadEmergencyAbortedData
data: FragLoadEmergencyAbortedData,
) => void;
[Events.FRAG_LOADED]: (
event: Events.FRAG_LOADED,
data: FragLoadedData
data: FragLoadedData,
) => void;
[Events.FRAG_DECRYPTED]: (
event: Events.FRAG_DECRYPTED,
data: FragDecryptedData
data: FragDecryptedData,
) => void;
[Events.FRAG_PARSING_INIT_SEGMENT]: (
event: Events.FRAG_PARSING_INIT_SEGMENT,
data: FragParsingInitSegmentData
data: FragParsingInitSegmentData,
) => void;
[Events.FRAG_PARSING_USERDATA]: (
event: Events.FRAG_PARSING_USERDATA,
data: FragParsingUserdataData
data: FragParsingUserdataData,
) => void;
[Events.FRAG_PARSING_METADATA]: (
event: Events.FRAG_PARSING_METADATA,
data: FragParsingMetadataData
data: FragParsingMetadataData,
) => void;
// [Events.FRAG_PARSING_DATA]: TodoEventType
[Events.FRAG_PARSED]: (
event: Events.FRAG_PARSED,
data: FragParsedData
data: FragParsedData,
) => void;
[Events.FRAG_BUFFERED]: (
event: Events.FRAG_BUFFERED,
data: FragBufferedData
data: FragBufferedData,
) => void;
[Events.FRAG_CHANGED]: (
event: Events.FRAG_CHANGED,
data: FragChangedData
data: FragChangedData,
) => void;
[Events.FPS_DROP]: (event: Events.FPS_DROP, data: FPSDropData) => void;
[Events.FPS_DROP_LEVEL_CAPPING]: (
event: Events.FPS_DROP_LEVEL_CAPPING,
data: FPSDropLevelCappingData
data: FPSDropLevelCappingData,
) => void;
[Events.ERROR]: (event: Events.ERROR, data: ErrorData) => void;
[Events.DESTROYING]: (event: Events.DESTROYING) => void;
[Events.KEY_LOADING]: (
event: Events.KEY_LOADING,
data: KeyLoadingData
data: KeyLoadingData,
) => void;
[Events.KEY_LOADED]: (event: Events.KEY_LOADED, data: KeyLoadedData) => void;
[Events.LIVE_BACK_BUFFER_REACHED]: (
event: Events.LIVE_BACK_BUFFER_REACHED,
data: LiveBackBufferData
data: LiveBackBufferData,
) => void;
[Events.BACK_BUFFER_REACHED]: (
event: Events.BACK_BUFFER_REACHED,
data: BackBufferData
data: BackBufferData,
) => void;
[Events.STEERING_MANIFEST_LOADED]: (
event: Events.STEERING_MANIFEST_LOADED,
data: SteeringManifestLoadedData
data: SteeringManifestLoadedData,
) => void;
}
export interface HlsEventEmitter {
on<E extends keyof HlsListeners, Context = undefined>(
event: E,
listener: HlsListeners[E],
context?: Context
context?: Context,
): void;
once<E extends keyof HlsListeners, Context = undefined>(
event: E,
listener: HlsListeners[E],
context?: Context
context?: Context,
): void;
removeAllListeners<E extends keyof HlsListeners>(event?: E): void;
@@ -386,14 +386,14 @@ export interface HlsEventEmitter {
event: E,
listener?: HlsListeners[E],
context?: Context,
once?: boolean
once?: boolean,
): void;
listeners<E extends keyof HlsListeners>(event: E): HlsListeners[E][];
emit<E extends keyof HlsListeners>(
event: E,
name: E,
eventObject: Parameters<HlsListeners[E]>[1]
eventObject: Parameters<HlsListeners[E]>[1],
): boolean;
listenerCount<E extends keyof HlsListeners>(event: E): number;
}
+16 -16
View File
@@ -153,7 +153,7 @@ export default class Hls implements HlsEventEmitter {
: null;
const levelController = (this.levelController = new LevelController(
this,
contentSteering
contentSteering,
));
// FragmentTracker must be defined before StreamController because the order of event handling is important
const fragmentTracker = new FragmentTracker(this);
@@ -161,7 +161,7 @@ export default class Hls implements HlsEventEmitter {
const streamController = (this.streamController = new StreamController(
this,
fragmentTracker,
keyLoader
keyLoader,
));
// Cap level controller uses streamController to flush the buffer
@@ -190,37 +190,37 @@ export default class Hls implements HlsEventEmitter {
this.audioTrackController = this.createController(
config.audioTrackController,
networkControllers
networkControllers,
);
const AudioStreamControllerClass = config.audioStreamController;
if (AudioStreamControllerClass) {
networkControllers.push(
new AudioStreamControllerClass(this, fragmentTracker, keyLoader)
new AudioStreamControllerClass(this, fragmentTracker, keyLoader),
);
}
// subtitleTrackController must be defined before subtitleStreamController because the order of event handling is important
this.subtitleTrackController = this.createController(
config.subtitleTrackController,
networkControllers
networkControllers,
);
const SubtitleStreamControllerClass = config.subtitleStreamController;
if (SubtitleStreamControllerClass) {
networkControllers.push(
new SubtitleStreamControllerClass(this, fragmentTracker, keyLoader)
new SubtitleStreamControllerClass(this, fragmentTracker, keyLoader),
);
}
this.createController(config.timelineController, coreComponents);
keyLoader.emeController = this.emeController = this.createController(
config.emeController,
coreComponents
coreComponents,
);
this.cmcdController = this.createController(
config.cmcdController,
coreComponents
coreComponents,
);
this.latencyController = this.createController(
LatencyController,
coreComponents
coreComponents,
);
this.coreComponents = coreComponents;
@@ -249,7 +249,7 @@ export default class Hls implements HlsEventEmitter {
on<E extends keyof HlsListeners, Context = undefined>(
event: E,
listener: HlsListeners[E],
context: Context = this as any
context: Context = this as any,
) {
this._emitter.on(event, listener, context);
}
@@ -257,7 +257,7 @@ export default class Hls implements HlsEventEmitter {
once<E extends keyof HlsListeners, Context = undefined>(
event: E,
listener: HlsListeners[E],
context: Context = this as any
context: Context = this as any,
) {
this._emitter.once(event, listener, context);
}
@@ -270,7 +270,7 @@ export default class Hls implements HlsEventEmitter {
event: E,
listener?: HlsListeners[E] | undefined,
context: Context = this as any,
once?: boolean | undefined
once?: boolean | undefined,
) {
this._emitter.off(event, listener, context, once);
}
@@ -282,14 +282,14 @@ export default class Hls implements HlsEventEmitter {
emit<E extends keyof HlsListeners>(
event: E,
name: E,
eventObject: Parameters<HlsListeners[E]>[1]
eventObject: Parameters<HlsListeners[E]>[1],
): boolean {
return this._emitter.emit(event, name, eventObject);
}
trigger<E extends keyof HlsListeners>(
event: E,
eventObject: Parameters<HlsListeners[E]>[1]
eventObject: Parameters<HlsListeners[E]>[1],
): boolean {
if (this.config.debug) {
return this.emit(event, event, eventObject);
@@ -303,7 +303,7 @@ export default class Hls implements HlsEventEmitter {
'. Error message: "' +
error.message +
'". Here is a stacktrace:',
error
error,
);
// Prevent recursion in error event handlers that throw #5497
if (!this.triggeringException) {
@@ -380,7 +380,7 @@ export default class Hls implements HlsEventEmitter {
url,
{
alwaysNormalize: true,
}
},
));
logger.log(`loadSource:${loadingSource}`);
if (
+4 -4
View File
@@ -47,7 +47,7 @@ export class DateRange {
dateRangeAttr[key] !== previousAttr[key]
) {
logger.warn(
`DATERANGE tag attribute: "${key}" does not match for tags with ID: "${dateRangeAttr.ID}"`
`DATERANGE tag attribute: "${key}" does not match for tags with ID: "${dateRangeAttr.ID}"`,
);
this._badValueForSameId = key;
break;
@@ -57,7 +57,7 @@ export class DateRange {
dateRangeAttr = Object.assign(
new AttrList({}),
previousAttr,
dateRangeAttr
dateRangeAttr,
);
}
this.attr = dateRangeAttr;
@@ -96,7 +96,7 @@ export class DateRange {
get duration(): number | null {
if (DateRangeAttribute.DURATION in this.attr) {
const duration = this.attr.decimalFloatingPoint(
DateRangeAttribute.DURATION
DateRangeAttribute.DURATION,
);
if (Number.isFinite(duration)) {
return duration;
@@ -110,7 +110,7 @@ export class DateRange {
get plannedDuration(): number | null {
if (DateRangeAttribute.PLANNED_DURATION in this.attr) {
return this.attr.decimalFloatingPoint(
DateRangeAttribute.PLANNED_DURATION
DateRangeAttribute.PLANNED_DURATION,
);
}
return null;
+15 -15
View File
@@ -41,7 +41,7 @@ export default class FragmentLoader {
load(
frag: Fragment,
onProgress?: FragmentLoadProgressCallback
onProgress?: FragmentLoadProgressCallback,
): Promise<FragLoadedData> {
const url = frag.url;
if (!url) {
@@ -52,10 +52,10 @@ export default class FragmentLoader {
fatal: false,
frag,
error: new Error(
`Fragment does not have a ${url ? 'part list' : 'url'}`
`Fragment does not have a ${url ? 'part list' : 'url'}`,
),
networkDetails: null,
})
}),
);
}
this.abort();
@@ -85,7 +85,7 @@ export default class FragmentLoader {
: (new DefaultILoader(config) as Loader<FragmentLoaderContext>));
const loaderContext = createLoaderContext(frag);
const loadPolicy = getLoaderConfigWithoutReties(
config.fragLoadPolicy.default
config.fragLoadPolicy.default,
);
const loaderConfig: LoaderConfiguration = {
loadPolicy,
@@ -124,7 +124,7 @@ export default class FragmentLoader {
error: new Error(`HTTP Error ${response.code} ${response.text}`),
networkDetails,
stats,
})
}),
);
},
onAbort: (stats, context, networkDetails) => {
@@ -138,7 +138,7 @@ export default class FragmentLoader {
error: new Error('Aborted'),
networkDetails,
stats,
})
}),
);
},
onTimeout: (stats, context, networkDetails) => {
@@ -152,7 +152,7 @@ export default class FragmentLoader {
error: new Error(`Timeout after ${loaderConfig.timeout}ms`),
networkDetails,
stats,
})
}),
);
},
onProgress: (stats, context, data, networkDetails) => {
@@ -172,7 +172,7 @@ export default class FragmentLoader {
public loadPart(
frag: Fragment,
part: Part,
onProgress: FragmentLoadProgressCallback
onProgress: FragmentLoadProgressCallback,
): Promise<FragLoadedData> {
this.abort();
@@ -197,7 +197,7 @@ export default class FragmentLoader {
const loaderContext = createLoaderContext(frag, part);
// Should we define another load policy for parts?
const loadPolicy = getLoaderConfigWithoutReties(
config.fragLoadPolicy.default
config.fragLoadPolicy.default,
);
const loaderConfig: LoaderConfiguration = {
loadPolicy,
@@ -239,7 +239,7 @@ export default class FragmentLoader {
error: new Error(`HTTP Error ${response.code} ${response.text}`),
networkDetails,
stats,
})
}),
);
},
onAbort: (stats, context, networkDetails) => {
@@ -255,7 +255,7 @@ export default class FragmentLoader {
error: new Error('Aborted'),
networkDetails,
stats,
})
}),
);
},
onTimeout: (stats, context, networkDetails) => {
@@ -270,7 +270,7 @@ export default class FragmentLoader {
error: new Error(`Timeout after ${loaderConfig.timeout}ms`),
networkDetails,
stats,
})
}),
);
},
});
@@ -286,7 +286,7 @@ export default class FragmentLoader {
const estTotalParts = Math.round(frag.duration / part.duration);
const estLoadedParts = Math.min(
Math.round(fragStats.loaded / partTotal),
estTotalParts
estTotalParts,
);
const estRemainingParts = estTotalParts - estLoadedParts;
const estRemainingBytes =
@@ -319,7 +319,7 @@ export default class FragmentLoader {
function createLoaderContext(
frag: Fragment,
part: Part | null = null
part: Part | null = null,
): FragmentLoaderContext {
const segment: BaseSegment = part || frag;
const loaderContext: FragmentLoaderContext = {
@@ -395,5 +395,5 @@ export interface FragLoadFailResult extends ErrorData {
}
export type FragmentLoadProgressCallback = (
result: FragLoadedData | PartsLoadedData
result: FragLoadedData | PartsLoadedData,
) => void;
+2 -2
View File
@@ -235,7 +235,7 @@ export class Fragment extends BaseSegment {
endPTS: number,
startDTS: number,
endDTS: number,
partial: boolean = false
partial: boolean = false,
) {
const { elementaryStreams } = this;
const info = elementaryStreams[type];
@@ -282,7 +282,7 @@ export class Part extends BaseSegment {
frag: Fragment,
baseurl: string,
index: number,
previous?: Part
previous?: Part,
) {
super(baseurl);
this.duration = partAttrs.decimalFloatingPoint('DURATION');
+25 -25
View File
@@ -74,7 +74,7 @@ export default class KeyLoader implements ComponentAPI {
details: ErrorDetails = ErrorDetails.KEY_LOAD_ERROR,
error: Error,
networkDetails?: any,
response?: { url: string; data: undefined; code: number; text: string }
response?: { url: string; data: undefined; code: number; text: string },
): LoadError {
return new LoadError({
type: ErrorTypes.NETWORK_ERROR,
@@ -89,7 +89,7 @@ export default class KeyLoader implements ComponentAPI {
loadClear(
loadingFrag: Fragment,
encryptedFragments: Fragment[]
encryptedFragments: Fragment[],
): void | Promise<void> {
if (this.emeController && this.config.emeEnabled) {
// access key-system with nearest key on start (loaidng frag is unencrypted)
@@ -126,7 +126,7 @@ export default class KeyLoader implements ComponentAPI {
loadInternal(
frag: Fragment,
keySystemFormat?: KeySystemFormats
keySystemFormat?: KeySystemFormats,
): Promise<KeyLoadedData> {
if (keySystemFormat) {
frag.setKeyFormat(keySystemFormat);
@@ -136,10 +136,10 @@ export default class KeyLoader implements ComponentAPI {
const error = new Error(
keySystemFormat
? `Expected frag.decryptdata to be defined after setting format ${keySystemFormat}`
: 'Missing decryption data on fragment in onKeyLoading'
: 'Missing decryption data on fragment in onKeyLoading',
);
return Promise.reject(
this.createKeyLoadError(frag, ErrorDetails.KEY_LOAD_ERROR, error)
this.createKeyLoadError(frag, ErrorDetails.KEY_LOAD_ERROR, error),
);
}
const uri = decryptdata.uri;
@@ -148,8 +148,8 @@ export default class KeyLoader implements ComponentAPI {
this.createKeyLoadError(
frag,
ErrorDetails.KEY_LOAD_ERROR,
new Error(`Invalid key URI: "${uri}"`)
)
new Error(`Invalid key URI: "${uri}"`),
),
);
}
let keyInfo = this.keyUriToKeyInfo[uri];
@@ -201,9 +201,9 @@ export default class KeyLoader implements ComponentAPI {
frag,
ErrorDetails.KEY_LOAD_ERROR,
new Error(
`Key supplied with unsupported METHOD: "${decryptdata.method}"`
)
)
`Key supplied with unsupported METHOD: "${decryptdata.method}"`,
),
),
);
}
}
@@ -218,7 +218,7 @@ export default class KeyLoader implements ComponentAPI {
(keySessionContext) => {
keyInfo.mediaKeySessionContext = keySessionContext;
return keyLoadedData;
}
},
)).catch((error) => {
// Remove promise for license renewal or retry
keyInfo.keyLoadPromise = null;
@@ -260,7 +260,7 @@ export default class KeyLoader implements ComponentAPI {
response: LoaderResponse,
stats: LoaderStats,
context: KeyLoaderContext,
networkDetails: any
networkDetails: any,
) => {
const { frag, keyInfo, url: uri } = context;
if (!frag.decryptdata || keyInfo !== this.keyUriToKeyInfo[uri]) {
@@ -269,13 +269,13 @@ export default class KeyLoader implements ComponentAPI {
frag,
ErrorDetails.KEY_LOAD_ERROR,
new Error('after key load, decryptdata unset or changed'),
networkDetails
)
networkDetails,
),
);
}
keyInfo.decryptdata.key = frag.decryptdata.key = new Uint8Array(
response.data as ArrayBuffer
response.data as ArrayBuffer,
);
// detach fragment key loader on load success
@@ -288,7 +288,7 @@ export default class KeyLoader implements ComponentAPI {
response: { code: number; text: string },
context: KeyLoaderContext,
networkDetails: any,
stats: LoaderStats
stats: LoaderStats,
) => {
this.resetLoader(context);
reject(
@@ -296,18 +296,18 @@ export default class KeyLoader implements ComponentAPI {
frag,
ErrorDetails.KEY_LOAD_ERROR,
new Error(
`HTTP Error ${response.code} loading key ${response.text}`
`HTTP Error ${response.code} loading key ${response.text}`,
),
networkDetails,
{ url: loaderContext.url, data: undefined, ...response }
)
{ url: loaderContext.url, data: undefined, ...response },
),
);
},
onTimeout: (
stats: LoaderStats,
context: KeyLoaderContext,
networkDetails: any
networkDetails: any,
) => {
this.resetLoader(context);
reject(
@@ -315,15 +315,15 @@ export default class KeyLoader implements ComponentAPI {
frag,
ErrorDetails.KEY_LOAD_TIMEOUT,
new Error('key loading timed out'),
networkDetails
)
networkDetails,
),
);
},
onAbort: (
stats: LoaderStats,
context: KeyLoaderContext,
networkDetails: any
networkDetails: any,
) => {
this.resetLoader(context);
reject(
@@ -331,8 +331,8 @@ export default class KeyLoader implements ComponentAPI {
frag,
ErrorDetails.INTERNAL_ABORTED,
new Error('key loading aborted'),
networkDetails
)
networkDetails,
),
);
},
};
+1 -1
View File
@@ -88,7 +88,7 @@ export class LevelDetails {
get hasProgramDateTime(): boolean {
if (this.fragments.length) {
return Number.isFinite(
this.fragments[this.fragments.length - 1].programDateTime as number
this.fragments[this.fragments.length - 1].programDateTime as number,
);
}
return false;
+7 -7
View File
@@ -43,7 +43,7 @@ export class LevelKey implements DecryptData {
uri: string,
format: string,
formatversions: number[] = [1],
iv: Uint8Array | null = null
iv: Uint8Array | null = null,
) {
this.method = method;
this.uri = uri;
@@ -95,7 +95,7 @@ export class LevelKey implements DecryptData {
// It must have an IV defined. We cannot substitute the Segment Number in.
if (this.method === 'AES-128' && !this.iv) {
logger.warn(
`missing IV for initialization segment with method="${this.method}" - compliance issue`
`missing IV for initialization segment with method="${this.method}" - compliance issue`,
);
}
// Explicitly set sn to resulting value from implicit conversions 'initSegment' values for IV generation.
@@ -107,7 +107,7 @@ export class LevelKey implements DecryptData {
this.uri,
'identity',
this.keyFormatVersions,
iv
iv,
);
return decryptdata;
}
@@ -126,7 +126,7 @@ export class LevelKey implements DecryptData {
if (keyBytes.length >= 22) {
this.keyId = keyBytes.subarray(
keyBytes.length - 22,
keyBytes.length - 6
keyBytes.length - 6,
);
}
break;
@@ -141,17 +141,17 @@ export class LevelKey implements DecryptData {
const keyBytesUtf16 = new Uint16Array(
keyBytes.buffer,
keyBytes.byteOffset,
keyBytes.byteLength / 2
keyBytes.byteLength / 2,
);
const keyByteStr = String.fromCharCode.apply(
null,
Array.from(keyBytesUtf16)
Array.from(keyBytesUtf16),
);
// Parse Playready WRMHeader XML
const xmlKeyBytes = keyByteStr.substring(
keyByteStr.indexOf('<'),
keyByteStr.length
keyByteStr.length,
);
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlKeyBytes, 'text/xml');
+23 -23
View File
@@ -57,7 +57,7 @@ const LEVEL_PLAYLIST_REGEX_FAST = new RegExp(
/#EXT-X-PROGRAM-DATE-TIME:(.+)/.source, // next segment's program date/time group 5 => the datetime spec
/#.*/.source, // All other non-segment oriented tags will match with all groups empty
].join('|'),
'g'
'g',
);
const LEVEL_PLAYLIST_REGEX_SLOW = new RegExp(
@@ -70,13 +70,13 @@ const LEVEL_PLAYLIST_REGEX_SLOW = new RegExp(
/#EXT-X-(DISCONTINUITY|ENDLIST|GAP)/.source,
/(#)([^:]*):(.*)/.source,
/(#)(.*)(?:.*)\r?\n?/.source,
].join('|')
].join('|'),
);
export default class M3U8Parser {
static findGroup(
groups: Array<AudioGroup>,
mediaGroupId: string
mediaGroupId: string,
): AudioGroup | undefined {
for (let i = 0; i < groups.length; i++) {
const group = groups[i];
@@ -108,7 +108,7 @@ export default class M3U8Parser {
static parseMasterPlaylist(
string: string,
baseurl: string
baseurl: string,
): ParsedMultivariantPlaylist {
const hasVariableRefs = __USE_VARIABLE_SUBSTITUTION__
? hasVariableReferences(string)
@@ -166,7 +166,7 @@ export default class M3U8Parser {
setCodecs(
((attrs.CODECS as string) || '').split(/[ ,]+/).filter((c) => c),
level
level,
);
if (level.videoCodec && level.videoCodec.indexOf('avc1') !== -1) {
@@ -212,7 +212,7 @@ export default class M3U8Parser {
parsed.sessionKeys.push(sessionKey);
} else {
logger.warn(
`[Keys] Ignoring invalid EXT-X-SESSION-KEY tag: "${attributes}"`
`[Keys] Ignoring invalid EXT-X-SESSION-KEY tag: "${attributes}"`,
);
}
break;
@@ -237,13 +237,13 @@ export default class M3U8Parser {
substituteVariablesInAttributes(
parsed,
contentSteeringAttributes,
['SERVER-URI', 'PATHWAY-ID']
['SERVER-URI', 'PATHWAY-ID'],
);
}
parsed.contentSteering = {
uri: M3U8Parser.resolve(
contentSteeringAttributes['SERVER-URI'],
baseurl
baseurl,
),
pathwayId: contentSteeringAttributes['PATHWAY-ID'] || '.',
};
@@ -277,7 +277,7 @@ export default class M3U8Parser {
static parseMasterPlaylistMedia(
string: string,
baseurl: string,
parsed: ParsedMultivariantPlaylist
parsed: ParsedMultivariantPlaylist,
): ParsedMultivariantMediaOptions {
let result: RegExpExecArray | null;
const results: ParsedMultivariantMediaOptions = {};
@@ -354,7 +354,7 @@ export default class M3U8Parser {
id: number,
type: PlaylistLevelType,
levelUrlId: number,
multivariantVariableList: VariableMap | null
multivariantVariableList: VariableMap | null,
): LevelDetails {
const level = new LevelDetails(baseurl);
const fragments: M3U8ParserFragments = level.fragments;
@@ -484,7 +484,7 @@ export default class M3U8Parser {
currentSN += skippedSegments;
}
const recentlyRemovedDateranges = skipAttrs.enumeratedString(
'RECENTLY-REMOVED-DATERANGES'
'RECENTLY-REMOVED-DATERANGES',
);
if (recentlyRemovedDateranges) {
level.recentlyRemovedDateranges =
@@ -534,12 +534,12 @@ export default class M3U8Parser {
substituteVariablesInAttributes(
level,
dateRangeAttr,
dateRangeAttr.clientAttrs
dateRangeAttr.clientAttrs,
);
}
const dateRange = new DateRange(
dateRangeAttr,
level.dateRanges[dateRangeAttr.ID]
level.dateRanges[dateRangeAttr.ID],
);
if (dateRange.isValid || level.skippedSegments) {
level.dateRanges[dateRange.id] = dateRange;
@@ -563,7 +563,7 @@ export default class M3U8Parser {
importVariableDefinition(
level,
variableAttributes,
multivariantVariableList
multivariantVariableList,
);
} else {
addVariableDefinition(level, variableAttributes, baseurl);
@@ -632,14 +632,14 @@ export default class M3U8Parser {
level.canBlockReload = serverControlAttrs.bool('CAN-BLOCK-RELOAD');
level.canSkipUntil = serverControlAttrs.optionalFloat(
'CAN-SKIP-UNTIL',
0
0,
);
level.canSkipDateRanges =
level.canSkipUntil > 0 &&
serverControlAttrs.bool('CAN-SKIP-DATERANGES');
level.partHoldBack = serverControlAttrs.optionalFloat(
'PART-HOLD-BACK',
0
0,
);
level.holdBack = serverControlAttrs.optionalFloat('HOLD-BACK', 0);
break;
@@ -669,7 +669,7 @@ export default class M3U8Parser {
frag,
baseurl,
index,
previousFragmentPart
previousFragmentPart,
);
partList.push(part);
frag.duration += part.duration;
@@ -758,7 +758,7 @@ export default class M3U8Parser {
function parseKey(
keyTagAttributes: string,
baseurl: string,
parsed: ParsedMultivariantPlaylist | LevelDetails
parsed: ParsedMultivariantPlaylist | LevelDetails,
): LevelKey {
// https://tools.ietf.org/html/rfc8216#section-4.3.2.4
const keyAttrs = new AttrList(keyTagAttributes);
@@ -796,7 +796,7 @@ function parseKey(
resolvedUri,
decryptkeyformat,
keyFormatVersions,
decryptiv
decryptiv,
);
}
@@ -832,7 +832,7 @@ function assignCodec(media, groupItem, codecProperty) {
function backfillProgramDateTimes(
fragments: M3U8ParserFragments,
firstPdtIndex: number
firstPdtIndex: number,
) {
let fragPrev = fragments[firstPdtIndex] as Fragment;
for (let i = firstPdtIndex; i--; ) {
@@ -864,7 +864,7 @@ function setInitSegment(
frag: Fragment,
mapAttrs: AttrList,
id: number,
levelkeys: { [key: string]: LevelKey } | undefined
levelkeys: { [key: string]: LevelKey } | undefined,
) {
frag.relurl = mapAttrs.URI;
if (mapAttrs.BYTERANGE) {
@@ -881,7 +881,7 @@ function setInitSegment(
function setFragLevelKeys(
frag: Fragment,
levelkeys: { [key: string]: LevelKey },
level: LevelDetails
level: LevelDetails,
) {
frag.levelkeys = levelkeys;
const { encryptedFragments } = level;
@@ -890,7 +890,7 @@ function setFragLevelKeys(
encryptedFragments[encryptedFragments.length - 1].levelkeys !==
levelkeys) &&
Object.keys(levelkeys).some(
(format) => levelkeys![format].isCommonEncryption
(format) => levelkeys![format].isCommonEncryption,
)
) {
encryptedFragments.push(frag);
+24 -24
View File
@@ -35,7 +35,7 @@ import type { MediaAttributes } from '../types/media-playlist';
import type { LoaderConfig, RetryConfig } from '../config';
function mapContextToLevelType(
context: PlaylistLoaderContext
context: PlaylistLoaderContext,
): PlaylistLevelType {
const { type } = context;
@@ -51,7 +51,7 @@ function mapContextToLevelType(
function getResponseUrl(
response: LoaderResponse,
context: PlaylistLoaderContext
context: PlaylistLoaderContext,
): string {
let url = response.url;
// responseURL not supported on some browsers (it is used to detect URL redirection)
@@ -101,7 +101,7 @@ class PlaylistLoader implements NetworkComponentAPI {
* Returns defaults or configured loader-type overloads (pLoader and loader config params)
*/
private createInternalLoader(
context: PlaylistLoaderContext
context: PlaylistLoaderContext,
): Loader<LoaderContext> {
const config = this.hls.config;
const PLoader = config.pLoader;
@@ -114,7 +114,7 @@ class PlaylistLoader implements NetworkComponentAPI {
}
private getInternalLoader(
context: PlaylistLoaderContext
context: PlaylistLoaderContext,
): Loader<LoaderContext> | undefined {
return this.loaders[context.type];
}
@@ -147,7 +147,7 @@ class PlaylistLoader implements NetworkComponentAPI {
private onManifestLoading(
event: Events.MANIFEST_LOADING,
data: ManifestLoadingData
data: ManifestLoadingData,
) {
const { url } = data;
this.variableList = null;
@@ -175,7 +175,7 @@ class PlaylistLoader implements NetworkComponentAPI {
private onAudioTrackLoading(
event: Events.AUDIO_TRACK_LOADING,
data: TrackLoadingData
data: TrackLoadingData,
) {
const { id, groupId, url, deliveryDirectives } = data;
this.load({
@@ -191,7 +191,7 @@ class PlaylistLoader implements NetworkComponentAPI {
private onSubtitleTrackLoading(
event: Events.SUBTITLE_TRACK_LOADING,
data: TrackLoadingData
data: TrackLoadingData,
) {
const { id, groupId, url, deliveryDirectives } = data;
this.load({
@@ -220,7 +220,7 @@ class PlaylistLoader implements NetworkComponentAPI {
return;
}
logger.log(
`[playlist-loader]: aborting previous loader for type: ${context.type}`
`[playlist-loader]: aborting previous loader for type: ${context.type}`,
);
loader.abort();
}
@@ -267,11 +267,11 @@ class PlaylistLoader implements NetworkComponentAPI {
loadPolicy = Object.assign({}, loadPolicy, {
maxTimeToFirstByteMs: Math.min(
maxLowLatencyPlaylistRefresh,
loadPolicy.maxTimeToFirstByteMs
loadPolicy.maxTimeToFirstByteMs,
),
maxLoadTimeMs: Math.min(
maxLowLatencyPlaylistRefresh,
loadPolicy.maxTimeToFirstByteMs
loadPolicy.maxTimeToFirstByteMs,
),
});
}
@@ -304,7 +304,7 @@ class PlaylistLoader implements NetworkComponentAPI {
context,
new Error('no EXTM3U delimiter'),
networkDetails || null,
stats
stats,
);
return;
}
@@ -316,7 +316,7 @@ class PlaylistLoader implements NetworkComponentAPI {
stats,
context,
networkDetails || null,
loader
loader,
);
} else {
this.handleMasterPlaylist(response, stats, context, networkDetails);
@@ -328,7 +328,7 @@ class PlaylistLoader implements NetworkComponentAPI {
networkDetails,
false,
response,
stats
stats,
);
},
onTimeout: (stats, context, networkDetails) => {
@@ -337,7 +337,7 @@ class PlaylistLoader implements NetworkComponentAPI {
networkDetails,
true,
undefined,
stats
stats,
);
},
};
@@ -351,7 +351,7 @@ class PlaylistLoader implements NetworkComponentAPI {
response: LoaderResponse,
stats: LoaderStats,
context: PlaylistLoaderContext,
networkDetails: any
networkDetails: any,
): void {
const hls = this.hls;
const string = response.data as string;
@@ -366,7 +366,7 @@ class PlaylistLoader implements NetworkComponentAPI {
context,
parsedResult.playlistParsingError,
networkDetails,
stats
stats,
);
return;
}
@@ -391,7 +391,7 @@ class PlaylistLoader implements NetworkComponentAPI {
if (audioTracks.length) {
// check if we have found an audio track embedded in main playlist (audio track without URI attribute)
const embeddedAudioFound: boolean = audioTracks.some(
(audioTrack) => !audioTrack.url
(audioTrack) => !audioTrack.url,
);
// if no embedded audio track defined, but audio codec signaled in quality level,
@@ -404,7 +404,7 @@ class PlaylistLoader implements NetworkComponentAPI {
!levels[0].attrs.AUDIO
) {
logger.log(
'[playlist-loader]: audio codec signaled in quality level, but no embedded audio track signaled, create one'
'[playlist-loader]: audio codec signaled in quality level, but no embedded audio track signaled, create one',
);
audioTracks.unshift({
type: 'main',
@@ -442,7 +442,7 @@ class PlaylistLoader implements NetworkComponentAPI {
stats: LoaderStats,
context: PlaylistLoaderContext,
networkDetails: any,
loader: Loader<PlaylistLoaderContext> | undefined
loader: Loader<PlaylistLoaderContext> | undefined,
): void {
const hls = this.hls;
const { id, level, type } = context;
@@ -459,7 +459,7 @@ class PlaylistLoader implements NetworkComponentAPI {
levelId,
levelType,
levelUrlId,
this.variableList
this.variableList,
);
// We have done our first request (Manifest-type) and receive
@@ -501,7 +501,7 @@ class PlaylistLoader implements NetworkComponentAPI {
stats,
context,
networkDetails,
loader
loader,
);
}
@@ -510,7 +510,7 @@ class PlaylistLoader implements NetworkComponentAPI {
context: PlaylistLoaderContext,
error: Error,
networkDetails: any,
stats: LoaderStats
stats: LoaderStats,
): void {
this.hls.trigger(Events.ERROR, {
type: ErrorTypes.NETWORK_ERROR,
@@ -532,7 +532,7 @@ class PlaylistLoader implements NetworkComponentAPI {
networkDetails: any,
timeout = false,
response: { code: number; text: string } | undefined,
stats: LoaderStats
stats: LoaderStats,
): void {
let message = `A network ${
timeout
@@ -611,7 +611,7 @@ class PlaylistLoader implements NetworkComponentAPI {
stats: LoaderStats,
context: PlaylistLoaderContext,
networkDetails: any,
loader: Loader<PlaylistLoaderContext> | undefined
loader: Loader<PlaylistLoaderContext> | undefined,
): void {
const hls = this.hls;
const { type, level, id, groupId, deliveryDirectives } = context;
+1 -1
View File
@@ -5,7 +5,7 @@
class AAC {
static getSilentFrame(
codec?: string,
channelCount?: number
channelCount?: number,
): Uint8Array | undefined {
switch (codec) {
case 'mp4a.40.2':
+27 -27
View File
@@ -258,7 +258,7 @@ class MP4 {
majorBrand,
minorVersion,
majorBrand,
avc1Brand
avc1Brand,
);
MP4.DINF = MP4.box(MP4.types.dinf, MP4.box(MP4.types.dref, dref));
}
@@ -338,7 +338,7 @@ class MP4 {
0xc4, // 'und' language (undetermined)
0x00,
0x00,
])
]),
);
}
@@ -347,7 +347,7 @@ class MP4 {
MP4.types.mdia,
MP4.mdhd(track.timescale, track.duration),
MP4.hdlr(track.type),
MP4.minf(track)
MP4.minf(track),
);
}
@@ -363,7 +363,7 @@ class MP4 {
(sequenceNumber >> 16) & 0xff,
(sequenceNumber >> 8) & 0xff,
sequenceNumber & 0xff, // sequence_number
])
]),
);
}
@@ -373,14 +373,14 @@ class MP4 {
MP4.types.minf,
MP4.box(MP4.types.smhd, MP4.SMHD),
MP4.DINF,
MP4.stbl(track)
MP4.stbl(track),
);
} else {
return MP4.box(
MP4.types.minf,
MP4.box(MP4.types.vmhd, MP4.VMHD),
MP4.DINF,
MP4.stbl(track)
MP4.stbl(track),
);
}
}
@@ -389,7 +389,7 @@ class MP4 {
return MP4.box(
MP4.types.moof,
MP4.mfhd(sn),
MP4.traf(track, baseMediaDecodeTime)
MP4.traf(track, baseMediaDecodeTime),
);
}
@@ -405,7 +405,7 @@ class MP4 {
null,
[MP4.types.moov, MP4.mvhd(tracks[0].timescale, tracks[0].duration)]
.concat(boxes)
.concat(MP4.mvex(tracks))
.concat(MP4.mvex(tracks)),
);
}
@@ -566,7 +566,7 @@ class MP4 {
MP4.box(MP4.types.stts, MP4.STTS),
MP4.box(MP4.types.stsc, MP4.STSC),
MP4.box(MP4.types.stsz, MP4.STSZ),
MP4.box(MP4.types.stco, MP4.STCO)
MP4.box(MP4.types.stco, MP4.STCO),
);
}
@@ -613,8 +613,8 @@ class MP4 {
.concat([
track.pps.length, // numOfPictureParameterSets
])
.concat(pps)
)
.concat(pps),
),
); // "PPS"
const width = track.width;
const height = track.height;
@@ -719,7 +719,7 @@ class MP4 {
0x2d,
0xc6,
0xc0,
])
]),
), // avgBitrate
MP4.box(
MP4.types.pasp,
@@ -732,8 +732,8 @@ class MP4 {
(vSpacing >> 16) & 0xff,
(vSpacing >> 8) & 0xff,
vSpacing & 0xff,
])
)
]),
),
);
}
@@ -772,7 +772,7 @@ class MP4 {
]
.concat([configlen])
.concat(track.config)
.concat([0x06, 0x01, 0x02])
.concat([0x06, 0x01, 0x02]),
); // GASpecificConfig)); // length + audio config descriptor
}
@@ -814,7 +814,7 @@ class MP4 {
return MP4.box(
MP4.types.mp4a,
MP4.audioStsd(track),
MP4.box(MP4.types.esds, MP4.esds(track))
MP4.box(MP4.types.esds, MP4.esds(track)),
);
}
@@ -826,7 +826,7 @@ class MP4 {
return MP4.box(
MP4.types['ac-3'],
MP4.audioStsd(track),
MP4.box(MP4.types.dac3, track.config)
MP4.box(MP4.types.dac3, track.config),
);
}
@@ -950,7 +950,7 @@ class MP4 {
height & 0xff,
0x00,
0x00, // height
])
]),
);
}
@@ -958,10 +958,10 @@ class MP4 {
const sampleDependencyTable = MP4.sdtp(track);
const id = track.id;
const upperWordBaseMediaDecodeTime = Math.floor(
baseMediaDecodeTime / (UINT32_MAX + 1)
baseMediaDecodeTime / (UINT32_MAX + 1),
);
const lowerWordBaseMediaDecodeTime = Math.floor(
baseMediaDecodeTime % (UINT32_MAX + 1)
baseMediaDecodeTime % (UINT32_MAX + 1),
);
return MP4.box(
MP4.types.traf,
@@ -976,7 +976,7 @@ class MP4 {
(id >> 16) & 0xff,
(id >> 8) & 0xff,
id & 0xff, // track_ID
])
]),
),
MP4.box(
MP4.types.tfdt,
@@ -993,7 +993,7 @@ class MP4 {
(lowerWordBaseMediaDecodeTime >> 16) & 0xff,
(lowerWordBaseMediaDecodeTime >> 8) & 0xff,
lowerWordBaseMediaDecodeTime & 0xff,
])
]),
),
MP4.trun(
track,
@@ -1003,9 +1003,9 @@ class MP4 {
8 + // traf header
16 + // mfhd
8 + // moof header
8
8,
), // mdat header
sampleDependencyTable
sampleDependencyTable,
);
}
@@ -1047,7 +1047,7 @@ class MP4 {
0x01,
0x00,
0x01, // default_sample_flags
])
]),
);
}
@@ -1078,7 +1078,7 @@ class MP4 {
(offset >>> 8) & 0xff,
offset & 0xff, // data_offset
],
0
0,
);
for (i = 0; i < len; i++) {
sample = samples[i];
@@ -1108,7 +1108,7 @@ class MP4 {
(cts >>> 8) & 0xff,
cts & 0xff, // sample_composition_time_offset
],
12 + 16 * i
12 + 16 * i,
);
}
return MP4.box(MP4.types.trun, array);
+49 -49
View File
@@ -55,7 +55,7 @@ export default class MP4Remuxer implements Remuxer {
observer: HlsEventEmitter,
config: HlsConfig,
typeSupported,
vendor = ''
vendor = '',
) {
this.observer = observer;
this.config = config;
@@ -119,7 +119,7 @@ export default class MP4Remuxer implements Remuxer {
timeOffset: number,
accurateTimeOffset: boolean,
flush: boolean,
playlistType: PlaylistLevelType
playlistType: PlaylistLevelType,
): RemuxerResult {
let video: RemuxedTrack | undefined;
let audio: RemuxedTrack | undefined;
@@ -152,7 +152,7 @@ export default class MP4Remuxer implements Remuxer {
audioTrack,
videoTrack,
timeOffset,
accurateTimeOffset
accurateTimeOffset,
);
}
@@ -166,7 +166,7 @@ export default class MP4Remuxer implements Remuxer {
independent = true;
if (firstKeyFrameIndex > 0) {
logger.warn(
`[mp4-remuxer]: Dropped ${firstKeyFrameIndex} out of ${length} video samples due to a missing keyframe`
`[mp4-remuxer]: Dropped ${firstKeyFrameIndex} out of ${length} video samples due to a missing keyframe`,
);
const startPTS = this.getVideoStartPts(videoTrack.samples);
videoTrack.samples = videoTrack.samples.slice(firstKeyFrameIndex);
@@ -177,7 +177,7 @@ export default class MP4Remuxer implements Remuxer {
firstKeyFramePTS = videoTimeOffset;
} else if (firstKeyFrameIndex === -1) {
logger.warn(
`[mp4-remuxer]: No keyframe found out of ${length} video samples`
`[mp4-remuxer]: No keyframe found out of ${length} video samples`,
);
independent = false;
}
@@ -203,13 +203,13 @@ export default class MP4Remuxer implements Remuxer {
// if initSegment was generated without audio samples, regenerate it again
if (!audioTrack.samplerate) {
logger.warn(
'[mp4-remuxer]: regenerate InitSegment as audio detected'
'[mp4-remuxer]: regenerate InitSegment as audio detected',
);
initSegment = this.generateIS(
audioTrack,
videoTrack,
timeOffset,
accurateTimeOffset
accurateTimeOffset,
);
}
audio = this.remuxAudio(
@@ -221,27 +221,27 @@ export default class MP4Remuxer implements Remuxer {
enoughVideoSamples ||
playlistType === PlaylistLevelType.AUDIO
? videoTimeOffset
: undefined
: undefined,
);
if (enoughVideoSamples) {
const audioTrackLength = audio ? audio.endPTS - audio.startPTS : 0;
// if initSegment was generated without video samples, regenerate it again
if (!videoTrack.inputTimeScale) {
logger.warn(
'[mp4-remuxer]: regenerate InitSegment as video detected'
'[mp4-remuxer]: regenerate InitSegment as video detected',
);
initSegment = this.generateIS(
audioTrack,
videoTrack,
timeOffset,
accurateTimeOffset
accurateTimeOffset,
);
}
video = this.remuxVideo(
videoTrack,
videoTimeOffset,
isVideoContiguous,
audioTrackLength
audioTrackLength,
);
}
} else if (enoughVideoSamples) {
@@ -249,7 +249,7 @@ export default class MP4Remuxer implements Remuxer {
videoTrack,
videoTimeOffset,
isVideoContiguous,
0
0,
);
}
if (video) {
@@ -267,7 +267,7 @@ export default class MP4Remuxer implements Remuxer {
id3Track,
timeOffset,
this._initPTS,
this._initDTS
this._initDTS,
);
}
@@ -275,7 +275,7 @@ export default class MP4Remuxer implements Remuxer {
text = flushTextTrackUserdataCueSamples(
textTrack,
timeOffset,
this._initPTS
this._initPTS,
);
}
}
@@ -294,7 +294,7 @@ export default class MP4Remuxer implements Remuxer {
audioTrack: DemuxedAudioTrack,
videoTrack: DemuxedVideoTrack,
timeOffset: number,
accurateTimeOffset: boolean
accurateTimeOffset: boolean,
): InitSegmentData | undefined {
const audioSamples = audioTrack.samples;
const videoSamples = videoTrack.samples;
@@ -378,7 +378,7 @@ export default class MP4Remuxer implements Remuxer {
const startOffset = Math.round(timescale * timeOffset);
initDTS = Math.min(
initDTS as number,
normalizePts(videoSamples[0].dts, startPTS) - startOffset
normalizePts(videoSamples[0].dts, startPTS) - startOffset,
);
initPTS = Math.min(initPTS as number, startPTS - startOffset);
} else {
@@ -414,7 +414,7 @@ export default class MP4Remuxer implements Remuxer {
track: DemuxedVideoTrack,
timeOffset: number,
contiguous: boolean,
audioTrackLength: number
audioTrackLength: number,
): RemuxedTrack | undefined {
const timeScale: number = track.inputTimeScale;
const inputSamples: Array<VideoSample> = track.samples;
@@ -483,15 +483,15 @@ export default class MP4Remuxer implements Remuxer {
logger.warn(
`AVC: ${toMsFromMpegTsClock(
delta,
true
)} ms (${delta}dts) hole between fragments detected, filling it`
true,
)} ms (${delta}dts) hole between fragments detected, filling it`,
);
} else {
logger.warn(
`AVC: ${toMsFromMpegTsClock(
-delta,
true
)} ms (${delta}dts) overlapping between fragments detected`
true,
)} ms (${delta}dts) overlapping between fragments detected`,
);
}
if (!foundOverlap || nextAvcDts >= inputSamples[0].pts) {
@@ -502,11 +502,11 @@ export default class MP4Remuxer implements Remuxer {
logger.log(
`Video: First PTS/DTS adjusted: ${toMsFromMpegTsClock(
firstPTS,
true
true,
)}/${toMsFromMpegTsClock(
firstDTS,
true
)}, delta: ${toMsFromMpegTsClock(delta, true)} ms`
true,
)}, delta: ${toMsFromMpegTsClock(delta, true)} ms`,
);
}
}
@@ -621,7 +621,7 @@ export default class MP4Remuxer implements Remuxer {
deltaToFrameEnd / 90
} ms to the next segment; using duration ${
mp4SampleDuration / 90
} ms for the last video frame.`
} ms for the last video frame.`,
);
} else {
mp4SampleDuration = lastFrameDuration;
@@ -631,7 +631,7 @@ export default class MP4Remuxer implements Remuxer {
}
}
const compositionTimeOffset = Math.round(
VideoSample.pts - VideoSample.dts
VideoSample.pts - VideoSample.dts,
);
minDtsDelta = Math.min(minDtsDelta, mp4SampleDuration);
maxDtsDelta = Math.max(maxDtsDelta, mp4SampleDuration);
@@ -643,8 +643,8 @@ export default class MP4Remuxer implements Remuxer {
VideoSample.key,
mp4SampleDuration,
mp4SampleLength,
compositionTimeOffset
)
compositionTimeOffset,
),
);
}
@@ -666,7 +666,7 @@ export default class MP4Remuxer implements Remuxer {
outputSamples[0].cts === 0
) {
logger.warn(
'Found irregular gaps in sample duration. Using PTS instead of DTS to determine MP4 sample duration.'
'Found irregular gaps in sample duration. Using PTS instead of DTS to determine MP4 sample duration.',
);
let dts = firstDTS;
for (let i = 0, len = outputSamples.length; i < len; i++) {
@@ -699,7 +699,7 @@ export default class MP4Remuxer implements Remuxer {
firstDTS,
Object.assign({}, track, {
samples: outputSamples,
})
}),
);
const type: SourceBufferName = 'video';
const data = {
@@ -736,7 +736,7 @@ export default class MP4Remuxer implements Remuxer {
timeOffset: number,
contiguous: boolean,
accurateTimeOffset: boolean,
videoTimeOffset?: number
videoTimeOffset?: number,
): RemuxedTrack | undefined {
const inputTimeScale: number = track.inputTimeScale;
const mp4timeScale: number = track.samplerate
@@ -775,7 +775,7 @@ export default class MP4Remuxer implements Remuxer {
Math.abs(timeOffsetMpegTS - nextAudioPts) < 9000) ||
Math.abs(
normalizePts(inputSamples[0].pts - initTime, timeOffsetMpegTS) -
nextAudioPts
nextAudioPts,
) <
20 * inputSampleDuration)) as boolean);
@@ -830,10 +830,10 @@ export default class MP4Remuxer implements Remuxer {
if (i === 0) {
logger.warn(
`Audio frame @ ${(pts / inputTimeScale).toFixed(
3
3,
)}s overlaps nextAudioPts by ${Math.round(
(1000 * delta) / inputTimeScale
)} ms.`
(1000 * delta) / inputTimeScale,
)} ms.`,
);
this.nextAudioPts = nextAudioPts = nextPts = pts;
}
@@ -864,18 +864,18 @@ export default class MP4Remuxer implements Remuxer {
`[mp4-remuxer]: Injecting ${missing} audio frame @ ${(
nextPts / inputTimeScale
).toFixed(3)}s due to ${Math.round(
(1000 * delta) / inputTimeScale
)} ms gap.`
(1000 * delta) / inputTimeScale,
)} ms gap.`,
);
for (let j = 0; j < missing; j++) {
const newStamp = Math.max(nextPts as number, 0);
let fillFrame = AAC.getSilentFrame(
track.manifestCodec || track.codec,
track.channelCount
track.channelCount,
);
if (!fillFrame) {
logger.log(
'[mp4-remuxer]: Unable to get silent frame for given audio codec; duplicating last frame instead.'
'[mp4-remuxer]: Unable to get silent frame for given audio codec; duplicating last frame instead.',
);
fillFrame = sample.unit.subarray();
}
@@ -969,7 +969,7 @@ export default class MP4Remuxer implements Remuxer {
: MP4.moof(
track.sequenceNumber++,
firstPTS! / scaleFactor,
Object.assign({}, track, { samples: outputSamples })
Object.assign({}, track, { samples: outputSamples }),
);
// Clear the track samples. This also clears the samples array in the demuxer, since the reference is shared
@@ -998,7 +998,7 @@ export default class MP4Remuxer implements Remuxer {
track: DemuxedAudioTrack,
timeOffset: number,
contiguous: boolean,
videoData: Fragment
videoData: Fragment,
): RemuxedTrack | undefined {
const inputTimeScale: number = track.inputTimeScale;
const mp4timeScale: number = track.samplerate
@@ -1021,14 +1021,14 @@ export default class MP4Remuxer implements Remuxer {
// silent frame
const silentFrame: Uint8Array | undefined = AAC.getSilentFrame(
track.manifestCodec || track.codec,
track.channelCount
track.channelCount,
);
logger.warn('[mp4-remuxer]: remux empty Audio');
// Can't remux if we can't generate a silent frame...
if (!silentFrame) {
logger.trace(
'[mp4-remuxer]: Unable to remuxEmptyAudio since we were unable to get a silent frame for given audio codec'
'[mp4-remuxer]: Unable to remuxEmptyAudio since we were unable to get a silent frame for given audio codec',
);
return;
}
@@ -1080,7 +1080,7 @@ export function flushTextTrackMetadataCueSamples(
track: DemuxedMetadataTrack,
timeOffset: number,
initPTS: RationalTimestamp,
initDTS: RationalTimestamp
initDTS: RationalTimestamp,
): RemuxedMetadata | undefined {
const length = track.samples.length;
if (!length) {
@@ -1094,12 +1094,12 @@ export function flushTextTrackMetadataCueSamples(
sample.pts =
normalizePts(
sample.pts - (initPTS.baseTime * inputTimeScale) / initPTS.timescale,
timeOffset * inputTimeScale
timeOffset * inputTimeScale,
) / inputTimeScale;
sample.dts =
normalizePts(
sample.dts - (initDTS.baseTime * inputTimeScale) / initDTS.timescale,
timeOffset * inputTimeScale
timeOffset * inputTimeScale,
) / inputTimeScale;
}
const samples = track.samples;
@@ -1112,7 +1112,7 @@ export function flushTextTrackMetadataCueSamples(
export function flushTextTrackUserdataCueSamples(
track: DemuxedUserdataTrack,
timeOffset: number,
initPTS: RationalTimestamp
initPTS: RationalTimestamp,
): RemuxedUserdata | undefined {
const length = track.samples.length;
if (!length) {
@@ -1127,7 +1127,7 @@ export function flushTextTrackUserdataCueSamples(
sample.pts =
normalizePts(
sample.pts - (initPTS.baseTime * inputTimeScale) / initPTS.timescale,
timeOffset * inputTimeScale
timeOffset * inputTimeScale,
) / inputTimeScale;
}
track.samples.sort((a, b) => a.pts - b.pts);
@@ -1157,7 +1157,7 @@ class Mp4Sample {
isKeyframe: boolean,
duration: number,
size: number,
cts: number
cts: number,
) {
this.duration = duration;
this.size = size;
+11 -11
View File
@@ -56,7 +56,7 @@ class PassThroughRemuxer implements Remuxer {
initSegment: Uint8Array | undefined,
audioCodec: string | undefined,
videoCodec: string | undefined,
decryptdata: DecryptData | null
decryptdata: DecryptData | null,
) {
this.audioCodec = audioCodec;
this.videoCodec = videoCodec;
@@ -77,14 +77,14 @@ class PassThroughRemuxer implements Remuxer {
if (initData.audio) {
audioCodec = getParsedTrackCodec(
initData.audio,
ElementaryStreamTypes.AUDIO
ElementaryStreamTypes.AUDIO,
);
}
if (initData.video) {
videoCodec = getParsedTrackCodec(
initData.video,
ElementaryStreamTypes.VIDEO
ElementaryStreamTypes.VIDEO,
);
}
@@ -112,7 +112,7 @@ class PassThroughRemuxer implements Remuxer {
};
} else {
logger.warn(
'[passthrough-remuxer.ts]: initSegment does not contain moov or trak boxes.'
'[passthrough-remuxer.ts]: initSegment does not contain moov or trak boxes.',
);
}
this.initTracks = tracks;
@@ -124,7 +124,7 @@ class PassThroughRemuxer implements Remuxer {
id3Track: DemuxedMetadataTrack,
textTrack: DemuxedUserdataTrack,
timeOffset: number,
accurateTimeOffset: boolean
accurateTimeOffset: boolean,
): RemuxerResult {
let { initPTS, lastEndTime } = this;
const result: RemuxerResult = {
@@ -178,7 +178,7 @@ class PassThroughRemuxer implements Remuxer {
initSegment.initPTS = decodeTime - timeOffset;
if (initPTS && initPTS.timescale === 1) {
logger.warn(
`Adjusting initPTS by ${initSegment.initPTS - initPTS.baseTime}`
`Adjusting initPTS by ${initSegment.initPTS - initPTS.baseTime}`,
);
}
this.initPTS = initPTS = {
@@ -232,14 +232,14 @@ class PassThroughRemuxer implements Remuxer {
id3Track,
timeOffset,
initPTS,
initPTS
initPTS,
);
if (textTrack.samples.length) {
result.text = flushTextTrackUserdataCueSamples(
textTrack,
timeOffset,
initPTS
initPTS,
);
}
@@ -251,7 +251,7 @@ function isInvalidInitPts(
initPTS: RationalTimestamp | null,
startDTS: number,
timeOffset: number,
duration: number
duration: number,
): initPTS is null {
if (initPTS === null) {
return true;
@@ -264,7 +264,7 @@ function isInvalidInitPts(
function getParsedTrackCodec(
track: InitDataTrack,
type: ElementaryStreamTypes.AUDIO | ElementaryStreamTypes.VIDEO
type: ElementaryStreamTypes.AUDIO | ElementaryStreamTypes.VIDEO,
): string {
const parsedCodec = track?.codec;
if (parsedCodec && parsedCodec.length > 4) {
@@ -283,7 +283,7 @@ function getParsedTrackCodec(
}
const result = 'mp4a.40.5';
logger.info(
`Parsed audio codec "${parsedCodec}" or audio object type not handled. Using "${result}"`
`Parsed audio codec "${parsedCodec}" or audio object type not handled. Using "${result}"`,
);
return result;
}
+3 -3
View File
@@ -5,12 +5,12 @@ export interface Demuxer {
data: Uint8Array,
timeOffset: number,
isSampleAes?: boolean,
flush?: boolean
flush?: boolean,
): DemuxerResult;
demuxSampleAes(
data: Uint8Array,
keyData: KeyData,
timeOffset: number
timeOffset: number,
): Promise<DemuxerResult>;
flush(timeOffset?: number): DemuxerResult | Promise<DemuxerResult>;
destroy(): void;
@@ -18,7 +18,7 @@ export interface Demuxer {
initSegment: Uint8Array | undefined,
audioCodec: string | undefined,
videoCodec: string | undefined,
trackDuration: number
trackDuration: number,
);
resetTimeStamp(defaultInitPTS?: RationalTimestamp | null): void;
resetContiguity(): void;
+1 -1
View File
@@ -207,7 +207,7 @@ export class Level {
export function addGroupId(
level: Level,
type: string,
id: string | undefined
id: string | undefined,
): void {
if (!id) {
return;
+6 -6
View File
@@ -99,14 +99,14 @@ export type LoaderOnSuccess<T extends LoaderContext> = (
response: LoaderResponse,
stats: LoaderStats,
context: T,
networkDetails: any
networkDetails: any,
) => void;
export type LoaderOnProgress<T extends LoaderContext> = (
stats: LoaderStats,
context: T,
data: string | ArrayBuffer,
networkDetails: any
networkDetails: any,
) => void;
export type LoaderOnError<T extends LoaderContext> = (
@@ -118,19 +118,19 @@ export type LoaderOnError<T extends LoaderContext> = (
},
context: T,
networkDetails: any,
stats: LoaderStats
stats: LoaderStats,
) => void;
export type LoaderOnTimeout<T extends LoaderContext> = (
stats: LoaderStats,
context: T,
networkDetails: any
networkDetails: any,
) => void;
export type LoaderOnAbort<T extends LoaderContext> = (
stats: LoaderStats,
context: T,
networkDetails: any
networkDetails: any,
) => void;
export interface LoaderCallbacks<T extends LoaderContext> {
@@ -147,7 +147,7 @@ export interface Loader<T extends LoaderContext> {
load(
context: T,
config: LoaderConfiguration,
callbacks: LoaderCallbacks<T>
callbacks: LoaderCallbacks<T>,
): void;
/**
* `getCacheAge()` is called by hls.js to get the duration that a given object
+2 -2
View File
@@ -21,13 +21,13 @@ export interface Remuxer {
timeOffset: number,
accurateTimeOffset: boolean,
flush: boolean,
playlistType: PlaylistLevelType
playlistType: PlaylistLevelType,
): RemuxerResult;
resetInitSegment(
initSegment: Uint8Array | undefined,
audioCodec: string | undefined,
videoCodec: string | undefined,
decryptdata: DecryptData | null
decryptdata: DecryptData | null,
): void;
resetTimeStamp(defaultInitPTS: RationalTimestamp | null): void;
resetNextTimestamp(): void;
+1 -1
View File
@@ -30,7 +30,7 @@ export class ChunkMetadata {
id: number,
size = 0,
part = -1,
partial = false
partial = false,
) {
this.level = level;
this.sn = sn;
+1 -1
View File
@@ -18,7 +18,7 @@ const BinarySearch = {
*/
search: function <T>(
list: T[],
comparisonFn: BinarySearchComparison<T>
comparisonFn: BinarySearchComparison<T>,
): T | null {
let minIndex: number = 0;
let maxIndex: number = list.length - 1;
+2 -2
View File
@@ -55,7 +55,7 @@ export class BufferHelper {
static bufferInfo(
media: Bufferable | null,
pos: number,
maxHoleDuration: number
maxHoleDuration: number,
): BufferInfo {
try {
if (media) {
@@ -79,7 +79,7 @@ export class BufferHelper {
static bufferedInfo(
buffered: BufferTimeRange[],
pos: number,
maxHoleDuration: number
maxHoleDuration: number,
): {
len: number;
start: number;
+24 -21
View File
@@ -412,13 +412,13 @@ export class Row {
if (this.pos < 0) {
this.logger.log(
VerboseLevel.DEBUG,
'Negative cursor position ' + this.pos
'Negative cursor position ' + this.pos,
);
this.pos = 0;
} else if (this.pos > NR_COLS) {
this.logger.log(
VerboseLevel.DEBUG,
'Too large cursor position ' + this.pos
'Too large cursor position ' + this.pos,
);
this.pos = NR_COLS;
}
@@ -461,7 +461,7 @@ export class Row {
char +
') at position ' +
this.pos +
'. Skipping it!'
'. Skipping it!',
);
return;
}
@@ -601,7 +601,7 @@ export class CaptionScreen {
setPAC(pacData: PACData) {
this.logger.log(
VerboseLevel.INFO,
() => 'pacData = ' + JSON.stringify(pacData)
() => 'pacData = ' + JSON.stringify(pacData),
);
let newRow = pacData.row - 1;
if (this.nrRollUpRows && newRow < this.nrRollUpRows - 1) {
@@ -627,7 +627,7 @@ export class CaptionScreen {
if (prevLineTime !== null && time !== null && prevLineTime < time) {
for (let i = 0; i < this.nrRollUpRows; i++) {
this.rows[newRow - this.nrRollUpRows + i + 1].copy(
lastOutputScreen.rows[topRowIndex + i]
lastOutputScreen.rows[topRowIndex + i],
);
}
}
@@ -658,7 +658,7 @@ export class CaptionScreen {
setBkgData(bkgData: Partial<PenStyles>) {
this.logger.log(
VerboseLevel.INFO,
() => 'bkgData = ' + JSON.stringify(bkgData)
() => 'bkgData = ' + JSON.stringify(bkgData),
);
this.backSpace();
this.setPen(bkgData);
@@ -673,7 +673,7 @@ export class CaptionScreen {
if (this.nrRollUpRows === null) {
this.logger.log(
VerboseLevel.DEBUG,
'roll_up but nrRollUpRows not set yet'
'roll_up but nrRollUpRows not set yet',
);
return; // Not properly setup
}
@@ -745,7 +745,7 @@ class Cea608Channel {
constructor(
channelNumber: number,
outputFilter: OutputFilter,
logger: CaptionsLogger
logger: CaptionsLogger,
) {
this.chNr = channelNumber;
this.outputFilter = outputFilter;
@@ -818,12 +818,12 @@ class Cea608Channel {
this.writeScreen === this.displayedMemory ? 'DISP' : 'NON_DISP';
this.logger.log(
VerboseLevel.INFO,
() => screen + ': ' + this.writeScreen.getDisplayText(true)
() => screen + ': ' + this.writeScreen.getDisplayText(true),
);
if (this.mode === 'MODE_PAINT-ON' || this.mode === 'MODE_ROLL-UP') {
this.logger.log(
VerboseLevel.TEXT,
() => 'DISPLAYED: ' + this.displayedMemory.getDisplayText(true)
() => 'DISPLAYED: ' + this.displayedMemory.getDisplayText(true),
);
this.outputDataUpdate();
}
@@ -925,7 +925,7 @@ class Cea608Channel {
this.writeScreen = this.nonDisplayedMemory;
this.logger.log(
VerboseLevel.TEXT,
() => 'DISP: ' + this.displayedMemory.getDisplayText()
() => 'DISP: ' + this.displayedMemory.getDisplayText(),
);
}
this.outputDataUpdate(true);
@@ -976,7 +976,7 @@ class Cea608Channel {
this.outputFilter.newCue(
this.cueStartTime!,
time,
this.lastOutputScreen
this.lastOutputScreen,
);
if (dispatch && this.outputFilter.dispatchCue) {
this.outputFilter.dispatchCue();
@@ -1065,7 +1065,7 @@ class Cea608Parser {
numArrayToHexArray([byteList[i], byteList[i + 1]]) +
'] -> (' +
numArrayToHexArray([a, b]) +
')'
')',
);
}
@@ -1093,7 +1093,7 @@ class Cea608Parser {
} else {
this.logger.log(
VerboseLevel.WARNING,
'No channel found yet. TEXT-MODE?'
'No channel found yet. TEXT-MODE?',
);
}
}
@@ -1104,7 +1104,7 @@ class Cea608Parser {
"Couldn't parse cleaned data " +
numArrayToHexArray([a, b]) +
' orig: ' +
numArrayToHexArray([byteList[i], byteList[i + 1]])
numArrayToHexArray([byteList[i], byteList[i + 1]]),
);
}
}
@@ -1129,7 +1129,7 @@ class Cea608Parser {
setLastCmd(null, null, cmdHistory);
this.logger.log(
VerboseLevel.DEBUG,
'Repeated command (' + numArrayToHexArray([a, b]) + ') is dropped'
'Repeated command (' + numArrayToHexArray([a, b]) + ') is dropped',
);
return true;
}
@@ -1196,7 +1196,7 @@ class Cea608Parser {
if (chNr !== this.currentChannel) {
this.logger.log(
VerboseLevel.ERROR,
'Mismatch channel in midrow parsing'
'Mismatch channel in midrow parsing',
);
return false;
}
@@ -1207,7 +1207,7 @@ class Cea608Parser {
channel.ccMIDROW(b);
this.logger.log(
VerboseLevel.DEBUG,
'MIDROW (' + numArrayToHexArray([a, b]) + ')'
'MIDROW (' + numArrayToHexArray([a, b]) + ')',
);
return true;
}
@@ -1324,7 +1324,10 @@ class Cea608Parser {
this.logger.log(
VerboseLevel.INFO,
"Special char '" + getCharForByte(oneCode) + "' in channel " + channelNr
"Special char '" +
getCharForByte(oneCode) +
"' in channel " +
channelNr,
);
charCodes = [oneCode];
} else if (a >= 0x20 && a <= 0x7f) {
@@ -1334,7 +1337,7 @@ class Cea608Parser {
const hexCodes = numArrayToHexArray(charCodes);
this.logger.log(
VerboseLevel.DEBUG,
'Char codes = ' + hexCodes.join(',')
'Char codes = ' + hexCodes.join(','),
);
setLastCmd(a, b, this.cmdHistory);
}
@@ -1403,7 +1406,7 @@ class Cea608Parser {
function setLastCmd(
a: number | null,
b: number | null,
cmdHistory: CmdHistory
cmdHistory: CmdHistory,
) {
cmdHistory.a = a;
cmdHistory.b = b;
+4 -4
View File
@@ -88,7 +88,7 @@ export function isCodecType(codec: string, type: CodecType): boolean {
export function areCodecsMediaSourceSupported(
codecs: string,
type: CodecType
type: CodecType,
): boolean {
return !codecs
.split(',')
@@ -123,7 +123,7 @@ const CODEC_COMPATIBLE_NAMES: CodecNameCache = {};
type LowerCaseCodecType = 'flac' | 'opus';
function getCodecCompatibleNameLower(
lowerCaseCodec: LowerCaseCodecType
lowerCaseCodec: LowerCaseCodecType,
): string {
if (CODEC_COMPATIBLE_NAMES[lowerCaseCodec]) {
return CODEC_COMPATIBLE_NAMES[lowerCaseCodec]!;
@@ -150,13 +150,13 @@ function getCodecCompatibleNameLower(
const AUDIO_CODEC_REGEXP = /flac|opus/i;
export function getCodecCompatibleName(codec: string): string {
return codec.replace(AUDIO_CODEC_REGEXP, (m) =>
getCodecCompatibleNameLower(m.toLowerCase() as LowerCaseCodecType)
getCodecCompatibleNameLower(m.toLowerCase() as LowerCaseCodecType),
);
}
export function pickMostCompleteCodecName(
parsedCodec: string,
levelCodec: string
levelCodec: string,
): string {
// Parsing of mp4a codecs strings in mp4-tools from media is incomplete as of d8c6c7a
// so use level codec is parsed codec is unavailable or incomplete
+2 -2
View File
@@ -10,7 +10,7 @@ export interface CuesInterface {
track: TextTrack | null,
startTime: number,
endTime: number,
captionScreen: CaptionScreen
captionScreen: CaptionScreen,
): VTTCue[];
}
@@ -19,7 +19,7 @@ const Cues: CuesInterface = {
track: TextTrack | null,
startTime: number,
endTime: number,
captionScreen: CaptionScreen
captionScreen: CaptionScreen,
): VTTCue[] {
const result: VTTCue[] = [];
let row: Row;
+8 -8
View File
@@ -8,7 +8,7 @@ import type { RequiredProperties } from '../types/general';
export function findFirstFragWithCC(
fragments: Fragment[],
cc: number
cc: number,
): Fragment | null {
for (let i = 0, len = fragments.length; i < len; i++) {
if (fragments[i]?.cc === cc) {
@@ -21,7 +21,7 @@ export function findFirstFragWithCC(
export function shouldAlignOnDiscontinuities(
lastFrag: Fragment | null,
lastLevel: Level,
details: LevelDetails
details: LevelDetails,
): lastLevel is RequiredProperties<Level, 'details'> {
if (lastLevel.details) {
if (
@@ -37,7 +37,7 @@ export function shouldAlignOnDiscontinuities(
// Find the first frag in the previous level which matches the CC of the first frag of the new level
export function findDiscontinuousReferenceFrag(
prevDetails: LevelDetails,
curDetails: LevelDetails
curDetails: LevelDetails,
) {
const prevFrags = prevDetails.fragments;
const curFrags = curDetails.fragments;
@@ -91,7 +91,7 @@ export function adjustSlidingStart(sliding: number, details: LevelDetails) {
export function alignStream(
lastFrag: Fragment | null,
lastLevel: Level | null,
details: LevelDetails
details: LevelDetails,
) {
if (!lastLevel) {
return;
@@ -125,16 +125,16 @@ export function alignStream(
function alignDiscontinuities(
lastFrag: Fragment | null,
details: LevelDetails,
lastLevel: Level
lastLevel: Level,
) {
if (shouldAlignOnDiscontinuities(lastFrag, lastLevel, details)) {
const referenceFrag = findDiscontinuousReferenceFrag(
lastLevel.details,
details
details,
);
if (referenceFrag && Number.isFinite(referenceFrag.start)) {
logger.log(
`Adjusting PTS using last level due to CC increase within current level ${details.url}`
`Adjusting PTS using last level due to CC increase within current level ${details.url}`,
);
adjustSlidingStart(referenceFrag.start, details);
}
@@ -156,7 +156,7 @@ function alignDiscontinuities(
*/
export function alignMediaPlaylistByPDT(
details: LevelDetails,
refDetails: LevelDetails
refDetails: LevelDetails,
) {
if (!details.hasProgramDateTime || !refDetails.hasProgramDateTime) {
return;
+5 -5
View File
@@ -15,7 +15,7 @@ export function isTimeoutError(error: ErrorData): boolean {
export function getRetryConfig(
loadPolicy: LoadPolicy,
error: ErrorData
error: ErrorData,
): RetryConfig | null {
const isTimeout = isTimeoutError(error);
return loadPolicy.default[`${isTimeout ? 'timeout' : 'error'}Retry`];
@@ -23,19 +23,19 @@ export function getRetryConfig(
export function getRetryDelay(
retryConfig: RetryConfig,
retryCount: number
retryCount: number,
): number {
// exponential backoff capped to max retry delay
const backoffFactor =
retryConfig.backoff === 'linear' ? 1 : Math.pow(2, retryCount);
return Math.min(
backoffFactor * retryConfig.retryDelayMs,
retryConfig.maxRetryDelayMs
retryConfig.maxRetryDelayMs,
);
}
export function getLoaderConfigWithoutReties(
loderConfig: LoaderConfig
loderConfig: LoaderConfig,
): LoaderConfig {
return {
...loderConfig,
@@ -50,7 +50,7 @@ export function shouldRetry(
retryConfig: RetryConfig | null | undefined,
retryCount: number,
isTimeout: boolean,
httpStatus?: number | undefined
httpStatus?: number | undefined,
): retryConfig is RetryConfig & boolean {
return (
!!retryConfig &&
+1 -1
View File
@@ -21,7 +21,7 @@ class EwmaBandWidthEstimator {
slow: number,
fast: number,
defaultEstimate: number,
defaultTTFB: number = 100
defaultTTFB: number = 100,
) {
this.defaultEstimate_ = defaultEstimate;
this.minWeight_ = 0.001;
+15 -12
View File
@@ -75,7 +75,7 @@ class FetchLoader implements Loader<LoaderContext> {
this.callbacks.onAbort(
this.stats,
this.context as LoaderContext,
this.response
this.response,
);
}
}
@@ -83,7 +83,7 @@ class FetchLoader implements Loader<LoaderContext> {
load(
context: LoaderContext,
config: LoaderConfiguration,
callbacks: LoaderCallbacks<LoaderContext>
callbacks: LoaderCallbacks<LoaderContext>,
): void {
const stats = this.stats;
if (stats.loading.start) {
@@ -121,17 +121,20 @@ class FetchLoader implements Loader<LoaderContext> {
self.clearTimeout(this.requestTimeout);
config.timeout = maxLoadTimeMs;
this.requestTimeout = self.setTimeout(() => {
this.abortInternal();
callbacks.onTimeout(stats, context, this.response);
}, maxLoadTimeMs - (first - stats.loading.start));
this.requestTimeout = self.setTimeout(
() => {
this.abortInternal();
callbacks.onTimeout(stats, context, this.response);
},
maxLoadTimeMs - (first - stats.loading.start),
);
if (!response.ok) {
const { status, statusText } = response;
throw new FetchError(
statusText || 'fetch, bad network response',
status,
response
response,
);
}
stats.loading.first = first;
@@ -144,7 +147,7 @@ class FetchLoader implements Loader<LoaderContext> {
stats,
context,
config.highWaterMark,
onProgress
onProgress,
);
}
@@ -164,7 +167,7 @@ class FetchLoader implements Loader<LoaderContext> {
self.clearTimeout(this.requestTimeout);
stats.loading.end = Math.max(
self.performance.now(),
stats.loading.first
stats.loading.first,
);
const total = responseData[LENGTH];
if (total) {
@@ -196,7 +199,7 @@ class FetchLoader implements Loader<LoaderContext> {
{ code, text },
context,
error ? error.details : null,
stats
stats,
);
});
}
@@ -219,7 +222,7 @@ class FetchLoader implements Loader<LoaderContext> {
stats: LoaderStats,
context: LoaderContext,
highWaterMark: number = 0,
onProgress: LoaderOnProgress<LoaderContext>
onProgress: LoaderOnProgress<LoaderContext>,
): Promise<ArrayBuffer> {
const chunkCache = new ChunkCache();
const reader = (response.body as ReadableStream).getReader();
@@ -275,7 +278,7 @@ function getRequestParameters(context: LoaderContext, signal): any {
if (context.rangeEnd) {
initParams.headers.set(
'Range',
'bytes=' + context.rangeStart + '-' + String(context.rangeEnd - 1)
'bytes=' + context.rangeStart + '-' + String(context.rangeEnd - 1),
);
}
+7 -7
View File
@@ -28,7 +28,7 @@ export function parseIMSC1(
payload: ArrayBuffer,
initPTS: RationalTimestamp,
callBack: (cues: Array<VTTCue>) => any,
errorCallBack: (error: Error) => any
errorCallBack: (error: Error) => any,
) {
const results = findBox(new Uint8Array(payload), ['mdat']);
if (results.length === 0) {
@@ -65,16 +65,16 @@ function parseTTML(ttml: string, syncTime: number): Array<VTTCue> {
result[key] = tt.getAttribute(`ttp:${key}`) || defaultRateInfo[key];
return result;
},
{}
{},
);
const trim = tt.getAttribute('xml:space') !== 'preserve';
const styleElements = collectionToDictionary(
getElementCollection(tt, 'styling', 'style')
getElementCollection(tt, 'styling', 'style'),
);
const regionElements = collectionToDictionary(
getElementCollection(tt, 'layout', 'region')
getElementCollection(tt, 'layout', 'region'),
);
const cueElements = getElementCollection(tt, 'body', '[begin]');
@@ -87,7 +87,7 @@ function parseTTML(ttml: string, syncTime: number): Array<VTTCue> {
}
const startTime = parseTtmlTime(
cueElement.getAttribute('begin'),
rateInfo
rateInfo,
);
const duration = parseTtmlTime(cueElement.getAttribute('dur'), rateInfo);
let endTime = parseTtmlTime(cueElement.getAttribute('end'), rateInfo);
@@ -127,7 +127,7 @@ function parseTTML(ttml: string, syncTime: number): Array<VTTCue> {
function getElementCollection(
fromElement,
parentName,
childName
childName,
): Array<HTMLElement> {
const parent = fromElement.getElementsByTagName(parentName)[0];
if (parent) {
@@ -165,7 +165,7 @@ function getTextContent(element, trim): string {
function getTtmlStyles(
region,
style,
styleElements
styleElements,
): { [style: string]: string } {
const ttsNs = 'http://www.w3.org/ns/ttml#styling';
let regionStyle = null;
+1 -1
View File
@@ -43,6 +43,6 @@ export function convertDataUriToArrayBytes(uri: string): Uint8Array | null {
export function strToUtf8array(str: string): Uint8Array {
return Uint8Array.from(unescape(encodeURIComponent(str)), (c) =>
c.charCodeAt(0)
c.charCodeAt(0),
);
}
+18 -18
View File
@@ -14,7 +14,7 @@ type PartIntersection = (oldPart: Part, newPart: Part) => void;
export function updatePTS(
fragments: Fragment[],
fromIdx: number,
toIdx: number
toIdx: number,
): void {
const fragFrom = fragments[fromIdx];
const fragTo = fragments[toIdx];
@@ -59,7 +59,7 @@ export function updateFragPTSDTS(
startPTS: number,
endPTS: number,
startDTS: number,
endDTS: number
endDTS: number,
): number {
const parsedMediaDuration = endPTS - startPTS;
if (parsedMediaDuration <= 0) {
@@ -134,7 +134,7 @@ export function updateFragPTSDTS(
export function mergeDetails(
oldDetails: LevelDetails,
newDetails: LevelDetails
newDetails: LevelDetails,
): void {
// Track the last initSegment processed. Initialize it to the last one on the timeline.
let currentInitSegment: Fragment | null = null;
@@ -194,7 +194,7 @@ export function mergeDetails(
newFrag.initSegment = oldFrag.initSegment;
currentInitSegment = oldFrag.initSegment;
}
}
},
);
if (currentInitSegment) {
@@ -215,7 +215,7 @@ export function mergeDetails(
newDetails.deltaUpdateFailed = newDetails.fragments.some((frag) => !frag);
if (newDetails.deltaUpdateFailed) {
logger.warn(
'[level-helper] Previous playlist missing segments skipped in delta playlist'
'[level-helper] Previous playlist missing segments skipped in delta playlist',
);
for (let i = newDetails.skippedSegments; i--; ) {
newDetails.fragments.shift();
@@ -226,7 +226,7 @@ export function mergeDetails(
newDetails.dateRanges = mergeDateRanges(
oldDetails.dateRanges,
newDetails.dateRanges,
newDetails.recentlyRemovedDateranges
newDetails.recentlyRemovedDateranges,
);
}
}
@@ -249,7 +249,7 @@ export function mergeDetails(
(oldPart: Part, newPart: Part) => {
newPart.elementaryStreams = oldPart.elementaryStreams;
newPart.stats = oldPart.stats;
}
},
);
// if at least one fragment contains PTS info, recompute PTS information for all fragments
@@ -260,7 +260,7 @@ export function mergeDetails(
PTSFrag.startPTS,
PTSFrag.endPTS,
PTSFrag.startDTS,
PTSFrag.endDTS
PTSFrag.endDTS,
);
} else {
// ensure that delta is within oldFragments range
@@ -294,7 +294,7 @@ export function mergeDetails(
function mergeDateRanges(
oldDateRanges: Record<string, DateRange>,
deltaDateRanges: Record<string, DateRange>,
recentlyRemovedDateranges: string[] | undefined
recentlyRemovedDateranges: string[] | undefined,
): Record<string, DateRange> {
const dateRanges = Object.assign({}, oldDateRanges);
if (recentlyRemovedDateranges) {
@@ -309,8 +309,8 @@ function mergeDateRanges(
} else {
logger.warn(
`Ignoring invalid Playlist Delta Update DATERANGE tag: "${JSON.stringify(
deltaDateRanges[id].attr
)}"`
deltaDateRanges[id].attr,
)}"`,
);
}
});
@@ -320,7 +320,7 @@ function mergeDateRanges(
export function mapPartIntersection(
oldParts: Part[] | null,
newParts: Part[] | null,
intersectionFn: PartIntersection
intersectionFn: PartIntersection,
) {
if (oldParts && newParts) {
let delta = 0;
@@ -344,7 +344,7 @@ export function mapPartIntersection(
export function mapFragmentIntersection(
oldDetails: LevelDetails,
newDetails: LevelDetails,
intersectionFn: FragmentIntersection
intersectionFn: FragmentIntersection,
): void {
const skippedSegments = newDetails.skippedSegments;
const start =
@@ -378,7 +378,7 @@ export function mapFragmentIntersection(
export function adjustSliding(
oldDetails: LevelDetails,
newDetails: LevelDetails
newDetails: LevelDetails,
): void {
const delta =
newDetails.startSN + newDetails.skippedSegments - oldDetails.startSN;
@@ -403,7 +403,7 @@ export function addSliding(details: LevelDetails, start: number) {
export function computeReloadInterval(
newDetails: LevelDetails,
distanceToLiveEdgeMs: number = Infinity
distanceToLiveEdgeMs: number = Infinity,
): number {
let reloadInterval = 1000 * newDetails.targetduration;
@@ -435,7 +435,7 @@ export function computeReloadInterval(
export function getFragmentWithSN(
level: Level,
sn: number,
fragCurrent: Fragment | null
fragCurrent: Fragment | null,
): Fragment | null {
if (!level?.details) {
return null;
@@ -459,7 +459,7 @@ export function getFragmentWithSN(
export function getPartWith(
level: Level,
sn: number,
partIndex: number
partIndex: number,
): Part | null {
if (!level?.details) {
return null;
@@ -470,7 +470,7 @@ export function getPartWith(
export function findPart(
partList: Part[] | null | undefined,
sn: number,
partIndex: number
partIndex: number,
): Part | null {
if (partList) {
for (let i = partList.length; i--; ) {
+2 -2
View File
@@ -66,13 +66,13 @@ export function enableLogs(debugConfig: boolean | ILogger, id: string): void {
'log',
'info',
'warn',
'error'
'error',
);
// Some browsers don't allow to use bind on console object anyway
// fallback to default if needed
try {
exportedLogger.log(
`Debug logs enabled for "${id}" in hls.js version ${__VERSION__}`
`Debug logs enabled for "${id}" in hls.js version ${__VERSION__}`,
);
} catch (e) {
exportedLogger = fakeLogger;
+4 -4
View File
@@ -3,7 +3,7 @@ import type { MediaAttributes, MediaPlaylist } from '../types/media-playlist';
export function subtitleOptionsIdentical(
trackList1: MediaPlaylist[] | Level[],
trackList2: MediaPlaylist[]
trackList2: MediaPlaylist[],
): boolean {
if (trackList1.length !== trackList2.length) {
return false;
@@ -12,7 +12,7 @@ export function subtitleOptionsIdentical(
if (
!subtitleAttributesIdentical(
trackList1[i].attrs as MediaAttributes,
trackList2[i].attrs
trackList2[i].attrs,
)
) {
return false;
@@ -23,7 +23,7 @@ export function subtitleOptionsIdentical(
export function subtitleAttributesIdentical(
attrs1: MediaAttributes,
attrs2: MediaAttributes
attrs2: MediaAttributes,
): boolean {
// Media options with the same rendition ID must be bit identical
const stableRenditionId = attrs1['STABLE-RENDITION-ID'];
@@ -40,6 +40,6 @@ export function subtitleAttributesIdentical(
'FORCED',
].some(
(subtitleAttribute) =>
attrs1[subtitleAttribute] !== attrs2[subtitleAttribute]
attrs1[subtitleAttribute] !== attrs2[subtitleAttribute],
);
}
+4 -4
View File
@@ -34,7 +34,7 @@ export function requiresMediaCapabilitiesDecodingInfo(
mediaCapabilities: MediaCapabilities | undefined,
currentVideoRange: VideoRange | undefined,
currentFrameRate: number,
currentBw: number
currentBw: number,
): boolean {
// Only test support when configuration is exceeds minimum options
const audioGroupId = level.audioCodec ? level.audioGroupId : null;
@@ -57,7 +57,7 @@ export function requiresMediaCapabilitiesDecodingInfo(
export function getMediaDecodingInfoPromise(
level: Level,
audioTracksByGroup: AudioTracksByGroup,
mediaCapabilities: MediaCapabilities
mediaCapabilities: MediaCapabilities,
): Promise<MediaDecodingInfo> {
const videoCodecs = level.videoCodec;
const audioCodecs = level.audioCodec;
@@ -106,7 +106,7 @@ export function getMediaDecodingInfoPromise(
// spatialRendering:
// audioCodec === 'ec-3' && channels.indexOf('JOC'),
},
}))
})),
);
}
}
@@ -122,7 +122,7 @@ export function getMediaDecodingInfoPromise(
(SUPPORTED_INFO_CACHE[decodingInfoKey] =
mediaCapabilities.decodingInfo(configuration))
);
})
}),
)
.then((decodingInfoResults) => ({
supported: !decodingInfoResults.some((info) => !info.supported),
+8 -8
View File
@@ -19,7 +19,7 @@ export const enum KeySystemFormats {
}
export function keySystemFormatToKeySystemDomain(
format: KeySystemFormats
format: KeySystemFormats,
): KeySystems | undefined {
switch (format) {
case KeySystemFormats.FAIRPLAY:
@@ -43,7 +43,7 @@ export const enum KeySystemIds {
}
export function keySystemIdToKeySystemDomain(
systemId: KeySystemIds
systemId: KeySystemIds,
): KeySystems | undefined {
if (systemId === KeySystemIds.WIDEVINE) {
return KeySystems.WIDEVINE;
@@ -55,7 +55,7 @@ export function keySystemIdToKeySystemDomain(
}
export function keySystemDomainToKeySystemFormat(
keySystem: KeySystems
keySystem: KeySystems,
): KeySystemFormats | undefined {
switch (keySystem) {
case KeySystems.FAIRPLAY:
@@ -70,7 +70,7 @@ export function keySystemDomainToKeySystemFormat(
}
export function getKeySystemsForConfig(
config: EMEControllerConfig
config: EMEControllerConfig,
): KeySystems[] {
const { drmSystems, widevineLicenseUrl } = config;
const keySystemsToAttempt: KeySystems[] = drmSystems
@@ -89,7 +89,7 @@ export function getKeySystemsForConfig(
export type MediaKeyFunc = (
keySystem: KeySystems,
supportedConfigurations: MediaKeySystemConfiguration[]
supportedConfigurations: MediaKeySystemConfiguration[],
) => Promise<MediaKeySystemAccess>;
export const requestMediaKeySystemAccess = (function (): MediaKeyFunc | null {
@@ -111,7 +111,7 @@ export function getSupportedMediaKeySystemConfigurations(
keySystem: KeySystems,
audioCodecs: string[],
videoCodecs: string[],
drmSystemOptions: DRMSystemOptions
drmSystemOptions: DRMSystemOptions,
): MediaKeySystemConfiguration[] {
let initDataTypes: string[];
switch (keySystem) {
@@ -132,7 +132,7 @@ export function getSupportedMediaKeySystemConfigurations(
initDataTypes,
audioCodecs,
videoCodecs,
drmSystemOptions
drmSystemOptions,
);
}
@@ -140,7 +140,7 @@ function createMediaKeySystemConfigurations(
initDataTypes: string[],
audioCodecs: string[],
videoCodecs: string[],
drmSystemOptions: DRMSystemOptions
drmSystemOptions: DRMSystemOptions,
): MediaKeySystemConfiguration[] {
const baseConfig: MediaKeySystemConfiguration = {
initDataTypes: initDataTypes,
+17 -17
View File
@@ -406,7 +406,7 @@ function addLeadingZero(num: number): string {
export function patchEncyptionData(
initSegment: Uint8Array | undefined,
decryptdata: DecryptData | null
decryptdata: DecryptData | null,
): Uint8Array | undefined {
if (!initSegment || !decryptdata) {
return initSegment;
@@ -437,8 +437,8 @@ export function patchEncyptionData(
`[eme] Patching keyId in 'enc${
isAudio ? 'a' : 'v'
}>sinf>>tenc' box: ${Hex.hexDump(tencKeyId)} -> ${Hex.hexDump(
keyId
)}`
keyId,
)}`,
);
tenc.set(keyId, 8);
}
@@ -482,7 +482,7 @@ export function parseSinf(sinf: Uint8Array): Uint8Array | null {
*/
export function getStartDTS(
initData: InitData,
fmp4: Uint8Array
fmp4: Uint8Array,
): number | null {
// we need info from two children of each track fragment box
return findBox(fmp4, ['moof', 'traf']).reduce(
@@ -502,7 +502,7 @@ export function getStartDTS(
// https://github.com/video-dev/hls.js/issues/5303
if (baseTime === UINT32_MAX) {
logger.warn(
`[mp4-demuxer]: Ignoring assumed invalid signed 64-bit track fragment decode time`
`[mp4-demuxer]: Ignoring assumed invalid signed 64-bit track fragment decode time`,
);
return result;
}
@@ -522,7 +522,7 @@ export function getStartDTS(
}
return result;
},
null
null,
);
if (
start !== null &&
@@ -533,7 +533,7 @@ export function getStartDTS(
}
return result;
},
null
null,
);
}
@@ -607,7 +607,7 @@ export function getDuration(data: Uint8Array, initData: InitData) {
if (sidx?.references) {
sidxDuration += sidx.references.reduce(
(dur, ref) => dur + ref.info.duration || 0,
0
0,
);
}
}
@@ -682,7 +682,7 @@ export function computeRawDurationFromSamples(trun): number {
export function offsetStartDTS(
initData: InitData,
fmp4: Uint8Array,
timeOffset: number
timeOffset: number,
) {
findBox(fmp4, ['moof', 'traf']).forEach((traf) => {
findBox(traf, ['tfhd']).forEach((tfhd) => {
@@ -746,7 +746,7 @@ export interface SegmentedRange {
export function appendUint8Array(
data1: Uint8Array,
data2: Uint8Array
data2: Uint8Array,
): Uint8Array {
const temp = new Uint8Array(data1.length + data2.length);
temp.set(data1);
@@ -768,7 +768,7 @@ export interface IEmsgParsingData {
export function parseSamples(
timeOffset: number,
track: PassthroughTrack
track: PassthroughTrack,
): UserdataSample[] {
const seiSamples = [] as UserdataSample[];
const videoData = track.samples;
@@ -888,13 +888,13 @@ export function parseSamples(
if (isSEIMessage(isHEVCFlavor, videoData[sampleOffset])) {
const data = videoData.subarray(
sampleOffset,
sampleOffset + naluSize
sampleOffset + naluSize,
);
parseSEIMessageFromNALu(
data,
isHEVCFlavor ? 2 : 1,
timeOffset + compositionOffset / timescale,
seiSamples
seiSamples,
);
}
sampleOffset += naluSize;
@@ -941,7 +941,7 @@ export function parseSEIMessageFromNALu(
unescapedData: Uint8Array,
headerSize: number,
pts: number,
samples: UserdataSample[]
samples: UserdataSample[],
) {
const data = discardEPB(unescapedData);
let seiPtr = 0;
@@ -1134,7 +1134,7 @@ export function parseEmsg(data: Uint8Array): IEmsgParsingData {
if (!Number.isSafeInteger(presentationTime)) {
presentationTime = Number.MAX_SAFE_INTEGER;
logger.warn(
'Presentation time exceeds safe integer limit and wrapped to max safe integer in parsing emsg box'
'Presentation time exceeds safe integer limit and wrapped to max safe integer in parsing emsg box',
);
}
@@ -1196,7 +1196,7 @@ export function mp4Box(type: ArrayLike<number>, ...payload: Uint8Array[]) {
export function mp4pssh(
systemId: Uint8Array,
keyids: Array<Uint8Array> | null,
data: Uint8Array
data: Uint8Array,
) {
if (systemId.byteLength !== 16) {
throw new RangeError('Invalid system id');
@@ -1242,7 +1242,7 @@ export function mp4pssh(
kidCount,
kids,
dataSize,
data || new Uint8Array()
data || new Uint8Array(),
);
}
+1 -1
View File
@@ -24,7 +24,7 @@ export default class OutputFilter {
this.startTime,
this.endTime as number,
this.screen as CaptionScreen,
this.cueRanges
this.cueRanges,
);
this.startTime = null;
}
+12 -12
View File
@@ -30,7 +30,7 @@ type StartParameters = {
export function getStartCodecTier(
codecTiers: Record<string, CodecSetTier>,
videoRange: VideoRange | undefined,
currentBw: number
currentBw: number,
): StartParameters {
const codecSets = Object.keys(codecTiers);
// Use first level set to determine stereo, and minimum resolution and framerate
@@ -70,49 +70,49 @@ export function getStartCodecTier(
if (candidateTier.minBitrate > currentBw) {
logStartCodecCandidateIgnored(
candidate,
`min bitrate of ${candidateTier.minBitrate} > current estimate of ${currentBw}`
`min bitrate of ${candidateTier.minBitrate} > current estimate of ${currentBw}`,
);
return selected;
}
if (!candidateTier.hasDefaultAudio) {
logStartCodecCandidateIgnored(
candidate,
`no renditions with default or auto-select sound found`
`no renditions with default or auto-select sound found`,
);
return selected;
}
if (hasStereo && candidateTier.channels['2'] === 0) {
logStartCodecCandidateIgnored(
candidate,
`no renditions with stereo sound found`
`no renditions with stereo sound found`,
);
return selected;
}
if (candidateTier.minHeight > maxHeight) {
logStartCodecCandidateIgnored(
candidate,
`min resolution of ${candidateTier.minHeight} > maximum of ${maxHeight}`
`min resolution of ${candidateTier.minHeight} > maximum of ${maxHeight}`,
);
return selected;
}
if (candidateTier.minFramerate > maxFramerate) {
logStartCodecCandidateIgnored(
candidate,
`min framerate of ${candidateTier.minFramerate} > maximum of ${maxFramerate}`
`min framerate of ${candidateTier.minFramerate} > maximum of ${maxFramerate}`,
);
return selected;
}
if (videoRange && candidateTier.videoRanges[videoRange] === 0) {
logStartCodecCandidateIgnored(
candidate,
`no variants with VIDEO-RANGE of ${videoRange} found`
`no variants with VIDEO-RANGE of ${videoRange} found`,
);
return selected;
}
if (candidateTier.maxScore < selectedScore) {
logStartCodecCandidateIgnored(
candidate,
`max score of ${candidateTier.maxScore} < selected max of ${selectedScore}`
`max score of ${candidateTier.maxScore} < selected max of ${selectedScore}`,
);
return selected;
}
@@ -128,7 +128,7 @@ export function getStartCodecTier(
selectedScore = candidateTier.maxScore;
return candidate;
},
undefined
undefined,
);
return {
codecSet,
@@ -140,7 +140,7 @@ export function getStartCodecTier(
function logStartCodecCandidateIgnored(codeSet: string, reason: string) {
logger.log(
`[abr] start candidates with "${codeSet}" ignored because ${reason}`
`[abr] start candidates with "${codeSet}" ignored because ${reason}`,
);
}
@@ -180,7 +180,7 @@ export function getAudioTracksByGroup(allAudioTracks: MediaPlaylist[]) {
hasDefaultAudio: false,
hasAutoSelectAudio: false,
groups: {},
}
},
);
}
@@ -188,7 +188,7 @@ export function getCodecTiers(
levels: Level[],
audioTracksByGroup: AudioTracksByGroup,
minAutoLevel: number,
maxAutoLevel: number
maxAutoLevel: number,
): Record<string, CodecSetTier> {
return levels
.slice(minAutoLevel, maxAutoLevel + 1)
+5 -5
View File
@@ -33,13 +33,13 @@ export function addCueToTrack(track: TextTrack, cue: VTTCue) {
const textTrackCue = new (self.TextTrackCue as any)(
cue.startTime,
cue.endTime,
cue.text
cue.text,
);
textTrackCue.id = cue.id;
track.addCue(textTrackCue);
} catch (err2) {
logger.debug(
`[texttrack-utils]: Legacy TextTrackCue fallback failed: ${err2}`
`[texttrack-utils]: Legacy TextTrackCue fallback failed: ${err2}`,
);
}
}
@@ -71,7 +71,7 @@ export function removeCuesInRange(
track: TextTrack,
start: number,
end: number,
predicate?: (cue: TextTrackCue) => boolean
predicate?: (cue: TextTrackCue) => boolean,
) {
const mode = track.mode;
if (mode === 'disabled') {
@@ -95,7 +95,7 @@ export function removeCuesInRange(
// Modified version of binary search O(log(n)).
function getFirstCueIndexAfterTime(
cues: TextTrackCueList | TextTrackCue[],
time: number
time: number,
): number {
// If first cue starts after time, start there
if (time < cues[0].startTime) {
@@ -132,7 +132,7 @@ function getFirstCueIndexAfterTime(
export function getCuesInRange(
cues: TextTrackCueList | TextTrackCue[],
start: number,
end: number
end: number,
): TextTrackCue[] {
const cuesFound: TextTrackCue[] = [];
const firstCueInRange = getFirstCueIndexAfterTime(cues, start);
+4 -4
View File
@@ -9,7 +9,7 @@ export function toTimescaleFromBase(
baseTime: number,
destScale: number,
srcBase: number = 1,
round: boolean = false
round: boolean = false,
): number {
const result = baseTime * destScale * srcBase; // equivalent to `(value * scale) / (1 / base)`
return round ? Math.round(result) : result;
@@ -19,21 +19,21 @@ export function toTimescaleFromScale(
baseTime: number,
destScale: number,
srcScale: number = 1,
round: boolean = false
round: boolean = false,
): number {
return toTimescaleFromBase(baseTime, destScale, 1 / srcScale, round);
}
export function toMsFromMpegTsClock(
baseTime: number,
round: boolean = false
round: boolean = false,
): number {
return toTimescaleFromBase(baseTime, 1000, 1 / MPEG_TS_CLOCK_FREQ_HZ, round);
}
export function toMpegTsClockFromTimescale(
baseTime: number,
srcScale: number = 1
srcScale: number = 1,
): number {
return toTimescaleFromBase(baseTime, MPEG_TS_CLOCK_FREQ_HZ, 1 / srcScale);
}
+1 -1
View File
@@ -1,7 +1,7 @@
export function sliceUint8(
array: Uint8Array,
start?: number,
end?: number
end?: number,
): Uint8Array {
// @ts-expect-error This polyfills IE11 usage of Uint8Array slice.
// It always exists in the TypeScript definition so fails, but it fails at runtime on IE11.
+11 -11
View File
@@ -15,7 +15,7 @@ export function substituteVariablesInAttributes(
'variableList' | 'hasVariableRefs' | 'playlistParsingError'
>,
attr: AttrList,
attributeNames: string[]
attributeNames: string[],
) {
if (parsed.variableList !== null || parsed.hasVariableRefs) {
for (let i = attributeNames.length; i--; ) {
@@ -33,7 +33,7 @@ export function substituteVariables(
ParsedMultivariantPlaylist | LevelDetails,
'variableList' | 'hasVariableRefs' | 'playlistParsingError'
>,
value: string
value: string,
): string {
if (parsed.variableList !== null || parsed.hasVariableRefs) {
const variableList = parsed.variableList;
@@ -42,17 +42,17 @@ export function substituteVariables(
(variableReference: string) => {
const variableName = variableReference.substring(
2,
variableReference.length - 1
variableReference.length - 1,
);
const variableValue = variableList?.[variableName];
if (variableValue === undefined) {
parsed.playlistParsingError ||= new Error(
`Missing preceding EXT-X-DEFINE tag for Variable Reference: "${variableName}"`
`Missing preceding EXT-X-DEFINE tag for Variable Reference: "${variableName}"`,
);
return variableReference;
}
return variableValue;
}
},
);
}
return value;
@@ -64,7 +64,7 @@ export function addVariableDefinition(
'variableList' | 'playlistParsingError'
>,
attr: AttrList,
parentUrl: string
parentUrl: string,
) {
let variableList = parsed.variableList;
if (!variableList) {
@@ -80,12 +80,12 @@ export function addVariableDefinition(
VALUE = searchParams.get(NAME);
} else {
throw new Error(
`"${NAME}" does not match any query parameter in URI: "${parentUrl}"`
`"${NAME}" does not match any query parameter in URI: "${parentUrl}"`,
);
}
} catch (error) {
parsed.playlistParsingError ||= new Error(
`EXT-X-DEFINE QUERYPARAM: ${error.message}`
`EXT-X-DEFINE QUERYPARAM: ${error.message}`,
);
}
} else {
@@ -94,7 +94,7 @@ export function addVariableDefinition(
}
if (NAME in variableList) {
parsed.playlistParsingError ||= new Error(
`EXT-X-DEFINE duplicate Variable Name declarations: "${NAME}"`
`EXT-X-DEFINE duplicate Variable Name declarations: "${NAME}"`,
);
} else {
variableList[NAME] = VALUE || '';
@@ -107,7 +107,7 @@ export function importVariableDefinition(
'variableList' | 'playlistParsingError'
>,
attr: AttrList,
sourceVariableList: VariableMap | null
sourceVariableList: VariableMap | null,
) {
const IMPORT = attr.IMPORT;
if (sourceVariableList && IMPORT in sourceVariableList) {
@@ -118,7 +118,7 @@ export function importVariableDefinition(
variableList[IMPORT] = sourceVariableList[IMPORT];
} else {
parsed.playlistParsingError ||= new Error(
`EXT-X-DEFINE IMPORT attribute not found in Multivariant Playlist: "${IMPORT}"`
`EXT-X-DEFINE IMPORT attribute not found in Multivariant Playlist: "${IMPORT}"`,
);
}
}
+21 -21
View File
@@ -58,14 +58,14 @@ export default (function () {
function findDirectionSetting(value: string) {
return isAllowedValue<typeof AllowedDirections, Direction>(
AllowedDirections,
value
value,
);
}
function findAlignSetting(value: string) {
return isAllowedValue<typeof AllowedAlignments, Alignment>(
AllowedAlignments,
value
value,
);
}
@@ -124,7 +124,7 @@ export default (function () {
set: function (value: string) {
_id = '' + value;
},
})
}),
);
Object.defineProperty(
@@ -137,7 +137,7 @@ export default (function () {
set: function (value: boolean) {
_pauseOnExit = !!value;
},
})
}),
);
Object.defineProperty(
@@ -155,7 +155,7 @@ export default (function () {
_startTime = value;
this.hasBeenReset = true;
},
})
}),
);
Object.defineProperty(
@@ -173,7 +173,7 @@ export default (function () {
_endTime = value;
this.hasBeenReset = true;
},
})
}),
);
Object.defineProperty(
@@ -187,7 +187,7 @@ export default (function () {
_text = '' + value;
this.hasBeenReset = true;
},
})
}),
);
// todo: implement VTTRegion polyfill?
@@ -202,7 +202,7 @@ export default (function () {
_region = value;
this.hasBeenReset = true;
},
})
}),
);
Object.defineProperty(
@@ -217,14 +217,14 @@ export default (function () {
// Have to check for false because the setting an be an empty string.
if (setting === false) {
throw new SyntaxError(
'An invalid or illegal string was specified.'
'An invalid or illegal string was specified.',
);
}
_vertical = setting;
this.hasBeenReset = true;
},
})
}),
);
Object.defineProperty(
@@ -238,7 +238,7 @@ export default (function () {
_snapToLines = !!value;
this.hasBeenReset = true;
},
})
}),
);
Object.defineProperty(
@@ -251,14 +251,14 @@ export default (function () {
set: function (value: number | 'auto') {
if (typeof value !== 'number' && value !== 'auto') {
throw new SyntaxError(
'An invalid number or illegal string was specified.'
'An invalid number or illegal string was specified.',
);
}
_line = value;
this.hasBeenReset = true;
},
})
}),
);
Object.defineProperty(
@@ -272,14 +272,14 @@ export default (function () {
const setting = findAlignSetting(value);
if (!setting) {
throw new SyntaxError(
'An invalid or illegal string was specified.'
'An invalid or illegal string was specified.',
);
}
_lineAlign = setting;
this.hasBeenReset = true;
},
})
}),
);
Object.defineProperty(
@@ -297,7 +297,7 @@ export default (function () {
_position = value;
this.hasBeenReset = true;
},
})
}),
);
Object.defineProperty(
@@ -311,14 +311,14 @@ export default (function () {
const setting = findAlignSetting(value);
if (!setting) {
throw new SyntaxError(
'An invalid or illegal string was specified.'
'An invalid or illegal string was specified.',
);
}
_positionAlign = setting;
this.hasBeenReset = true;
},
})
}),
);
Object.defineProperty(
@@ -336,7 +336,7 @@ export default (function () {
_size = value;
this.hasBeenReset = true;
},
})
}),
);
Object.defineProperty(
@@ -350,14 +350,14 @@ export default (function () {
const setting = findAlignSetting(value);
if (!setting) {
throw new SyntaxError(
'An invalid or illegal string was specified.'
'An invalid or illegal string was specified.',
);
}
_align = setting;
this.hasBeenReset = true;
},
})
}),
);
/**
+5 -4
View File
@@ -101,7 +101,7 @@ function parseOptions(
input: string,
callback: (k: string, v: any) => void,
keyValueDelim: RegExp,
groupDelim?: RegExp
groupDelim?: RegExp,
) {
const groups = groupDelim ? input.split(groupDelim) : [input];
for (const i in groups) {
@@ -198,7 +198,7 @@ function parseCue(input: string, cue: VTTCue, regionList: Region[]) {
}
},
/:/,
/\s/
/\s/,
);
// Apply default values for any missing fields.
@@ -238,7 +238,8 @@ function parseCue(input: string, cue: VTTCue, regionList: Region[]) {
if (input.slice(0, 3) !== '-->') {
// (3) next characters must match '-->'
throw new Error(
"Malformed time stamp (time stamps must be separated by '-->'): " + oInput
"Malformed time stamp (time stamps must be separated by '-->'): " +
oInput,
);
}
input = input.slice(3);
@@ -329,7 +330,7 @@ export class VTTParser {
// break;
// }
},
/:/
/:/,
);
}
+4 -4
View File
@@ -13,7 +13,7 @@ const LINEBREAKS = /\r\n|\n\r|\n|\r/g;
const startsWith = function (
inputString: string,
searchString: string,
position: number = 0
position: number = 0,
) {
return (
inputString.slice(position, position + searchString.length) === searchString
@@ -61,7 +61,7 @@ const hash = function (text: string) {
export function generateCueId(
startTime: number,
endTime: number,
text: string
text: string,
) {
return hash(startTime.toString()) + hash(endTime.toString()) + hash(text);
}
@@ -97,7 +97,7 @@ export function parseWebVTT(
cc: number,
timeOffset: number,
callBack: (cues: VTTCue[]) => void,
errorCallBack: (error: Error) => void
errorCallBack: (error: Error) => void,
) {
const parser = new VTTParser();
// Convert byteArray into string, replacing any somewhat exotic linefeeds with "\n", then split on that character.
@@ -146,7 +146,7 @@ export function parseWebVTT(
const startTime =
normalizePts(
(cue.startTime + cueOffset - timestampMapLOCAL) * 90000,
timeOffset * 90000
timeOffset * 90000,
) / 90000;
cue.startTime = Math.max(startTime, 0);
cue.endTime = Math.max(startTime + duration, 0);

Some files were not shown because too many files have changed in this diff Show More