Concepts
The entry point for the recorder SDK is the io.video.videokit.recorder.Recorder
interface.
This interface provides functions to:
- start and stop the recording
- control the camera through
Recorder.camera
- configure the upload
- preview the recorded video
- build a responsive UI to show controls to the user.
The recorder will also forward all relevant events to subscribers that were registered with the
addListener*
functions. We recommend listening at least to the result and error event:
val recorder: Recorder = ...
recorder.addListener(lifecycle, object : RecorderListener {
override fun onResult(record: Record) {
// handle result!
}
override fun onError(error: VideoError) {
// handle error!
}
})
We provide different implementations that can be used within your app depending on your needs, but all of them share the same API surface described below. All of them will also automatically request the appropriate permissions: camera, microphone and, in some cases, storage.
Recorder interface
Note: if you use the default controls, the user will be able to control the recorder through the user interface, so there's no need to interact directly with these functions.
Recording
The recorder is able to record multiple clips together in a single file. This means that recording can be paused and resumed as many times as you want. To start recording:
recorder.start()
This will soon move the recorder.state
from RecorderState.IDLE
to RecorderState.RECORDING
.
To pause recording:
recorder.pause()
This will bring back recorder.state
to RecorderState.IDLE
. At this point, the video is not finalized,
and you have different options:
- resume recording, with
recorder.start()
- confirm the video, with
recorder.confirm()
- discard the video, with
recorder.reset()
- enter or exit preview mode
The recorder can go through multiple start()
/ pause()
calls and the new video will
just be appended to the existing content. You can also change camera sensor and settings in between.
Record and clips
As you record clips with start()
and pause()
, the recorder will expose information about
the recorded data with Record
and Clip
objects:
// After the first start / stop cycle, you will find a non-null Record
val record: Record? = recorder.record
// List of clips, each one representing a start / stop cycle
val clips: List<Clip> = recorder.clips
// Recorded duration in milliseconds, keeps growing
val duration: Long = recorder.duration
Removing the last clip
When multiple clips are recorded (through multiple start / pause cycles), we offer the option to seamlessly remove the last clip - as many modern apps do - without losing the previous segments.
recorder.removeLastClip()
If the recorder only has 1 clip, calling removeLastClip
has the same effect of canceling the video.
Canceling the recording
To discard the recorded data (assuming it was not confirmed yet), simply call reset()
. This will
move the recorder to its original state, with no pending record and zero clips:
recorder.reset()
Confirm the recording
To confirm the recorded data (be it 1 or multiple clips), simply call confirm()
. This tells
the recorder that you are not planning to write anything else to this file.
recorder.confirm()
After this call, you should soon receive a complete Record
in the onResult()
listener callback.
The record will contain several properties, most importantly an uri
pointing to the resulting file.
Writing each clip as a separate file
As said, each start()
/ pause()
cycle appends a new clip to the clips
list, and the final Record
will contain a video that is made of all the clips, merged together. On top of this, it is possible
to have a separate video file for each clip:
recorder.writeClips = true
When this option is enabled, the clips returned by Recorder.clips
(and, after confirmation, by Record.clips
)
will include a non-null uri that you can retreive with Clips.uri
. This media file only includes that video
segment. This is very useful if you want to process all clips later, for example pass them to our Editor SDK.
Duration limits
The recorder has an option to stop recording automatically after a certain duration has been
reached. This duration can be set through recorder.maxDuration
in milliseconds:
// Stop automatically after 15 seconds:
recorder.maxDuration = 15 * 1000L
Importing videos
You have the option to import videos from the gallery using the import*
functions.
// Opens the gallery picker to choose a video
recorder.import()
// Imports a specific video by Uri
recorder.import(uri)
In both cases, the recorder will enter preview mode to preview the video.
Configuring video parameters
You can configure both audio and video encoding parameters using the AudioOptions
and VideoOptions
class
and passing them to the recorder. Since the encoders available on-device might not support all configuration,
the recorder class accepts a list of options instead of a single value.
The recorder will try each option and, if not supported, try with the next one.
recorder.audioOptions = listOf(AudioOptions(
samplingFrequency = 44100,
channels = 1,
bitRate = 96000,
))
val mainVideoOptions = VideoOptions(
size = VideoSize(1280, 720),
frameRate = 30
)
val fallbackVideoOptions = VideoOptions(
size = VideoSize(720, 480),
frameRate = 24
)
recorder.videoOptions = listOf(mainVideoOptions, fallbackVideoOptions)