Multi-source recording
Multi-source recording extends the short video SDK with view recording (screen recording), letting you combine camera feeds and view recordings into composite videos.
Supported editions
|
Edition |
Supported |
|
Professional |
Yes |
|
Standard |
Yes |
|
Basic |
No |
Concepts
Before using this feature, familiarize yourself with these key concepts: multi-source recording, track, and track layout.
Related classes
|
Class |
Description |
|
The core class for multi-source recording. Handles recording, preview configuration, effect settings, and callback handling. |
|
|
A factory class for creating video recording instances. |
|
|
Defines recording parameters, such as video resolution, encoder type, and frame rate. |
|
|
An interface for configuring video data capture, with methods for adding camera and view recording capturers. |
|
|
An interface for camera recording. |
|
|
An interface for view recording. |
|
|
An interface for recording listeners, including callbacks for recording completion, progress, and errors. |
|
|
An audio callback interface that provides audio data in PCM format. |
|
|
A callback interface for camera data capture, with callbacks for preview resolution selection, captured frames, and camera startup failures. |
|
|
A callback interface for taking photos and screenshots. |
|
|
An interface for managing video clips, such as deleting clips and setting the recording duration. |
Procedure
To use multi-source recording, you must grant camera and microphone permissions. Otherwise, recording will fail.
|
Phase |
Step |
Description |
Sample code |
|
Basic |
1 |
Create and destroy recording instances, and configure recording parameters. |
Initialize the AliyunIVideoRecorder class and configure parameters |
|
2 |
Configure parameters for view recording and camera recording. |
||
|
3 |
Set up callbacks. |
||
|
4 |
Set a preview view and enable the preview. |
||
|
5 |
Start, stop, and cancel recording of a video clip. |
||
|
6 |
Finish recording to generate the final video. |
||
|
Advanced |
7 |
Configure camera controls (such as camera type and flash mode) and clip management parameters (such as maximum or minimum recording duration, deleting a clip, and querying the number of clips). These settings are optional. |
|
|
8 |
Optionally, configure recording effects such as retouching, filters, and animated stickers. |
||
|
9 |
Set background music, background images, and speed ramping. |
Initialize and configure parameters
Initialize the AliyunIVideoRecorder class, create a recording instance, and configure recording parameters. For more information about the code parameters, refer to Related classes.
Initialize the class
// Create a recording instance.
AliyunIVideoRecorder recorder = AliyunMultiRecorderCreator.getVideoRecorderInstance(context, config);
// Destroy the recording instance.
// Call this method when you no longer need the SDK or before exiting the application.
// We recommend calling it in Activity#onDestroy. Do not destroy the instance during a recording session.
recorder.destroy();
Configure recording parameters
AliyunVideoRecorderConfig config = AliyunVideoRecorderConfig.builder()
// Required parameters
.videoWidth(***)
.videoHeight(***)
.outputPath(***)
// Optional parameters
.***()
.***()
.build();
Configure video sources
Combine multiple video sources as needed. After adding all sources, call recorder.prepare() to finalize the configuration.
Camera recording
For more information about API parameters, see AliyunICameraCapture.
// 1. Configure the layout.
AliyunLayoutParam cameraLayoutParam = AliyunLayoutParam.builder()
.layoutLevel(***)
.centerX(***)
.centerY(***)
.widthRatio(***)
.heightRatio(***)
.displayMode(***)
.build();
// 2. Add the video source.
AliyunICameraCapture cameraCapture = recorder.getVideoCapture().addCameraCapture(cameraLayoutParam);
// 3. Configure the video source.
// Set the camera preview view. This is a required property.
cameraCapture.setDisplayView(SurfaceView)
// Other settings (configure as needed).
cameraCapture.set***();
View recording
For more information about API parameters, see AliyunIViewCapture.
// 1. Configure the layout.
AliyunLayoutParam viewLayoutParam = AliyunLayoutParam.builder()
.layoutLevel(***)
.centerX(***)
.centerY(***)
.widthRatio(***)
.heightRatio(***)
.displayMode(***)
.build();
// 2. Add the video source.
// Get the current recording view.
View recordView = getRecordView();
AliyunIViewCapture viewCapture = recorder.getVideoCapture().addViewCapture(viewLayoutParam, recordView);
// 3. Configure the video source (as needed).
viewCapture.set***();
Prepare video sources
After adding all video sources, call the following method to complete the configuration.
recorder.prepare();
Configure callbacks
Set up callbacks for real-time audio and video processing status updates. For more information about the parameters used in the code, see the API reference in Related classes.
// Set the recording callback (optional).
recorder.setOnRecordListener(OnVideoRecordListener);
// Set the callback for captured audio data (optional).
recorder.setOnAudioCallback(OnAudioCallback);
Enable preview
Typically, you call startPreview in Activity#onResume and stopPreview in Activity#onPause. For more information about the parameters used in the code, see the API reference in Related classes.
// Start the preview.
// Typically called in Activity#onResume.
AliyunIRecorder.startPreview();
// Stop the preview.
// Typically called in Activity#onPause.
AliyunIRecorder.stopPreview();
Start recording
During recording, you can stop, cancel, and restart multiple times. Stopping the recording saves a video clip, while canceling discards the current one. For more information about the parameters used in the code, see the API reference in Related classes.
Start recording
// Start recording.
recorder.startRecording();
Record a clip
// Start recording.
recorder.startRecording();
// Stop recording. A video clip is generated.
recorder.stopRecording();
recorder.startRecording();
// Cancel recording. The current video clip is not saved.
recorder.cancelRecording();
// Continue recording the next video clip.
recorder.startRecording();
recorder.stopRecording();
Finish recording
When you finish recording, you can either merge all clips into a single video or generate a configuration file for the clips without merging them. For more information about the parameters used in the code, see the API reference in Related classes.
// Finish recording and merge the video clips into a single video.
recorder.finishRecording();
// Finish recording and generate a configuration file for the clips (without merging).
recorder.finishRecordingForEdit();
Camera control and clip management
Configure camera controls (such as camera type and flash mode) and clip management parameters (such as maximum or minimum recording duration, deleting a clip, and querying the number of clips). These settings are optional. For more information about the parameters used in the code, see the API reference in Related classes.
Camera controls
// Get the number of cameras.
AliyunICameraCapture.getCameraCount();
// Set the camera type: front camera or rear camera.
AliyunICameraCapture.setCamera(CameraType cameraType);
// Set the sensor rotation angle.
// Important: Refer to the API reference for correct usage.
AliyunICameraCapture.setRotation(int rotation);
// Set the video recording rotation angle.
// Important: Refer to the API reference for correct usage.
AliyunICameraCapture.setRecordRotation(int rotation);
// Set camera preview parameters (flash, focus mode, zoom, exposure).
// You can also set these parameters individually using the methods below.
AliyunICameraCapture.setCameraParam(CameraParam cameraParam);
// Switch between the front and rear cameras.
AliyunICameraCapture.switchCamera();
// Set the flash mode.
AliyunICameraCapture.setLight(FlashType flashType);
// Set the zoom level.
AliyunICameraCapture.setZoom(float rate);
// Set the exposure compensation ratio.
AliyunICameraCapture.setExposureCompensationRatio(float value);
// Set the focus mode.
AliyunICameraCapture.setFocusMode(int mode);
// Manually set the focus point.
AliyunICameraCapture.setFocus(float xRatio, float yRatio);
Clip management
// Get the clip manager.
AliyunIClipManager manager = AliyunIVideoRecorder.getClipManager();
// Set the maximum recording duration (total duration, not for a single clip).
manager.setMaxDuration(int maxDurationMs);
// Set the minimum recording duration (total duration, not for a single clip).
manager.setMinDuration(int minDurationMs);
// Delete the last clip.
manager.deletePart();
// Delete a clip at a specific index.
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 file paths.
manager.getVideoPathList();
Configure effects
Optionally, configure recording effects such as retouching, filters, and animated stickers. For more information about the parameters used in the code, see the API reference in Related classes.
Filters
You can create custom filters. For more information about how to create a filter, see Filters and transitions.
// Apply a filter.
AliyunICameraCapture.applyFilter(EffectFilter effectFilter);
// Remove the filter.
AliyunICameraCapture.removeFilter();
Animated filters
// Apply an animated filter.
AliyunICameraCapture.applyAnimationFilter(EffectFilter effectFilter);
// Remove an animated filter.
AliyunICameraCapture.removeAnimationFilter(EffectFilter effctFilter);
Static stickers
// Add a static sticker.
AliyunICameraCapture.addImage(EffectImage effctImage);
// Remove a static sticker.
AliyunICameraCapture.removeImage(EffectImage effctImage);
// Update the position of a static sticker.
AliyunICameraCapture.setEffectView(float xRatio,float yRatio,float widthRatio,float heightRatio,EffectBase effectBase);
Animated stickers
You can create custom animated stickers. For more information about how to create an animated sticker, see Animations.
// Add an animated sticker.
AliyunICameraCapture.addPaster(EffectPaster effectPaster,float sx,float sy,float sw,float sh,float rotation,boolean flip);
// Remove an animated sticker.
AliyunICameraCapture.removePaster(EffectPaster effectPaster);
// Update the position of an animated sticker.
AliyunICameraCapture.setEffectView(float xRatio,float yRatio,float widthRatio,float heightRatio,EffectBase effectBase);
Advanced retouching
The video recording module includes basic built-in retouching and supports third-party SDKs such as the Alibaba Cloud Queen SDK and FaceUnity. Built-in retouching only adjusts the retouching level, while third-party SDKs provide advanced capabilities including retouching, face shaping, makeup, filters, and stickers.
-
Built-in retouching
// Enable or disable retouching. AliyunICameraCapture.setBeautyStatus(boolean on); // Set the retouching level. AliyunICameraCapture.setBeautyLevel(int level); -
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 a camera texture ID and raw camera frame data to apply effects. The following code shows how to obtain this data.
-
Get camera texture ID data
AliyunICameraCapture.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. // In SDK versions 3.7.8 and later, destroy GL resources in this callback. if (mBeautyInterface != null) { mBeautyInterface.release(); mBeautyInterface = null; } } }); -
Get raw camera frame data
AliyunICameraCapture.setOnFrameCallback(new OnFrameCallback() { @Override public void onFrameBack(byte[] bytes, int width, int height, Camera.CameraInfo info) { // The callback provides raw NV21 data. 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
Add background music, watermarks, and speed ramping. For more information about the parameters used in the code, see the API reference in Related classes.
Speed ramping
// Set the recording speed.
AliyunIVideoRecorder.setRate(float rate);
Mute
// Mute the microphone.
AliyunIVideoRecorder.setMute(boolean isMute);
Autoclear
// Controls whether recorded video clips are automatically cleared when you exit the recording interface.
AliyunIVideoRecorder.setIsAutoClearClipVideos(boolean isAutoClear);
Background music
// Set the background music.
AliyunIVideoRecorder.setMusic(String path,long startTime,long duration);
// Remove the background music.
AliyunIVideoRecorder.removeMusic();
Watermark
// Add a watermark.
AliyunIVideoRecorder.addWaterMark(EffectImage effectImage);
// Remove the watermark.
AliyunIVideoRecorder.removeWaterMark(EffectImage effectImage);
Configure the background
// Set the background color.
AliyunIVideoRecorder.setBackgroundColor(int color);
// Set the background image from a bitmap.
AliyunIVideoRecorder.setBackgroundImage(Bitmap bitmap);
// Set the background image from a file path.
AliyunIVideoRecorder.setBackgroundImage(String path);
// Clear the background.
AliyunIVideoRecorder.clearBackground();
Sample code
import android.os.Bundle;
import android.os.Environment;
import android.view.SurfaceView;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.aliyun.svideosdk.common.struct.common.AliyunLayoutParam;
import com.aliyun.svideosdk.common.struct.common.VideoDisplayMode;
import com.aliyun.svideosdk.common.struct.encoder.VideoCodecs;
import com.aliyun.svideosdk.common.struct.recorder.CameraType;
import com.aliyun.svideosdk.multirecorder.AliyunICameraCapture;
import com.aliyun.svideosdk.multirecorder.AliyunIVideoRecorder;
import com.aliyun.svideosdk.multirecorder.AliyunIViewCapture;
import com.aliyun.svideosdk.multirecorder.OnVideoRecordListener;
import com.aliyun.svideosdk.multirecorder.config.AliyunVideoRecorderConfig;
import com.aliyun.svideosdk.multirecorder.impl.AliyunMultiRecorderCreator;
import java.io.File;
/**
* A demo for multi-source recording.
* Note: You must grant storage, camera, and microphone permissions before you start.
*/
public class MultiRecorderDemo extends AppCompatActivity {
private AliyunIVideoRecorder mRecorder;
private TextView mBtnRecord;
private SurfaceView mCameraPreview;
private View mViewRecord;
private View mViewRecordIcon;
private boolean mIsRecording = false;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.multi_recoder_demo_layout);
initViews();
initRecorder();
}
@Override
protected void onResume() {
super.onResume();
mRecorder.startPreview();
}
@Override
protected void onPause() {
super.onPause();
stopRecording();
mRecorder.stopPreview();
}
@Override
protected void onDestroy() {
super.onDestroy();
mRecorder.destroy();
}
private String getSaveDir() {
String saveDir = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "MultiRecord";
File dirFile = new File(saveDir);
if (!dirFile.exists()) {
dirFile.mkdirs();
}
return saveDir;
}
private void initViews() {
mBtnRecord = findViewById(R.id.record_btn);
mCameraPreview = findViewById(R.id.multi_record_camera);
mViewRecord = findViewById(R.id.multi_record_view);
mViewRecordIcon = mViewRecord.findViewById(R.id.record_view_icon);
}
private void initRecorder() {
// 1. Configure parameters.
AliyunVideoRecorderConfig config = AliyunVideoRecorderConfig.builder()
// Required parameters
.videoWidth(1080)
.videoHeight(1920)
.outputPath(getSaveDir() + File.separator + System.currentTimeMillis() + ".mp4")
// Optional parameters
.videoCodecs(VideoCodecs.H264_HARDWARE) // Use hardware encoding.
.build();
// 2. Create a recording instance.
mRecorder = AliyunMultiRecorderCreator.getVideoRecorderInstance(this, config);
// 3. Configure video sources.
// 3.1 Configure camera recording.
addCameraCapture();
// 3.2 Configure view recording.
addViewCapture();
// 3.3 Prepare the video sources.
mRecorder.prepare();
// 4. Configure callbacks.
mRecorder.setOnRecordListener(new OnVideoRecordListener() {
@Override
public void onProgress(long duration) {
}
@Override
public void onFinish(String outputPath) {
}
@Override
public void onClipComplete(boolean validClip, long clipDuration) {
}
@Override
public void onMaxDuration() {
runOnUiThread(new Runnable() {
@Override
public void run() {
stopRecording();
}
});
}
@Override
public void onError(int errorCode) {
runOnUiThread(new Runnable() {
@Override
public void run() {
stopRecording();
}
});
}
@Override
public void onInitReady() {
}
});
}
private void addCameraCapture() {
// 1. Configure the layout for the left side.
AliyunLayoutParam cameraLayoutParam = AliyunLayoutParam.builder()
.layoutLevel(1)
.centerX(0.25f)
.centerY(0.5f)
.widthRatio(0.5f)
.heightRatio(1.0f)
.displayMode(VideoDisplayMode.FILL)
.build();
// 2. Add the video source.
AliyunICameraCapture cameraCapture = mRecorder.getVideoCapture().addCameraCapture(cameraLayoutParam);
// 3. Configure the video source.
// Set the camera preview view. This is a required property.
cameraCapture.setDisplayView(mCameraPreview);
// Optional settings
cameraCapture.setCamera(CameraType.BACK);// Use the rear camera.
}
private void addViewCapture() {
// 1. Configure the layout for the right side.
AliyunLayoutParam viewLayoutParam = AliyunLayoutParam.builder()
.layoutLevel(2)
.centerX(0.75f)
.centerY(0.5f)
.widthRatio(0.5f)
.heightRatio(1.0f)
.displayMode(VideoDisplayMode.FILL)
.build();
// 2. Add the video source.
// Get the current recording view.
View recordView = mViewRecord;
AliyunIViewCapture viewCapture = mRecorder.getVideoCapture().addViewCapture(viewLayoutParam, recordView);
// 3. Configure the video source (optional).
}
private void startRecording() {
if (mIsRecording) {
return;
}
mIsRecording = true;
mRecorder.startRecording();
}
private void stopRecording() {
if (!mIsRecording) {
return;
}
mRecorder.stopRecording();
mIsRecording = false;
}
public void onClickRecord(View view) {
if (mIsRecording) {
stopRecording();
mBtnRecord.setText("Start recording");
} else {
startRecording();
mBtnRecord.setText("Stop recording");
}
}
}
Sample XML configuration
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/demo_root_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<SurfaceView
android:id="@+id/multi_record_camera"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<FrameLayout
android:id="@+id/multi_record_view"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<TextView
android:id="@+id/record_view_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="View recording" />
</FrameLayout>
</LinearLayout>
<Button
android:id="@+id/record_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginLeft="5dp"
android:layout_marginBottom="5dp"
android:onClick="onClickRecord"
android:text="Start recording" />
</RelativeLayout>