Multi-source recording

更新时间:
复制 MD 格式

The short video SDK's upgraded recording module expands on its basic features, adding support for screen recording and real-time compositing of multiple input sources, such as a camera, the screen, and local videos. For example, you can combine camera and screen recording for whiteboard tutorials, or create duet recording videos by mixing camera input with a local video.

Supported editions

EditionSupported
Professional EditionYes
Standard EditionYes
Basic EditionNo

Key concepts

This section describes the terms that help you better understand multi-source recording. For more information, see Multi-source recording, Track, and Track layout.

Related classes

ClassDescription
AliyunRecorderCore class for multi-source recording. Manages essential functions such as recording, preview configuration, effects, and callbacks.
AliyunRecorderConfigConfigures multi-source recording. Use this class to set the output path, add input sources, apply a watermark, and configure background music.
AliyunRecorderVideoConfigA configuration class for the output video. It defines video parameters (resolution, frame rate, rotation, and scaling mode) and compression parameters (encoding, GOP, bitrate, and video quality). You can typically leave the compression parameters at their default values.
AliyunMicRecordControllerThe protocol for the microphone controller.
AliyunVideoRecordLayoutParamSets the layout parameters for an input source, such as the video layer and scaling mode.
AliyunCameraRecordSourceRepresents the camera recording input source.
AliyunCameraRecordControllerThe protocol for the camera recording controller.
AliyunViewRecordSourceRepresents the screen recording input source.
AliyunViewRecordControllerThe protocol for the screen recording controller.
AliyunPlayerRecordSourceConfigures the local video playback input source.
AliyunPlayerRecordControllerThe protocol for the local video playback controller.
AliyunClipManagerManages recorded clips. Use this class to retrieve clip information and delete video clips.
AliyunRecorderDelegateReceives recording callbacks.

Workflow

Note Multi-source recording requires camera and microphone permissions to function correctly.
The following diagram illustrates the multi-source recording workflow:I多源录制
StageStepDescriptionSample code
Basic1Create a recorder instance, configure recording parameters, and add input sources.Initialize the recorder
2Start or stop the preview.Control the preview
3Start or stop recording.Start recording
4Finalize the recording to generate the output file.Finish recording
Advanced5Configure individual input sources.Control the camera recording source

Control the screen recording source

Control the local video source

6Configure advanced features, such as background music, speed ramping, and custom rendering.Other features
7Implement recording callbacks.Recording callbacks

Initialize the recorder

Initialize AliyunRecorder to create and configure a recorder instance. For more information about the parameters used in the code, see Related classes.

Set output parameters

Use AliyunRecorderVideoConfig to set the output video's display parameters (resolution, frame rate, rotation angle, and scaling mode) and compression parameters (encoding, GOP, bitrate, and video quality). In most cases, you do not need to configure compression parameters unless you have specific requirements.
AliyunRecorderVideoConfig *videoConfig = [[AliyunRecorderVideoConfig alloc] init];
videoConfig.resolution = CGSizeMake(720, 1280);           // 720p
videoConfig.fps = 30;
...

Add input sources

First, create a configuration object by using the output parameter object and outputPath. Then, add the input sources.
Note
  • You can add multiple input sources, but we recommend using no more than three for optimal performance.
  • You can add only one camera recording source. Subsequent attempts to add another will be ignored.
// Create a configuration object.
AliyunRecorderConfig *config = [[AliyunRecorderConfig alloc] initWithVideoConfig:videoConfig outputPath:[taskPath stringByAppendingPathComponent:@"output.mp4"]];


// Add a camera recording source.
// Specify the camera layout parameters.
AliyunVideoRecordLayoutParam *cameraLayout = [[AliyunVideoRecordLayoutParam alloc] initWithRenderMode:AliyunRenderMode_ResizeAspectFill];
cameraLayout.size = resolution;
cameraLayout.center = CGPointMake(resolution.width / 2.0, resolution.height / 2.0);
cameraLayout.zPosition = 1;
// Add the recording source and get its controller.
self.cameraRecorderController = [config addCamera:cameraLayout];
self.cameraRecorderController.preview = self.videoView;
self.cameraRecorderController.camera.resolution = AliyunRecordCameraResolution_3840x2160;
self.cameraRecorderController.camera.position = AVCaptureDevicePositionBack;


