Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

159 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Capacitor Camera View Banner

Capacitor Camera View

A Capacitor plugin for embedding a live camera feed directly into your app.

npm version Build Status Capacitor Plugin License


πŸš€ Features

  • πŸ“Ή Embed a live camera feed directly into your app.
  • πŸ“Έ Capture photos or frames from the camera preview.
  • πŸŽ₯ Video recording with optional audio support.
  • πŸ” Barcode detection support.
  • πŸ“± Virtual device support for automatic lens selection based on zoom level and focus (iOS only).
  • πŸ”¦ Control zoom, flash and torch modes programmatically.
  • ⚑ High performance with optimized native implementations.
  • 🎯 Simple to use with a clean and intuitive API.
  • 🌐 Works seamlessly on iOS, Android, and Web.

πŸͺ§ Demo

Capacitor Camera View Demo

πŸ“¦ Installation

Install the plugin using npm:

npm install capacitor-camera-view
npx cap sync

Platform Configuration

iOS

Add the following keys to your app's Info.plist file:

<key>NSCameraUsageDescription</key>
<string>To capture photos and videos</string>

If you plan to use startRecording with enableAudio: true, also add:

<key>NSMicrophoneUsageDescription</key>
<string>To record audio with video</string>

Important

The NSMicrophoneUsageDescription key must be present in Info.plist before microphone permission is ever requested β€” even if the request happens automatically when starting a recording with audio. Omitting it will cause your app to crash at runtime.

Android

The CAMERA permission is added to your app's AndroidManifest.xml automatically by the plugin. If you plan to use startRecording with enableAudio: true, the RECORD_AUDIO permission is also declared automatically by the plugin. You can verify these in your merged manifest:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

Important

Declaring a permission in AndroidManifest.xml is required for the system to allow requesting it at runtime. The plugin handles this for you, but make sure you are not accidentally stripping the permission in your build configuration.

πŸ”’ Permissions

The plugin handles permissions for you automatically when a feature that requires them is used. However, you can also request permissions explicitly in advance.

Requesting permissions explicitly

By default, requestPermissions() only requests camera permission, preserving backward compatibility:

// Request camera permission only (default behavior)
const status = await CameraView.requestPermissions();
console.log(status.camera); // 'granted' | 'denied' | 'prompt'

To also request microphone permission (needed for video recording with audio), pass the permissions option:

// Request both camera and microphone permissions
const status = await CameraView.requestPermissions({
  permissions: ['camera', 'microphone'],
});
console.log(status.camera);     // 'granted' | 'denied' | 'prompt'
console.log(status.microphone); // 'granted' | 'denied' | 'prompt'

Automatic permission requests

You do not need to call requestPermissions() manually. The plugin will automatically request the required permissions when a feature is first used:

  • Camera permission is requested automatically when start() is called.
  • Microphone permission is requested automatically when startRecording({ enableAudio: true }) is called.

Regardless of whether you request permissions manually or rely on the automatic flow, the corresponding entries must be declared in your app's platform configuration (Info.plist on iOS, AndroidManifest.xml on Android) as described above.

Checking permission status

Use checkPermissions() to query the current permission state without triggering a system prompt:

const status = await CameraView.checkPermissions();
console.log(status.camera);     // 'granted' | 'denied' | 'prompt'
console.log(status.microphone); // 'granted' | 'denied' | 'prompt'

▢️ Basic Usage

import { CameraView } from 'capacitor-camera-view';

// Start the camera preview
const startCamera = async () => {
  try {
    await CameraView.start();
    console.log('Camera started');
    // Add the CSS class to make the WebView transparent
    document.body.classList.add('camera-running');
  } catch (e) {
    console.error('Error starting camera:', e);
  }
};

// Stop the camera preview
const stopCamera = async () => {
  try {
    document.body.classList.remove('camera-running');
    await CameraView.stop();
    console.log('Camera stopped');
  } catch (e) {
    console.error('Error stopping camera:', e);
  }
};

// Capture a photo
const capturePhoto = async () => {
  try {
    const result = await CameraView.capture();
    console.log('Photo captured:', result.photo); // Base64 encoded string
  } catch (e) {
    console.error('Error capturing photo:', e);
  }
};

⚠️ Make the WebView transparent when starting the camera view

