Skip to main content

VideoColorSpace

The VideoColorSpace class describes the color representation of video content. It specifies how color values should be interpreted, including the color gamut (primaries), brightness encoding (transfer), and YUV conversion (matrix).

Quick Example

import { VideoColorSpace } from 'node-webcodecs';

// Standard Dynamic Range - web video, HD content
const sdrColorSpace = new VideoColorSpace({
  primaries: 'bt709',      // Standard HD color gamut
  transfer: 'bt709',       // SDR gamma curve
  matrix: 'bt709',         // BT.709 YUV conversion
  fullRange: false         // Limited range (16-235)
});

console.log(sdrColorSpace.primaries);  // 'bt709'
console.log(sdrColorSpace.toJSON());   // Returns VideoColorSpaceInit object

Constructor

Creates a new VideoColorSpace from initialization data.
new VideoColorSpace(init?: VideoColorSpaceInit)
init
VideoColorSpaceInit
Optional configuration object for the color space.

Properties

All properties are readonly after construction.
primaries
VideoColorPrimaries | null
required
The color primaries defining the color gamut. Returns null if not specified.
transfer
VideoTransferCharacteristics | null
required
The transfer characteristics (gamma/EOTF) for brightness encoding. Returns null if not specified.
matrix
VideoMatrixCoefficients | null
required
The matrix coefficients for RGB-to-YUV conversion. Returns null if not specified.
fullRange
boolean | null
required
Whether full range (0-255) or limited range (16-235) is used. Returns null if not specified.

Methods

toJSON()

Returns a plain object representation of the color space, suitable for serialization.
colorSpace.toJSON(): VideoColorSpaceInit
Returns: A VideoColorSpaceInit object containing all color space properties.
const colorSpace = new VideoColorSpace({
  primaries: 'bt2020',
  transfer: 'pq',
  matrix: 'bt2020-ncl',
  fullRange: false
});

const json = colorSpace.toJSON();
// {
//   primaries: 'bt2020',
//   transfer: 'pq',
//   matrix: 'bt2020-ncl',
//   fullRange: false
// }

// Use for VideoFrame or encoder configuration
const frame = new VideoFrame(data, {
  format: 'RGBA',
  codedWidth: 1920,
  codedHeight: 1080,
  timestamp: 0,
  colorSpace: colorSpace.toJSON()
});

Color Primaries

Color primaries define the color gamut (range of colors) that can be represented.
PrimaryDescriptionUse Case
bt709BT.709 (Rec. 709)SDR, HD video, web video
bt2020BT.2020 (Rec. 2020)HDR, 4K/8K, wide color gamut
smpte432DCI-P3Digital cinema, Apple displays
bt470bgBT.470 BGLegacy PAL/SECAM
smpte170mSMPTE 170MLegacy NTSC
The standard for HD television and web video. Covers approximately 35% of visible colors. This is the default for most SDR content and should be used for web distribution.
The standard for HDR and UHD content. Covers approximately 75% of visible colors. Required for HDR10 and HLG content. Use with pq or hlg transfer functions.
Used in digital cinema projection and Apple displays. Covers approximately 45% of visible colors. A middle ground between BT.709 and BT.2020.

Transfer Characteristics

Transfer characteristics (also called EOTF - Electro-Optical Transfer Function) define how brightness values are encoded.
TransferDescription
bt709SDR gamma curve (~2.4)
pqHDR10 Perceptual Quantizer (ST.2084)
hlgHybrid Log-Gamma for broadcast HDR
linearLinear light (no gamma)
iec61966-2-1sRGB (~2.2 gamma)
smpte170mSMPTE 170M (NTSC gamma)
The standard gamma curve for SDR content. Uses approximately 2.4 gamma with a linear segment near black. Use for all standard web and broadcast video.
The transfer function for HDR10 content (SMPTE ST.2084). Encodes absolute brightness up to 10,000 nits. Provides the best HDR quality but requires display calibration. Most common HDR format.
A relative brightness encoding that is backward-compatible with SDR displays. Used primarily in broadcast (BBC, NHK). Simpler than PQ and degrades gracefully on SDR displays.
No gamma correction applied. Values represent linear light intensity. Used for compositing and color grading workflows, not for display.

Matrix Coefficients

