import type { Size } from '../common-types/Size'; import type { VideoCodec } from '../common-types/VideoCodec'; import type { Location } from '../location/Location.nitro'; import type { CameraOutput } from './CameraOutput.nitro'; import type { Recorder } from './Recorder.nitro'; /** * Configuration options for a {@linkcode CameraVideoOutput}. * * @see {@linkcode CameraVideoOutput} * @see {@linkcode useVideoOutput | useVideoOutput(...)} */ export interface VideoOutputOptions { /** * The target Video Resolution to use. * * @discussion * The {@linkcode CameraSession} will negotiate all * output {@linkcode targetResolution}s and constraints (such * as HDR, FPS, etc) in a {@linkcode CameraSessionConfig} to * finalize the Resolution used for the Output. * This is therefore merely a resolution _target_, and may * not be exactly met. * * If the given {@linkcode targetResolution} cannot be met * exactly, its aspect ratio (computed by * {@linkcode Size.width} / {@linkcode Size.height}) will * be prioritized over pixel count. */ targetResolution: Size; /** * Whether to enable, or disable audio in video * recordings. * By default, no audio is recorded. * * This requires audio/microphone permission. * * @default false */ enableAudio?: boolean; /** * If set to `true`, the {@linkcode CameraVideoOutput} * will be persistent. * * A persistent {@linkcode CameraVideoOutput} can continue * to record even while switching Cameras. * * This may require additional processing power, * or choose a different (non-fully-native) path * for recording, so it is disabled by default. * * - On iOS, enabling {@linkcode enablePersistentRecorder} * will use a custom [`AVCaptureVideoDataOutput`](https://developer.apple.com/documentation/avfoundation/avcapturevideodataoutput) + * `AVAssetWriter` pipeline instead of the fully internal [`AVCaptureMovieFileOutput`](https://developer.apple.com/documentation/avfoundation/avcapturemoviefileoutput). * - On Android, enabling {@linkcode enablePersistentRecorder} * will use [`asPersistentRecording()`](https://developer.android.com/reference/androidx/camera/video/PendingRecording#asPersistentRecording()). * * @default false */ enablePersistentRecorder?: boolean; /** * If set to `true`, the {@linkcode CameraVideoOutput} * supports using higher resolution (and potentially * also higher bit-rate and higher frame rate) media codecs * to encode video frames to the video container. * * On Android, this binds to [`VIDEO_CAPABILITIES_SOURCE_CAMCORDER_PROFILE`](https://developer.android.com/reference/kotlin/androidx/camera/video/Recorder#VIDEO_CAPABILITIES_SOURCE_CAMCORDER_PROFILE()) * if `true`, and [`VIDEO_CAPABILITIES_SOURCE_CAMCORDER_PROFILE`](https://developer.android.com/reference/kotlin/androidx/camera/video/Recorder#VIDEO_CAPABILITIES_SOURCE_CAMCORDER_PROFILE()) * if set to `false`. * * In practice, enabling this allows using formats with higher * video resolutions, at the risk of higher power usage. * * As codecs are very device-specific, enabling this may cause * instability issues, so use this with caution. * * @platform Android * @default false */ enableHigherResolutionCodecs?: boolean; /** * Specifies the target bit-rate for the * {@linkcode CameraVideoOutput}, in bits per second. * * The encoder may or may not encode with exactly this bit-rate, * depending on system pressure, moving pixels, and file size * constraints - but it will be taken as reference. * * @default undefined */ targetBitRate?: number; /** * The container file type for recordings produced by this output. * * On Android this is always `.mp4` and this field is ignored. * * @platform iOS * @default 'mov' */ fileType?: RecorderFileType; } /** * Container file type for a {@linkcode CameraVideoOutput}'s recordings. */ export type RecorderFileType = 'mp4' | 'mov'; /** * Output settings for a {@linkcode CameraVideoOutput}. * * @see {@linkcode CameraVideoOutput} * @see {@linkcode CameraVideoOutput.setOutputSettings | CameraVideoOutput.setOutputSettings(...)} */ export interface VideoOutputSettings { /** * Configures the {@linkcode VideoCodec} to use for recording a video. * By default, it is `undefined`, and the most efficient codec will * be selected (likely {@linkcode VideoCodec | h265}) */ codec?: VideoCodec; } /** * Video Recorder settings for a {@linkcode Recorder} * created by a {@linkcode CameraVideoOutput}. * * @see {@linkcode CameraVideoOutput} * @see {@linkcode Recorder} * @see {@linkcode CameraVideoOutput.createRecorder | CameraVideoOutput.createRecorder(...)} */ export interface RecorderSettings { /** * Sets the given {@linkcode Location} to be embedded * into the video metadata using the ISO-6709 standard. */ location?: Location; /** * The absolute path (including file name and extension) where * the recording file should be written to, or `undefined` to * create a file in the device's temporary directory. * Pass a filesystem path, not a `file://` URL. * * All parent directories in this {@linkcode filePath} will * be automatically created if they do not yet exist. * * @default undefined */ filePath?: string; /** * If set, the recording automatically stops once it reaches * this duration, in seconds. * * When the limit is reached, the recording is finalized * successfully, and the `onRecordingFinished` callback * passed to {@linkcode Recorder.startRecording | startRecording(...)} * is invoked with the resulting file path — the same * behavior as calling {@linkcode Recorder.stopRecording | stopRecording()}. * * @default undefined */ maxDuration?: number; /** * If set, the recording automatically stops once the file * reaches this size, in bytes. * * When the limit is reached, the recording is finalized * successfully, and the `onRecordingFinished` callback * passed to {@linkcode Recorder.startRecording | startRecording(...)} * is invoked with the resulting file path — the same * behavior as calling {@linkcode Recorder.stopRecording | stopRecording()}. * * @default undefined */ maxFileSize?: number; } /** * A Video output allows recording videos (possibly with audio) * to a file. * * @see {@linkcode VideoOutputOptions} * @see {@linkcode Recorder} * @see {@linkcode useVideoOutput | useVideoOutput(...)} * @example * Creating a `CameraVideoOutput` via the Hooks API: * ```ts * const videoOutput = useVideoOutput() * ``` * * @example * Creating a `CameraVideoOutput` via the Imperative API: * ```ts * const videoOutput = VisionCamera.createVideoOutput({ * targetResolution: CommonResolutions.FHD_16_9, * }) * ``` */ export interface CameraVideoOutput extends CameraOutput { /** * Get all supported {@linkcode VideoCodec | VideoCodecs} this * {@linkcode CameraVideoOutput} currently can record in. * * This method must be called after the {@linkcode CameraVideoOutput} * has been attached to a Camera Session. * * @platform iOS * @throws This method throws if you call it before this output * is attached to a Camera Session (via `configure(...)`) */ getSupportedVideoCodecs(): VideoCodec[]; /** * Set the output settings for this video output. * This method must be called after the output has been * attached to the Camera Session, and before * {@linkcode createRecorder | createRecorder(...)}. * * @platform iOS */ setOutputSettings(settings: VideoOutputSettings): Promise; /** * Creates and prepares a new {@linkcode Recorder} * instance with the given {@linkcode RecorderSettings}. * * The {@linkcode Recorder} will record to the configured * file path, or to a temporary file if no path was provided. * The {@linkcode Recorder}'s file paths are filesystem paths, * not `file://` URLs. * It can only record once. * * If you want to create a second recording, * you must create a new {@linkcode Recorder}. */ createRecorder(settings: RecorderSettings): Promise; }