To display the camera view through your app, you need to ensure that the WebView is made transparent. For Ionic applications, this can be done by adding the following styles to your global CSS file and applying the respective class to the body element as soon as you start the camera (see example app on how to do this in Angular):

body.camera-running {
  visibility: hidden;
  --background: transparent;
  --ion-background-color: transparent;
}

.camera-modal {
  visibility: visible;
}

πŸ“Έ Virtual Camera Support for iOS

On supported iPhone models (like the Pro series), this plugin can utilize the virtual triple camera. This feature combines the ultra-wide, wide, and telephoto cameras into a single virtual device. iOS will then automatically switch between the physical cameras based on factors like zoom level and lighting conditions, providing seamless transitions and optimal image quality across a wider zoom range. You can enable this by setting the useTripleCameraIfAvailable option to true when calling start().

Pros:

  • Smoother zooming experience across different focal lengths.
  • Automatic selection of the best lens for the current scene and zoom factor.

Cons:

  • Slightly higher resource usage compared to using a single physical camera (the camera view will take a little longer until initialized).
  • Only available on specific iPhone models with triple camera systems.

For more details on the underlying technology, refer to Apple's documentation on AVCaptureDevice.builtInTripleCamera.

Alternatively, you can specify the preferredCameraDeviceTypes option in the CameraSessionConfiguration to prioritize specific virtual cameras, such as the dual camera system. While this provides similar functionality, the useTripleCameraIfAvailable option offers the advantage of a smoother transition during camera initialization and lens switching (blurred overlay).

πŸ” Barcode Detection

This plugin supports real-time barcode detection directly from the live camera feed.

How it works:

Note

Web Support: The Barcode Detection API is not supported in all browsers (e.g., Windows browsers). For full browser compatibility, consider using a polyfill such as @undecaf/barcode-detector-polyfill or barcode-detector.

Enabling Barcode Detection: To enable this feature, set the enableBarcodeDetection option to true when calling the start() method:

await CameraView.start({ enableBarcodeDetection: true });

Listening for Barcodes: Once enabled, you can listen for the barcodeDetected event to receive data about scanned barcodes:

import { CameraView } from 'capacitor-camera-view';

CameraView.addListener('barcodeDetected', (data) => {
  console.log('Barcode detected:', data.value, data.type);
  // Handle the detected barcode data (e.g., display it, navigate)
});

See the BarcodeDetectionData interface for details on the event payload.

πŸŽ₯ Video Recording

This plugin supports recording video directly from the live camera feed.

How it works:

  • iOS: Uses AVCaptureMovieFileOutput on top of the existing AVCaptureSession. Output is saved as .mp4.
  • Android: Uses the CameraX VideoCapture use case via LifecycleCameraController. Output is saved as .mp4.
  • Web: Uses the browser MediaRecorder API on the existing MediaStream. Output is a .webm blob URL (MP4 is not broadly supported by browsers).

Basic usage:

import { CameraView } from 'capacitor-camera-view';

// Start recording (camera must already be running)
await CameraView.startRecording({ enableAudio: false });

// Stop recording and get the result
const result = await CameraView.stopRecording();
console.log('Video saved to:', result.webPath);

Playing back the recorded video:

<video [src]="videoPath" controls></video>

Recording with audio:

await CameraView.startRecording({ enableAudio: true });

Recording with explicit quality preset (native):

await CameraView.startRecording({
  enableAudio: true,
  videoQuality: 'fhd', // lowest | sd | hd | fhd | uhd | highest
});

Note

When enableAudio: true is used, the plugin automatically requests microphone permission from the user if it has not been granted yet. The permission declaration must still be present in your platform configuration β€” see the Permissions section for details.

See the VideoRecordingOptions and VideoRecordingResponse interfaces in the API section for the full set of options.

πŸ§ͺ Example App

To see the plugin in action, check out the example app in the example-app folder. The app demonstrates how to integrate and use the Capacitor Camera View plugin in an Ionic Angular project.

Semantic Release

This project uses semantic-release for automated versioning and changelog generation based on conventional commits.

Conventional Commits

Follow the Conventional Commits specification for your commit messages. Example:

feat(camera): add autofocus support
fix(android): resolve crash on startup
chore: update dependencies

Resources

API

Main plugin interface for Capacitor Camera View functionality.

