@skax/hls-parse 0.0.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +271 -0
- package/dist/index.esm.js +6 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.js +6 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/types/index.d.ts +1102 -0
- package/package.json +68 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Shine Shao
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
# @skax/hls-parse
|
|
2
|
+
|
|
3
|
+
A robust M3U8/HLS playlist parser for JavaScript/TypeScript, compliant with [RFC 8216](https://datatracker.ietf.org/doc/html/rfc8216) (HTTP Live Streaming).
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✅ **Full RFC 8216 Compliance** – Supports all standard HLS tags and attributes
|
|
8
|
+
- ✅ **Master Playlists** – Parse `EXT-X-STREAM-INF`, `EXT-X-I-FRAME-STREAM-INF`, `EXT-X-MEDIA`, etc.
|
|
9
|
+
- ✅ **Media Playlists** – Parse segments, encryption keys, byte ranges, discontinuities, etc.
|
|
10
|
+
- ✅ **LL-HLS (Low-Latency HLS)** – Full support for `EXT-X-PART`, `EXT-X-PRELOAD-HINT`, `EXT-X-SERVER-CONTROL`, `EXT-X-SKIP`, `EXT-X-RENDITION-REPORT`, `EXT-X-PREFETCH`, and more
|
|
11
|
+
- ✅ **Relative URL Resolution** – Resolve all relative URIs in a playlist against a base URL
|
|
12
|
+
- ✅ **Automatic Protocol Version Detection** – Detects required protocol version based on features used
|
|
13
|
+
- ✅ **Rigorous Validation** – Enforces RFC 8216 rules and constraints
|
|
14
|
+
- ✅ **TypeScript First** – Full type definitions for all parsed structures
|
|
15
|
+
- ✅ **SCTE-35 Support** – Parse splice markers, `EXT-X-CUE-OUT`, `EXT-X-CUE-IN`, `EXT-X-DATERANGE` with SCTE-35 attributes
|
|
16
|
+
- ✅ **Vendor-Specific Extensions** – Supports `EXT-X-CUE`, `EXT-OATCLS-SCTE35`, `EXT-X-ASSET`, `EXT-X-SCTE35`
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# npm
|
|
22
|
+
npm install @skax/hls-parse
|
|
23
|
+
|
|
24
|
+
# or pnpm
|
|
25
|
+
pnpm install @skax/hls-parse
|
|
26
|
+
|
|
27
|
+
# or yarn
|
|
28
|
+
yarn add @skax/hls-parse
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { parse } from "@skax/hls-parse";
|
|
35
|
+
|
|
36
|
+
// Parse a Media Playlist
|
|
37
|
+
const playlist = parse(`#EXTM3U
|
|
38
|
+
#EXT-X-TARGETDURATION:10
|
|
39
|
+
#EXTINF:9.009,
|
|
40
|
+
segment1.ts
|
|
41
|
+
#EXTINF:9.009,
|
|
42
|
+
segment2.ts
|
|
43
|
+
#EXT-X-ENDLIST`);
|
|
44
|
+
|
|
45
|
+
console.log(playlist.segments.length); // 2
|
|
46
|
+
console.log(playlist.segments[0].duration); // 9.009
|
|
47
|
+
|
|
48
|
+
// Parse a Master Playlist
|
|
49
|
+
const master = parse(`#EXTM3U
|
|
50
|
+
#EXT-X-STREAM-INF:BANDWIDTH=1280000,RESOLUTION=1280x720
|
|
51
|
+
low.m3u8
|
|
52
|
+
#EXT-X-STREAM-INF:BANDWIDTH=2560000,RESOLUTION=1920x1080
|
|
53
|
+
high.m3u8`);
|
|
54
|
+
|
|
55
|
+
console.log(master.variants[0].bandwidth); // 1280000
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## URL Resolution
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import { parse } from "@skax/hls-parse";
|
|
62
|
+
|
|
63
|
+
const playlist = parse(m3u8Content, {
|
|
64
|
+
uri: "https://example.com/hls/main.m3u8",
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// All relative URIs are resolved to absolute URLs
|
|
68
|
+
console.log(playlist.segments[0].uri); // https://example.com/hls/segment1.ts
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## API Reference
|
|
72
|
+
|
|
73
|
+
### `parse(text: string, options?: ParseOptions): Playlist`
|
|
74
|
+
|
|
75
|
+
Parses an M3U8 playlist string into a structured object.
|
|
76
|
+
|
|
77
|
+
| Parameter | Type | Description |
|
|
78
|
+
| ------------- | -------- | ----------------------------------------------- |
|
|
79
|
+
| `text` | `string` | The raw M3U8 playlist content |
|
|
80
|
+
| `options.uri` | `string` | (Optional) Base URI for resolving relative URLs |
|
|
81
|
+
|
|
82
|
+
**Returns:** `MasterPlaylist | MediaPlaylist`
|
|
83
|
+
|
|
84
|
+
**Throws:** `InvalidPlaylistError` if the playlist violates RFC 8216 syntax rules.
|
|
85
|
+
|
|
86
|
+
### `resolveUrl(base: string | undefined, relative: string): string`
|
|
87
|
+
|
|
88
|
+
Resolves a relative URI against a base URI.
|
|
89
|
+
|
|
90
|
+
### `InvalidPlaylistError`
|
|
91
|
+
|
|
92
|
+
Error class thrown when parsing invalid playlists.
|
|
93
|
+
|
|
94
|
+
## Types
|
|
95
|
+
|
|
96
|
+
### `Playlist`
|
|
97
|
+
|
|
98
|
+
Union type of `MasterPlaylist` and `MediaPlaylist`.
|
|
99
|
+
|
|
100
|
+
### `MasterPlaylist`
|
|
101
|
+
|
|
102
|
+
| Property | Type | Description |
|
|
103
|
+
| ---------------------- | ----------------------- | -------------------------------------------- |
|
|
104
|
+
| `isMasterPlaylist` | `true` | Type discriminator |
|
|
105
|
+
| `version?` | `number` | Protocol version |
|
|
106
|
+
| `variants` | `Variant[]` | Variant streams |
|
|
107
|
+
| `sessionDataList` | `SessionData[]` | Session data entries |
|
|
108
|
+
| `sessionKeyList` | `Key[]` | Session keys |
|
|
109
|
+
| `independentSegments?` | `boolean` | Whether segments are independently decodable |
|
|
110
|
+
| `start?` | `StartData` | Preferred start position |
|
|
111
|
+
| `contentSteering?` | `ContentSteering` | Content steering configuration |
|
|
112
|
+
| `defines?` | `Record<string, any>[]` | Variable definitions |
|
|
113
|
+
|
|
114
|
+
### `MediaPlaylist`
|
|
115
|
+
|
|
116
|
+
| Property | Type | Description |
|
|
117
|
+
| ---------------------------- | ------------------------- | ---------------------------------------- |
|
|
118
|
+
| `isMasterPlaylist` | `false` | Type discriminator |
|
|
119
|
+
| `version?` | `number` | Protocol version |
|
|
120
|
+
| `targetDuration?` | `number` | Maximum segment duration |
|
|
121
|
+
| `mediaSequenceBase?` | `number` | Base media sequence number |
|
|
122
|
+
| `discontinuitySequenceBase?` | `number` | Base discontinuity sequence number |
|
|
123
|
+
| `endlist?` | `boolean` | Whether the playlist is complete |
|
|
124
|
+
| `playlistType?` | `string` | `"EVENT"` or `"VOD"` |
|
|
125
|
+
| `isIFrame?` | `boolean` | Whether this is an I-frame only playlist |
|
|
126
|
+
| `segments` | `Segment[]` | Media segments |
|
|
127
|
+
| `prefetchSegments` | `PrefetchSegment[]` | Prefetch segments (LL-HLS) |
|
|
128
|
+
| `renditionReports` | `RenditionReport[]` | Rendition reports (LL-HLS) |
|
|
129
|
+
| `dateRanges` | `DateRange[]` | Date ranges |
|
|
130
|
+
| `lowLatencyCompatibility?` | `LowLatencyCompatibility` | LL-HLS server control |
|
|
131
|
+
| `partTargetDuration?` | `number` | Partial segment target duration (LL-HLS) |
|
|
132
|
+
| `skip?` | `number` | Skipped segments (LL-HLS) |
|
|
133
|
+
|
|
134
|
+
### `Segment`
|
|
135
|
+
|
|
136
|
+
| Property | Type | Description |
|
|
137
|
+
| ----------------------- | ------------------------------------ | --------------------------------------- |
|
|
138
|
+
| `uri` | `string` | URI of the media segment |
|
|
139
|
+
| `duration?` | `number` | Duration in seconds |
|
|
140
|
+
| `title?` | `string` | Optional title |
|
|
141
|
+
| `byterange?` | `Byterange` | Byte range |
|
|
142
|
+
| `mediaSequenceNumber` | `number` | Media sequence number |
|
|
143
|
+
| `discontinuitySequence` | `number` | Discontinuity sequence number |
|
|
144
|
+
| `discontinuity?` | `boolean` | Whether this segment is a discontinuity |
|
|
145
|
+
| `gap?` | `boolean` | Whether this segment is a gap |
|
|
146
|
+
| `key?` | `Key \| null` | Encryption key |
|
|
147
|
+
| `map?` | `MediaInitializationSection \| null` | Media initialization section |
|
|
148
|
+
| `programDateTime?` | `Date` | Program date/time |
|
|
149
|
+
| `dateRange?` | `DateRange` | Date range metadata |
|
|
150
|
+
| `markers?` | `SpliceInfo[]` | Splice/marker information |
|
|
151
|
+
| `parts?` | `PartialSegment[]` | Partial segments (LL-HLS) |
|
|
152
|
+
|
|
153
|
+
### `PartialSegment` (LL-HLS)
|
|
154
|
+
|
|
155
|
+
| Property | Type | Description |
|
|
156
|
+
| -------------- | ----------- | ------------------------------- |
|
|
157
|
+
| `hint?` | `boolean` | Whether this is a preload hint |
|
|
158
|
+
| `uri` | `string` | URI of the partial segment |
|
|
159
|
+
| `byterange?` | `Byterange` | Byte range |
|
|
160
|
+
| `duration?` | `number` | Duration in seconds |
|
|
161
|
+
| `independent?` | `boolean` | Whether independently decodable |
|
|
162
|
+
| `gap?` | `boolean` | Whether this is a gap |
|
|
163
|
+
|
|
164
|
+
### `Variant`
|
|
165
|
+
|
|
166
|
+
| Property | Type | Description |
|
|
167
|
+
| ------------------- | ------------- | ------------------------- |
|
|
168
|
+
| `uri` | `string` | URI of the media playlist |
|
|
169
|
+
| `bandwidth` | `number` | Peak bit rate |
|
|
170
|
+
| `averageBandwidth?` | `number` | Average bit rate |
|
|
171
|
+
| `codecs?` | `string` | Codec identifiers |
|
|
172
|
+
| `resolution?` | `Resolution` | Display resolution |
|
|
173
|
+
| `frameRate?` | `number` | Maximum frame rate |
|
|
174
|
+
| `audio?` | `Rendition[]` | Audio renditions |
|
|
175
|
+
| `video?` | `Rendition[]` | Video renditions |
|
|
176
|
+
| `subtitles?` | `Rendition[]` | Subtitle renditions |
|
|
177
|
+
| `closedCaptions?` | `Rendition[]` | Closed-caption renditions |
|
|
178
|
+
|
|
179
|
+
## Supported Tags
|
|
180
|
+
|
|
181
|
+
### Basic Tags
|
|
182
|
+
|
|
183
|
+
- `#EXTM3U`
|
|
184
|
+
- `#EXT-X-VERSION`
|
|
185
|
+
- `#EXT-X-CONTENT-STEERING`
|
|
186
|
+
|
|
187
|
+
### Media Segment Tags
|
|
188
|
+
|
|
189
|
+
- `#EXTINF` – Segment duration and title
|
|
190
|
+
- `#EXT-X-BYTERANGE` – Byte range
|
|
191
|
+
- `#EXT-X-DISCONTINUITY` – Discontinuity marker
|
|
192
|
+
- `#EXT-X-PREFETCH-DISCONTINUITY` – LL-HLS discontinuity in prefetch
|
|
193
|
+
- `#EXT-X-KEY` – Encryption key
|
|
194
|
+
- `#EXT-X-MAP` – Media initialization section
|
|
195
|
+
- `#EXT-X-PROGRAM-DATE-TIME` – Absolute date/time
|
|
196
|
+
- `#EXT-X-DATERANGE` – Date range metadata
|
|
197
|
+
- `#EXT-X-CUE-OUT` / `#EXT-X-CUE-IN` – Splice markers
|
|
198
|
+
- `#EXT-X-CUE-OUT-CONT` / `#EXT-X-CUE` – Additional splice markers
|
|
199
|
+
- `#EXT-X-GAP` – Gap segment
|
|
200
|
+
- `#EXT-X-PART` – Partial segment (LL-HLS)
|
|
201
|
+
- `#EXT-X-PRELOAD-HINT` – Preload hint (LL-HLS)
|
|
202
|
+
|
|
203
|
+
### Media Playlist Tags
|
|
204
|
+
|
|
205
|
+
- `#EXT-X-TARGETDURATION` – Maximum segment duration
|
|
206
|
+
- `#EXT-X-MEDIA-SEQUENCE` – Media sequence number
|
|
207
|
+
- `#EXT-X-DISCONTINUITY-SEQUENCE` – Discontinuity sequence number
|
|
208
|
+
- `#EXT-X-ENDLIST` – End of playlist
|
|
209
|
+
- `#EXT-X-PLAYLIST-TYPE` – `EVENT` or `VOD`
|
|
210
|
+
- `#EXT-X-I-FRAMES-ONLY` – I-frame only playlist
|
|
211
|
+
- `#EXT-X-SERVER-CONTROL` – LL-HLS server control
|
|
212
|
+
- `#EXT-X-PART-INF` – LL-HLS part target
|
|
213
|
+
- `#EXT-X-PREFETCH` – Prefetch segment (LL-HLS)
|
|
214
|
+
- `#EXT-X-RENDITION-REPORT` – Rendition report (LL-HLS)
|
|
215
|
+
- `#EXT-X-SKIP` – Skip segments (LL-HLS)
|
|
216
|
+
|
|
217
|
+
### Master Playlist Tags
|
|
218
|
+
|
|
219
|
+
- `#EXT-X-MEDIA` – Alternative renditions
|
|
220
|
+
- `#EXT-X-STREAM-INF` – Variant stream
|
|
221
|
+
- `#EXT-X-I-FRAME-STREAM-INF` – I-frame variant stream
|
|
222
|
+
- `#EXT-X-SESSION-DATA` – Session metadata
|
|
223
|
+
- `#EXT-X-SESSION-KEY` – Session encryption key
|
|
224
|
+
|
|
225
|
+
### Media or Master Playlist Tags
|
|
226
|
+
|
|
227
|
+
- `#EXT-X-INDEPENDENT-SEGMENTS` – Independent segments
|
|
228
|
+
- `#EXT-X-START` – Preferred start position
|
|
229
|
+
- `#EXT-X-DEFINE` – Variable definitions
|
|
230
|
+
|
|
231
|
+
## Error Handling
|
|
232
|
+
|
|
233
|
+
The parser throws `InvalidPlaylistError` (a subclass of `Error`) when a playlist violates RFC 8216 rules:
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
import { parse, InvalidPlaylistError } from "@skax/hls-parse";
|
|
237
|
+
|
|
238
|
+
try {
|
|
239
|
+
const playlist = parse(invalidM3u8);
|
|
240
|
+
} catch (error) {
|
|
241
|
+
if (error instanceof InvalidPlaylistError) {
|
|
242
|
+
console.error("Invalid playlist:", error.message);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Examples
|
|
248
|
+
|
|
249
|
+
See the [examples](./examples) directory for runnable examples:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
npx ts-node examples/basic.ts
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Build
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
npm run build
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Produces CJS, ESM, and TypeScript declaration files in `dist/`.
|
|
262
|
+
|
|
263
|
+
## Test
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
npm test
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## License
|
|
270
|
+
|
|
271
|
+
MIT
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @skax/hls-parse v0.0.1-beta.1
|
|
3
|
+
* Copyright (c) 2026-05-23 ShineShao <xiaoshaoqq@gmail.com>
|
|
4
|
+
* Released under the MIT License.
|
|
5
|
+
*/
|
|
6
|
+
function _array_like_to_array$1(arr,len){(null==len||len>arr.length)&&(len=arr.length);for(var i=0,arr2=new Array(len);i<len;i++)arr2[i]=arr[i];return arr2}function _construct(Parent,args,Class){return _construct=_is_native_reflect_construct()?Reflect.construct:function(Parent,args,Class){var a=[null];a.push.apply(a,args);var instance=new(Function.bind.apply(Parent,a));return Class&&_set_prototype_of(instance,Class.prototype),instance},_construct.apply(null,arguments)}function _get_prototype_of(o){return _get_prototype_of=Object.setPrototypeOf?Object.getPrototypeOf:function(o){return o.__proto__||Object.getPrototypeOf(o)},_get_prototype_of(o)}function _set_prototype_of(o,p){return _set_prototype_of=Object.setPrototypeOf||function(o,p){return o.__proto__=p,o},_set_prototype_of(o,p)}function _wrap_native_super(Class){var _cache="function"==typeof Map?new Map:void 0;return _wrap_native_super=function(Class){if(null===Class||(fn=Class,-1===Function.toString.call(fn).indexOf("[native code]")))return Class;var fn;if("function"!=typeof Class)throw new TypeError("Super expression must either be null or a function");if(void 0!==_cache){if(_cache.has(Class))return _cache.get(Class);_cache.set(Class,Wrapper)}function Wrapper(){return _construct(Class,arguments,_get_prototype_of(this).constructor)}return Wrapper.prototype=Object.create(Class.prototype,{constructor:{value:Wrapper,enumerable:!1,writable:!0,configurable:!0}}),_set_prototype_of(Wrapper,Class)},_wrap_native_super(Class)}function _is_native_reflect_construct(){try{var result=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(_){}return(_is_native_reflect_construct=function(){return!!result})()}function _create_for_of_iterator_helper_loose$1(o,allowArrayLike){var it="undefined"!=typeof Symbol&&o[Symbol.iterator]||o["@@iterator"];if(it)return(it=it.call(o)).next.bind(it);if(Array.isArray(o)||(it=function(o,minLen){if(o){if("string"==typeof o)return _array_like_to_array$1(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);return"Object"===n&&o.constructor&&(n=o.constructor.name),"Map"===n||"Set"===n?Array.from(n):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_array_like_to_array$1(o,minLen):void 0}}(o))||allowArrayLike){it&&(o=it);var i=0;return function(){return i>=o.length?{done:!0}:{done:!1,value:o[i++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var InvalidPlaylistError=function(Error1){function InvalidPlaylistError(message){var _this;return(_this=Error1.call(this,message)||this).name="InvalidPlaylistError",_this}return function(subClass,superClass){if("function"!=typeof superClass&&null!==superClass)throw new TypeError("Super expression must either be null or a function");subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,writable:!0,configurable:!0}}),superClass&&_set_prototype_of(subClass,superClass)}(InvalidPlaylistError,Error1),InvalidPlaylistError}(_wrap_native_super(Error));function trim(str,char){if(void 0!==str){for(var start=0,end=str.length-1;start<=end&&str[start]===char;)start++;for(;end>=start&&str[end]===char;)end--;return str.slice(start,end+1)}}function splitAt(str,delimiter){var index=str.indexOf(delimiter);return-1===index?[str,""]:[str.slice(0,index),str.slice(index+1)]}function toNumber(str){return Number(str)}function hexToByteSequence(hex){var h=hex;(h.startsWith("0x")||h.startsWith("0X"))&&(h=h.slice(2)),h.length%2!=0&&(h="0"+h);for(var bytes=new Uint8Array(h.length/2),i=0;i<bytes.length;i++)bytes[i]=parseInt(h.slice(2*i,2*i+2),16);return bytes}function camelify(str){return str.toLowerCase().replace(/[-_](.)/g,function(_,c){return c.toUpperCase()})}function resolveUrl(base,relative){if(!base)return relative;if(/^[a-zA-Z][a-zA-Z0-9+\-.]*:/.test(relative))return relative;try{var baseUrl=new URL(base);return relative.startsWith("//")?baseUrl.protocol+relative:new URL(relative,baseUrl).href}catch(unused){if(relative.startsWith("/")){var match=base.match(/^[a-zA-Z][a-zA-Z0-9+\-.]*:\/\/[^/]+/);if(match)return match[0]+relative}for(var _step,result=[],_iterator=_create_for_of_iterator_helper_loose$1((base.replace(/\/[^/]*$/,"/")+relative).split("/"));!(_step=_iterator()).done;){var part=_step.value;".."===part?result.pop():"."!==part&&result.push(part)}return result.join("/")}}var constants=Object.freeze({__proto__:null,EXTINF:"EXTINF",EXTM3U:"EXTM3U",EXT_OATCLS_SCTE35:"EXT-OATCLS-SCTE35",EXT_X_ASSET:"EXT-X-ASSET",EXT_X_BITRATE:"EXT-X-BITRATE",EXT_X_BYTERANGE:"EXT-X-BYTERANGE",EXT_X_CONTENT_STEERING:"EXT-X-CONTENT-STEERING",EXT_X_CUE:"EXT-X-CUE",EXT_X_CUE_IN:"EXT-X-CUE-IN",EXT_X_CUE_OUT:"EXT-X-CUE-OUT",EXT_X_CUE_OUT_CONT:"EXT-X-CUE-OUT-CONT",EXT_X_DATERANGE:"EXT-X-DATERANGE",EXT_X_DEFINE:"EXT-X-DEFINE",EXT_X_DISCONTINUITY:"EXT-X-DISCONTINUITY",EXT_X_DISCONTINUITY_SEQUENCE:"EXT-X-DISCONTINUITY-SEQUENCE",EXT_X_ENDLIST:"EXT-X-ENDLIST",EXT_X_GAP:"EXT-X-GAP",EXT_X_INDEPENDENT_SEGMENTS:"EXT-X-INDEPENDENT-SEGMENTS",EXT_X_I_FRAMES_ONLY:"EXT-X-I-FRAMES-ONLY",EXT_X_I_FRAME_STREAM_INF:"EXT-X-I-FRAME-STREAM-INF",EXT_X_KEY:"EXT-X-KEY",EXT_X_MAP:"EXT-X-MAP",EXT_X_MEDIA:"EXT-X-MEDIA",EXT_X_MEDIA_SEQUENCE:"EXT-X-MEDIA-SEQUENCE",EXT_X_PART:"EXT-X-PART",EXT_X_PART_INF:"EXT-X-PART-INF",EXT_X_PLAYLIST_TYPE:"EXT-X-PLAYLIST-TYPE",EXT_X_PREFETCH:"EXT-X-PREFETCH",EXT_X_PREFETCH_DISCONTINUITY:"EXT-X-PREFETCH-DISCONTINUITY",EXT_X_PRELOAD_HINT:"EXT-X-PRELOAD-HINT",EXT_X_PROGRAM_DATE_TIME:"EXT-X-PROGRAM-DATE-TIME",EXT_X_RENDITION_REPORT:"EXT-X-RENDITION-REPORT",EXT_X_SCTE35:"EXT-X-SCTE35",EXT_X_SERVER_CONTROL:"EXT-X-SERVER-CONTROL",EXT_X_SESSION_DATA:"EXT-X-SESSION-DATA",EXT_X_SESSION_KEY:"EXT-X-SESSION-KEY",EXT_X_SKIP:"EXT-X-SKIP",EXT_X_START:"EXT-X-START",EXT_X_STREAM_INF:"EXT-X-STREAM-INF",EXT_X_TARGETDURATION:"EXT-X-TARGETDURATION",EXT_X_VERSION:"EXT-X-VERSION"});function _array_like_to_array(arr,len){(null==len||len>arr.length)&&(len=arr.length);for(var i=0,arr2=new Array(len);i<len;i++)arr2[i]=arr[i];return arr2}function _type_of(obj){return obj&&"undefined"!=typeof Symbol&&obj.constructor===Symbol?"symbol":typeof obj}function _create_for_of_iterator_helper_loose(o,allowArrayLike){var it="undefined"!=typeof Symbol&&o[Symbol.iterator]||o["@@iterator"];if(it)return(it=it.call(o)).next.bind(it);if(Array.isArray(o)||(it=function(o,minLen){if(o){if("string"==typeof o)return _array_like_to_array(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);return"Object"===n&&o.constructor&&(n=o.constructor.name),"Map"===n||"Set"===n?Array.from(n):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_array_like_to_array(o,minLen):void 0}}(o))||allowArrayLike){it&&(o=it);var i=0;return function(){return i>=o.length?{done:!0}:{done:!1,value:o[i++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function parseEXTINF(param){var pair=splitAt(param,",");return{duration:toNumber(pair[0]),title:pair[1]?decodeURIComponent(encodeURIComponent(pair[1])):void 0}}function parseBYTERANGE(param){var pair=splitAt(param,"@");return{length:toNumber(pair[0]),offset:pair[1]?toNumber(pair[1]):-1}}function parseResolution(str){var pair=splitAt(str,"x");return{width:toNumber(pair[0]),height:toNumber(pair[1])}}function parseAllowedCpc(str){for(var _step,allowedCpcList=[],_iterator=_create_for_of_iterator_helper_loose(str.split(","));!(_step=_iterator()).done;){var _utils_splitAt=splitAt(_step.value,":"),format=_utils_splitAt[0],cpcText=_utils_splitAt[1];format&&cpcText&&allowedCpcList.push({format:format,cpcList:cpcText.split("/")})}return allowedCpcList}function parseIV(str){var iv=hexToByteSequence(str);return iv.length,iv}function parseUserAttribute(str){return str.startsWith('"')?trim(str,'"'):str.startsWith("0x")||str.startsWith("0X")?hexToByteSequence(str):toNumber(str)}function setCompatibleVersionOfKey(params,attributes){attributes.IV&¶ms.compatibleVersion<2&&(params.compatibleVersion=2),(attributes.KEYFORMAT||attributes.KEYFORMATVERSIONS)&¶ms.compatibleVersion<5&&(params.compatibleVersion=5)}function parseAttributeList(param){for(var _step,attributes={},_iterator=_create_for_of_iterator_helper_loose(function(str){for(var result=[],current="",inQuotes=!1,i=0;i<str.length;i++){var char=str[i];'"'===char?(inQuotes=!inQuotes,current+=char):","!==char||inQuotes?current+=char:(result.push(current),current="")}return current&&result.push(current),result}(param));!(_step=_iterator()).done;){var _utils_splitAt=splitAt(_step.value,"="),key=_utils_splitAt[0],value=_utils_splitAt[1],val=trim(value,'"');switch(key){case"URI":attributes[key]=val;break;case"START-DATE":case"END-DATE":attributes[key]=new Date(val);break;case"IV":attributes[key]=parseIV(val);break;case"BYTERANGE":attributes[key]=parseBYTERANGE(val);break;case"RESOLUTION":attributes[key]=parseResolution(val);break;case"ALLOWED-CPC":attributes[key]=parseAllowedCpc(val);break;case"END-ON-NEXT":case"DEFAULT":case"AUTOSELECT":case"FORCED":case"PRECISE":case"CAN-BLOCK-RELOAD":case"INDEPENDENT":case"GAP":attributes[key]="YES"===val;break;case"DURATION":case"PLANNED-DURATION":case"BANDWIDTH":case"AVERAGE-BANDWIDTH":case"FRAME-RATE":case"TIME-OFFSET":case"CAN-SKIP-UNTIL":case"HOLD-BACK":case"PART-HOLD-BACK":case"PART-TARGET":case"BYTERANGE-START":case"BYTERANGE-LENGTH":case"LAST-MSN":case"LAST-PART":case"SKIPPED-SEGMENTS":case"SCORE":case"PROGRAM-ID":attributes[key]=toNumber(val);break;default:key.startsWith("SCTE35-")?attributes[key]=hexToByteSequence(val):key.startsWith("X-")?attributes[key]=parseUserAttribute(value):attributes[key]=val}}return attributes}function parseTag(line,params){var _splitTag=function(line){var index=line.indexOf(":");return-1===index?[line.slice(1).trim(),null]:[line.slice(1,index).trim(),line.slice(index+1).trim()]}(line),name=_splitTag[0],param=_splitTag[1],category=function(tagName){switch(tagName){case"EXTM3U":case"EXT-X-VERSION":case"EXT-X-CONTENT-STEERING":return"Basic";case"EXTINF":case"EXT-X-BYTERANGE":case"EXT-X-DISCONTINUITY":case"EXT-X-PREFETCH-DISCONTINUITY":case"EXT-X-KEY":case"EXT-X-MAP":case"EXT-X-PROGRAM-DATE-TIME":case"EXT-X-DATERANGE":case"EXT-X-CUE-OUT":case"EXT-X-CUE-IN":case"EXT-X-CUE-OUT-CONT":case"EXT-X-CUE":case"EXT-OATCLS-SCTE35":case"EXT-X-ASSET":case"EXT-X-SCTE35":case"EXT-X-PART":case"EXT-X-PRELOAD-HINT":case"EXT-X-GAP":return"Segment";case"EXT-X-BITRATE":case"EXT-X-TARGETDURATION":case"EXT-X-MEDIA-SEQUENCE":case"EXT-X-DISCONTINUITY-SEQUENCE":case"EXT-X-ENDLIST":case"EXT-X-PLAYLIST-TYPE":case"EXT-X-I-FRAMES-ONLY":case"EXT-X-SERVER-CONTROL":case"EXT-X-PART-INF":case"EXT-X-PREFETCH":case"EXT-X-RENDITION-REPORT":case"EXT-X-SKIP":return"MediaPlaylist";case"EXT-X-MEDIA":case"EXT-X-STREAM-INF":case"EXT-X-I-FRAME-STREAM-INF":case"EXT-X-SESSION-DATA":case"EXT-X-SESSION-KEY":return"MasterPlaylist";case"EXT-X-INDEPENDENT-SEGMENTS":case"EXT-X-START":case"EXT-X-DEFINE":return"MediaorMasterPlaylist";default:return"Unknown"}}(name);if(function(category,params){if("Segment"===category||"MediaPlaylist"===category)return void 0===params.isMasterPlaylist?void(params.isMasterPlaylist=!1):void params.isMasterPlaylist;if("MasterPlaylist"===category){if(void 0===params.isMasterPlaylist)return void(params.isMasterPlaylist=!0);params.isMasterPlaylist}}(category,params),"Unknown"===category)return null;"MediaPlaylist"===category&&"EXT-X-RENDITION-REPORT"!==name&&"EXT-X-PREFETCH"!==name&&(params.hash[name],params.hash[name]=!0);var _parseTagParam=function(name,param){if(null===param)return[null,null];switch(name){case"EXTM3U":case"EXT-X-DISCONTINUITY":case"EXT-X-ENDLIST":case"EXT-X-I-FRAMES-ONLY":case"EXT-X-INDEPENDENT-SEGMENTS":case"EXT-X-CUE-IN":case"EXT-X-GAP":return[null,null];case"EXT-X-VERSION":case"EXT-X-TARGETDURATION":case"EXT-X-MEDIA-SEQUENCE":case"EXT-X-DISCONTINUITY-SEQUENCE":case"EXT-X-BITRATE":return[toNumber(param),null];case"EXT-X-CUE-OUT":return Number.isNaN(Number(param))?[null,parseAttributeList(param)]:[toNumber(param),null];case"EXT-X-KEY":case"EXT-X-MAP":case"EXT-X-DATERANGE":case"EXT-X-MEDIA":case"EXT-X-STREAM-INF":case"EXT-X-I-FRAME-STREAM-INF":case"EXT-X-SESSION-DATA":case"EXT-X-SESSION-KEY":case"EXT-X-START":case"EXT-X-SERVER-CONTROL":case"EXT-X-PART-INF":case"EXT-X-PART":case"EXT-X-PRELOAD-HINT":case"EXT-X-RENDITION-REPORT":case"EXT-X-SKIP":case"EXT-X-DEFINE":case"EXT-X-CONTENT-STEERING":return[null,parseAttributeList(param)];case"EXTINF":return[parseEXTINF(param),null];case"EXT-X-BYTERANGE":return[parseBYTERANGE(param),null];case"EXT-X-PROGRAM-DATE-TIME":return[new Date(param),null];default:return[param,null]}}(name,param);return{name:name,category:category,value:_parseTagParam[0],attributes:_parseTagParam[1]||{}}}function parseVariant(variantAttrs,uri,iFrameOnly,params,mediaGroups){for(var variant={uri:uri,bandwidth:variantAttrs.BANDWIDTH,averageBandwidth:variantAttrs["AVERAGE-BANDWIDTH"],score:variantAttrs.SCORE,codecs:variantAttrs.CODECS,resolution:variantAttrs.RESOLUTION,frameRate:variantAttrs["FRAME-RATE"],hdcpLevel:variantAttrs["HDCP-LEVEL"],allowedCpc:variantAttrs["ALLOWED-CPC"],videoRange:variantAttrs["VIDEO-RANGE"],stableVariantId:variantAttrs["STABLE-VARIANT-ID"],pathwayId:variantAttrs["PATHWAY-ID"]||variantAttrs["STABLE-PATHWAY-ID"],programId:variantAttrs["PROGRAM-ID"],isIFrameOnly:iFrameOnly},_i=0,_iter=["AUDIO","VIDEO","SUBTITLES","CLOSED-CAPTIONS"];_i<_iter.length;_i++){var type=_iter[_i],attrsGroupId=variantAttrs[type];if(attrsGroupId){var typeMap=mediaGroups.get(type);if(typeMap){var renditions=typeMap.get(attrsGroupId);if(renditions)for(var _step,_iterator=_create_for_of_iterator_helper_loose(renditions);!(_step=_iterator()).done;){addRenditionToList(variant,_step.value,type)}}}}return function(attrs,variant,params){for(var _loop=function(_i,_iter){var type=_iter[_i];if("CLOSED-CAPTIONS"===type&&"NONE"===attrs[type])params.isClosedCaptionsNone=!0,variant.closedCaptions=[];else if(attrs[type]){var key=camelify(type),renditions=variant[key]||[];renditions.length>0&&renditions.some(function(item){return item.groupId===attrs[type]})}},_i=0,_iter=["AUDIO","VIDEO","SUBTITLES","CLOSED-CAPTIONS"];_i<_iter.length;_i++)_loop(_i,_iter)}(variantAttrs,variant,params),variant}function addRenditionToList(variant,rendition,type){var key=camelify(type),renditions=variant[key];renditions||(renditions=[],variant[key]=renditions),renditions.push(rendition)}function parseMasterPlaylist(lines,params){for(var _step,_loop=function(){var _step_value=_step.value,index=_step_value[0],line=_step_value[1];if("string"==typeof line)return"continue";var name=line.name,value=line.value,attributes=line.attributes;if("EXT-X-VERSION"===name)playlist.version=value;else if("EXT-X-CONTENT-STEERING"===name)playlist.contentSteering={serverUri:attributes["SERVER-URI"],pathwayId:attributes["PATHWAY-ID"]};else if("EXT-X-STREAM-INF"===name){var uriLine=lines[index+1];"string"!=typeof uriLine||uriLine.startsWith("#");var variant=parseVariant(attributes,uriLine,!1,params,mediaGroups);"number"==typeof variant.score&&(variantIsScored=!0,variant.score),playlist.variants.push(variant)}else if("EXT-X-I-FRAME-STREAM-INF"===name){var variant1=parseVariant(attributes,attributes.URI,!0,params,mediaGroups);playlist.variants.push(variant1)}else if("EXT-X-SESSION-DATA"===name){var sessionData={id:attributes["DATA-ID"],value:attributes.VALUE,uri:attributes.URI,language:attributes.LANGUAGE};playlist.sessionDataList.some(function(item){return item.id===sessionData.id&&item.language===sessionData.language}),playlist.sessionDataList.push(sessionData)}else if("EXT-X-SESSION-KEY"===name){attributes.METHOD;var sessionKey={method:attributes.METHOD,uri:attributes.URI,iv:attributes.IV,format:attributes.KEYFORMAT,formatVersion:attributes.KEYFORMATVERSIONS};playlist.sessionKeyList.some(function(item){return function(key1,key2){if(key1.method!==key2.method)return!1;if(key1.uri!==key2.uri)return!1;if(key1.iv){if(!key2.iv)return!1;if(key1.iv.byteLength!==key2.iv.byteLength)return!1;for(var i=0;i<key1.iv.byteLength;i++)if(key1.iv[i]!==key2.iv[i])return!1}else if(key2.iv)return!1;return key1.format===key2.format&&key1.formatVersion===key2.formatVersion}(item,sessionKey)}),setCompatibleVersionOfKey(params,attributes),playlist.sessionKeyList.push(sessionKey)}else"EXT-X-INDEPENDENT-SEGMENTS"===name?(playlist.independentSegments,playlist.independentSegments=!0):"EXT-X-START"===name?(playlist.start,attributes["TIME-OFFSET"],playlist.start={offset:attributes["TIME-OFFSET"],precise:attributes.PRECISE||!1}):"EXT-X-DEFINE"===name&&(playlist.defines||(playlist.defines=[]),playlist.defines.push(attributes))},playlist={isMasterPlaylist:!0,variants:[],sessionDataList:[],sessionKeyList:[]},mediaGroups=function(lines){for(var _step,_loop=function(){var attrs,line=_step.value;if("object"===(void 0===line?"undefined":_type_of(line))&&"EXT-X-MEDIA"===line.name){var rendition={type:(attrs=line.attributes).TYPE,uri:attrs.URI,groupId:attrs["GROUP-ID"],language:attrs.LANGUAGE,assocLanguage:attrs["ASSOC-LANGUAGE"],name:attrs.NAME,isDefault:attrs.DEFAULT,autoselect:attrs.AUTOSELECT,forced:attrs.FORCED,instreamId:attrs["INSTREAM-ID"],characteristics:attrs.CHARACTERISTICS,channels:attrs.CHANNELS,pathwayId:attrs["PATHWAY-ID"]},type=rendition.type,groupId=rendition.groupId,typeMap=index.get(type);typeMap||(typeMap=new Map,index.set(type,typeMap));var group=typeMap.get(groupId);group||(group=[],typeMap.set(groupId,group)),group.some(function(r){return r.name===rendition.name}),rendition.isDefault&&group.some(function(r){return r.isDefault}),group.push(rendition)}},index=new Map,_iterator=_create_for_of_iterator_helper_loose(lines);!(_step=_iterator()).done;)_loop();return index}(lines),variantIsScored=!1,_iterator=_create_for_of_iterator_helper_loose(lines.entries());!(_step=_iterator()).done;)_loop();if(variantIsScored)for(var _step1,_iterator1=_create_for_of_iterator_helper_loose(playlist.variants);!(_step1=_iterator1()).done;){_step1.value.score}if(params.isClosedCaptionsNone)for(var _step2,_iterator2=_create_for_of_iterator_helper_loose(playlist.variants);!(_step2=_iterator2()).done;){var cc=_step2.value.closedCaptions;cc&&cc.length}return playlist}function parseDateRange(attributes){for(var _step,attrs={},_iterator=_create_for_of_iterator_helper_loose(Object.keys(attributes));!(_step=_iterator()).done;){var key=_step.value;(key.startsWith("SCTE35-")||key.startsWith("X-"))&&(attrs[key]=attributes[key])}return{id:attributes.ID,classId:attributes.CLASS,start:attributes["START-DATE"],cue:attributes.CUE,end:attributes["END-DATE"],duration:attributes.DURATION,plannedDuration:attributes["PLANNED-DURATION"],endOnNext:attributes["END-ON-NEXT"],attributes:attrs}}function parseSegment(lines,uri,start,end,mediaSequenceNumber,discontinuitySequence,params){for(var segment={uri:uri,mediaSequenceNumber:mediaSequenceNumber,discontinuitySequence:discontinuitySequence,markers:[],parts:[]},partHint=!1,i=start;i<=end;i++)if("string"!=typeof lines[i]){var _lines_i=lines[i],name=_lines_i.name,value=_lines_i.value,attributes=_lines_i.attributes;if("EXTINF"===name)!Number.isInteger(value.duration)&¶ms.compatibleVersion<3&&(params.compatibleVersion=3),Math.round(value.duration),params.targetDuration,segment.duration=value.duration,segment.title=value.title;else if("EXT-X-BYTERANGE"===name)params.compatibleVersion<4&&(params.compatibleVersion=4),segment.byterange=value;else if("EXT-X-DISCONTINUITY"===name)segment.parts&&segment.parts.length,segment.discontinuity=!0;else if("EXT-X-GAP"===name)params.compatibleVersion<8&&(params.compatibleVersion=8),segment.gap=!0;else if("EXT-X-KEY"===name)segment.parts&&segment.parts.length,setCompatibleVersionOfKey(params,attributes),segment.key={method:attributes.METHOD,uri:attributes.URI,iv:attributes.IV,format:attributes.KEYFORMAT,formatVersion:attributes.KEYFORMATVERSIONS};else if("EXT-X-MAP"===name)segment.parts&&segment.parts.length,params.compatibleVersion<5&&(params.compatibleVersion=5),params.hasMap=!0,segment.map={uri:attributes.URI,byterange:attributes.BYTERANGE};else if("EXT-X-PROGRAM-DATE-TIME"===name)segment.programDateTime=value;else if("EXT-X-DATERANGE"===name)segment.dateRange=parseDateRange(attributes);else if("EXT-X-CUE-OUT"===name)segment.markers||(segment.markers=[]),segment.markers.push({type:"OUT",duration:attributes&&attributes.DURATION||value});else if("EXT-X-CUE-IN"===name)segment.markers||(segment.markers=[]),segment.markers.push({type:"IN"});else if("EXT-X-CUE-OUT-CONT"===name||"EXT-X-CUE"===name||"EXT-OATCLS-SCTE35"===name||"EXT-X-ASSET"===name||"EXT-X-SCTE35"===name)segment.markers||(segment.markers=[]),segment.markers.push({type:"RAW",tagName:name,value:value});else if("EXT-X-PRELOAD-HINT"!==name||attributes.TYPE)if("EXT-X-PRELOAD-HINT"===name&&"PART"===attributes.TYPE&&partHint);else if("EXT-X-PART"!==name&&"EXT-X-PRELOAD-HINT"!==name||attributes.URI){if("EXT-X-PRELOAD-HINT"===name&&"MAP"===attributes.TYPE)params.hasMap=!0,segment.map={hint:!0,uri:attributes.URI,byterange:{length:attributes["BYTERANGE-LENGTH"],offset:attributes["BYTERANGE-START"]||0}};else if("EXT-X-PART"===name||"EXT-X-PRELOAD-HINT"===name&&"PART"===attributes.TYPE){"EXT-X-PART"===name&&attributes.DURATION,"EXT-X-PRELOAD-HINT"===name&&(partHint=!0),segment.parts||(segment.parts=[]);var partialSegment={hint:"EXT-X-PRELOAD-HINT"===name,uri:attributes.URI,byterange:"EXT-X-PART"===name?attributes.BYTERANGE:{length:attributes["BYTERANGE-LENGTH"],offset:attributes["BYTERANGE-START"]||0},duration:attributes.DURATION,independent:attributes.INDEPENDENT,gap:attributes.GAP};segment.gap,segment.parts.push(partialSegment)}}else;else;}return segment}function parsePrefetchSegment(lines,uri,start,end,mediaSequenceNumber,discontinuitySequence,params){for(var segment={uri:uri,mediaSequenceNumber:mediaSequenceNumber,discontinuitySequence:discontinuitySequence},i=start;i<=end;i++)if("string"!=typeof lines[i]){var _lines_i=lines[i],name=_lines_i.name,attributes=_lines_i.attributes;"EXTINF"===name||"EXT-X-DISCONTINUITY"===name||("EXT-X-PREFETCH-DISCONTINUITY"===name?segment.discontinuity=!0:"EXT-X-KEY"===name&&(setCompatibleVersionOfKey(params,attributes),segment.key={method:attributes.METHOD,uri:attributes.URI,iv:attributes.IV,format:attributes.KEYFORMAT,formatVersion:attributes.KEYFORMATVERSIONS}))}return segment}function addSegment(playlist,segment,discontinuitySequence,currentKey,currentMap){var _segment_key,_segment_map,discontinuity=segment.discontinuity,key=segment.key,map=segment.map,byterange=segment.byterange,uri=segment.uri;if(discontinuity&&(segment.discontinuitySequence=discontinuitySequence+1),key||(segment.key=currentKey),map||(segment.map=currentMap),byterange&&-1===byterange.offset){var segments=playlist.segments;if(segments.length>0){var prevSegment=segments[segments.length-1];prevSegment.byterange&&prevSegment.uri===uri&&(byterange.offset=prevSegment.byterange.offset+prevSegment.byterange.length)}}return playlist.segments.push(segment),[segment.discontinuitySequence,null!=(_segment_key=segment.key)?_segment_key:null,null!=(_segment_map=segment.map)?_segment_map:null]}function parseMediaPlaylist(lines,params){for(var _step,playlist={isMasterPlaylist:!1,segments:[],prefetchSegments:[],renditionReports:[],dateRanges:[]},segmentStart=-1,mediaSequence=0,discontinuitySequence=0,currentKey=null,currentMap=null,containsParts=!1,_iterator=_create_for_of_iterator_helper_loose(lines.entries());!(_step=_iterator()).done;){var _step_value=_step.value,index=_step_value[0],line=_step_value[1];if("string"!=typeof line){var name=line.name,value=line.value,attributes=line.attributes,category=line.category;if("EXT-X-DATERANGE"===name){var dateRange=parseDateRange(attributes);playlist.dateRanges.push(dateRange)}if("Segment"!==category)if("EXT-X-VERSION"===name)void 0===playlist.version&&(playlist.version=value);else if("EXT-X-TARGETDURATION"===name)playlist.targetDuration=params.targetDuration=value;else if("EXT-X-MEDIA-SEQUENCE"===name)playlist.segments.length,playlist.mediaSequenceBase=value,mediaSequence=value;else if("EXT-X-BITRATE"===name)playlist.bitrate=value;else if("EXT-X-DISCONTINUITY-SEQUENCE"===name)playlist.segments.length,playlist.discontinuitySequenceBase=value,discontinuitySequence=value;else if("EXT-X-ENDLIST"===name)playlist.endlist=!0;else if("EXT-X-PLAYLIST-TYPE"===name)playlist.playlistType=value;else if("EXT-X-I-FRAMES-ONLY"===name)params.compatibleVersion<4&&(params.compatibleVersion=4),playlist.isIFrame=!0;else if("EXT-X-INDEPENDENT-SEGMENTS"===name)playlist.independentSegments,playlist.independentSegments=!0;else if("EXT-X-START"===name)playlist.start,attributes["TIME-OFFSET"],playlist.start={offset:attributes["TIME-OFFSET"],precise:attributes.PRECISE||!1};else if("EXT-X-SERVER-CONTROL"===name)attributes["CAN-BLOCK-RELOAD"],playlist.lowLatencyCompatibility={canBlockReload:attributes["CAN-BLOCK-RELOAD"],canSkipUntil:attributes["CAN-SKIP-UNTIL"],holdBack:attributes["HOLD-BACK"],partHoldBack:attributes["PART-HOLD-BACK"]};else if("EXT-X-PART-INF"===name)attributes["PART-TARGET"],playlist.partTargetDuration=attributes["PART-TARGET"];else if("EXT-X-RENDITION-REPORT"===name)attributes.URI,/^[a-z]+:/i.test(attributes.URI),playlist.renditionReports.push({uri:attributes.URI,lastMSN:attributes["LAST-MSN"],lastPart:attributes["LAST-PART"]});else if("EXT-X-SKIP"===name)attributes["SKIPPED-SEGMENTS"],params.compatibleVersion<9&&(params.compatibleVersion=9),playlist.skip=attributes["SKIPPED-SEGMENTS"],mediaSequence+=playlist.skip;else if("EXT-X-PREFETCH"===name){var segment1=parsePrefetchSegment(lines,value,-1===segmentStart?index:segmentStart,index-1,mediaSequence++,discontinuitySequence,params);segment1.discontinuity&&(segment1.discontinuitySequence++,discontinuitySequence=segment1.discontinuitySequence),segment1.key||(segment1.key=currentKey),playlist.prefetchSegments.push(segment1),segmentStart=-1}else"EXT-X-DEFINE"===name&&(playlist.defines||(playlist.defines=[]),playlist.defines.push(attributes));else-1===segmentStart&&(segmentStart=index)}else{playlist.targetDuration;var segment=parseSegment(lines,line,segmentStart,index-1,mediaSequence++,discontinuitySequence,params),_addSegment=addSegment(playlist,segment,discontinuitySequence,currentKey,currentMap);discontinuitySequence=_addSegment[0],currentKey=_addSegment[1],currentMap=_addSegment[2],!containsParts&&segment.parts&&segment.parts.length>0&&(containsParts=!0),segmentStart=-1}}if(-1!==segmentStart){var _parts_,segment2=parseSegment(lines,"",segmentStart,lines.length-1,mediaSequence++,discontinuitySequence,params),parts=segment2.parts;parts&&parts.length>0&&!playlist.endlist&&(null==(_parts_=parts[parts.length-1])||_parts_.hint),addSegment(playlist,segment2,discontinuitySequence,currentKey,currentMap),!containsParts&&segment2.parts&&segment2.parts.length>0&&(containsParts=!0)}return function(segments){for(var earliestDates=new Map,rangeList=new Map,i=segments.length-1;i>=0;i--){var _segments_i=segments[i];_segments_i.programDateTime;var dateRange=_segments_i.dateRange;if(dateRange&&dateRange.start){dateRange.endOnNext&&(dateRange.end||dateRange.duration);var start=dateRange.start.getTime(),duration=dateRange.duration||0;dateRange.end&&dateRange.duration&&dateRange.end.getTime(),dateRange.endOnNext&&dateRange.classId&&(dateRange.end=earliestDates.get(dateRange.classId)),earliestDates.set(dateRange.classId,dateRange.start);var end=dateRange.end?dateRange.end.getTime():start+1e3*duration;if(dateRange.classId){var range=rangeList.get(dateRange.classId);if(range){for(var _step,_iterator=_create_for_of_iterator_helper_loose(range);!(_step=_iterator()).done;){var entry=_step.value;entry.start<=start&&entry.end>start||entry.start>=start&&entry.start}range.push({start:start,end:end})}else rangeList.set(dateRange.classId,[{start:start,end:end}])}}}}(playlist.segments),playlist.lowLatencyCompatibility&&function(playlist,containsParts){var lowLatencyCompatibility=playlist.lowLatencyCompatibility;if(playlist.targetDuration,playlist.partTargetDuration,lowLatencyCompatibility&&(lowLatencyCompatibility.canSkipUntil,lowLatencyCompatibility.holdBack,lowLatencyCompatibility.partHoldBack,containsParts)){for(var _step,_iterator=_create_for_of_iterator_helper_loose(playlist.segments.entries());!(_step=_iterator()).done;){var _step_value=_step.value,parts=(_step_value[0],_step_value[1].parts);if(parts&&0!==parts.length){playlist.segments.length;for(var _step1,_iterator1=_create_for_of_iterator_helper_loose(parts.entries());!(_step1=_iterator1()).done;){var _step_value1=_step1.value;void 0!==(_step_value1[0],_step_value1[1].duration)&&parts.length}}}for(var _step2,_iterator2=_create_for_of_iterator_helper_loose(playlist.renditionReports);!(_step2=_iterator2()).done;){var report=_step2.value,lastSegment=playlist.segments[playlist.segments.length-1];void 0===report.lastMSN&&lastSegment&&(report.lastMSN=lastSegment.mediaSequenceNumber),(void 0===report.lastPart||null===report.lastPart)&&lastSegment&&lastSegment.parts&&lastSegment.parts.length>0&&(report.lastPart=lastSegment.parts.length-1)}}}(playlist,containsParts),playlist}function parse(text,options){var params={isMasterPlaylist:void 0,hasMap:!1,targetDuration:0,compatibleVersion:1,isClosedCaptionsNone:!1,hash:{}},lines=function(text,params){var lines=[],normalized=text;65279===normalized.charCodeAt(0)&&(normalized=normalized.slice(1));for(var _step,_iterator=_create_for_of_iterator_helper_loose(normalized.split(/\r?\n/));!(_step=_iterator()).done;){var line=_step.value.trim();if(line)if(line.startsWith("#")){if(line.startsWith("#EXT")){var tag=parseTag(line,params);tag&&lines.push(tag)}}else lines.push(line)}return 0===lines.length||"object"!==_type_of(lines[0])||lines[0].name,lines}(text,params),playlist=function(lines,params){var playlist;return params.isMasterPlaylist?playlist=parseMasterPlaylist(lines,params):!(playlist=parseMediaPlaylist(lines,params)).isMasterPlaylist&&!playlist.isIFrame&¶ms.hasMap&¶ms.compatibleVersion<6&&(params.compatibleVersion=6),params.compatibleVersion>1&&void 0!==playlist.version&&null!==playlist.version&&playlist.version<params.compatibleVersion&¶ms.compatibleVersion,playlist}(lines,params);return playlist.source=text,(null==options?void 0:options.uri)&&function(playlist,baseUri){if(playlist.isMasterPlaylist){for(var _step,master=playlist,_iterator=_create_for_of_iterator_helper_loose(master.variants);!(_step=_iterator()).done;){var variant=_step.value;variant.uri=resolveUrl(baseUri,variant.uri);for(var _i=0,_iter=["audio","video","subtitles","closedCaptions"];_i<_iter.length;_i++){var renditions=variant[_iter[_i]];if(renditions)for(var _step1,_iterator1=_create_for_of_iterator_helper_loose(renditions);!(_step1=_iterator1()).done;){var r=_step1.value;r.uri&&(r.uri=resolveUrl(baseUri,r.uri))}}}for(var _step2,_iterator2=_create_for_of_iterator_helper_loose(master.sessionDataList);!(_step2=_iterator2()).done;){var sd=_step2.value;sd.uri&&(sd.uri=resolveUrl(baseUri,sd.uri))}for(var _step3,_iterator3=_create_for_of_iterator_helper_loose(master.sessionKeyList);!(_step3=_iterator3()).done;){var sk=_step3.value;sk.uri&&(sk.uri=resolveUrl(baseUri,sk.uri))}var steering=master.contentSteering;steering&&(steering.serverUri=resolveUrl(baseUri,steering.serverUri))}else{for(var _step4,mp=playlist,_iterator4=_create_for_of_iterator_helper_loose(mp.segments);!(_step4=_iterator4()).done;){var segment=_step4.value;if(segment.uri=resolveUrl(baseUri,segment.uri),segment.key&&segment.key.uri&&(segment.key.uri=resolveUrl(baseUri,segment.key.uri)),segment.map&&segment.map.uri&&(segment.map.uri=resolveUrl(baseUri,segment.map.uri)),segment.parts)for(var _step5,_iterator5=_create_for_of_iterator_helper_loose(segment.parts);!(_step5=_iterator5()).done;){var part=_step5.value;part.uri=resolveUrl(baseUri,part.uri)}}for(var _step6,_iterator6=_create_for_of_iterator_helper_loose(mp.prefetchSegments);!(_step6=_iterator6()).done;){var prefetch=_step6.value;prefetch.uri=resolveUrl(baseUri,prefetch.uri),prefetch.key&&prefetch.key.uri&&(prefetch.key.uri=resolveUrl(baseUri,prefetch.key.uri))}for(var _step7,_iterator7=_create_for_of_iterator_helper_loose(mp.renditionReports);!(_step7=_iterator7()).done;){var report=_step7.value;report.uri=resolveUrl(baseUri,report.uri)}}}(playlist,options.uri),playlist}function isMasterPlaylist(pl){return!0===pl.isMasterPlaylist}function isMediaPlaylist(pl){return!1===pl.isMasterPlaylist}export{InvalidPlaylistError,constants as TAGS,parse as default,isMasterPlaylist,isMediaPlaylist,parse,resolveUrl};
|