Skip to content
This repository was archived by the owner on Apr 9, 2025. It is now read-only.

Update - #1

Open
emilienbidet wants to merge 337 commits into
dashdoc:mainfrom
mrousavy:main
Open

Update#1
emilienbidet wants to merge 337 commits into
dashdoc:mainfrom
mrousavy:main

Conversation

@emilienbidet

Copy link
Copy Markdown

What

Changes

Tested on

Related issues

mrousavy and others added 30 commits April 21, 2026 13:01
…rename (#3757)

The rename in #3754 (Orientation to CameraOrientation) also replaced
references to UIKit's nested UIImage.Orientation enum, which caused
iOS builds to fail with:

    'CameraOrientation' is not a member type of class 'UIKit.UIImage'

UIImage is an Apple UIKit class and its nested enum is literally named
Orientation, so the references must remain UIImage.Orientation.
UIImageOrientation+exif.swift already uses the correct name, which is
how the partial rename was spotted.

Affected (8 occurrences across 7 files):
- packages/react-native-vision-camera/ios/Extensions/Converters/UI+CameraOrientation.swift (x3)
- packages/react-native-vision-camera/ios/Extensions/AVFoundation/AVCapturePhoto+getMediaSampleMetadata.swift
- packages/react-native-vision-camera/ios/Extensions/AVFoundation/AVDepthData+toUIImage.swift
- packages/react-native-vision-camera/ios/Extensions/CoreMedia/CMSampleBuffer+toUIImage.swift
- packages/react-native-vision-camera/ios/Extensions/CIImage+toUIImage.swift
- packages/react-native-vision-camera/ios/Public/MediaSampleMetadata.swift
- packages/react-native-vision-camera-barcode-scanner/ios/Extensions/UI+CameraOrientation.swift
* docs: Add JSON+LD data

* Use Organization as publisher

* link to margelo too
The `postinstall: "tsc || exit 0;"` script in
packages/react-native-vision-camera/package.json runs `tsc` on every
consumer install. When `tsc` is on the consumer's PATH (commonly the
case on Linux CI runners and Windows dev machines), the unprovisioned
`tsc` walks up the consumer's tree to find a tsconfig.json, then
emits compiled .js files next to every .ts source it can reach. The
`|| exit 0` swallows the error so install "succeeds", leaving stray
files behind in the consumer's project. On macOS dev machines `tsc`
usually isn't on the postinstall PATH, so the bug is invisible there.

This re-applies the fix from #3275, which addressed the same symptom
for v4.6.x but was lost in the 5.x rewrite. The package ships a
pre-built `lib/` (per the `files` field and `main: "lib/index"`), so
consumers never need to compile anything on install. The existing
`build: "tsc"` script remains for explicit invocation by maintainers
and release tooling.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: Array.reduce doesnt have initial value

* move to safer version
* chore: Create issue templates

* build error

* version

* update

* screenshot

* Update bug.yml

* make checkboxes required

* remove discussions
* feat(recorder): allow configuring MP4 or MOV output via `RecorderSettings.fileType`

iOS's `HybridVideoRecorder` has historically hardcoded
`AVFileType.quickTimeMovie`, forcing `.mov` output even when the consumer
(server, CDN, video pipeline) expects MP4. V4 exposed an explicit
`fileType: 'mp4' | 'mov'` on `startRecording`; v5 removed it and left
the persistent recorder with a `// TODO: Allow configuring this` next to
the hardcoded `AVFileType.mov`.

This commit adds an optional `fileType: 'mp4' | 'mov'` to `RecorderSettings`,
honored by the default (non-persistent) recorder:

- `src/specs/outputs/CameraVideoOutput.nitro.ts` — new `RecorderFileType`
  union and `RecorderSettings.fileType` field. Default unchanged (`mov` on
  iOS) so this is additive and backward-compatible.
- `ios/.../Recording/HybridVideoRecorder.swift` — accepts the file type in
  its initializer, stores it on the instance, and forwards it to
  `URL.createTempURL(fileType:)`.