start(...)

start(options?: CameraSessionConfiguration | undefined) => Promise<void>

Start the camera view with optional configuration.

Param Type Description
options CameraSessionConfiguration - Configuration options for the camera session

Since: 1.0.0


stop()

stop() => Promise<void>

Stop the camera view and release resources.

Since: 1.0.0


isRunning()

isRunning() => Promise<IsRunningResponse>

Check if the camera view is currently running.

Returns: Promise<IsRunningResponse>

Since: 1.0.0


capture(...)

capture<T extends CaptureOptions>(options: T) => Promise<CaptureResponse<T>>

Capture a photo using the current camera configuration.

Param Type Description
options T - Capture configuration options

Returns: Promise<CaptureResponse<T>>

Since: 1.0.0


captureSample(...)

captureSample<T extends CaptureOptions>(options: T) => Promise<CaptureResponse<T>>

Captures a frame from the current camera preview without using the full camera capture pipeline.

Unlike capture() which may trigger hardware-level photo capture on native platforms, this method quickly samples the current video stream. This is suitable computer vision or simple snapshots where high fidelity is not required.

On web this method does exactly the same as capture() as it only captures a frame from the video stream because unfortunately ImageCapture API is not yet well supported on the web.

Param Type Description
options T - Capture configuration options

Returns: Promise<CaptureResponse<T>>

Since: 1.0.0


startRecording(...)

startRecording(options?: VideoRecordingOptions | undefined) => Promise<void>

Start recording video from the current camera. Camera must be running. Throws if already recording.

Param Type Description
options VideoRecordingOptions - Optional recording configuration

Since: 2.3.0


stopRecording()

stopRecording() => Promise<VideoRecordingResponse>

Stop the current video recording and return the result. Throws if no recording is in progress.

Returns: Promise<VideoRecordingResponse>

Since: 2.3.0


flipCamera()

flipCamera() => Promise<void>

Switch between front and back camera.

Since: 1.0.0


getAvailableDevices()

getAvailableDevices() => Promise<GetAvailableDevicesResponse>

Get available camera devices for capturing photos.

Returns: Promise<GetAvailableDevicesResponse>

Since: 1.0.0


getZoom()

getZoom() => Promise<GetZoomResponse>

Get current zoom level information and available range.

Returns: Promise<GetZoomResponse>

Since: 1.0.0


setZoom(...)

setZoom(options: { level: number; ramp?: boolean; }) => Promise<void>

Set the camera zoom level.

Param Type Description
options { level: number; ramp?: boolean; } - Zoom configuration options

Since: 1.0.0


getFlashMode()

getFlashMode() => Promise<GetFlashModeResponse>

Get current flash mode setting.

Returns: Promise<GetFlashModeResponse>

Since: 1.0.0


getSupportedFlashModes()

getSupportedFlashModes() => Promise<GetSupportedFlashModesResponse>

Get supported flash modes for the current camera.

Returns: Promise<GetSupportedFlashModesResponse>

Since: 1.0.0


setFlashMode(...)

setFlashMode(options: { mode: FlashMode; }) => Promise<void>

Set the camera flash mode.

Param Type Description
options { mode: FlashMode; } - Flash mode configuration options

Since: 1.0.0


isTorchAvailable()

isTorchAvailable() => Promise<IsTorchAvailableResponse>

Check if the device supports torch (flashlight) functionality.

Returns: Promise<IsTorchAvailableResponse>

Since: 1.2.0


getTorchMode()

getTorchMode() => Promise<GetTorchModeResponse>

Get the current torch (flashlight) state.

Returns: Promise<GetTorchModeResponse>

Since: 1.2.0


setTorchMode(...)

setTorchMode(options: { enabled: boolean; level?: number; }) => Promise<void>

Set the torch (flashlight) mode and intensity.

Param Type Description
options { enabled: boolean; level?: number; } - Torch configuration options

Since: 1.2.0


checkPermissions()

checkPermissions() => Promise<PermissionStatus>

Check camera and microphone permission status without requesting permissions.

Returns: Promise<PermissionStatus>

Since: 1.0.0


requestPermissions(...)

requestPermissions(options?: { permissions?: CameraPermissionType[] | undefined; } | undefined) => Promise<PermissionStatus>

Request camera and/or microphone permissions from the user.