// Add a screen recording source.
// Specify the layout parameters for screen recording.
AliyunVideoRecordLayoutParam *viewRecordLayout = [[AliyunVideoRecordLayoutParam alloc] initWithRenderMode:AliyunRenderMode_ResizeAspect];
viewRecordLayout.size = CGSizeMake(0.5*videoConfig.resolution.width, 0.5*videoConfig.resolution.height);
viewRecordLayout.center = CGPointMake(0.5*videoConfig.resolution.width, 0.5*videoConfig.resolution.height);
viewRecordLayout.zPosition = 2;
// Specify the parameters for the screen recording source.
AliyunViewRecordSource *viewSource = [[AliyunViewRecordSource alloc] initWithTargetView:drawView fps:videoConfig.fps];
viewSource.captureInBackground = YES;
// Add the recording source and get its controller.
self.viewRecordController = [config addViewSource:viewSource layout:viewRecordLayout];


// Add a local video playback source.
// Specify the layout parameters for the local video source.
AliyunVideoRecordLayoutParam *playerRecordLayout = [[AliyunVideoRecordLayoutParam alloc] initWithRenderMode:AliyunRenderMode_ResizeAspect];
playerRecordLayout.size = CGSizeMake(0.5*videoConfig.resolution.width, 0.5*videoConfig.resolution.height);
playerRecordLayout.center = CGPointMake(0.5*videoConfig.resolution.width, 0.5*videoConfig.resolution.height);
playerRecordLayout.zPosition = 2;
// Specify the parameters for the local video playback source.
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:videoPath] options:nil];
AliyunPlayerRecordSource *playerSource = [[AliyunPlayerRecordSource alloc] initWithAsset:asset fps:videoConfig.fps];
// Add the recording source and get its controller.
self.playerRecordController = [config addMVSource:playerSource layout:playerRecordLayout];
self.playerRecordController.preview = self.playerView;
Create an instance
// Create the recorder instance with the configuration object.
AliyunRecorder *recorder = [[AliyunRecorder alloc] initWithConfig:config];
recorder.delegate = self;
recorder.clipManager.maxDuration = 5;
recorder.clipManager.minDuration = 1;
recorder.clipManager.deleteVideoClipsOnExit = YES;
self.aliyunRecorder = recorder;

Preview control

For more information about the parameters used in the code, see Related classes.

// Start the preview.
[self.aliyunRecorder startPreview];

// Stop the preview, typically after recording is complete.
[self.aliyunRecorder stopPreview];

Start recording

The startRecording and stopRecording methods must be called in pairs. Call these methods multiple times to generate multiple video clips. For more information about the parameters used in the code, see Related classes.
// Start recording a video clip.
[self.aliyunRecorder startRecord];  

// Stop recording a video clip. The process is not instantaneous. 
// Listen for state changes through the onAliyunRecorder:stateDidChange: callback.
[self.aliyunRecorder stopRecord];
The following table describes the recording states.
StateDescription
AliyunRecorderState_IdleThe recorder is idle and waiting to start.
AliyunRecorderState_LoadingForRecordThe recorder is preparing to record. It waits for the first frame from each input source before automatically transitioning to the Recording state.
AliyunRecorderState_RecordingThe recorder is actively recording.
AliyunRecorderState_StoppingThe recorder is stopping. It automatically transitions to the Stop state after internal buffers are processed.
AliyunRecorderState_StopThe recorder is stopped.
AliyunRecorderState_ErrorAn error occurred. You can call cancel to reset the state to Idle.

Finish recording

After recording, you can either merge all clips into a single video or generate a configuration file for later editing. For more information about the parameters used in the code, see Related classes.
  • finishRecord: Merges video clips into a complete video. Use this method if no further editing is required.
  • finishRecordForEdit: Generates a task path for the clips without merging them. Use this method if you plan to edit the video later. You can initialize the editor with the output taskPath. For more information, see Initialize the editor.
// Finish recording and merge all clips into a single video file.
[self.aliyunRecorder finishRecord:^(NSString *outputPath, NSError *error) {
    if (!error) {
        // Recording is complete. You can preview, edit, or upload the video at outputPath.
    }
}];

// Finish recording and generate a taskPath for further editing. Clips are not merged.
[self.aliyunRecorder finishRecordForEdit:^(NSString *taskPath, NSError *error) {
    if (!error) {
        // Recording is complete. You can use taskPath to initialize the editor (AliyunEditor) 
        // for post-production. See the video editing documentation for details.
    }
}];

