Add support for reading/writing non-square pixel video frames (fixes #309)

This commit is contained in:
Vanilagy
2026-02-25 17:16:33 +01:00
parent a7dc2c198b
commit bb4749cd8d
25 changed files with 744 additions and 69 deletions
+2 -2
View File
@@ -350,7 +350,7 @@ type CanvasSinkOptions = {
- `rotation`\
The clockwise rotation by which to rotate the raw video frame. Defaults to the rotation set in the file metadata. Rotation is applied before cropping and resizing.
- `crop`\
Specifies the rectangular region of the input video to crop to. The crop region will automatically be clamped to the dimensions of the input video track. Cropping is performed after rotation but before resizing.
Specifies the rectangular region of the input video to crop to. The crop region will automatically be clamped to the dimensions of the input video track. Cropping is performed after rotation but before resizing. The crop region is in the _display pixel space_ of the underlying video data.
- `poolSize`\
See [Canvas pool](#canvas-pool).
@@ -374,7 +374,7 @@ new CanvasSink(videoTrack, {
fit: 'cover',
});
// This sink yields canvases with the unaltered coded dimensions of the track,
// This sink yields canvases with the unrotated dimensions of the track,
// and without applying any rotation.
new CanvasSink(videoTrack, {
rotation: 0,
+9
View File
@@ -281,6 +281,10 @@ videoSample.format; // => VideoPixelFormat | null
videoSample.codedWidth; // => number
videoSample.codedHeight; // => number
// Pixel aspect ratio-corrected dimensions of the sample
videoSample.squarePixelWidth;
videoSample.squarePixelHeight;
// Transformed display dimensions of the sample (after rotation)
videoSample.displayWidth; // => number
videoSample.displayHeight; // => number
@@ -289,6 +293,9 @@ videoSample.displayHeight; // => number
// rotated by this amount when it is presented.
videoSample.rotation; // => 0 | 90 | 180 | 270
// The sample's pixel aspect ratio
videoSample.pixelAspectRatio; // => { num: number, den: number }
// Timing information
videoSample.timestamp; // => Presentation timestamp in seconds
videoSample.duration; // => Duration in seconds
@@ -297,6 +304,8 @@ videoSample.microsecondDuration; // => Duration in microseconds
// Color space of the sample
videoSample.colorSpace; // => VideoColorSpace
videoSample.visibleRect; // Rectangle
```
While all of these properties are read-only, you can use the `setTimestamp`, `setDuration` and `setRotation` methods to modify some of the metadata of the video sample.
+11 -2
View File
@@ -216,17 +216,26 @@ This will only look at the first ~50 packets and then return the result. This is
In addition to the [common track metadata](#common-track-metadata), video tracks have additional metadata you can query:
```ts
// Get the raw pixel dimensions of the track's coded samples, before rotation:
// Get the raw pixel dimensions of the track's coded samples:
videoTrack.codedWidth; // => number
videoTrack.codedHeight; // => number
// Get the displayed pixel dimensions of the track's samples, after rotation:
// Get the pixel dimensions of the track after aspect ratio adjustments,
// but before rotation:
videoTrack.squarePixelWidth; // => number
videoTrack.squarePixelHeight; // => number
// Get the displayed pixel dimensions of the track's samples, after
// aspect ratio adjustments and rotation:
videoTrack.displayWidth; // => number
videoTrack.displayHeight; // => number
// Get the clockwise rotation in degrees by which the
// track's frames should be rotated:
videoTrack.rotation; // => 0 | 90 | 180 | 270
// Get the aspect ratio of the track's pixels (usually 1:1):
videoTrack.pixelAspectRatio; // => { num: number, den: number }
```
To compute a video track's average frame rate (FPS), use [`computePacketStats`](#packet-statistics):