@michaeljones2001/m3u8-parser v5.4.1
m3u8-parser
This is a fork (from this repository) with stringifying functionality. You can write the manifest object back to a file.
To see what tags are supported in stringifying see this section. I will develop this package to support more tags in the future. Any PR is welcome.
m3u8 parser
Installation
npm install --save @michaeljones2001/m3u8-parser
Usage
var manifest = [
'#EXTM3U',
'#EXT-X-VERSION:3',
'#EXT-X-TARGETDURATION:6',
'#EXT-X-MEDIA-SEQUENCE:0',
'#EXT-X-DISCONTINUITY-SEQUENCE:0',
'#EXTINF:6,',
'0.ts',
'#EXTINF:6,',
'1.ts',
'#EXTINF:6,',
'2.ts',
'#EXT-X-ENDLIST'
].join('\n');
var parser = new m3u8Parser.Parser();
parser.push(manifest);
parser.end();
var parsedManifest = parser.manifest;
Parsed Output
The parser ouputs a plain javascript object with the following structure:
Manifest {
allowCache: boolean,
endList: boolean,
mediaSequence: number,
discontinuitySequence: number,
playlistType: string,
custom: {},
playlists: [
{
attributes: {},
Manifest
}
],
mediaGroups: {
AUDIO: {
'GROUP-ID': {
NAME: {
default: boolean,
autoselect: boolean,
language: string,
uri: string,
instreamId: string,
characteristics: string,
forced: boolean
}
}
},
VIDEO: {},
'CLOSED-CAPTIONS': {},
SUBTITLES: {}
},
dateTimeString: string,
dateTimeObject: Date,
targetDuration: number,
totalDuration: number,
discontinuityStarts: [number],
segments: [
{
byterange: {
length: number,
offset: number
},
duration: number,
attributes: {},
discontinuity: number,
uri: string,
timeline: number,
key: {
method: string,
uri: string,
iv: string
},
map: {
uri: string,
byterange: {
length: number,
offset: number
}
},
'cue-out': string,
'cue-out-cont': string,
'cue-in': string,
custom: {}
}
]
}
Stringify
To stringify a manifest object call stringify
method. You can directly write the string to a file.
const stringified = parser.stringify();
NOTE: encryption for Widevine is not supported in stringifying
Supported Tags
Basic Playlist Tags
Media Segment Tags
Media Playlist Tags
- EXT-X-TARGETDURATION
- EXT-X-MEDIA-SEQUENCE
- EXT-X-DISCONTINUITY-SEQUENCE
- EXT-X-ENDLIST
- EXT-X-PLAYLIST-TYPE
- EXT-X-START
- EXT-X-INDEPENDENT-SEGMENTS
Master Playlist Tags
Experimental Tags
m3u8-parser supports 3 additional Media Segment Tags not present in the HLS specification.
EXT-X-CUE-OUT
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:
#EXT-X-CUE-OUT:<duration>
where duration
is a decimal-floating-point or decimal-integer number that specifies the total duration of the interstitial in seconds.
EXT-X-CUE-OUT-CONT
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:
#EXT-X-CUE-OUT-CONT:<n>/<duration>
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.'
EXT-X-CUE-IN
The EXT-X-CUE-IN
indicates the end of the interstitial and the return of the main content. Its format is:
#EXT-X-CUE-IN
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.
Example media playlist using EXT-X-CUE-
tags.
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXTINF:10,
0.ts
#EXTINF:10,
1.ts
#EXT-X-CUE-OUT:30
#EXTINF:10,
2.ts
#EXT-X-CUE-OUT-CONT:10/30
#EXTINF:10,
3.ts
#EXT-X-CUE-OUT-CONT:20/30
#EXTINF:10,
4.ts
#EXT-X-CUE-IN
#EXTINF:10,
5.ts
#EXTINF:10,
6.ts
#EXT-X-ENDLIST
Not Yet Supported
Custom Parsers
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.
const manifest = [
'#EXTM3U',
'#EXT-X-VERSION:3',
'#VOD-FRAMERATE:29.97',
''
].join('\n');
const parser = new m3u8Parser.Parser();
parser.addParser({
expression: /^#VOD-FRAMERATE/,
customType: 'framerate'
});
parser.push(manifest);
parser.end();
parser.manifest.custom.framerate // "#VOD-FRAMERATE:29.97"
Custom parsers may additionally be provided a data parsing function that take a line and return a value.
const manifest = [
'#EXTM3U',
'#EXT-X-VERSION:3',
'#VOD-FRAMERATE:29.97',
''
].join('\n');
const parser = new m3u8Parser.Parser();
parser.addParser({
expression: /^#VOD-FRAMERATE/,
customType: 'framerate',
dataParser: function(line) {
return parseFloat(line.split(':')[1]);
}
});
parser.push(manifest);
parser.end();
parser.manifest.custom.framerate // 29.97
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.
const manifest = [
'#EXTM3U',
'#VOD-TIMING:1511816599485',
'#EXTINF:8.0,',
'ex1.ts',
''
].join('\n');
const parser = new m3u8Parser.Parser();
parser.addParser({
expression: /#VOD-TIMING/,
customType: 'vodTiming',
segment: true
});
parser.push(manifest);
parser.end();
parser.manifest.segments[0].custom.vodTiming // #VOD-TIMING:1511816599485
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.
const manifest = [
'#EXTM3U',
'#EXAMPLE',
'#EXTINF:8.0,',
'ex1.ts',
''
].join('\n');
const parser = new m3u8Parser.Parser();
parser.addTagMapper({
expression: /#EXAMPLE/,
map(line) {
return `#NEW-TAG:123`;
}
});
parser.addParser({
expression: /#NEW-TAG/,
customType: 'mappingExample',
segment: true
});
parser.push(manifest);
parser.end();
parser.manifest.segments[0].custom.mappingExample // #NEW-TAG:123
Stringifying supported tag
- #EXTM3U
- #EXT-X-ALLOW-CACHE
- #EXT-X-VERSION
- #EXT-X-MEDIA
- #EXT-X-STREAM-INF
- #EXT-X-TARGETDURATION
- #EXT-X-MEDIA-SEQUENCE
- #EXT-X-PLAYLIST-TYPE
- #EXTINF
- #EXT-X-ENDLIST
- #EXT-X-PROGRAM-DATE-TIME
- #EXT-X-BYTERANGE
- #EXT-X-DISCONTINUITY
- #EXT-X-DISCONTINUITY-SEQUENCE
- #EXT-X-START
- #EXT-X-KEY
- #EXT-X-MAP
- #EXT-X-INDEPENDENT-SEGMENTS
Including the Parser
To include m3u8-parser on your website or web application, use any of the following methods.
<script>
Tag
This is the simplest case. Get the script in whatever way you prefer and include it on your page.
<script src="//path/to/m3u8-parser.min.js"></script>
<script>
var parser = new m3u8Parser.Parser();
</script>
Browserify
When using with Browserify, install m3u8-parser via npm and require
the parser as you would any other module.
var m3u8Parser = require('m3u8-parser');
var parser = new m3u8Parser.Parser();
With ES6:
import { Parser } from 'm3u8-parser';
const parser = new Parser();
RequireJS/AMD
When using with RequireJS (or another AMD library), get the script in whatever way you prefer and require
the parser as you normally would:
require(['m3u8-parser'], function(m3u8Parser) {
var parser = new m3u8Parser.Parser();
});
License
Apache-2.0. Copyright (c) Brightcove, Inc