7.1.0 • Published 9 months ago

m3u8-parser v7.1.0

Weekly downloads
200,044
License
Apache-2.0
Repository
github
Last release
9 months ago

m3u8-parser

Build Status Greenkeeper badge Slack Status

NPM

m3u8 parser

Installation

npm install --save m3u8-parser

The npm installation is preferred, but Bower works, too.

bower install  --save 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',
  '#EXT-X-PROGRAM-DATE-TIME:2019-02-14T02:14:00.106Z'
  '#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,
  dateRanges: [],
  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: [
    {
      title: string,
      byterange: {
        length: number,
        offset: number
      },
      duration: number,
      programDateTime:  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: {}
    }
  ]
}

Supported Tags

Basic Playlist Tags

Media Segment Tags

Media Playlist Tags

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

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

videoyj-http-streamingfarakav-hls-quality-selectorreact-m3u8-player@infinitebrahmanuniverse/nolb-m3@everything-registry/sub-chunk-2117m3u8-conver-corem3u8-downloader-mp4drive-video-jsstream-engine-playerdownloadsound.cloud@dalongrong/m3u8_multi_downloaderdlm3u8p2p-media-loader-hlsjs-basytonp2p-media-loader-hlsjschzzk-sdk@cave/m3u8-parser@soundhub/soundhub_vkpronarrcontus-mf-peerspulsar-utilsparse-m3u8@cutting-mat/widgets@cutting-mat/widgets-v3oasis-playerradicast@dminc/http-streamingcrunchdowncrunchyroll.tscrunchyroll-dldashacssesc-wbgquick-and-dirty-encrypted-m3u8-downloader@dpants/utilsnode-hls-downloadernode-hls-downloader-amirnode-hls-stream-downloaderartillery-plugin-hls@emliri/mmjs@jienco/http-streaming@lzwme/m3u8-dl@s3bubble/player@rstruhl/videojs-contrib-hls@knowbly/http-streaming@jontsnz/http-streaming@jontsnz/video.js@mfts2048/mfts@mgara/http-streaming@messypack/video-processor@minits/media-formatter@minits/media-grouper@minits/media-processor@mkbkkj/m3u8-downloader@node-spider/vimeo@shrijal/video.js@silvermine/video.js@perillamint/node-hls-downloader@peertube/p2p-media-loader-hlsjs@repk/m3u8-dl@leonchabbey/rio-videojs-http-streaming@my-videojs/videojs-contrib-hls@mlytics/p2sp-sdk@vipstorage/video.js@zackdk/m3u8tomp4@zackradisic/hls-dl@webtor/p2p-media-loader-hlsjs@wyckid/hls-fetcher@xdml/http-streamingmraiguo-videojs-contrib-hlsmstreamanimekit@sunlt/m3u8-downloader@sully_al/p2p@videojs/http-streaming@videojs/plugin-concatalm-video-player-test@zhangyapeng/video-dwb-live-recbaha-anime-dlfaux-tunerfetch-videofarakav-quality-selectorfree-hls-livevhs-fork-dashkevichhs-new-video.jsvodtwitchhls-har-analyzerhls-fetcherhls-recorderhttp-streaming-buddytvhttp-streaming-pktwitchvod-youtubeglobular-mvch265playervadoosdkvadootvsdkvadootvsdk_dashjspf-clixemphimwasm-utilwikimedia-extractors
6.2.0

11 months ago

7.0.0

9 months ago

7.1.0

9 months ago

6.1.0

11 months ago

6.0.0

2 years ago

4.8.0

2 years ago

5.0.0

2 years ago

4.7.1

2 years ago

4.7.0

3 years ago

4.6.0

3 years ago

4.5.2

3 years ago

4.5.1

3 years ago

4.5.0

3 years ago

4.4.3

4 years ago

4.4.2

5 years ago

4.4.1

5 years ago

4.4.1-1

5 years ago

4.4.1-0

5 years ago

4.4.0

5 years ago

4.3.0

5 years ago

4.2.0

6 years ago

4.1.0

6 years ago

4.0.0

6 years ago

3.0.0

7 years ago

2.1.0

7 years ago

2.0.1

7 years ago

2.0.0

7 years ago

1.2.0

8 years ago

1.1.0

8 years ago

1.0.2

8 years ago

1.0.1-1

8 years ago

1.0.1-0

8 years ago

1.0.1

8 years ago

1.0.0

8 years ago