@miadabdi/m3u8-parser

    5.4.1 • Public • Published

    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 @miadabdi/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

    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

    Install

    npm i @miadabdi/m3u8-parser

    DownloadsWeekly Downloads

    2

    Version

    5.4.1

    License

    Apache-2.0

    Unpacked Size

    516 kB

    Total Files

    134

    Last publish

    Collaborators

    • miadabdi