- `ios/.../Outputs/HybridCameraVideoOutput.swift#createRecorder(settings:)`
  — maps `settings.fileType` to the matching `AVFileType` and passes it to
  the recorder. `nil` preserves the current `.quickTimeMovie` default.
- `ios/.../Outputs/HybridCameraVideoFrameOutput.swift#createRecorder(settings:)`
  — the persistent recorder path binds `fileType` at the output level
  (used for codec negotiation and track setup), so passing
  `settings.fileType` here now throws a clear error instead of silently
  ignoring it. Making the persistent recorder fully configurable can be a
  follow-up.
- Android's `HybridVideoOutput.kt#createRecorder` already writes `.mp4`
  unconditionally (CameraX's `Recorder` has no QuickTime output). The new
  JSDoc documents this as an iOS-only knob.
- `docs/content/docs/recorder.mdx` — documents the new option under the
  Recorder guide.
- Regenerated nitrogen bindings (`bun camera specs`).

* refactor(recorder): move `fileType` to `VideoOutputOptions` so persistent + non-persistent share one code path

Addresses review feedback on #3774.

- Move `fileType` from `RecorderSettings` to `VideoOutputOptions`. The
  persistent recorder binds its container at the output level (codec
  negotiation via `availableVideoCodecTypesForAssetWriter(writingTo:)`,
  asset-writer track init, etc.), so a per-recorder setting couldn't be
  honored consistently on that path. Putting it on the output makes both
  paths honor the same field with zero branching.
- iOS `HybridCameraVideoOutput`: store `fileType: AVFileType` derived from
  `options.fileType?.toAVFileType() ?? .quickTimeMovie`, pass it to
  `HybridVideoRecorder` in `createRecorder`.
- iOS `HybridCameraVideoFrameOutput` (persistent path): replace the
  hardcoded `AVFileType.mov` with the option-derived `fileType`; drop the
  previous throw that rejected `settings.fileType`.
- iOS `HybridVideoRecorder`: drop the stored `fileType` property — the
  init parameter is only used to build the temp URL and isn't referenced
  afterwards.
- Add `AV+RecorderFileType.swift` with a `toAVFileType()` extension so
  both call sites use the clean `options.fileType?.toAVFileType() ?? .quickTimeMovie`
  form instead of a switch.
- `useVideoOutput.ts` forwards the new option.
- Updated the recorder guide to show `useVideoOutput({ fileType: 'mp4' })`
  instead of the old per-recorder form.
- Regenerated nitrogen bindings (`bun camera specs`).

Also tightened the JSDoc on `VideoOutputOptions.fileType` and the type
alias to match the surrounding style (one-liner description,
`@platform iOS`, `@default 'mov'`).

* docs(recorder): fix VideoOutputOptions link to /interfaces/ path
* feat: Add `onSubjectAreaChanged` listener

* impl

* Rename `addSubjectAreaChangedListener`

* Update SubjectAreaMonitor.swift

* Update HybridCameraController.kt

* simplify :)

* use it!

* Log it

* fix: Make `useListenerSubscription` stable

* Add docs for subject area changed

* Update CameraController.nitro.ts

* Update useCamera.ts

* lint
* docs: Add more docs for `CameraProps`

* Update useCamera.ts
* docs: Add more API documentation

* flow state

* fix broken links

* docs: Make `UseDepthOutputProps` and `UseObjectOutputProps` public

* fix: Fix hallucinated API code examples

* fix imported types

* import

* fix: Avoid re-exported index.ts imports - import directly from source

* add biome rule for that

* format

* fix typos

* add more examples, improve docs

* Update CameraPhotoOutput.nitro.ts

* more docs

* add hooks
hannojg and others added 30 commits July 17, 2026 14:50
* fix: Fix `getSupportedResolutions('video')` crashing on some Android phones

* Actually nvm use Camera2 sizes again.
…#4077)

* fix: Fix `getSupportedResolutions('photo')` throwing on some Androids