Camera source control

After adding the source, you receive a controller that conforms to the AliyunCameraRecordController protocol. Use this controller to adjust parameters, configure borders, apply basic retouching, face stickers, static stickers, animated GIFs, static filters, animated filters, and take photos.

Common parameters
// Flashlight
self.cameraRecorderController.camera.torchMode = AVCaptureTorchModeOn;

// Camera Position
self.cameraRecorderController.camera.position = AVCaptureDevicePositionBack;

// Zoom Factor
self.cameraRecorderController.camera.videoZoomFactor = 2.0;

// Exposure Level
self.cameraRecorderController.camera.exposureValue = 0.8;

// Orientation
self.cameraRecorderController.camera.orientation = UIDeviceOrientationLandscapeLeft;

// Capture Resolution. We recommend not changing this. The SDK automatically selects a suitable
// resolution based on the output size.
self.cameraRecorderController.camera.resolution = AliyunRecordCameraResolution_1280x720;

// Flash Mode (for taking photos).
self.cameraRecorderController.camera.flashMode = AVCaptureFlashModeOn;
Border
AliyunVideoRecordBorderInfo *cameraBorder = [AliyunVideoRecordBorderInfo new];
cameraBorder.color = UIColor.whiteColor;
cameraBorder.width = 3.0;
cameraBorder.cornerRadius = 10.0;
self.cameraRecorderController.borderInfo = cameraBorder;
Basic retouching
// Enable basic retouching.
self.cameraRecorderController.beautifyStatus = YES;
self.cameraRecorderController.beautifyValue = 80;

// Disable basic retouching.
self.cameraRecorderController.beautifyStatus = NO;
self.cameraRecorderController.beautifyValue = 0;
Face stickers
// Apply a face sticker.
[self.cameraRecorderController applyFaceSticker:[self.class resourcePath:@"Gif/hanfumei-800"]];

Filters

Custom filters are supported. For information on how to create filters, see Filters and transitions.

// Apply a filter.
AliyunEffectFilter *filter = [[AliyunEffectFilter alloc] initWithFile:path];
[self.cameraRecorderController applyFilter:filter];
Animated filters
// Apply an animated filter.
NSString *filterDir = [self.class resourcePath:@"AnimationEffect/split_screen_3"];
AliyunEffectFilter *animationFilter =[[AliyunEffectFilter alloc] initWithFile:filterDir];
[self.cameraRecorderController applyAnimationFilter:animationFilter];
Static stickers
// Add a static sticker.
AliyunImageStickerController *imageController = [self.cameraRecorderController addImageSticker:imagePath];
[imageController beginEdit];
imageController.image.center = CGPointMake(150, 200);
[imageController endEdit];

Animated stickers

You can create custom animated stickers. For more information, see animated GIF.
// Add an animated sticker.
AliyunGifStickerController * gifController = [self.cameraController addGifStickerWithConfig:[PathTool boundlePathWithPath:@"Resource/Gif/hanfumei-800"]];
[gifController beginEdit];
gifController.gif.center = CGPointMake(150, 200);
[gifController endEdit];
Take photos
// Take a photo and get the images asynchronously.
// image: The final rendered image.
// rawImage: The original captured image.
[self.cameraRecorderController takePhoto:^(UIImage *image, UIImage *rawImage) {
        
}];

Screen source control

After adding a screen recording source, you receive a controller conforming to the AliyunViewRecordController protocol, which you can use to adjust its border.

Border
AliyunVideoRecordBorderInfo *border = [AliyunVideoRecordBorderInfo new];
border.color = UIColor.whiteColor;
border.width = 3.0;
border.cornerRadius = 10.0;
self.viewRecorderController.borderInfo = border;

Local video source control

After adding a local video source, you receive a controller conforming to the AliyunPlayerRecordController protocol, which you can use to adjust its border.

Border
AliyunVideoRecordBorderInfo *border = [AliyunVideoRecordBorderInfo new];
border.color = UIColor.whiteColor;
border.width = 3.0;
border.cornerRadius = 10.0;
self.playerRecordController.borderInfo = border;

Other features

This section describes how to add background music, apply watermarks, and set a background. For more information about the parameters used in the code, see Related classes.

Clip management

