@transmitlive/m3u8-parser 4.7.2-beta.6

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.
Files changed (134) hide show
  1. package/CONTRIBUTING.md +30 -0
  2. package/LICENSE +13 -0
  3. package/README.md +388 -0
  4. package/dist/m3u8-parser.cjs.js +1563 -0
  5. package/dist/m3u8-parser.es.js +1549 -0
  6. package/dist/m3u8-parser.js +1748 -0
  7. package/dist/m3u8-parser.min.js +2 -0
  8. package/index.html +15 -0
  9. package/package.json +100 -0
  10. package/scripts/karma.conf.js +12 -0
  11. package/scripts/rollup.config.js +47 -0
  12. package/src/index.js +19 -0
  13. package/src/line-stream.js +35 -0
  14. package/src/parse-stream.js +619 -0
  15. package/src/parser.js +748 -0
  16. package/test/fixtures/integration/absoluteUris.js +31 -0
  17. package/test/fixtures/integration/absoluteUris.m3u8 +12 -0
  18. package/test/fixtures/integration/allowCache.js +165 -0
  19. package/test/fixtures/integration/allowCache.m3u8 +58 -0
  20. package/test/fixtures/integration/allowCacheInvalid.js +21 -0
  21. package/test/fixtures/integration/allowCacheInvalid.m3u8 +10 -0
  22. package/test/fixtures/integration/alternateAudio.js +56 -0
  23. package/test/fixtures/integration/alternateAudio.m3u8 +9 -0
  24. package/test/fixtures/integration/alternateVideo.js +48 -0
  25. package/test/fixtures/integration/alternateVideo.m3u8 +8 -0
  26. package/test/fixtures/integration/brightcove.js +57 -0
  27. package/test/fixtures/integration/brightcove.m3u8 +9 -0
  28. package/test/fixtures/integration/byteRange.js +161 -0
  29. package/test/fixtures/integration/byteRange.m3u8 +56 -0
  30. package/test/fixtures/integration/dateTime.js +27 -0
  31. package/test/fixtures/integration/dateTime.m3u8 +12 -0
  32. package/test/fixtures/integration/diff-init-key.js +164 -0
  33. package/test/fixtures/integration/diff-init-key.m3u8 +57 -0
  34. package/test/fixtures/integration/disallowCache.js +21 -0
  35. package/test/fixtures/integration/disallowCache.m3u8 +10 -0
  36. package/test/fixtures/integration/disc-sequence.js +32 -0
  37. package/test/fixtures/integration/disc-sequence.m3u8 +15 -0
  38. package/test/fixtures/integration/discontinuity.js +59 -0
  39. package/test/fixtures/integration/discontinuity.m3u8 +26 -0
  40. package/test/fixtures/integration/domainUris.js +31 -0
  41. package/test/fixtures/integration/domainUris.m3u8 +12 -0
  42. package/test/fixtures/integration/empty.js +5 -0
  43. package/test/fixtures/integration/empty.m3u8 +0 -0
  44. package/test/fixtures/integration/emptyAllowCache.js +21 -0
  45. package/test/fixtures/integration/emptyAllowCache.m3u8 +10 -0
  46. package/test/fixtures/integration/emptyMediaSequence.js +31 -0
  47. package/test/fixtures/integration/emptyMediaSequence.m3u8 +14 -0
  48. package/test/fixtures/integration/emptyPlaylistType.js +40 -0
  49. package/test/fixtures/integration/emptyPlaylistType.m3u8 +16 -0
  50. package/test/fixtures/integration/emptyTargetDuration.js +57 -0
  51. package/test/fixtures/integration/emptyTargetDuration.m3u8 +10 -0
  52. package/test/fixtures/integration/encrypted.js +61 -0
  53. package/test/fixtures/integration/encrypted.m3u8 +28 -0
  54. package/test/fixtures/integration/event.js +41 -0
  55. package/test/fixtures/integration/event.m3u8 +16 -0
  56. package/test/fixtures/integration/extXPlaylistTypeInvalidPlaylist.js +15 -0
  57. package/test/fixtures/integration/extXPlaylistTypeInvalidPlaylist.m3u8 +8 -0
  58. package/test/fixtures/integration/extinf.js +165 -0
  59. package/test/fixtures/integration/extinf.m3u8 +57 -0
  60. package/test/fixtures/integration/fmp4.js +44 -0
  61. package/test/fixtures/integration/fmp4.m3u8 +14 -0
  62. package/test/fixtures/integration/headerOnly.js +5 -0
  63. package/test/fixtures/integration/headerOnly.m3u8 +1 -0
  64. package/test/fixtures/integration/invalidAllowCache.js +21 -0
  65. package/test/fixtures/integration/invalidAllowCache.m3u8 +10 -0
  66. package/test/fixtures/integration/invalidMediaSequence.js +31 -0
  67. package/test/fixtures/integration/invalidMediaSequence.m3u8 +14 -0
  68. package/test/fixtures/integration/invalidPlaylistType.js +40 -0
  69. package/test/fixtures/integration/invalidPlaylistType.m3u8 +16 -0
  70. package/test/fixtures/integration/invalidTargetDuration.js +164 -0
  71. package/test/fixtures/integration/invalidTargetDuration.m3u8 +57 -0
  72. package/test/fixtures/integration/liveMissingSegmentDuration.js +25 -0
  73. package/test/fixtures/integration/liveMissingSegmentDuration.m3u8 +9 -0
  74. package/test/fixtures/integration/liveStart30sBefore.js +54 -0
  75. package/test/fixtures/integration/liveStart30sBefore.m3u8 +22 -0
  76. package/test/fixtures/integration/llhls-byte-range.js +253 -0
  77. package/test/fixtures/integration/llhls-byte-range.m3u8 +66 -0
  78. package/test/fixtures/integration/llhls-delta-byte-range.js +149 -0
  79. package/test/fixtures/integration/llhls-delta-byte-range.m3u8 +30 -0
  80. package/test/fixtures/integration/llhls.js +214 -0
  81. package/test/fixtures/integration/llhls.m3u8 +56 -0
  82. package/test/fixtures/integration/llhlsDelta.js +186 -0
  83. package/test/fixtures/integration/llhlsDelta.m3u8 +50 -0
  84. package/test/fixtures/integration/manifestExtTTargetdurationNegative.js +14 -0
  85. package/test/fixtures/integration/manifestExtTTargetdurationNegative.m3u8 +5 -0
  86. package/test/fixtures/integration/manifestExtXEndlistEarly.js +35 -0
  87. package/test/fixtures/integration/manifestExtXEndlistEarly.m3u8 +14 -0
  88. package/test/fixtures/integration/manifestNoExtM3u.js +15 -0
  89. package/test/fixtures/integration/manifestNoExtM3u.m3u8 +4 -0
  90. package/test/fixtures/integration/master-fmp4.js +465 -0
  91. package/test/fixtures/integration/master-fmp4.m3u8 +76 -0
  92. package/test/fixtures/integration/master.js +57 -0
  93. package/test/fixtures/integration/master.m3u8 +10 -0
  94. package/test/fixtures/integration/media.js +31 -0
  95. package/test/fixtures/integration/media.m3u8 +12 -0
  96. package/test/fixtures/integration/mediaSequence.js +31 -0
  97. package/test/fixtures/integration/mediaSequence.m3u8 +14 -0
  98. package/test/fixtures/integration/missingEndlist.js +19 -0
  99. package/test/fixtures/integration/missingEndlist.m3u8 +6 -0
  100. package/test/fixtures/integration/missingExtinf.js +27 -0
  101. package/test/fixtures/integration/missingExtinf.m3u8 +11 -0
  102. package/test/fixtures/integration/missingMediaSequence.js +31 -0
  103. package/test/fixtures/integration/missingMediaSequence.m3u8 +13 -0
  104. package/test/fixtures/integration/missingSegmentDuration.js +31 -0
  105. package/test/fixtures/integration/missingSegmentDuration.m3u8 +11 -0
  106. package/test/fixtures/integration/multipleAudioGroups.js +89 -0
  107. package/test/fixtures/integration/multipleAudioGroups.m3u8 +17 -0
  108. package/test/fixtures/integration/multipleAudioGroupsCombinedMain.js +88 -0
  109. package/test/fixtures/integration/multipleAudioGroupsCombinedMain.m3u8 +17 -0
  110. package/test/fixtures/integration/multipleTargetDurations.js +28 -0
  111. package/test/fixtures/integration/multipleTargetDurations.m3u8 +8 -0
  112. package/test/fixtures/integration/multipleVideo.js +74 -0
  113. package/test/fixtures/integration/multipleVideo.m3u8 +16 -0
  114. package/test/fixtures/integration/negativeMediaSequence.js +31 -0
  115. package/test/fixtures/integration/negativeMediaSequence.m3u8 +14 -0
  116. package/test/fixtures/integration/playlist.js +165 -0
  117. package/test/fixtures/integration/playlist.m3u8 +57 -0
  118. package/test/fixtures/integration/playlistMediaSequenceHigher.js +16 -0
  119. package/test/fixtures/integration/playlistMediaSequenceHigher.m3u8 +8 -0
  120. package/test/fixtures/integration/start.js +36 -0
  121. package/test/fixtures/integration/start.m3u8 +13 -0
  122. package/test/fixtures/integration/streamInfInvalid.js +24 -0
  123. package/test/fixtures/integration/streamInfInvalid.m3u8 +6 -0
  124. package/test/fixtures/integration/twoMediaSequences.js +31 -0
  125. package/test/fixtures/integration/twoMediaSequences.m3u8 +15 -0
  126. package/test/fixtures/integration/versionInvalid.js +16 -0
  127. package/test/fixtures/integration/versionInvalid.m3u8 +8 -0
  128. package/test/fixtures/integration/whiteSpace.js +31 -0
  129. package/test/fixtures/integration/whiteSpace.m3u8 +13 -0
  130. package/test/fixtures/integration/zeroDuration.js +16 -0
  131. package/test/fixtures/integration/zeroDuration.m3u8 +7 -0
  132. package/test/line-stream.test.js +80 -0
  133. package/test/parse-stream.test.js +903 -0
  134. package/test/parser.test.js +884 -0