* fix: More things can be nullable apparently
Adds a third ScaleMode to the resizer: 'stretch' fills the whole output by
stretching the input independently on each axis - no bars, no cropping,
aspect ratio NOT preserved.

Motivation: ML models with fixed square inputs (e.g. 640x640 detectors) are
usually trained on stretched-to-square images. 'cover' crops away detector
targets near the frame edges and 'contain' wastes ~44% of a square input on
black bars when fed 16:9 frames - 'stretch' matches the training-time
preprocessing exactly and uses every input pixel.

- Vulkan (Android) + Metal (iOS) compute kernels: ordinal 2u maps the entire
  source [0,1]^2 to the entire output [0,1]^2 per-axis; cover/contain paths
  are unchanged (refactored into per-case blocks since stretch has no
  scale factor or centering offset)
- ScaleMode TS union + docs
- nitrogen-generated ScaleMode.swift / ScaleMode.hpp updated to match
  (same output 'nitrogen' produces for the updated spec)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* chore: Test `'locked'` focus(..)

* Simpler
* feat: add targetResolution prop to skia camera

* fix: lint
* feat: Add `zoom`, `exposure` and `torchMode` to `<SkiaCamera>`

* Update useCamera.ts

* feat: Add `canvas` to `<SkiaCamera>`

* Add to docs
#4081)

* fix: Fix uncatchable NSException crash in `setOutputSettings()` on iOS

`AVCaptureMovieFileOutput.outputSettings(for:)` returns a fully-resolved
dictionary that also contains `AVVideoWidthKey`/`AVVideoHeightKey`, but
`supportedOutputSettingsKeys(for:)` may only allow `AVVideoCodecKey` and
`AVVideoCompressionPropertiesKey`. Passing the resolved dictionary back into
`setOutputSettings(_:for:)` then throws an `NSInvalidArgumentException`,
which Swift cannot catch - crashing the app on the video queue for any
`setOutputSettings()` call (even with an empty settings object).

Instead, only pass the keys we actually want to change (codec + average
bit-rate, same approach as `setBitRate`) and let AVFoundation fill in the
rest. Also guard against inactive connections and unsupported codecs by
throwing a catchable RuntimeError instead of crashing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: guard unsupported video compression settings

* refactor: remove redundant connection activity guard

* refactor: simplify video output settings

* test: cover video output settings on iOS

---------

Co-authored-by: yuyuan <yuyuan@winnerpoints.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Marc Rousavy <me@mrousavy.com>
* feat: Add `allowHapticsAndSystemSoundsPlayback`

* Generate specs

* feat: Implement `allowHapticsAndSystemSoundsPlayback` on iOS

* fix: `try`

* chore: Add Harness tests for both audio configuration props
* test: harden frame processing coverage

* fix: align barcode Frame scanning with ML Kit

* remove doc

* test: remove Frame Converter coverage

* refactor: simplify synchronous barcode scanning

* test: keep Resizer coverage in Harness

* refactor: await barcode scans in coroutines

* test: simplify Resizer pixel rasterization

* test: keep focused barcode lifecycle coverage
…e_mutex` (#4112)

* fix: Update Nitro to 0.36.4 to fix ANR in Frame Output `std::recursive_mutex`

* chore: Podfile
… strip in View space on iOS (#4113)

test: Add Harness test for square Frame region -> square View region

The existing end-to-end coordinate test projects the frame center only, and
the center is a fixed point of an axis-scaling error: it maps to camera
(0.5, 0.5) under both a correct and an anisotropic matrix, so it lands on
the view center either way.

This test projects a region instead. A square in Frame space must stay
square in View space, since the sensor scale, the orientation
counter-rotation and the preview's aspect-preserving crop all preserve
aspect. Camera space is allowed to be anisotropic in between (iOS
normalizes per-axis to [0, 1]); converting out of it has to undo the same
per-axis scaling.

Expected to fail on iOS and pass on Android — see the PR description for
the measured numbers and the suspected cause in
FrameCoordinateSystemConverter.getFrameToCameraMatrix.

Co-authored-by: Florian Preusner <claude.ai@florian.preusner.de>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.