By default, only camera permission is requested. To also request microphone permission (needed for video recording with audio), pass { permissions: ['camera', 'microphone'] }.

Param Type Description
options { permissions?: CameraPermissionType[]; } - Optional object specifying which permissions to request

Returns: Promise<PermissionStatus>

Since: 1.0.0


addListener('barcodeDetected', ...)

addListener(eventName: 'barcodeDetected', listenerFunc: (data: BarcodeDetectionData) => void) => Promise<PluginListenerHandle>

Listen for barcode detection events. This event is emitted when a barcode is detected in the camera preview.

Param Type Description
eventName 'barcodeDetected' - The name of the event to listen for ('barcodeDetected')
listenerFunc (data: BarcodeDetectionData) => void - The callback function to execute when a barcode is detected

Returns: Promise<PluginListenerHandle>

Since: 1.0.0


removeAllListeners(...)

removeAllListeners(eventName?: string | undefined) => Promise<void>

Remove all listeners for this plugin.

Param Type Description
eventName string - Optional event name to remove listeners for

Since: 1.0.0


Interfaces

CameraSessionConfiguration

Configuration options for starting a camera session.

Prop Type Description Default Since
enableBarcodeDetection boolean Enables the barcode detection functionality false
barcodeTypes BarcodeType[] Specific barcode types to detect. If not provided, all supported types are detected. Specifying only the types you need can significantly improve performance and reduce battery consumption, especially on mobile devices. undefined - all supported types are detected 2.1.0
position CameraPosition Position of the camera to use 'back'
deviceId string Specific device ID of the camera to use If provided, takes precedence over position
useTripleCameraIfAvailable boolean Whether to use the triple camera if available (iPhone Pro models only) false
preferredCameraDeviceTypes CameraDeviceType[] Ordered list of preferred camera device types to use (iOS only). The system will attempt to use the first available camera type in the list. If position is also provided, the system will use the first available camera type that matches the position and is in the list. This will fallback to the default camera type if none of the preferred types are available. undefined - system will decide based on position/deviceId
zoomFactor number The initial zoom factor to use 1.0
containerElementId string Optional HTML ID of the container element where the camera view should be rendered. If not provided, the camera view will be appended to the document body. Web only.

IsRunningResponse

Response for checking if the camera view is running.

Prop Type Description
isRunning boolean Indicates if the camera view is currently active and running

CaptureOptions

Configuration options for capturing photos and samples.

Prop Type Description Default Since
quality number The JPEG quality of the captured photo/sample on a scale of 0-100 1.1.0
saveToFile boolean If true, saves to a temporary file and returns the web path instead of base64. The web path can be used to set the src attribute of an image for efficient loading and rendering. This reduces the data that needs to be transferred over the bridge, which can improve performance especially for high-resolution images. false 1.1.0

VideoRecordingOptions

Configuration options for video recording.

Prop Type Description Default Since
enableAudio boolean Whether to record audio with the video. Requires microphone permission. false 2.3.0
videoQuality VideoRecordingQuality Video recording quality preset. Native platforms only (iOS/Android). Ignored on web. 'highest' 2.3.0

VideoRecordingResponse

Response from stopping a video recording.