@@ -0,0 +1,30 @@
1
+ # CONTRIBUTING
2
+
3
+ We welcome contributions from everyone!
4
+
5
+ ## Getting Started
6
+
7
+ Make sure you have Node.js 4.8 or higher and npm installed.
8
+
9
+ 1. Fork this repository and clone your fork
10
+ 1. Install dependencies: `npm install`
11
+ 1. Run a development server: `npm start`
12
+
13
+ ### Making Changes
14
+
15
+ Refer to the [video.js plugin conventions][conventions] for more detail on best practices and tooling for video.js plugin authorship.
16
+
17
+ When you've made your changes, push your commit(s) to your fork and issue a pull request against the original repository.
18
+
19
+ ### Running Tests
20
+
21
+ Testing is a crucial part of any software project. For all but the most trivial changes (typos, etc) test cases are expected. Tests are run in actual browsers using [Karma][karma].
22
+
23
+ - In all available and supported browsers: `npm test`
24
+ - In a specific browser: `npm run test:chrome`, `npm run test:firefox`, etc.
25
+ - While development server is running (`npm start`), navigate to [`http://localhost:9999/test/`][local]
26
+
27
+
28
+ [karma]: http://karma-runner.github.io/
29
+ [local]: http://localhost:9999/test/
30
+ [conventions]: https://github.com/videojs/generator-videojs-plugin/blob/master/docs/conventions.md
package/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright Brightcove, Inc
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,388 @@
1
+ # m3u8-parser
2
+ [![Build Status](https://travis-ci.org/videojs/m3u8-parser.svg?branch=master)](https://travis-ci.org/videojs/m3u8-parser)
3
+ [![Greenkeeper badge](https://badges.greenkeeper.io/videojs/m3u8-parser.svg)](https://greenkeeper.io/)
4
+ [![Slack Status](http://slack.videojs.com/badge.svg)](http://slack.videojs.com)
5
+
6
+ [![NPM](https://nodei.co/npm/m3u8-parser.png?downloads=true&downloadRank=true)](https://nodei.co/npm/m3u8-parser/)
7
+
8
+ m3u8 parser
9
+
10
+ <!-- START doctoc generated TOC please keep comment here to allow auto update -->
11
+ <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
12
+
13
+
14
+ - [Installation](#installation)
15
+ - [Usage](#usage)
16
+ - [Parsed Output](#parsed-output)
17
+ - [Supported Tags](#supported-tags)
18
+ - [Basic Playlist Tags](#basic-playlist-tags)
19
+ - [Media Segment Tags](#media-segment-tags)
20
+ - [Media Playlist Tags](#media-playlist-tags)
21
+ - [Master Playlist Tags](#master-playlist-tags)
22
+ - [Experimental Tags](#experimental-tags)
23
+ - [EXT-X-CUE-OUT](#ext-x-cue-out)
24
+ - [EXT-X-CUE-OUT-CONT](#ext-x-cue-out-cont)
25
+ - [EXT-X-CUE-IN](#ext-x-cue-in)
26
+ - [Not Yet Supported](#not-yet-supported)
27
+ - [Custom Parsers](#custom-parsers)
28
+ - [Including the Parser](#including-the-parser)
29
+ - [`<script>` Tag](#script-tag)
30
+ - [Browserify](#browserify)
31
+ - [RequireJS/AMD](#requirejsamd)
32
+ - [License](#license)
33
+
34
+ <!-- END doctoc generated TOC please keep comment here to allow auto update -->
35
+ ## Installation
36
+
37
+ ```sh
38
+ npm install --save m3u8-parser
39
+ ```
40
+
41
+ The npm installation is preferred, but Bower works, too.
42
+
43
+ ```sh
44
+ bower install --save m3u8-parser
45
+ ```
46
+
47
+ ## Usage
48
+
49
+ ```js
50
+ var manifest = [
51
+ '#EXTM3U',
52
+ '#EXT-X-VERSION:3',
53
+ '#EXT-X-TARGETDURATION:6',
54
+ '#EXT-X-MEDIA-SEQUENCE:0',
55
+ '#EXT-X-DISCONTINUITY-SEQUENCE:0',
56
+ '#EXTINF:6,',
57
+ '0.ts',
58
+ '#EXTINF:6,',
59
+ '1.ts',
60
+ '#EXTINF:6,',
61
+ '2.ts',
62
+ '#EXT-X-ENDLIST'
63
+ ].join('\n');
64
+
65
+ var parser = new m3u8Parser.Parser();
66
+
67
+ parser.push(manifest);
68
+ parser.end();
69
+
70
+ var parsedManifest = parser.manifest;
71
+ ```
72
+
73
+ ### Parsed Output
74
+
75
+ The parser ouputs a plain javascript object with the following structure:
76
+
77
+ ```js
78
+ Manifest {
79
+ allowCache: boolean,
80
+ endList: boolean,
81
+ mediaSequence: number,
82
+ discontinuitySequence: number,
83
+ playlistType: string,
84
+ custom: {},
85
+ playlists: [
86
+ {
87
+ attributes: {},
88
+ Manifest
89
+ }
90
+ ],
91
+ mediaGroups: {
92
+ AUDIO: {
93
+ 'GROUP-ID': {
94
+ NAME: {
95
+ default: boolean,
96
+ autoselect: boolean,
97
+ language: string,
98
+ uri: string,
99
+ instreamId: string,
100
+ characteristics: string,
101
+ forced: boolean
102
+ }
103
+ }
104
+ },
105
+ VIDEO: {},
106
+ 'CLOSED-CAPTIONS': {},
107
+ SUBTITLES: {}
108
+ },
109
+ dateTimeString: string,
110
+ dateTimeObject: Date,
111
+ targetDuration: number,
112
+ totalDuration: number,
113
+ discontinuityStarts: [number],
114
+ segments: [
115
+ {
116
+ byterange: {
117
+ length: number,
118
+ offset: number
119
+ },
120
+ duration: number,
121
+ attributes: {},
122
+ discontinuity: number,
123
+ uri: string,
124
+ timeline: number,
125
+ key: {
126
+ method: string,
127
+ uri: string,
128
+ iv: string
129
+ },
130
+ map: {
131
+ uri: string,
132
+ byterange: {
133
+ length: number,
134
+ offset: number
135
+ }
136
+ },
137
+ 'cue-out': string,
138
+ 'cue-out-cont': string,
139
+ 'cue-in': string,
140
+ custom: {}
141
+ }
142
+ ]
143
+ }
144
+ ```
145
+
146
+ ## Supported Tags
147
+
148
+ ### Basic Playlist Tags
149
+
150
+ * [EXTM3U](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.1.1)
151
+ * [EXT-X-VERSION](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.1.2)
152
+
153
+ ### Media Segment Tags
154
+
155
+ * [EXTINF](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.2.1)
156
+ * [EXT-X-BYTERANGE](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.2.2)
157
+ * [EXT-X-DISCONTINUITY](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.2.3)
158
+ * [EXT-X-KEY](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.2.4)
159
+ * [EXT-X-MAP](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.2.5)
160
+ * [EXT-X-PROGRAM-DATE-TIME](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.2.6)
161
+
162
+ ### Media Playlist Tags
163
+
164
+ * [EXT-X-TARGETDURATION](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.3.1)
165
+ * [EXT-X-MEDIA-SEQUENCE](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.3.2)
166
+ * [EXT-X-DISCONTINUITY-SEQUENCE](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.3.3)
167
+ * [EXT-X-ENDLIST](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.3.4)
168
+ * [EXT-X-PLAYLIST-TYPE](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.3.5)
169
+ * [EXT-X-START](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.5.2)
170
+
171
+ ### Master Playlist Tags
172
+
173
+ * [EXT-X-MEDIA](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.4.1)
174
+ * [EXT-X-STREAM-INF](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.4.2)
175
+
176
+ ### Experimental Tags
177
+
178
+ m3u8-parser supports 3 additional **Media Segment Tags** not present in the HLS specification.
179
+
180
+ #### EXT-X-CUE-OUT
181
+
182
+ The `EXT-X-CUE-OUT` indicates that the following media segment is a break in main content and the start of interstitial content. Its format is:
183
+
184
+ ```
185
+ #EXT-X-CUE-OUT:<duration>
186
+ ```
187
+
188
+ where `duration` is a decimal-floating-point or decimal-integer number that specifies the total duration of the interstitial in seconds.
189
+
190
+ #### EXT-X-CUE-OUT-CONT
191
+
192
+ The `EXT-X-CUE-OUT-CONT` indicates that the following media segment is a part of interstitial content and not the main content. Every media segment following a media segment with an `EXT-X-CUE-OUT` tag *SHOULD* have an `EXT-X-CUE-OUT-CONT` applied to it until there is an `EXT-X-CUE-IN` tag. A media segment between a `EXT-X-CUE-OUT` and `EXT-X-CUE-IN` segment without a `EXT-X-CUE-OUT-CONT` is assumed to be part of the interstitial. Its format is:
193
+
194
+ ```
195
+ #EXT-X-CUE-OUT-CONT:<n>/<duration>
196
+ ```
197
+
198
+ where `n` is a decimal-floating-point or decimal-integer number that specifies the time in seconds the first sample of the media segment lies within the interstitial content and `duration` is a decimal-floating-point or decimal-integer number that specifies the total duration of the interstitial in seconds. `n` *SHOULD* be the sum of `EXTINF` durations for all preceding media segments up to the `EXT-X-CUE-OUT` tag for the current interstitial. `duration` *SHOULD* match the `duration` specified in the `EXT-X-CUE-OUT` tag for the current interstitial.'
199
+
200
+ #### EXT-X-CUE-IN
201
+
202
+ The `EXT-X-CUE-IN` indicates the end of the interstitial and the return of the main content. Its format is:
203
+
204
+ ```
205
+ #EXT-X-CUE-IN
206
+ ```
207
+
208
+ There *SHOULD* be a closing `EXT-X-CUE-IN` tag for every `EXT-X-CUE-OUT` tag. If a second `EXT-X-CUE-OUT` tag is encountered before an `EXT-X-CUE-IN` tag, the client *MAY* choose to ignore the `EXT-X-CUE-OUT` and treat it as part of the interstitial, or reject the playlist.
209
+
210
+ Example media playlist using `EXT-X-CUE-` tags.
211
+
212
+ ```
213
+ #EXTM3U
214
+ #EXT-X-VERSION:3
215
+ #EXT-X-TARGETDURATION:10
216
+ #EXTINF:10,
217
+ 0.ts
218
+ #EXTINF:10,
219
+ 1.ts
220
+ #EXT-X-CUE-OUT:30
221
+ #EXTINF:10,
222
+ 2.ts
223
+ #EXT-X-CUE-OUT-CONT:10/30
224
+ #EXTINF:10,
225
+ 3.ts
226
+ #EXT-X-CUE-OUT-CONT:20/30
227
+ #EXTINF:10,
228
+ 4.ts
229
+ #EXT-X-CUE-IN
230
+ #EXTINF:10,
231
+ 5.ts
232
+ #EXTINF:10,
233
+ 6.ts
234
+ #EXT-X-ENDLIST
235
+ ```
236
+
237
+ ### Not Yet Supported
238
+
239
+ * [EXT-X-DATERANGE](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.2.7)
240
+ * [EXT-X-I-FRAMES-ONLY](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.3.6)
241
+ * [EXT-X-I-FRAME-STREAM-INF](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.4.3)
242
+ * [EXT-X-SESSION-DATA](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.4.4)
243
+ * [EXT-X-SESSION-KEY](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.4.5)
244
+ * [EXT-X-INDEPENDENT-SEGMENTS](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.5.1)
245
+
246
+ ### Custom Parsers
247
+
248
+ To add a parser for a non-standard tag the parser object allows for the specification of custom tags using regular expressions. If a custom parser is specified, a `custom` object is appended to the manifest object.
249
+
250
+ ```js
251
+ const manifest = [
252
+ '#EXTM3U',
253
+ '#EXT-X-VERSION:3',
254
+ '#VOD-FRAMERATE:29.97',
255
+ ''
256
+ ].join('\n');
257
+
258
+ const parser = new m3u8Parser.Parser();
259
+ parser.addParser({
260
+ expression: /^#VOD-FRAMERATE/,
261
+ customType: 'framerate'
262
+ });
263
+
264
+ parser.push(manifest);
265
+ parser.end();
266
+ parser.manifest.custom.framerate // "#VOD-FRAMERATE:29.97"
267
+ ```
268
+
269
+ Custom parsers may additionally be provided a data parsing function that take a line and return a value.
270
+
271
+ ```js
272
+ const manifest = [
273
+ '#EXTM3U',
274
+ '#EXT-X-VERSION:3',
275
+ '#VOD-FRAMERATE:29.97',
276
+ ''
277
+ ].join('\n');
278
+
279
+ const parser = new m3u8Parser.Parser();
280
+ parser.addParser({
281
+ expression: /^#VOD-FRAMERATE/,
282
+ customType: 'framerate',
283
+ dataParser: function(line) {
284
+ return parseFloat(line.split(':')[1]);
285
+ }
286
+ });
287
+
288
+ parser.push(manifest);
289
+ parser.end();
290
+ parser.manifest.custom.framerate // 29.97
291
+ ```
292
+
293
+ Custom parsers may also extract data at a segment level by passing `segment: true` to the options object. Having a segment level custom parser will add a `custom` object to the segment data.
294
+
295
+ ```js
296
+ const manifest = [
297
+ '#EXTM3U',
298
+ '#VOD-TIMING:1511816599485',
299
+ '#EXTINF:8.0,',
300
+ 'ex1.ts',
301
+ ''
302
+ ].join('\n');
303
+
304
+ const parser = new m3u8Parser.Parser();
305
+ parser.addParser({
306
+ expression: /#VOD-TIMING/,
307
+ customType: 'vodTiming',
308
+ segment: true
309
+ });
310
+
311
+ parser.push(manifest);
312
+ parser.end();
313
+ parser.manifest.segments[0].custom.vodTiming // #VOD-TIMING:1511816599485
314
+ ```
315
+
316
+ Custom parsers may also map a tag to another tag. The old tag will not be replaced and all matching registered mappers and parsers will be executed.
317
+ ```js
318
+ const manifest = [
319
+ '#EXTM3U',
320
+ '#EXAMPLE',
321
+ '#EXTINF:8.0,',
322
+ 'ex1.ts',
323
+ ''
324
+ ].join('\n');
325
+
326
+ const parser = new m3u8Parser.Parser();
327
+ parser.addTagMapper({
328
+ expression: /#EXAMPLE/,
329
+ map(line) {
330
+ return `#NEW-TAG:123`;
331
+ }
332
+ });
333
+ parser.addParser({
334
+ expression: /#NEW-TAG/,
335
+ customType: 'mappingExample',
336
+ segment: true
337
+ });
338
+
339
+ parser.push(manifest);
340
+ parser.end();
341
+ parser.manifest.segments[0].custom.mappingExample // #NEW-TAG:123
342
+ ```
343
+
344
+ ## Including the Parser
345
+
346
+ To include m3u8-parser on your website or web application, use any of the following methods.
347
+
348
+ ### `<script>` Tag
349
+
350
+ This is the simplest case. Get the script in whatever way you prefer and include it on your page.
351
+
352
+ ```html
353
+ <script src="//path/to/m3u8-parser.min.js"></script>
354
+ <script>
355
+ var parser = new m3u8Parser.Parser();
356
+ </script>
357
+ ```
358
+
359
+ ### Browserify
360
+
361
+ When using with Browserify, install m3u8-parser via npm and `require` the parser as you would any other module.
362
+
363
+ ```js
364
+ var m3u8Parser = require('m3u8-parser');
365
+
366
+ var parser = new m3u8Parser.Parser();
367
+ ```
368
+
369
+ With ES6:
370
+ ```js
371
+ import { Parser } from 'm3u8-parser';
372
+
373
+ const parser = new Parser();
374
+ ```
375
+
376
+ ### RequireJS/AMD
377
+
378
+ When using with RequireJS (or another AMD library), get the script in whatever way you prefer and `require` the parser as you normally would:
379
+
380
+ ```js
381
+ require(['m3u8-parser'], function(m3u8Parser) {
382
+ var parser = new m3u8Parser.Parser();
383
+ });
384
+ ```
385
+
386
+ ## License
387
+
388
+ Apache-2.0. Copyright (c) Brightcove, Inc