Buckets:
| import type { DateRange } from './date-range'; | |
| import type { Fragment, MediaFragment, Part } from './fragment'; | |
| import type { LevelKey } from './level-key'; | |
| import type { VariableMap } from '../types/level'; | |
| import type { AttrList } from '../utils/attr-list'; | |
| import type { KeySystemFormats } from '../utils/mediakeys-helper'; | |
| const DEFAULT_TARGET_DURATION = 10; | |
| /** | |
| * Object representing parsed data from an HLS Media Playlist. Found in {@link hls.js#Level.details}. | |
| */ | |
| export class LevelDetails { | |
| public PTSKnown: boolean = false; | |
| public alignedSliding: boolean = false; | |
| public averagetargetduration?: number; | |
| public endCC: number = 0; | |
| public endSN: number = 0; | |
| public fragments: MediaFragment[]; | |
| public fragmentHint?: MediaFragment; | |
| public partList: Part[] | null = null; | |
| public dateRanges: Record<string, DateRange | undefined>; | |
| public dateRangeTagCount: number = 0; | |
| public live: boolean = true; | |
| public requestScheduled: number = -1; | |
| public ageHeader: number = 0; | |
| public advancedDateTime?: number; | |
| public updated: boolean = true; | |
| public advanced: boolean = true; | |
| public misses: number = 0; | |
| public startCC: number = 0; | |
| public startSN: number = 0; | |
| public startTimeOffset: number | null = null; | |
| public targetduration: number = 0; | |
| public totalduration: number = 0; | |
| public type: string | null = null; | |
| public url: string; | |
| public m3u8: string = ''; | |
| public version: number | null = null; | |
| public canBlockReload: boolean = false; | |
| public canSkipUntil: number = 0; | |
| public canSkipDateRanges: boolean = false; | |
| public skippedSegments: number = 0; | |
| public recentlyRemovedDateranges?: string[]; | |
| public partHoldBack: number = 0; | |
| public holdBack: number = 0; | |
| public partTarget: number = 0; | |
| public preloadHint?: AttrList; | |
| public renditionReports?: AttrList[]; | |
| public tuneInGoal: number = 0; | |
| public deltaUpdateFailed?: boolean; | |
| public driftStartTime: number = 0; | |
| public driftEndTime: number = 0; | |
| public driftStart: number = 0; | |
| public driftEnd: number = 0; | |
| public encryptedFragments: Fragment[]; | |
| public playlistParsingError: Error | null = null; | |
| public variableList: VariableMap | null = null; | |
| public hasVariableRefs = false; | |
| public appliedTimelineOffset?: number; | |
| constructor(baseUrl: string) { | |
| this.fragments = []; | |
| this.encryptedFragments = []; | |
| this.dateRanges = {}; | |
| this.url = baseUrl; | |
| } | |
| reloaded(previous: LevelDetails | undefined) { | |
| if (!previous) { | |
| this.advanced = true; | |
| this.updated = true; | |
| return; | |
| } | |
| const partSnDiff = this.lastPartSn - previous.lastPartSn; | |
| const partIndexDiff = this.lastPartIndex - previous.lastPartIndex; | |
| this.updated = | |
| this.endSN !== previous.endSN || | |
| !!partIndexDiff || | |
| !!partSnDiff || | |
| !this.live; | |
| this.advanced = | |
| this.endSN > previous.endSN || | |
| partSnDiff > 0 || | |
| (partSnDiff === 0 && partIndexDiff > 0); | |
| if (this.updated || this.advanced) { | |
| this.misses = Math.floor(previous.misses * 0.6); | |
| } else { | |
| this.misses = previous.misses + 1; | |
| } | |
| } | |
| hasKey(levelKey: LevelKey): boolean { | |
| return this.encryptedFragments.some((frag) => { | |
| let decryptdata = frag.decryptdata; | |
| if (!decryptdata) { | |
| frag.setKeyFormat(levelKey.keyFormat as KeySystemFormats); | |
| decryptdata = frag.decryptdata; | |
| } | |
| return !!decryptdata && levelKey.matches(decryptdata); | |
| }); | |
| } | |
| get hasProgramDateTime(): boolean { | |
| if (this.fragments.length) { | |
| return Number.isFinite( | |
| this.fragments[this.fragments.length - 1].programDateTime, | |
| ); | |
| } | |
| return false; | |
| } | |
| get levelTargetDuration(): number { | |
| return ( | |
| this.averagetargetduration || | |
| this.targetduration || | |
| DEFAULT_TARGET_DURATION | |
| ); | |
| } | |
| get drift(): number { | |
| const runTime = this.driftEndTime - this.driftStartTime; | |
| if (runTime > 0) { | |
| const runDuration = this.driftEnd - this.driftStart; | |
| return (runDuration * 1000) / runTime; | |
| } | |
| return 1; | |
| } | |
| get edge(): number { | |
| return this.partEnd || this.fragmentEnd; | |
| } | |
| get partEnd(): number { | |
| if (this.partList?.length) { | |
| return this.partList[this.partList.length - 1].end; | |
| } | |
| return this.fragmentEnd; | |
| } | |
| get fragmentEnd(): number { | |
| if (this.fragments.length) { | |
| return this.fragments[this.fragments.length - 1].end; | |
| } | |
| return 0; | |
| } | |
| get fragmentStart(): number { | |
| if (this.fragments.length) { | |
| return this.fragments[0].start; | |
| } | |
| return 0; | |
| } | |
| get age(): number { | |
| if (this.advancedDateTime) { | |
| return Math.max(Date.now() - this.advancedDateTime, 0) / 1000; | |
| } | |
| return 0; | |
| } | |
| get lastPartIndex(): number { | |
| if (this.partList?.length) { | |
| return this.partList[this.partList.length - 1].index; | |
| } | |
| return -1; | |
| } | |
| get maxPartIndex(): number { | |
| const partList = this.partList; | |
| if (partList) { | |
| const lastIndex = this.lastPartIndex; | |
| if (lastIndex !== -1) { | |
| for (let i = partList.length; i--; ) { | |
| if (partList[i].index > lastIndex) { | |
| return partList[i].index; | |
| } | |
| } | |
| return lastIndex; | |
| } | |
| } | |
| return 0; | |
| } | |
| get lastPartSn(): number { | |
| if (this.partList?.length) { | |
| return this.partList[this.partList.length - 1].fragment.sn; | |
| } | |
| return this.endSN; | |
| } | |
| get expired(): boolean { | |
| if (this.live && this.age && this.misses < 3) { | |
| const playlistWindowDuration = this.partEnd - this.fragmentStart; | |
| return ( | |
| this.age > | |
| Math.max(playlistWindowDuration, this.totalduration) + | |
| this.levelTargetDuration | |
| ); | |
| } | |
| return false; | |
| } | |
| } | |
Xet Storage Details
- Size:
- 5.7 kB
- Xet hash:
- ba8ef8a7b8e4e25a86d3bacf13c3ba7c41bcf30c57f4c3cc690f6e07df7b5ca2
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.