CML
    Preparing search index...

    Module @svta/cml-c2pa

    C2PA (Coalition for Content Provenance and Authenticity) validation for BMFF/MP4 live video streams.

    @svta/cml-c2pa

    C2PA (Coalition for Content Provenance and Authenticity) live video validation for BMFF and MP4 containers.

    Supported C2PA segment validation methods:

    • §19.3 Per-segment C2PA Manifest Box: each segment embeds a full C2PA manifest with a COSE signature
    • §19.4 Verifiable Segment Info (VSI/EMSG): the init segment contains the manifest and the session keys. Each media segment contains a small signed EMSG box
    • §15.12.2 / §18.6 VOD Merkle: for VOD assets in fragmented MP4, the init manifest stores one Merkle tree row per track. Each media segment contains its own leaf hash and proof
    npm i @svta/cml-c2pa
    

    Note: @svta/cml-iso-bmff, @svta/cml-utils, and cbor-x are peer dependencies. Most package managers install them automatically, but you may need to add them explicitly.

    Note: This library uses the Web Crypto API (crypto.subtle) to verify COSE signatures and compute BMFF hashes. In Node.js 20+, crypto.subtle is available globally. In browsers, it requires a secure context (HTTPS or localhost).

    import { validateC2paManifestBoxSegment } from '@svta/cml-c2pa'
    import type { ManifestBoxValidationState } from '@svta/cml-c2pa'

    async function validateManifestBoxStream(segmentUrls: string[]): Promise<void> {
    let lastManifestId: string | null = null
    let state: ManifestBoxValidationState | undefined

    for (const segmentUrl of segmentUrls) {
    const response = await fetch(segmentUrl)
    const bytes = new Uint8Array(await response.arrayBuffer())
    const { result, nextManifestId, nextState } = await validateC2paManifestBoxSegment(
    bytes,
    lastManifestId,
    state,
    )
    lastManifestId = nextManifestId
    state = nextState

    console.log(result.isValid, result.errorCodes)
    }
    }
    import { validateC2paInitSegment, validateC2paSegment } from '@svta/cml-c2pa'

    async function validateVsiSegment(initUrl: string, segmentUrl: string): Promise<void> {
    const initResponse = await fetch(initUrl)
    const init = await validateC2paInitSegment(new Uint8Array(await initResponse.arrayBuffer()))

    const segmentResponse = await fetch(segmentUrl)
    const segmentBytes = new Uint8Array(await segmentResponse.arrayBuffer())
    const validated = await validateC2paSegment(segmentBytes, init.sessionKeys)
    console.log(validated?.result.isValid)
    }
    import { validateC2paInitSegment, validateC2paMerkleSegment } from '@svta/cml-c2pa'

    async function validateMerkleSegment(initUrl: string, segmentUrl: string): Promise<void> {
    const initResponse = await fetch(initUrl)
    const init = await validateC2paInitSegment(new Uint8Array(await initResponse.arrayBuffer()))

    const segmentResponse = await fetch(segmentUrl)
    const segmentBytes = new Uint8Array(await segmentResponse.arrayBuffer())
    const { result } = await validateC2paMerkleSegment(segmentBytes, init.merkleMaps)
    console.log(result.isValid, result.errorCodes)
    }

    Documents

    Manifest Box Validation
    VOD Merkle Validation
    Results and Error Codes
    VSI/EMSG Validation

    Enumerations

    C2paStatusCode
    LiveVideoStatusCode
    SequenceValidationReason

    Type Aliases

    BmffHashConstraint
    BmffHashExclusion
    C2paAssertion
    C2paManifest
    C2paSignatureInfo
    CoseKeyJwk
    InitSegmentValidation
    ManifestBoxContinuityValidator
    ManifestBoxValidationOptions
    ManifestBoxValidationResult
    ManifestBoxValidationState
    MerkleMap
    MerkleSegmentState
    MerkleSegmentValidation
    SegmentValidationResult
    SequenceState
    SequenceValidationResult
    ValidatedSessionKey

    Functions

    validateC2paInitSegment
    validateC2paManifestBoxSegment
    validateC2paMerkleSegment
    validateC2paSegment