Basic recording
The short video SDK enables basic recording with various effects, such as background music, speed ramping, and face stickers.
Supported editions
Edition | Supported |
professional edition | Yes |
standard edition | Yes |
basic edition | Yes |
Related classes
Class | Description |
The core interface for recording. It includes key features such as starting a recording, setting up the preview, applying effects, and configuring callbacks. | |
A factory class for creating a recording instance. | |
A class for configuring recording parameters, such as video resolution, encoder type, and capture frame rate. | |
An interface that provides callbacks for recording events, such as completion, progress, and errors. | |
An interface that provides callbacks for camera data capture, including preview resolution selection, frame data capture, and camera startup failures. | |
An interface that provides callbacks for audio data in PCM format. | |
An interface for managing video clips. Use it to delete clips and set the recording duration. |
Workflow
Recording videos requires camera and microphone permissions.
Stage | Step | Description | Sample code |
Basic | 1 | Create and destroy the recording interface, and configure recording parameters. | |
2 | Set up callbacks. | ||
3 | Start and stop the preview. | ||
4 | Start, cancel, and stop recording a video clip. | ||
5 | Stop the recording and generate the output. | ||
Advanced | 6 | Optionally, configure camera controls such as camera type and flash mode, and clip management settings such as maximum and minimum recording durations and clip deletion. | |
7 | Optionally, apply effects such as retouching, filters, and background music. | ||
8 | Enable additional features such as photo capture or facial recognition. |
Initialization and parameter configuration
Initialize the recorder, create a recording instance using the AliyunIRecorder interface, and configure recording parameters. For details about the parameters used, see the API reference in the Related classes section.
Initialization
// Create a recording interface.
AliyunIRecorder recorder = AliyunRecorderCreator.getRecorderInstance(context);// The context parameter is the context of the current page.
// Destroy the recording interface.
// Call this method to destroy the interface when you no longer need it, such as before the app exits. Do not call it while the recorder is in use.
recorder.destroy();Configure recording parameters
// Set the quality of the recorded video.
recorder.setVideoQuality(quality);
// Set the bitrate of the recorded video.
recorder.setVideoBitrate(int bitrate);// Unit: Kbps.
// Set the output parameters for the recorded video.
recorder.setMediaInfo(mediaInfo);// For parameter details, see the MediaInfo API reference.
// Set the output path for the recorded video.
recorder.setOutputPath(string path);
// Set the GOP (Group of Pictures) size for the recorded video.
recorder.setGop(int gop);// Unit: frames.Callback settings
By setting up callbacks, you can receive timely updates on the progress and status of audio and video processing. For details about the parameters used, see the API reference in the Related classes section.
// Set the recording callback.
recorder.setRecordCallBack(RecordCallback callBack);
// Set the callback for video frame capture.
recorder.setOnFrameCallback(OnFrameCallBack callback);
// Set the callback for audio data capture.
recorder.setOnAudioCallback(OnAudioCallBack callback);Enable preview
To enable preview, you must set a SurfaceView container. Call startPreview in the onResume() method of your Activity or Fragment, and call stopPreview in onPause(). For details about the parameters used, see the API reference in the Related classes section.
// Set the preview view.
recorder.setDisplayView(SurfaceView displayView);
// Start the preview.
recorder.startPreview();
// Stop the preview.
// Call stopPreview in the onPause() method of your Activity or Fragment.
recorder.stopPreview();Start recording
During recording, you can stop, cancel, and restart multiple times. Stopping a recording generates a video clip, while canceling it discards the current video clip. For details about the parameters used, see the API reference in the Related classes section.
Start recording
// Start recording.
recorder.startRecording();Record a video clip
// Start recording.
recorder.startRecording();
// Stop recording to generate a video clip.
recorder.stopRecording();
recorder.startRecording();
// Cancel the recording. The current video clip will not be saved.
recorder.cancelRecording();
// Continue recording the next video clip.
recorder.startRecording();
recorder.stopRecording();Stop recording
When you stop recording, you can either merge the recorded clips into a single video or generate only the clip configuration information. For details about the parameters used, see the API reference in the Related classes section.
// Stop recording and merge the video clips into a single video.
recorder.finishRecording();
// Stop recording and generate configuration information for the clips (without merging).
recorder.finishRecordingForEdit();Recording control and management
Configure camera controls such as camera type and flash mode, and clip management settings such as maximum and minimum recording durations and clip deletion. This step is optional.
For details about the parameters used, see the API reference in the Related classes section.
Recording camera control
// Get the number of cameras.
AliyunIRrecorder.getCameraCount();
// Set the camera type.
AliyunIRecorder.setCamera(cameraType);
// Mute the recording.
AliyunIRecorder.setMute(boolean isMute);
// Set the sensor rotation angle.
// Important: Read the API reference carefully.
AliyunIRecorder.setRotation(int rotation);
// Set the recording rotation angle.
// Important: Read the API reference carefully.
AliyunIRecorder.setRecordRotation(int rotation);
// Set camera preview parameters (flash, focus mode, zoom, exposure level). You can also set these parameters individually using the methods below.
AliyunIRecorder.setCameraParam(CameraParam cameraParam);
// Switch between cameras.
AliyunIRecorder.switchCamera();
// Set the flash mode.
AliyunIRecorder.setLight(flashType);
// Set the zoom level.
AliyunIRecorder.setZoom(float rate);
// Set the exposure level.
AliyunIRecorder.setExposureCompensationRatio(float value);
// Set the focus mode.
AliyunIRecorder.setFocusMode(int mode);
// Manually set the focus.
AliyunIRecorder.setFocus(float xRatio, float yRatio);Video clip management
// Get the clip manager.
AliyunIClipManager manager = AliyunIRecorder.getClipManager();
// Set the maximum recording duration (total duration of all clips, not a single clip).
manager.setMaxDuration(int maxDurationMs);
// Set the minimum recording duration (total duration of all clips, not a single clip).
manager.setMinDuration(int minDurationMs);
// Delete the last clip.
manager.deletePart();
// Delete the specified clip.
manager.deletePart(int index);
// Delete all clips.
manager.deleteAllPart();
// Get the total duration of all clips.
manager.getDuration();
// Get the total number of clips.
manager.getPartCount();
// Get the list of clip paths.
manager.getVideoPathList();Set effects
Apply effects such as retouching, filters, and background music. This step is optional. For details about the parameters used, see the API reference in the Related classes section.
Filters
You can use custom filters. To learn how to create them, see Filters and transitions.
// Apply a filter.
AliyunIRecorder.applyFilter(EffectFilter effectFilter);// To remove the filter, set the path parameter to null.
// Remove the filter.
AliyunIRecorder.applyFilter(new EffectFilter(null));Animated filters
// Apply an animated filter.
AliyunIRecorder.applyAnimationFilter(EffectFilter effectFilter);
// Remove the animated filter.
AliyunIRecorder.removeAnimationFilter(EffectFilter effctFilter);Background music
// Set the background music.
AliyunIRecorder.setMusic(String path,long startTime,long duration);
// Remove the background music.
AliyunIRecorder.setMusic(null, 0, 0);Speed ramping
// Set the recording speed.
AliyunIRecorder.setRate(float rate);Static stickers and watermarks
// Add a static sticker or watermark.
AliyunIRecorder.addImage(EffectImage effctImage);
// Remove the static sticker or watermark.
AliyunIRecorder.removeImage(EffectImage effctImage);
// Update the position of the static sticker or watermark.
AliyunIRecorder.setEffectView(float xRatio,float yRatio,float widthRatio,float heightRatio,EffectBase effectBase);Animated stickers
You can use custom animated stickers. To learn how to create them, see Animations.
// Add an animated sticker.
AliyunIRecorder.addPaster(EffectPaster effectPaster,float sx,float sy,float sw,float sh,float rotation,boolean flip);
// Remove an animated sticker.
AliyunIRecorder.removePaster(EffectPaster effectPaster);
// Update the position of the animated sticker.
AliyunIRecorder.setEffectView(float xRatio,float yRatio,float widthRatio,float heightRatio,EffectBase effectBase);Advanced retouching
The video recording module provides a built-in basic retouching feature. It also supports third-party retouching SDKs, such as the Alibaba Cloud Queen SDK and FaceUnity. The built-in feature is simple, allowing you to set only the retouching level. Third-party SDKs typically offer more advanced features, including retouching, face shaping, makeup, filters, and stickers.
Built-in retouching
// Enable or disable retouching. AliyunIRecorder.setBeautyStatus(boolean on); // Set the retouching level. AliyunIRecorder.setBeautyLevel(int level);Third-party retouching SDKs
To use effects from a third-party retouching SDK, you must first obtain the necessary permissions and integrate that SDK with the short video SDK.
For information about how to integrate the Alibaba Cloud Queen SDK, see Alibaba Cloud Queen SDK. For sample code that shows how to configure effects, see Usage examples.
For information about how to purchase, integrate, and use FaceUnity, see FaceUnity.
Third-party retouching SDKs require two types of data to function: the camera texture ID and the camera raw frame data. The following code shows how to obtain this data.
Obtain the camera texture ID
AliyunIRecorder.setOnTextureIdCallback(new OnTextureIdCallBack() { @Override public int onTextureIdBack(int textureId, int textureWidth, int textureHeight, float[] matrix) { if (mBeautyInterface != null) { return mBeautyInterface.onTextureIdBack(textureId, textureWidth, textureHeight, matrix, mControlView.getCameraType().getType()); } return textureId; } @Override public int onScaledIdBack(int scaledId, int textureWidth, int textureHeight, float[] matrix) { return scaledId; } @Override public void onTextureDestroyed() { // To destroy GL resources for custom rendering (third-party rendering) in SDK versions earlier than 3.7.8, you can use GLSurfaceView.queueEvent. For SDK V3.7.8 and later, we recommend destroying GL resources in this callback. if (mBeautyInterface != null) { mBeautyInterface.release(); mBeautyInterface = null; } } });Obtain the camera raw frame data
AliyunIRecorder.setOnFrameCallback(new OnFrameCallBack() { @Override public void onFrameBack(byte[] bytes, int width, int height, Camera.CameraInfo info) { // The raw data callback provides data in NV21 format. This data is primarily used for advanced retouching with FaceUnity. if (mBeautyInterface != null) { mBeautyInterface.onFrameBack(bytes, width, height, info); } } @Override public Camera.Size onChoosePreviewSize(List<Camera.Size> supportedPreviewSizes, Camera.Size preferredPreviewSizeForVideo) { return null; } @Override public void openFailed() { } });
Other features
You can enable photo capture and facial recognition during video recording. For details about the parameters used, see the API reference in the Related classes section.
Photo capture
You can capture photos with effects or use the system camera to capture photos without effects. The photo data is returned through theRecordCallback.onPictureBack(Bitmap) orRecordCallback.onPictureDataBack(byte[]) callback.
// Capture a photo with effects.
AliyunIRecorder.takePhoto(boolean needBitmap);
// Capture a photo by using the system camera (no effects).
AliyunIRecorder.takePicture(boolean needBitmap);
// Set the photo size for system photo capture. This is not supported for photo capture with effects.
AliyunIRecorder.setPictureSize(Camera.Size size);Facial recognition
To use facial recognition, you must integrate a facial recognition model file into your app. For reference, you can download the facial recognition model file demo.
// Enable facial recognition.
AliyunIRecorder.needFaceTrackInternal(boolean need);
// Set the path of the facial recognition model file.
AliyunIRecorder.setFaceTrackInternalModelPath(String path);
// Set the face detection rotation angle.
// Important: Read the API reference carefully.
AliyunIRecorder.setFaceDetectRotation(int rotation);
// Set the maximum number of faces to detect.
// Set the maximum number of faces that the built-in facial recognition can detect. The maximum is 3.
AliyunIRecorder.setFaceTrackInternalMaxFaceCount(int maxFaceCount);
// Add an animated face sticker.
AliyunIRecorder.addPaster(EffectPaster effectPaster);Basic recording sample code
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceView;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.aliyun.svideosdk.common.struct.recorder.MediaInfo;
import com.aliyun.svideosdk.recorder.AliyunIRecorder;
import com.aliyun.svideosdk.recorder.RecordCallback;
import com.aliyun.svideosdk.recorder.impl.AliyunRecorderCreator;
import com.svideo.guide.R;
import java.io.FileOutputStream;
/**
* Demonstrates basic video recording.
*/
class RecordActivity : AppCompatActivity() {
enum class RecordStatus {
Idle,
Recording
}
private lateinit var mAliyunRecord : AliyunIRecorder
private lateinit var mCameraViiew : SurfaceView
private lateinit var mRecordBtn : ImageView
private var mRecordStatus = RecordStatus.Idle
companion object {
const val TAG = "RecordActivity"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_record)
mCameraViiew = findViewById(R.id.cameraPreviewView)
mRecordBtn = findViewById(R.id.btnRecordControl)
// Recording button.
mRecordBtn.setOnClickListener {
if(mRecordStatus == RecordStatus.Recording) {
mAliyunRecord.stopRecording()
Toast.makeText(this@RecordActivity, "Stop recording", Toast.LENGTH_SHORT).show()
updateRecordStatus(RecordStatus.Idle)
} else {
mAliyunRecord.takePhoto(true)
}
}
mRecordBtn.setOnLongClickListener {
if(mRecordStatus == RecordStatus.Idle) {
val curTime = System.currentTimeMillis()
mAliyunRecord.setOutputPath("/storage/emulated/0/DCIM/Camera/svideo_record_video_$curTime.mp4")
mAliyunRecord.startRecording()
Toast.makeText(this@RecordActivity, "Start recording", Toast.LENGTH_SHORT).show()
updateRecordStatus(RecordStatus.Recording)
}
true
}
mAliyunRecord = AliyunRecorderCreator.getRecorderInstance(this)
val mediaInfo = MediaInfo()
mediaInfo.fps = 30
mediaInfo.crf = 6
mediaInfo.videoWidth = 720
mediaInfo.videoHeight = 1080
mAliyunRecord.setMediaInfo(mediaInfo)
mAliyunRecord.setDisplayView(mCameraViiew)
mAliyunRecord.setRecordCallBack(object : RecordCallback {
override fun onComplete(validClip: Boolean, clipDuration: Long) {
Log.i(TAG, "onComplete")
}
override fun onFinish(outputPath: String?) {
Log.i(TAG, "onFinish path : $outputPath")
}
override fun onProgress(duration: Long) {
}
override fun onMaxDuration() {
Log.i(TAG, "onMaxDuration")
}
override fun onError(errorCode: Int) {
Log.i(TAG, "onError : $errorCode")
}
override fun onInitReady() {
Log.i(TAG, "onInitReady")
}
override fun onDrawReady() {
Log.i(TAG, "onDrawReady")
}
override fun onPictureBack(bitmap: Bitmap?) {
Log.i(TAG, "onPictureBack")
val curTime = System.currentTimeMillis()
val outputFile = "/storage/emulated/0/DCIM/Camera/svideo_record_photo_$curTime.png"
val outputStream = FileOutputStream(outputFile)
bitmap?.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
outputStream.flush()
outputStream.close()
runOnUiThread {
Toast.makeText(this@RecordActivity, "Photo saved to album", Toast.LENGTH_SHORT).show()
}
}
override fun onPictureDataBack(p0: ByteArray?) {
Log.i(TAG, "onPictureDataBack")
}
})
}
private fun updateRecordStatus(recordStatus: RecordStatus)
{
mRecordStatus = recordStatus
when(recordStatus) {
RecordStatus.Idle -> {
mRecordBtn.setImageResource(R.mipmap.alivc_svideo_bg_record_start)
}
RecordStatus.Recording -> {
mRecordBtn.setImageResource(R.mipmap.alivc_svideo_bg_record_storp)
}
}
}
override fun onResume() {
super.onResume()
mAliyunRecord.startPreview()
}
override fun onPause() {
super.onPause()
mAliyunRecord.stopPreview()
}
override fun onDestroy() {
super.onDestroy()
mAliyunRecord.destroy()
}
}XML configuration sample
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<SurfaceView
android:id="@+id/cameraPreviewView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</SurfaceView>
<ImageView
android:id="@+id/btnRecordControl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="50dp"
android:src="@mipmap/alivc_svideo_bg_record_storp"
android:visibility="visible">
</ImageView>
</androidx.constraintlayout.widget.ConstraintLayout>