@capacitor-community/video-recorder
CAPACITOR 7
capacitor plugin to record video
Capacitor v7
npm install @capacitor-community/video-recorder
npx cap syncCapacitor v6
npm install @capacitor-community/video-recorder@6
npx cap syncCapacitor v5
npm install @capacitor-community/video-recorder@5
npx cap syncTo ensure the Android lib is downloadable when building the app, you can add the following to the repositories section of your project's build.gradle file:
repositories {
google()
mavenCentral()
maven {
url "https://jitpack.io"
}
}- iOS
- Android
On a web browser, we will fake the behavior to allow for easier development.
In order to initialize the camera feed (note: you are not recording at this point), you must first specify a config to the video recorder.
Note: To overlay your web UI on-top of the camera output, you must use stackPosition: back and make all layers of your app transparent so that the camera can be seen under the webview.
There are 2 changes needed to make the webview transparent on Android and iOS:
// in the scss file of your page
ion-content {
--background: transparent;
}// in the capacitor.config.ts
{
'backgroundColor: '#ff000000', // this is needed mainly on iOS
}Next in your app:
import { VideoRecorderCamera, VideoRecorderPreviewFrame } from '@capacitor-community/video-recorder';
const { VideoRecorder } = Plugins;
const config: VideoRecorderPreviewFrame = {
id: 'video-record',
stackPosition: 'back', // 'front' overlays your app', 'back' places behind your app.
width: 'fill',
height: 'fill',
x: 0,
y: 0,
borderRadius: 0
};
await VideoRecorder.initialize({
camera: VideoRecorderCamera.FRONT, // Can use BACK
previewFrames: [config]
});Starts recording against the capture device.
VideoRecorder.startRecording();Stops the capture device and returns the path of the local video file.
const res = await VideoRecorder.stopRecording();
// The video url is the local file path location of the video output.
return res.videoUrl;Used to disconnect from the capture device and remove any native UI layers that exist.
VideoRecorder.destroy();The demo app can be found in the Example folder of this repo
initialize(...)destroy()flipCamera()toggleFlash()enableFlash()disableFlash()isFlashAvailable()isFlashEnabled()addPreviewFrameConfig(...)editPreviewFrameConfig(...)switchToPreviewFrame(...)showPreviewFrame(...)hidePreviewFrame()startRecording()stopRecording()getDuration()addListener('onVolumeInput', ...)addListener('audioStatusChanged', ...)addListener('recordingStopped', ...)- Interfaces
- Type Aliases
- Enums
initialize(options?: VideoRecorderOptions | undefined) => Promise<{ hasAudio: boolean; }>| Param | Type |
|---|---|
options |
VideoRecorderOptions |
Returns: Promise<{ hasAudio: boolean; }>
destroy() => Promise<void>flipCamera() => Promise<void>toggleFlash() => Promise<void>enableFlash() => Promise<void>disableFlash() => Promise<void>isFlashAvailable() => Promise<{ isAvailable: boolean; }>Returns: Promise<{ isAvailable: boolean; }>
isFlashEnabled() => Promise<{ isEnabled: boolean; }>Returns: Promise<{ isEnabled: boolean; }>
addPreviewFrameConfig(config: VideoRecorderPreviewFrame) => Promise<void>| Param | Type |
|---|---|
config |
VideoRecorderPreviewFrame |
editPreviewFrameConfig(config: VideoRecorderPreviewFrame) => Promise<void>| Param | Type |
|---|---|
config |
VideoRecorderPreviewFrame |
switchToPreviewFrame(options: { id: string; }) => Promise<void>| Param | Type |
|---|---|
options |
{ id: string; } |
showPreviewFrame(config: { position: number; quality: number; }) => Promise<void>| Param | Type |
|---|---|
config |
{ position: number; quality: number; } |
hidePreviewFrame() => Promise<void>startRecording() => Promise<void>stopRecording() => Promise<{ videoUrl: string; }>Returns: Promise<{ videoUrl: string; }>
getDuration() => Promise<{ value: number; }>Returns: Promise<{ value: number; }>
addListener(eventName: 'onVolumeInput', listenerFunc: (event: { value: number; }) => void) => Promise<PluginListenerHandle>| Param | Type |
|---|---|
eventName |
'onVolumeInput' |
listenerFunc |
(event: { value: number; }) => void |
Returns: Promise<PluginListenerHandle>
addListener(eventName: 'audioStatusChanged', listenerFunc: (event: { hasAudio: boolean; reason: AudioStatusReason; }) => void) => Promise<PluginListenerHandle>| Param | Type |
|---|---|
eventName |
'audioStatusChanged' |
listenerFunc |
(event: { hasAudio: boolean; reason: AudioStatusReason; }) => void |
Returns: Promise<PluginListenerHandle>
addListener(eventName: 'recordingStopped', listenerFunc: (event: { videoUrl: string; reason: 'interrupted'; }) => void) => Promise<PluginListenerHandle>| Param | Type |
|---|---|
eventName |
'recordingStopped' |
listenerFunc |
(event: { videoUrl: string; reason: 'interrupted'; }) => void |
Returns: Promise<PluginListenerHandle>
| Prop | Type | Description | Default |
|---|---|---|---|
camera |
VideoRecorderCamera |
||
quality |
VideoRecorderQuality |
||
autoShow |
boolean |
||
previewFrames |
VideoRecorderPreviewFrame[] |
||
videoBitrate |
number |
The default bitrate is 4.5Mbps | 4500000 |
disableAudio |
boolean |
Skip audio recording entirely. When not set, the plugin auto-detects active phone calls and disables audio automatically. iOS: Audio input is fully skipped — recorded video has no audio track. Android: Informational only. Audio recording is managed by the underlying FancyCamera library which does not expose an audio toggle. The hasAudio return value and audioStatusChanged events reflect the detected state, but the actual audio track in the recorded video is controlled by FancyCamera/Android OS. |
false |
| Prop | Type | Description | Default |
|---|---|---|---|
id |
string |
||
stackPosition |
'front' | 'back' |
||
x |
number |
||
y |
number |
||
width |
number | 'fill' |
||
height |
number | 'fill' |
||
borderRadius |
number |
||
dropShadow |
{ opacity?: number; radius?: number; color?: string; } |
||
mirrorFrontCam |
boolean |
Whether to mirror the front camera preview horizontally. Only applies to front camera. | true |
| Prop | Type |
|---|---|
remove |
() => Promise<void> |
'phoneCall' | 'userDisabled' | 'microphoneUnavailable' | 'audioSessionFailed' | 'interruptionRecoveryPending'
| Members | Value |
|---|---|
FRONT |
0 |
BACK |
1 |
| Members | Value |
|---|---|
MAX_480P |
0 |
MAX_720P |
1 |
MAX_1080P |
2 |
MAX_2160P |
3 |
HIGHEST |
4 |
LOWEST |
5 |
QVGA |
6 |
The Android code is using triniwiz/FancyCamera v1.2.4 (https://github.com/triniwiz/fancycamera)
The iOS code is implemented using AVFoundation
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!




