From 1c6c8c5217ae67abcf339911ecd80a871095eacc Mon Sep 17 00:00:00 2001 From: Vanilagy <1696106+Vanilagy@users.noreply.github.com> Date: Wed, 13 May 2026 20:03:46 +0200 Subject: [PATCH] Add missing stuff in docs --- docs/guide/packets-and-samples.md | 62 +++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/docs/guide/packets-and-samples.md b/docs/guide/packets-and-samples.md index 167218d..77c09b7 100644 --- a/docs/guide/packets-and-samples.md +++ b/docs/guide/packets-and-samples.md @@ -274,6 +274,26 @@ const sample = new VideoSample(buffer, { See [`VideoPixelFormat`](https://w3c.github.io/webcodecs/#enumdef-videopixelformat) for a list of pixel formats supported by WebCodecs. +#### Custom resource constructor + +For advanced use cases (custom decoders, GPU-backed frames, etc.), you can back a `VideoSample` with your own implementation of [`VideoSampleResource`](../api/VideoSampleResource): + +```ts +import { VideoSample, VideoSampleResource } from 'mediabunny'; + +class MyResource extends VideoSampleResource { + // Implement getFormat(), getCodedWidth(), getCodedHeight(), + // getSquarePixelWidth(), getSquarePixelHeight(), getColorSpace(), + // getDataPlanes(), toRgbSample(), and close(). +} + +const sample = new VideoSample(new MyResource(), { + timestamp: 0, +}); +``` + +This allows you to back a `VideoSample` with your own data without having to copy it. + ### Inspecting video samples A `VideoSample` has several read-only properties: @@ -402,6 +422,31 @@ You can pass additional options to `allocationSize` and `copyTo` to extract data --- +You can transform a `VideoSample` to resize, rotate, and/or crop it, producing a new `VideoSample`: +```ts +const transformed = await videoSample.transform({ + width: 640, + height: 360, + fit: 'cover', + rotate: 90, + crop: { left: 0, top: 0, width: 1920, height: 1000 }, + alpha: 'discard', +}); +``` + +In browser environments, the transform is performed using a canvas. In non-browser environments without `OffscreenCanvas` or `HTMLCanvasElement`, this method throws unless you register a custom transformer: +```ts +import { registerVideoSampleTransformer } from 'mediabunny'; + +registerVideoSampleTransformer((sample, description) => { + // Return a transformed VideoSample, or null to defer to the next transformer. +}); +``` + +The [`@mediabunny/server`](./extensions/server) extension registers such a transformer. + +--- + You can also clone a `VideoSample`: ```ts const clonedSample = videoSample.clone(); // => VideoSample @@ -463,6 +508,23 @@ Planar formats store each channel's data contiguously, while interleaved formats ![Planar vs. interleaved formats](../assets/planar_interleaved.svg) +#### Custom resource constructor + +For advanced use cases (custom decoders, etc.), you can back an `AudioSample` with your own implementation of [`AudioSampleResource`](../api/AudioSampleResource): + +```ts +import { AudioSample, AudioSampleResource } from 'mediabunny'; + +class MyResource extends AudioSampleResource { + // Implement getFormat(), getSampleRate(), getNumberOfFrames(), + // getNumberOfChannels(), getTimestamp(), getDataPlane(), and close(). +} + +const sample = new AudioSample(new MyResource()); +``` + +This allows you to back an `AudioSample` with your own data without having to copy it. + ### Inspecting audio samples An `AudioSample` has several read-only properties: