Basic recording

Updated at:
Copy as MD

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

AliyunIRecorder

The core interface for recording. It includes key features such as starting a recording, setting up the preview, applying effects, and configuring callbacks.

AliyunRecorderCreator

A factory class for creating a recording instance.

MediaInfo

A class for configuring recording parameters, such as video resolution, encoder type, and capture frame rate.

RecordCallback

An interface that provides callbacks for recording events, such as completion, progress, and errors.

OnFrameCallBack

An interface that provides callbacks for camera data capture, including preview resolution selection, frame data capture, and camera startup failures.

OnAudioCallBack

An interface that provides callbacks for audio data in PCM format.

AliyunIClipManager

An interface for managing video clips. Use it to delete clips and set the recording duration.

Workflow

Note

Recording videos requires camera and microphone permissions.

Stage

Step

Description

Sample code

Basic

1

Create and destroy the recording interface, and configure recording parameters.

Initialization and parameter configuration

2

Set up callbacks.

Callback settings

3

Start and stop the preview.

Enable preview

4

Start, cancel, and stop recording a video clip.

Start recording

5

Stop the recording and generate the output.

Stop recording

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.

Recording control and management

7

Optionally, apply effects such as retouching, filters, and background music.

Set effects

8

Enable additional features such as photo capture or facial recognition.

Other features

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>