Skip to content

Multimedia: rendition, media clip, and screen parameters

The Multimedia module models a Portable Document Format (PDF) rendition and its media parameters as immutable value objects. Each object validates its ISO 32000-2 invariants in the constructor, then serializes itself to the matching PDF dictionary. The Navigation module’s rendition action references that dictionary.

Terminal window
composer require nextpdf/core:^3

A PDF rendition describes playable media, such as audio, video, or an interactive clip, and the conditions under which a viewer plays it. ISO 32000-2 §13.2 defines the rendition and media-object model. This module is the typed, validating encoder for that model. Every class is a final readonly value object: it accepts entries in the constructor, enforces the spec’s structural rules there, and emits a PDF dictionary string from toDictionary(). It does not play media and does not embed file data. It produces the dictionary the Writer serializes.

Rendition is the root. A Media Rendition (/MR) carries a MediaClip and optional play and screen parameters. A Selector Rendition (/SR) carries an ordered list of fallback rendition references. The constructor enforces the spec’s mutual exclusions: a /MR requires a clip and rejects selector references, and an /SR rejects clip, play, and screen entries. As a result, an invalid rendition cannot be constructed.

MediaClip represents the media data or a section of it. The section subtype lets a rendition play a subrange without copying the data. MediaPlayInfo and MediaScreenInfo carry the play parameters (/P) and screen presentation (/SP). Both expose isEmpty() so you can omit the entry when the specification recommends omission instead of an empty dictionary. MediaCriteria carries the must-honour (/MH) and best-effort (/BE) requirement sets, with an extras escape hatch for entries the typed surface does not model. The whole module is @since 2.3.0.

ClassKey membersRole
Rendition__construct(...), toDictionary(), SUBTYPE_MEDIA, SUBTYPE_SELECTOR/MR or /SR rendition object (@since 2.3.0)
MediaClip__construct(...), toDictionary(), SUBTYPE_DATA, SUBTYPE_SECTIONMedia clip data / section object (@since 2.3.0)
MediaPlayInfotoDictionary(), isEmpty()/P play parameters (@since 2.3.0)
MediaScreenInfotoDictionary(), isEmpty()/SP screen parameters (@since 2.3.0)
MediaCriteriatoDictionary(), isEmpty()/MH and /BE requirement sets (@since 2.3.0)

Run composer docs:generate-api-php -- --module=Multimedia to generate the full PHPDoc table.

Build a media rendition for an embedded video clip.

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Multimedia\MediaClip;
use NextPDF\Multimedia\Rendition;
$clip = new MediaClip(
subtype: MediaClip::SUBTYPE_DATA,
dataRef: 42, // indirect object number of the embedded file specification
);
$rendition = new Rendition(
subtype: Rendition::SUBTYPE_MEDIA,
name: 'Intro Video',
clip: $clip,
);
$dictionary = $rendition->toDictionary();

Build a selector rendition that follows an ordered fallback chain and splits the must-honour and best-effort criteria explicitly.

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Multimedia\MediaCriteria;
use NextPDF\Multimedia\Rendition;
// Preferred rendition first, degraded fallback second.
$selector = new Rendition(
subtype: Rendition::SUBTYPE_SELECTOR,
name: 'Adaptive Media',
mustHonour: new MediaCriteria(/* strict /MH requirements */),
bestEffort: new MediaCriteria(/* soft /BE requirements */),
selectorRefs: [51, 52], // indirect rendition object numbers, in evaluation order
);
$dictionary = $selector->toDictionary();
  • A /MR rendition without a MediaClip throws an exception in the constructor. This is a spec rule, not a runtime warning. Construct it with the clip.
  • A /SR rendition rejects clip, play, and screen entries. Mixing the two rendition shapes is a programming error, caught at construction.
  • Use MediaPlayInfo::isEmpty() and MediaScreenInfo::isEmpty() to omit an empty /P or /SP. Emitting an empty dictionary where the spec recommends omission is structurally valid but wasteful; check isEmpty().
  • A rendition /N name must not contain a NUL byte. The constructor rejects it.
  • selectorRefs are indirect object numbers, each >= 1. The module emits the references; resolving them to live objects is the Writer’s job.

Each toDictionary() call builds a string linearly from a fixed set of entries. It runs at microsecond scale and performs no input/output (I/O). The reproducibility profile is bitwise: the same value object always emits the same dictionary bytes. The default reference workload stays well inside the 1500 ms wall / 64 MB peak budget. Multimedia dictionaries are small relative to the embedded media they reference.

This module emits dictionary structure; it does not embed or transmit media data. The Navigation file-attachment surface produces the embedded file specification that a MediaClip references, and it bounds and validates the embedded bytes. Treat any media filename or rendition name from user input as untrusted text. The constructor rejects NUL bytes but does not vet the semantic content of a valid string. See the engine threat model in /modules/core/security/.

The dictionaries this module emits follow the rendition and media-object model in ISO 32000-2 §13.2, including the media-clip data and section entries. The per-table entry mappings are documented inline in src/Multimedia/ against the §13.2 table numbers and covered by tests/Unit/Multimedia/ (RenditionTest, MediaClipTest, MediaCriteriaTest, MediaPlayInfoTest, MediaScreenInfoTest). These are implementation facts, not a statement of end-to-end PDF 2.0 conformance; the oracle and golden suites described in /modules/core/conformance/ validate full-document conformance.