0.0.3 • Published 6 years ago

node-hls-stream v0.0.3

Weekly downloads
4
License
MIT
Repository
github
Last release
6 years ago

Build Status Coverage Status Dependency Status XO code style

node-hls-stream

A readable/writable stream that can be used for manipulating a live/VOD HLS stream

Features

  • Provides a readable stream that can be used for extracting a particular variant/rendition from a running live/VOD HLS stream
    • Downloads and parses HLS playlist and segment files based on the spec.
    • Enables clients to choose a specific variant with specific rendition(s) to download.
    • Provides parsed playlists and segments as structured JS objects.
  • Provides a writable stream that can be used for generating HLS playlist/segment files in realtime
    • Enables clients to describe playlists/segments as JS objects.
    • Converts the JS objects into HLS playlist and segment files that conform to the spec.

Usage

Readable stream

const {createReadStream} = require('node-hls-stream');
// Create a readable stream from a URL
const stream = createReadStream('https://foo.com/bar.m3u8', {concurrency: 7});

stream.on('variants', (variants, cb) => {
  // Choose an appropriate variant
  for (let [index, variant] of variants.entries()) {
    if (variant.bandwidth >= MIN_BITRATE) {
      return cb(index);
    }
  }
  // If not specified, the first (index=0) variant will be used.
})
.on('renditions', (renditions, cb) => {
  // Choose an appropriate rendition
  for (let [index, rendition] of renditions.entries()) {
    if (rendition.type === 'AUDIO' && rendition.language === 'ja') {
      return cb(index);
    }
  }
  // If not specified, the default rendition will be used.
  // If there's no default rendition, the first (index=0) rendition will be used.
})
.on('data', data => {
  // The stream chosen above will be delivered here
  if (data.type === 'playlist') {
    const playlist = data;
    if (playlist.isMasterPlaylist) {
      console.log(`Master playlist`);
    } else {
      console.log(`Media playlist`);
    }
  } else if (data.type === 'segment') {
    const segment = data;
    console.log(`#${segment.mediaSequenceNumber}: duration = ${segment.duration}, byte length = ${segment.data.length}`);
  }
})
.on('end', () => {
  // For VOD streams, the stream ends after all data is consumed.
  // For Live streams, the stream continues until the ENDLIST tag.
  console.log('Done');
})
.on('error', err => {
  console.error(err.stack);
});

// To switch to another stream:
stream.updateVariant(); // 'variants' and 'renditions' events will be emitted again.

Writable stream

const {createWriteStream, types: {MediaPlaylist}} = require('node-hls-stream');
// Create a writable stream from a filepath
const stream = createWriteStream('./sample.m3u8');

stream.write(new MediaPlaylist({
  targetDuration: 9,
  playlistType: 'VOD',
  segments: [
    new Segment({uri: '', duration: 9})
  ]
}));

API

These features are provided via a ReadStream.

createReadStream(url[, options])

Creates a new ReadStream object.

params

NameTypeRequiredDefaultDescription
urlstringYesN/APlaylist URL
optionsobjectNo{}See below

options

NameTypeDefaultDescription
concurrencynumber6Max number of requests concurrently processed

return value

An instance of ReadStream.

ReadStream

A subclass of stream.Readable with additional events and methods as follows.

events

'variants'

variants event is emitted to let clients specify which variant to be downloaded. The event listener is called with the following arguments:

NameTypeDescription
variantsVariantA list of available variants
cbfunctionA callback function to be called by the client to specify the variant's index within the array.
'renditions'

renditions event is emitted to let clients specify which rendition to be downloaded. The event listener is called with the following arguments:

NameTypeDescription
renditionsRenditionA list of available renditions
cbfunctionA callback function to be called by the client to specify the rendition's index within the array.
'data'

data event is emitted when a playlist or segment is available. The event listener is called with the following arguments:

NameTypeDescription
dataDataAn instance of either of Segment, MasterPlaylist or MediaPlaylist

methods

updateVariant()

Emits variants/renditions events again so that the client can choose another variant/rendition. The method takes no params and returns no value.