← All @molecule/* packages · App templates

@molecule/api-media-streaming

Core interface · media-streaming · API (Node) · v1.0.1 · Apache-2.0

Media streaming core interface for molecule.dev — create adaptive streams, transcode, generate manifests, and retrieve segments

npm install @molecule/api-media-streaming

npm · Source on GitHub

How it works

@molecule/api-media-streaming is the media-streaming core interface on the API (Node) side: the API your app calls, with no vendor inside.

Choose the implementation by bonding one of its 1 provider: @molecule/api-media-streaming-hls.

import { setProvider, createStream, transcode } from '@molecule/api-media-streaming'
import { provider as hls } from '@molecule/api-media-streaming-hls'

setProvider(hls)

const manifest = await createStream('/path/to/video.mp4', {
  segmentDuration: 6,
  protocol: 'hls',
})

const result = await transcode('/path/to/video.mp4', [
  { name: '720p', width: 1280, height: 720, videoBitrate: 2_500_000, audioBitrate: 128_000 },
  { name: '1080p', width: 1920, height: 1080, videoBitrate: 5_000_000, audioBitrate: 192_000 },
])

Providers (1): @molecule/api-media-streaming-hls

Works with: @molecule/api-bond, @molecule/api-i18n

Reference

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

Provider-agnostic media streaming interface for molecule.dev.

Defines the StreamingProvider interface for creating adaptive bitrate streams, transcoding media into multiple quality variants, generating manifests, and retrieving individual stream segments. Bond packages (HLS, DASH, etc.) implement this interface. Application code uses the convenience functions (createStream, transcode, generateManifest, getSegment) which delegate to the bonded provider.

Quick Start

import { setProvider, createStream, transcode } from '@molecule/api-media-streaming'
import { provider as hls } from '@molecule/api-media-streaming-hls'

setProvider(hls)

const manifest = await createStream('/path/to/video.mp4', {
  segmentDuration: 6,
  protocol: 'hls',
})

const result = await transcode('/path/to/video.mp4', [
  { name: '720p', width: 1280, height: 720, videoBitrate: 2_500_000, audioBitrate: 128_000 },
  { name: '1080p', width: 1920, height: 1080, videoBitrate: 5_000_000, audioBitrate: 192_000 },
])

Type

core

Installation

npm install @molecule/api-media-streaming @molecule/api-bond @molecule/api-i18n

API

Interfaces

StreamingConfig

Configuration options for media streaming providers.

interface StreamingConfig {
  /** Default segment duration in seconds. */
  segmentDuration?: number

  /** Default streaming protocol. */
  protocol?: StreamProtocol

  /** Base path for output files. */
  outputBasePath?: string
}

StreamingProvider

Media streaming provider interface.

All media streaming providers must implement this interface. Bond packages (HLS, DASH, etc.) provide concrete implementations.

interface StreamingProvider {
  /**
   * Creates a stream from a media source.
   *
   * @param input - The source media as a Buffer or file path.
   * @param options - Optional streaming configuration.
   * @returns A manifest describing the generated stream.
   */
  createStream(input: Buffer | string, options?: StreamOptions): Promise<StreamManifest>

  /**
   * Transcodes a media source into multiple quality variants.
   *
   * @param input - The source media as a Buffer or file path.
   * @param profiles - One or more target quality profiles.
   * @returns The aggregated transcode result with variant URIs.
   */
  transcode(input: Buffer | string, profiles: TranscodeProfile[]): Promise<TranscodeResult>

  /**
   * Generates a playlist / manifest string from a list of segments.
   *
   * @param segments - Ordered stream segments.
   * @param options - Optional streaming configuration.
   * @returns The manifest content as a string (e.g. M3U8 or MPD).
   */
  generateManifest(segments: StreamSegment[], options?: StreamOptions): string

  /**
   * Retrieves a specific segment of a stream.
   *
   * @param streamId - The stream identifier.
   * @param segmentIndex - Zero-based index of the segment.
   * @returns The raw segment data.
   */
  getSegment(streamId: string, segmentIndex: number): Promise<Buffer>
}

StreamManifest

Manifest describing a generated stream.

interface StreamManifest {
  /** Unique stream identifier. */
  id: string

  /** The streaming protocol used. */
  protocol: StreamProtocol

  /** URI of the manifest / playlist file (e.g. `.m3u8` or `.mpd`). */
  manifestUri: string

  /** Total duration of the stream in seconds. */
  duration: number

  /** Ordered list of segments that compose the stream. */
  segments: StreamSegment[]
}

StreamOptions

Options for creating a stream from a source file.

interface StreamOptions {
  /** Target segment duration in seconds. Defaults to `6`. */
  segmentDuration?: number

  /** Streaming protocol to use. Defaults to `'hls'`. */
  protocol?: StreamProtocol

  /** Output directory or bucket path for generated segments. */
  outputPath?: string
}

StreamSegment

A single segment of a media stream (e.g. an HLS .ts chunk).

interface StreamSegment {
  /** Zero-based index of the segment within the stream. */
  index: number

  /** Duration of the segment in seconds. */
  duration: number

  /** URI to access the segment (relative or absolute). */
  uri: string
}

TranscodeProfile

A transcoding profile describing the desired output quality.

interface TranscodeProfile {
  /** Human-readable name for the profile (e.g. `'720p'`). */
  name: string

  /** Target video width in pixels. */
  width: number

  /** Target video height in pixels. */
  height: number

  /** Target video bitrate in bits per second. */
  videoBitrate: number