Use the clipManager to manage these clips, for example, by deleting the last clip or all clips. For more information about the parameters, see AliyunClipManager.
// Delete the last video clip.
[self.aliyunRecorder.clipManager deletePart];
// Delete all video clips.
[self.aliyunRecorder.clipManager deleteALLPart];

// Get the total number of clips.
[self.aliyunRecorder.clipManager partCount];
Speed ramping
// Set the recording speed. Recommended values are between 0.5 and 2.0.
[self.aliyunRecorder setRate:2];
Background music
// Add background music.
AVURLAsset *audioAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:filePath] options:nil];
float audioDuration = CMTimeGetSeconds(audioAsset.duration);
[self.aliyunRecorder.config setBgMusicWithFile:filePath
                                startTime:0.0    // Starts from 0 seconds.
                                duration:MIN(self.aliyunRecorder.clipManager.maxDuration, audioDuration)];

// Remove the background music.
[self.aliyunRecorder.config removeBgMusic];
Watermarks
// Create a watermark.
- (AliyunRecorderImageSticker *) waterMark
{
    if (!_waterMark) {
        NSString *watermarkPath = [AlivcImage pathOfImageName:@"shortVideo_paster_gif"];
        _waterMark = [[AliyunRecorderImageSticker alloc] initWithImagePath:watermarkPath];
        _waterMark.size = CGSizeMake(42, 30);
        _waterMark.center = CGPointMake(_waterMark.size.width * 0.5 + 4, _waterMark.size.height * 0.5 + 4);
        _waterMark.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;
    }
    return _waterMark;
}

// Apply the watermark.
[self.aliyunRecorder.config addWaterMark:self.waterMark];

// Remove the watermark.
[self.aliyunRecorder.config removeWaterMark:self.waterMark.stickerId];
Background
// Create a background object.
- (AliyunRecorderBackgroundInfo *) bgInfo
{
    if (!_bgInfo) {
        _bgInfo = [AliyunRecorderBackgroundInfo new];
         // _bgInfo.color = UIColor.redColor;
        NSString *imgName = @"xxx.png";
        _bgInfo.image = [UIImage imageNamed:imgName];
        _bgInfo.renderMode = AliyunRenderMode_ResizeAspectFill;
    }
    return _bgInfo;
}

// Apply the background object.
self.aliyunRecorder.config.bgInfo = self.bgInfo;

Custom rendering

After adding a camera recording source, the SDK passes captured data () to your app via the customRender callback. You can then perform custom rendering, for example with a third-party SDK, and return the processed to the short video SDK for composition.
// Step 1: Enable custom rendering. A camera recording source must be added.
self.aliyunRecorder.customRender = self;
// Step 2: Implement the AliyunRecorderCustomRender protocol.
- (CVPixelBufferRef) onAliyunRecorderCustomRenderToPixelBuffer:(AliyunRecorder *)recorder withSampleBuffer:(CMSampleBufferRef)sampleBuffer {
    // Perform custom rendering here, such as integrating a third-party beauty effects SDK.
    // Return the processed CVPixelBufferRef.
    // If no custom rendering is performed, return CMSampleBufferGetImageBuffer(sampleBuffer).
    ...
}
Note Custom rendering allows you to process raw camera data for various applications, including basic retouching, face shaping, makeup effects, gesture recognition, AI image matting, and chroma key. These features integrate with the short video SDK. For implementation details, see the short video SDK demo for iOS.

Recording callbacks

Implement delegate methods to receive real-time status updates during audio and video processing. For more information about the parameters used in the code, see Related classes.

// Common event callback handlers:
#pragma mark - AliyunRecorderDelegate

- (void)onAliyunRecorderWillStopWithMaxDuration:(AliyunRecorder *)recorder {
    NSLog(@"Record2 Will Stop Recording With Max Duration");
    [self.aliyunRecorder stopPreview];
}

- (void)onAliyunRecorderDidStopWithMaxDuration:(AliyunRecorder *)recorder {
    NSLog(@"Record2 Did Recording With Max Duration");
    [self.aliyunRecorder finishRecord:^(NSString *outputPath, NSError *error) {
        if (!error) {

        }
    }];
}

- (void)onAliyunRecorder:(AliyunRecorder *)recorder progressWithDuration:(CGFloat)duration {
    NSLog(@"Record2 Video Duration: %f", duration);
}

- (void)onAliyunRecorder:(AliyunRecorder *)recorder occursError:(NSError *)error {
    NSLog(@"Record2 Occurs Error: %@", error);
}