Prop Type Description Since
webPath string Web-accessible path to the recorded video file that can be used to set the src attribute of a video element for efficient loading and rendering. On web, this is a blob URL. On iOS/Android, this is a Capacitor bridge path served by the local web server. 2.3.0
path string The full, platform-specific file URL (file://...) to the recorded video, usable with the Filesystem API or Capacitor.convertFileSrc(). Native only (iOS/Android); undefined on web. 2.4.0

GetAvailableDevicesResponse

Response for getting available camera devices.

Prop Type Description
devices CameraDevice[] An array of available camera devices

CameraDevice

Represents a physical camera device on the device.

Prop Type Description
id string The unique identifier of the camera device
name string The human-readable name of the camera device
position CameraPosition The position of the camera device (front or back)
deviceType CameraDeviceType The type of the camera device (e.g., wide, ultra-wide, telephoto) - iOS only

GetZoomResponse

Response for getting zoom level information.

Prop Type Description
min number The minimum zoom level supported
max number The maximum zoom level supported
current number The current zoom level

GetFlashModeResponse

Response for getting the current flash mode.

Prop Type Description
flashMode FlashMode The current flash mode setting

GetSupportedFlashModesResponse

Response for getting supported flash modes.

Prop Type Description
flashModes FlashMode[] An array of flash modes supported by the current camera

IsTorchAvailableResponse

Response for checking torch availability.

Prop Type Description
available boolean Indicates if the device supports torch (flashlight) functionality

GetTorchModeResponse

Response for getting the current torch mode.

Prop Type Description
enabled boolean Indicates if the torch is currently enabled
level number The current torch intensity level (0.0 to 1.0, iOS only). Always 1.0 on Android when enabled

PermissionStatus

Response for the camera and microphone permission status.

Prop Type Description
camera PermissionState The state of the camera permission
microphone PermissionState The state of the microphone permission

PluginListenerHandle

Prop Type
remove () => Promise<void>

BarcodeDetectionData

Data for a detected barcode.

Prop Type Description Since
value string The decoded string value of the barcode
rawBytes number[] Raw bytes as they were encoded in the barcode. On Android, this is forwarded from ML Kit. On iOS, this is available for descriptor-backed formats such as QR, Aztec, PDF417, and Data Matrix. On web, this is not available because the Barcode Detection API only exposes the decoded string value. 2.2.0
displayValue string The display value of the barcode on Android. This is forwarded from ML Kit and may contain a formatted, human-readable representation that differs from the raw decoded value. iOS and web do not expose a separate display value, so this property is only emitted on Android.
type string The type/format of the barcode (e.g., 'qr', 'code128', etc.)
boundingRect BoundingRect The bounding rectangle of the barcode in the camera frame.

BoundingRect

Rectangle defining the boundary of the barcode in the camera frame. Coordinates are normalized between 0 and 1 relative to the camera frame.

Prop Type Description
x number X-coordinate of the top-left corner
y number Y-coordinate of the top-left corner
width number Width of the bounding rectangle (should match the actual width of the barcode)
height number Height of the bounding rectangle (should match the actual height of the barcode)

Type Aliases

BarcodeType

Supported barcode types for detection. Specifying only the barcode types you need can improve performance and reduce battery consumption.

'qr' | 'code128' | 'code39' | 'code39Mod43' | 'code93' | 'ean8' | 'ean13' | 'interleaved2of5' | 'itf14' | 'pdf417' | 'aztec' | 'dataMatrix' | 'upce'

CameraPosition

Position options for the camera.

  • 'front': Front-facing camera
  • 'back': Rear-facing camera

'front' | 'back'

CameraDeviceType

Available camera device types for iOS. Maps to AVCaptureDevice DeviceTypes in iOS.

'wideAngle' | 'ultraWide' | 'telephoto' | 'dual' | 'dualWide' | 'triple' | 'trueDepth'

CaptureResponse

Response for capturing a photo This will contain either a base64 encoded string or a web path to the captured photo, depending on the saveToFile option in the CaptureOptions.

T['saveToFile'] extends true ? { /** The web path to the captured photo that can be used to set the src attribute of an image for efficient loading and rendering (when saveToFile is true) / webPath: string; /* * The full, platform-specific file URL (file://...) to the captured photo, * usable with the Filesystem API or Capacitor.convertFileSrc(). * Native only (iOS/Android); undefined on web. * @since 2.4.0 / path?: string; } : { /* The base64 encoded string of the captured photo (when saveToFile is false or undefined) */ photo: string; }

VideoRecordingQuality

Video recording quality presets.

'lowest' | 'sd' | 'hd' | 'fhd' | 'uhd' | 'highest'

FlashMode

Flash mode options for the camera.

  • 'off': Flash disabled
  • 'on': Flash always on
  • 'auto': Flash automatically enabled in low-light conditions

'off' | 'on' | 'auto'

PermissionState

'prompt' | 'prompt-with-rationale' | 'granted' | 'denied'

CameraPermissionType

Permission types that can be requested.

  • 'camera': Camera access permission
  • 'microphone': Microphone access permission (needed for video recording with audio)

'camera' | 'microphone'

About

🎞️ A Capacitor plugin for embedding a live camera feed directly into your app.

Topics

Resources

Contributing

Stars

Watchers

Forks

Releases

Sponsor this project

Packages

Contributors

Languages