gkozlenko/node-video-lib

View on GitHub
README.md

Summary

Maintainability
Test Coverage
# node-video-lib

[![build status](https://github.com/gkozlenko/node-video-lib/actions/workflows/node.js.yml/badge.svg)](https://github.com/gkozlenko/node-video-lib/actions/workflows/node.js.yml)
[![test coverage](https://gkozlenko.github.io/node-video-lib/badges/coverage.svg)](https://github.com/gkozlenko/node-video-lib/actions/workflows/node.js.yml)
[![npm version](https://img.shields.io/npm/v/node-video-lib.svg)](https://www.npmjs.com/package/node-video-lib)
[![license](https://img.shields.io/github/license/gkozlenko/node-video-lib.svg)](https://github.com/gkozlenko/node-video-lib/blob/master/LICENSE)

Node.js Video Library / MP4 & FLV parser / MP4 builder / HLS muxer

## Limitations

**This library works only with MP4 and FLV video files encoded using H.264/H.265 video codecs and AAC audio codec.**

## Installation

```bash
$ npm install node-video-lib
```

## Usage

### Parse video file

```javascript
const fs = require('fs');
const VideoLib = require('node-video-lib');

let fd = fs.openSync('/path/to/file', 'r');
try {
    let movie = VideoLib.MovieParser.parse(fd);
    // Work with movie
    console.log('Duration:', movie.relativeDuration());
} catch (ex) {
    console.error('Error:', ex);
} finally {
    fs.closeSync(fd);
}
```

### Create MPEG-TS chunks

```javascript
const fs = require('fs');
const VideoLib = require('node-video-lib');

let fd = fs.openSync('/path/to/file', 'r');
try {
    let movie = VideoLib.MovieParser.parse(fd);
    let fragmentList = VideoLib.FragmentListBuilder.build(movie, 5);
    for (let i = 0; i < fragmentList.count(); i++) {
        let fragment = fragmentList.get(i);
        let sampleBuffers = VideoLib.FragmentReader.readSamples(fragment, fd);
        let buffer = VideoLib.HLSPacketizer.packetize(fragment, sampleBuffers);
        // Now buffer contains MPEG-TS chunk
    }
} catch (ex) {
    console.error('Error:', ex);
} finally {
    fs.closeSync(fd);
}
```

### Build MP4 file

```javascript
const fs = require('fs');
const VideoLib = require('node-video-lib');

let fd = fs.openSync('/path/to/file', 'r');
try {
    let movie = VideoLib.MovieParser.parse(fd);
    let fw = fs.openSync('/path/to/output.mp4', 'w');
    try {
        VideoLib.MP4Builder.build(movie, fd, fw);
    } catch (ex) {
        console.error('Error:', ex);
    } finally {
        fs.closeSync(fw);
    }
} catch (ex) {
    console.error('Error:', ex);
} finally {
    fs.closeSync(fd);
}
```

### Create index file

```javascript
const fs = require('fs');
const VideoLib = require('node-video-lib');

let fd = fs.openSync('/path/to/file', 'r');
try {
    let movie = VideoLib.MovieParser.parse(fd);
    let fragmentList = VideoLib.FragmentListBuilder.build(movie, 5);
    console.log('Duration:', fragmentList.relativeDuration());
    let fdi = fs.openSync('/path/to/index.idx', 'w');
    try {
        VideoLib.FragmentListIndexer.index(fragmentList, fdi);
    } catch (ex) {
        console.error('Error:', ex);
    } finally {
        fs.closeSync(fdi);
    }
} catch (ex) {
    console.error('Error:', ex);
} finally {
    fs.closeSync(fd);
}
```

### Create MPEG-TS chunks using index file

```javascript
const fs = require('fs');
const VideoLib = require('node-video-lib');

let fd = fs.openSync('/path/to/file', 'r');
let fdi = fs.openSync('/path/to/index.idx', 'r');
try {
    let fragmentList = VideoLib.FragmentListIndexer.read(fdi);
    console.log('Duration:', fragmentList.relativeDuration());
    for (let i = 0; i < fragmentList.count(); i++) {
        let fragment = fragmentList.get(i);
        let sampleBuffers = VideoLib.FragmentReader.readSamples(fragment, fd);
        let buffer = VideoLib.HLSPacketizer.packetize(fragment, sampleBuffers);
        // Now buffer contains MPEG-TS chunk
    }
} catch (ex) {
    console.error('Error:', ex);
} finally {
    fs.closeSync(fd);
    fs.closeSync(fdi);
}
```

## Classes

### MovieParser

A tool for parsing video files (MP4 or FLV).

```javascript
const MovieParser = require('node-video-lib').MovieParser
```

Methods:

* **parse(source)** - Parse video file
    * **source** *\<Integer\>*|[*\<Buffer\>*](https://nodejs.org/api/buffer.html) - Source (File descriptor or Buffer)
    * Return: [*\<Movie\>*](#movie)

### MP4Parser

A tool for parsing MP4 video files.

```javascript
const MP4Parser = require('node-video-lib').MP4Parser
```

Methods:

* **parse(source)** - Parse MP4 file
    * **source** *\<Integer\>*|[*\<Buffer\>*](https://nodejs.org/api/buffer.html) - Source (File descriptor or Buffer)
    * Return: [*\<Movie\>*](#movie)
* **check(buffer)** - Check MP4 header
    * **buffer** [*\<Buffer\>*](https://nodejs.org/api/buffer.html) - File header (first 8 bytes)
    * Return: *\<boolean\>*

### FLVParser

A tool for parsing FLV video files.

```javascript
const FLVParser = require('node-video-lib').FLVParser
```

Methods:

* **parse(source)** - Parse FLV file
    * **source** *\<Integer\>*|[*\<Buffer\>*](https://nodejs.org/api/buffer.html) - Source (File descriptor or Buffer)
    * Return: [*\<Movie\>*](#movie)
* **check(buffer)** - Check FLV header
    * **buffer** [*\<Buffer\>*](https://nodejs.org/api/buffer.html) - File header (first 8 bytes)
    * Return: *\<boolean\>*

### MP4Builder

A tool for building MP4 video files.

```javascript
const MP4Builder = require('node-video-lib').MP4Builder
```

Methods:

* **build(movie, source, fd)** - Build MP4 file
    * **movie** [*\<Movie\>*](#movie) - Movie
    * **source** *\<Integer\>*|[*\<Buffer\>*](https://nodejs.org/api/buffer.html) - Source (File descriptor or Buffer)
    * **fd** *\<Integer\>* - File descriptor

### HLSPacketizer

A tool for creating MPEG-TS chunks.

```javascript
const HLSPacketizer = require('node-video-lib').HLSPacketizer
```

Methods:

* **packetize(fragment, sampleBuffers)** - Create MPEG-TS chunk from movie fragment
    * **fragment** [*\<Fragment\>*](#fragment) - Movie fragment
    * **sampleBuffers** *\<Array\>* - Array of buffers
    * Return: [*\<Buffer\>*](https://nodejs.org/api/buffer.html)

### FragmentListBuilder

A tool for splitting the movie into a list of fragments.

```javascript
const FragmentListBuilder = require('node-video-lib').FragmentListBuilder
```

Methods:

* **build(movie, fragmentDuration)** - Split the movie to a list of fragments with an appropriate duration
    * **movie** [*\<Movie\>*](#movie) - Movie
    * **fragmentDuration** *\<Integer\>* - Fragment duration
    * Return: [*\<FragmentList\>*](#fragmentlist)

### FragmentListIndexer

A tool to work with index files.

```javascript
const FragmentListIndexer = require('node-video-lib').FragmentListIndexer
```

Methods:

* **index(fragmentList, fd)** - Index fragment list
    * **fragmentList** [*\<FragmentList\>*](#fragmentlist) - Fragment list
    * **fd** *\<Integer\>* - File descriptor
* **read(fd)** - Read fragment list from index
    * **fd** *\<Integer\>* - File descriptor
    * Return: [*\<FragmentList\>*](#fragmentlist)

### FragmentReader

A tool for reading samples data of the given movie fragment.

```javascript
const FragmentReader = require('node-video-lib').FragmentReader
```

Methods:

* **readSamples(fragment, source)** - Read samples data
    * **fragment** [*\<Fragment\>*](#fragment) - Movie fragment
    * **source** *\<Integer\>*|[*\<Buffer\>*](https://nodejs.org/api/buffer.html) - Source (File descriptor or Buffer)
    * Return: *\<Array\>* Array of buffers

### Movie

A movie class

```javascript
const Movie = require('node-video-lib').Movie
```

Properties:

* **duration** *\<Integer\>* - Movie duration
* **timescale** *\<Integer\>* - Movie timescale
* **tracks** *\<Array\>* - List of movie tracks

Methods:

* **relativeDuration()** - Movie duration in seconds
    * Return: *\<Number\>*
* **resolution()** - Video resolution
    * Return: *\<String\>*
* **size()** - Samples size
    * Return: *\<Integer\>*
* **addTrack(track)** - Add a track to the tracks list
    * **track** *\<Track\>* - Track
* **videoTrack()** - Get the first video track
    * Return: *\<VideoTrack\>*
* **audioTrack()** - Get the first audio track
    * Return: *\<AudioTrack\>*
* **samples()** - Get a list of movie samples ordered by relative timestamp
    * Return: *\<Array\>*
* **ensureDuration()** - Calculate and set duration based on the track durations (only if duration is zero)
    * Return: *\<Number\>*

### FragmentList

A list of movie fragments class.

```javascript
const FragmentList = require('node-video-lib').FragmentList
```

Properties:

* **fragmentDuration** *\<Integer\>* - Target fragment duration
* **duration** *\<Integer\>* - Movie duration
* **timescale** *\<Integer\>* - Movie timescale
* **video** *\<Object\>* - Video info
    * **timescale** *\<Integer\>* - Video timescale
    * **codec** *\<String\>* - Codec string
    * **extraData** [*\<Buffer\>*](https://nodejs.org/api/buffer.html) - Video codec information
    * **size** *\<Integer\>* - Video samples size
    * **width** *\<Integer\>* - Video width
    * **height** *\<Integer\>* - Video height
* **audio** *\<Object\>* - Audio info
    * **timescale** *\<Integer\>* - Audio timescale
    * **codec** *\<String\>* - Codec string
    * **extraData** [*\<Buffer\>*](https://nodejs.org/api/buffer.html) - Audio codec information
    * **size** *\<Integer\>* - Audio samples size

Methods:

* **relativeDuration()** - Movie duration in seconds
    * Return: *\<Number\>*
* **count()** - Fragments count
    * Return: *\<Integer\>*
* **size()** - Samples size
    * Return: *\<Integer\>*
* **get(index)** - Get fragment by index
    * Return: [*\<Fragment\>*](#fragment)

### Fragment

A movie fragment class

```javascript
const Fragment = require('node-video-lib').Fragment
```

Properties:

* **timestamp** *\<Integer\>* - Fragment timestamp
* **duration** *\<Integer\>* - Fragment duration
* **timescale** *\<Integer\>* - Fragment timescale
* **videoExtraData** [*\<Buffer\>*](https://nodejs.org/api/buffer.html) - Video codec information
* **audioExtraData** [*\<Buffer\>*](https://nodejs.org/api/buffer.html) - Audio codec information
* **samples** *\<Array\>* - List of fragment samples

Methods:

* **relativeTimestamp()** - Fragment timestamp in seconds
    * Return: *\<Number\>*
* **relativeDuration()** - Fragment duration in seconds
    * Return: *\<Number\>*
* **hasVideo()** - Fragment has a video track
    * Return: *\<Boolean\>*
* **hasAudio()** - Fragment has an audio track
    * Return: *\<Boolean\>*

### Track

A general track class

```javascript
const Track = require('node-video-lib').Track
```

Properties:

* **duration** *\<Integer\>* - Track duration
* **timescale** *\<Integer\>* - Track timescale
* **codec** *\<String\>* - Codec string
* **extraData** [*\<Buffer\>*](https://nodejs.org/api/buffer.html) - Codec information
* **samples** *\<Array\>* - List of track samples

Methods:

* **relativeDuration()** - Track duration in seconds
    * Return: *\<Number\>*
* **ensureDuration()** - Calculate and set duration based on the sample durations (only if duration is zero)
    * Return: *\<Number\>*
* **size()** - Samples size
    * Return: *\<Integer\>*

### AudioTrack

An audio track class. Extends the general track class

```javascript
const AudioTrack = require('node-video-lib').AudioTrack
```

Properties:

* **channels** *\<Integer\>* - Number of audio channels
* **sampleRate** *\<Integer\>* - Audio sample rate
* **sampleSize** *\<Integer\>* - Audio sample size

### VideoTrack

A video track class. Extends the general track class

```javascript
const VideoTrack = require('node-video-lib').VideoTrack
```

Properties:

* **width** *\<Integer\>* - Video width
* **height** *\<Integer\>* - Video height

Methods:

* **resolution()** - Video resolution
    * Return: *\<String\>*

### Sample

A general video sample class

```javascript
const Sample = require('node-video-lib').Sample
```

Properties:

* **timestamp** *\<Integer\>* - Sample timestamp
* **timescale** *\<Integer\>* - Sample timescale
* **size** *\<Integer\>* - Sample size
* **offset** *\<Integer\>* - Sample offset in the file

Methods:

* **relativeTimestamp()** - Sample timestamp in seconds
    * Return: *\<Number\>*

### AudioSample

An audio sample class. Extends the general sample class

```javascript
const AudioSample = require('node-video-lib').AudioSample
```

### VideoSample

A video sample class. Extends the general sample class

```javascript
const VideoSample = require('node-video-lib').VideoSample
```

Properties:

* **compositionOffset** *\<Integer\>* - Composition offset
* **keyframe** *\<Boolean\>* - Keyframe flag