  /** Target audio bitrate in bits per second. */
  audioBitrate: number

  /** Video codec to use (e.g. `'h264'`, `'vp9'`). */
  codec?: string
}

TranscodeResult

Aggregated result of a multi-profile transcoding operation.

interface TranscodeResult {
  /** Unique identifier for the transcode job. */
  id: string

  /** URI to the master manifest (adaptive bitrate). */
  masterManifestUri: string

  /** Individual variant results. */
  variants: TranscodeVariant[]
}

TranscodeVariant

Result of a transcoding operation for a single profile.

interface TranscodeVariant {
  /** Profile name used for this variant. */
  profile: string

  /** URI to the transcoded output. */
  uri: string

  /** Output width in pixels. */
  width: number

  /** Output height in pixels. */
  height: number

  /** Output bitrate in bits per second. */
  bitrate: number
}

Types

StreamProtocol

Supported streaming protocol.

type StreamProtocol = 'hls' | 'dash'

StreamStatus

Status of a streaming session.

type StreamStatus = 'pending' | 'processing' | 'ready' | 'error'

Functions

createStream(input, options)

Creates a stream from a media source.

function createStream(
  input: string | Buffer<ArrayBufferLike>,
  options?: StreamOptions,
): Promise<StreamManifest>
  • input — The source media as a Buffer or file path.
  • options — Optional streaming configuration.

Returns: A manifest describing the generated stream.

generateManifest(segments, options)

Generates a playlist / manifest string from a list of segments.

function generateManifest(segments: StreamSegment[], options?: StreamOptions): string
  • segments — Ordered stream segments.
  • options — Optional streaming configuration.

Returns: The manifest content as a string (e.g. M3U8 or MPD).

getProvider()

Retrieves the bonded media streaming provider, throwing if none is configured.

function getProvider(): StreamingProvider

Returns: The bonded media streaming provider.

getSegment(streamId, segmentIndex)

Retrieves a specific segment of a stream.

function getSegment(streamId: string, segmentIndex: number): Promise<Buffer<ArrayBufferLike>>
  • streamId — The stream identifier.
  • segmentIndex — Zero-based index of the segment.

Returns: The raw segment data.

hasProvider()

Checks whether a media streaming provider is currently bonded.

function hasProvider(): boolean

Returns: true if a media streaming provider is bonded.

setProvider(provider)

Registers a media streaming provider as the active singleton. Called by bond packages during application startup.

function setProvider(provider: StreamingProvider): void
  • provider — The media streaming provider implementation to bond.

transcode(input, profiles)

Transcodes a media source into multiple quality variants.

function transcode(
  input: string | Buffer<ArrayBufferLike>,
  profiles: TranscodeProfile[],
): Promise<TranscodeResult>
  • input — The source media as a Buffer or file path.
  • profiles — One or more target quality profiles.

Returns: The aggregated transcode result with variant URIs.

Available Providers

ProviderPackage
Media Streaming@molecule/api-media-streaming-hls

Injection Notes

Requirements

Peer dependencies:

  • @molecule/api-bond ^1.0.1
  • @molecule/api-i18n ^1.0.1

Runtime Dependencies

  • @molecule/api-bond

  • @molecule/api-i18n

  • Transcoding and stream creation are long-running CPU work — minutes for real videos, not request-scoped. Kick them off from a background job/queue and persist the returned ids + status; never await transcode(...) inline in an upload request with the client hanging.

  • The app must SERVE what this creates. Returned manifest/segment URIs only work if they resolve over HTTP: either point outputPath at a directory your server actually exposes, or wire endpoints that return generateManifest(segments) (correct manifest content-type) and stream getSegment(streamId, index) bytes. Writing segments to an unserved dir ships a player full of 404s.

  • generateManifest is synchronous (no await); getSegment resolves segments for a previously created stream — persist StreamManifest.id with your media record.

  • Runtime prerequisites (e.g. an ffmpeg binary for real transcoding) are bond-specific — check the bonded package's docs before shipping.

E2E Tests

Integration checklist — drive the real UI (live preview, no mocks), adapt each item to this app's actual upload/player screens, and check every box off one by one. A box you can't check is an integration bug to fix — not a skip. You can't judge real transcode QUALITY or a live A/V feed in the sandbox; verify the pipeline + playback WIRING you own:

  • Uploading/ingesting a media asset produces a real PLAYABLE stream: the returned manifestUri (.m3u8 for HLS / .mpd for DASH) loads in the app's video player and actually plays — frames advance and the player fetches segments (watch the network panel), never a broken/blank player.
  • The stream is served from/through the APP'S OWN origin — an outputPath under a directory the server exposes, or endpoints that return generateManifest(segments) and stream getSegment(streamId, index) bytes. The player must NOT hotlink a raw expiring provider URL, and no manifest or segment request may 404.
  • Processing STATE is observable and playback is gated on it: an asset moves pending → processing → ready (StreamStatus), the UI reflects that, and the player mounts only once status is 'ready' — never a dead player on a still-transcoding asset.
  • If adaptive bitrate is exposed, transcode() produced multiple renditions: the master manifest (masterManifestUri) lists more than one variant and the player can switch quality across them.
  • If the app exposes a poster/thumbnail for an asset, it generates and renders before playback (no blank tile).
  • SECURITY — private media is AUTHORIZED on playback: the manifest and segment endpoints check the requester (or hand out a signed/expiring URL), so a user CANNOT fetch another user's stream by guessing its id/URL; and provider keys stay server-side (never shipped to the client bundle).