Matrix coefficients define how RGB values are converted to/from YUV color space.
MatrixDescriptionUse Case
rgbNo conversion (RGB)RGB-only formats
bt709BT.709 coefficientsSDR HD video
bt2020-nclBT.2020 non-constant luminanceHDR video
bt470bgBT.470 BGLegacy PAL
smpte170mSMPTE 170MLegacy NTSC
For HDR content, always use bt2020-ncl (non-constant luminance). The bt2020-cl (constant luminance) variant exists but is rarely used in practice.

Common Presets

BT.709 SDR (Standard Web Video)

const bt709SDR = new VideoColorSpace({
  primaries: 'bt709',
  transfer: 'bt709',
  matrix: 'bt709',
  fullRange: false
});
Use for: HD video, web streaming, YouTube, social media.

BT.2020 HDR10

const bt2020HDR10 = new VideoColorSpace({
  primaries: 'bt2020',
  transfer: 'pq',
  matrix: 'bt2020-ncl',
  fullRange: false
});
Use for: 4K HDR content, Netflix, Apple TV+, streaming HDR.

BT.2020 HLG

const bt2020HLG = new VideoColorSpace({
  primaries: 'bt2020',
  transfer: 'hlg',
  matrix: 'bt2020-ncl',
  fullRange: false
});
Use for: Broadcast HDR, live TV, SDR-compatible HDR.

DCI-P3 (Apple Devices)

const dciP3 = new VideoColorSpace({
  primaries: 'smpte432',
  transfer: 'iec61966-2-1',  // sRGB
  matrix: 'bt709',
  fullRange: false
});
Use for: Apple displays, wide-gamut SDR content.

Full Range RGB (Computer Graphics)

const fullRangeRGB = new VideoColorSpace({
  primaries: 'bt709',
  transfer: 'iec61966-2-1',
  matrix: 'rgb',
  fullRange: true
});
Use for: Screen capture, computer graphics, game footage.

VideoColorSpaceInit Interface

The initialization object used to construct a VideoColorSpace.
interface VideoColorSpaceInit {
  primaries?: VideoColorPrimaries | null;
  transfer?: VideoTransferCharacteristics | null;
  matrix?: VideoMatrixCoefficients | null;
  fullRange?: boolean | null;
}
All properties are optional. Unspecified properties default to null, meaning the value is unknown or unspecified.

Type Definitions

VideoColorPrimaries

type VideoColorPrimaries =
  | 'bt709'      // BT.709 (SDR)
  | 'bt470bg'    // BT.470 BG (PAL)
  | 'smpte170m'  // SMPTE 170M (NTSC)
  | 'bt2020'     // BT.2020 (HDR)
  | 'smpte432';  // DCI-P3

VideoTransferCharacteristics

type VideoTransferCharacteristics =
  | 'bt709'          // SDR gamma
  | 'smpte170m'      // NTSC gamma
  | 'iec61966-2-1'   // sRGB
  | 'linear'         // Linear light
  | 'pq'             // HDR10 (ST.2084)
  | 'hlg';           // HLG

VideoMatrixCoefficients

type VideoMatrixCoefficients =
  | 'rgb'         // No conversion
  | 'bt709'       // BT.709
  | 'bt470bg'     // BT.470 BG
  | 'smpte170m'   // SMPTE 170M
  | 'bt2020-ncl'; // BT.2020 non-constant luminance

Usage with VideoEncoder

Specify color space when encoding to ensure proper metadata in the output:
import { VideoEncoder, VideoFrame, VideoColorSpace } from 'node-webcodecs';

const encoder = new VideoEncoder({
  output: (chunk, metadata) => {
    console.log(`Encoded ${chunk.byteLength} bytes`);
  },
  error: (e) => console.error(e)
});

// Configure encoder with HDR color space
encoder.configure({
  codec: 'hevc_videotoolbox',
  width: 3840,
  height: 2160,
  bitrate: 25_000_000,
  colorSpace: {
    primaries: 'bt2020',
    transfer: 'pq',
    matrix: 'bt2020-ncl',
    fullRange: false
  }
});

// Create frame with matching color space
const frame = new VideoFrame(hdrData, {
  format: 'RGBA',
  codedWidth: 3840,
  codedHeight: 2160,
  timestamp: 0,
  colorSpace: {
    primaries: 'bt2020',
    transfer: 'pq',
    matrix: 'bt2020-ncl'
  }
});

encoder.encode(frame, { keyFrame: true });
frame.close();

See Also