Recording API

Recording API

C++ Interface Class Description
Basic Methods(IRecordingEngine) The IRecordingEngine class provides the main methods that can be invoked by your application.
Callback Methods(IRecordingEngineEventHandler) The IRecordingEngineEventHandler class enables callback event notifications to your application.

Basic Methods(IRecordingEngine)

Create Recording Engine(createAgoraRecordingEngine)

public static IRecordingEngine* createAgoraRecordingEngine(const char * appId, IRecordingEngineEventHandler *eventHandler);

This method creates the Agora recording engine object.

Name Description
appId App ID. For details, see Get an App ID
eventHandler Agora Recording SDK notifies the application of its triggered events according to Callback Methods(IRecordingEngineEventHandler)

Join Channel (joinChannel)

public int joinChannel(const char * channelKey, const char *channelId, uid_t uid, const RecordingConfig &config)

This method lets the recording application join the channel and start recording.

Description Description
channelKey
  • For low-security requirement, set it as NULL
  • For high-security requirement, set it as Channel Key. If an App Certificate is enabled, you must use a Channel Key. For details, refer to dynamic_key
channelId A string providing the unique channel name. The length must be within 64 bytes.
uid User ID: a 32-bit unsigned integer ranges from 1 to (2^32-1). It must be unique.
config See the definition in the following table for details.

The following shows the structure of RecordingConfig:

typedef struct RecordingConfig {
    bool isAudioOnly;
    bool isVideoOnly;
    bool isMixingEnabled;
    bool mixedVideoAudio;
    char * mixResolution;
    char * decryptionMode;
    char * secret;
    char * appliteDir;
    char * recordFileRootDir;
    char * cfgFilePath;
    VIDEO_FORMAT_TYPE decodeVideo;
    AUDIO_FORMAT_TYPE decodeAudio;
    int lowUdpPort;
    int highUdpPort;
    int idleLimitSec;
    int captureInterval;
    CHANNEL_PROFILE_TYPE channelProfile;
    REMOTE_VIDEO_STREAM_TYPE streamType;
}
Name Description
channelProfile

It sets the channel mode:

  • CHANNEL_PROFILE_COMMUNICATION: Communication(default). Anyone in the channel can talk freely
  • CHANNEL_PROFILE _LIVE_BROADCASTING: Live Broadcast
isAudioOnly

Whether to record audio only:

  • true: enable audio recording only
  • false: record both audio and video (default)
isVideoOnly

Whether to record video only:

  • true: enable video recording only
  • false: record both audio and video (default)
isMixingEnabled

Whether to record audio mixing or/and video mixing. The parameter is disabled by default:

  • If isAudioOnly is enabled, this parameter(true/false) sets whether to enable the audio mixing function
  • If isAudioOnly is disabled, this parameter(true/false) sets whether to enable audio mixing and video mixing respectively
mixResolution [1] If you enabled the video mixing, with this parameter you can set the resolution in format: width, high, fps, kbps. Namely, the width, height, framerate, and bitrate of the video stream
decryptionMode

When the whole channel is encrypted, the recording SDK uses this parameter to enable the built-in decryption function:

  • “aes-128-xts”: AES-128, XTS mode
  • “aes-128-ecb”: AES-128, ECB mode
  • “aes-256-xts”: AES-256, XTS mode
mixedVideoAudio

Once you have set isMixingEnabled as true , this parameter allows you to mix audio and video in realtime:

  • false: mix audio and video respectively
  • true: mix audio and video in realtime. The format of the mixed audio and video is mp4, and the supported players are listed at Supported Players .
secret The decryption password after enabling the decryotion mode
idleLimitSec

If the user calls leaveChannel() to stop recording, then the recording file ends with a period of silence which is decided by the value set for this parameter.

The value must be no less than 3 seconds, and the default value is 300 seconds

appliteDir It sets the directory to store the Linux SDK built-in applite application
recordFileRootDir [4] It sets the root directory to store the recording files
cfgFilePath [4]

It sets the path of the configuration file. In this configuration file, you can set the absolute path of the recording file, and the content in the configuration file must be in Json format.

For example, “Recording_Dir” :”<recording path>”}, where Recording_Dir is fixed which can not be modified.

lowUdpPort [2] It sets the lowest UDP port
highUdpPort [2] It sets the highest UDP port
decodeAudio [3]
  • AUDIO_FORMAT_DEFAULT_TYPE = 0: default audio format
  • AUDIO_FORMAT_AAC_FRAME_TYPE = 1: AAC format
  • AUDIO_FORMAT_PCM_FRAME_TYPE = 2: PCM format
decodeVideo [3]
  • VIDEO_FORMAT_H264_FRAME_TYPE = 1: H.264 format
  • VIDEO_FORMAT_YUV_FRAME_TYPE = 2: YUV format
  • VIDEO_FORMAT_JPG_FRAME_TYPE = 3: JPG format
  • VIDEO_FORMAT_JPG_FILE_TYPE = 4: JPG format
captureInterval The time intervel of the captured screenshot, 1 second in minimum, 5 seconds in maximum
streamType The setting will only take effect if the Agora Native SDK enabled the dual stream mode(High Stream by default), otherwise it directly uses the single stream type enabled by the Agora Native SDK.

Footnotes

[1]See the following video profile table for the mixed resolution.
[2](1, 2) All the ports being set must be positive integers, and the value of highUdpPort - lowUdpPort must be no less than 4.
[3](1, 2) When enabled the raw data function, it does not support mixing video. Web currently only support audio raw data, not video raw data.
[4](1, 2) Do not set recordFileRootDir and cfgFilePath at the same time.

Video Profile for Communication:

Resolution FPS MinBR MaxBR Recommend
3840x2160 15 3000 9000 6000
2560x1440 15 1600 4800 3200
1920x1080 15 1000 3000 2000
1280x720 15 600 1800 1200
960x720 15 480 1440 960
848x480 15 300 900 600
640x480 15 250 750 500
480x480 15 200 600 400
640x360 15 200 600 400
360x360 15 130 390 260
424x240 15 110 330 220
320x240 15 90 270 180
240x240 15 70 210 140
320x180 15 70 210 140
240X180 15 60 180 120
180x180 15 50 150 100
160x120 15 30 90 60
120x120 15 25 75 50

Video Profile for Live Broadcast:

Resolution FPS MinBR MaxBR Recommend
3840x2160 15 6000 18000 12000
2560x1440 15 3200 9600 6400
1920x1080 15 2000 6000 4000
1280x720 15 1200 3600 2400
960x720 15 960 2880 1920
848x480 15 600 1800 1200
640x480 15 500 1500 1000
480x480 15 400 1200 800
640x360 15 400 1200 800
360x360 15 260 780 520
424x240 15 220 660 440
320x240 15 180 540 360
240x240 15 140 420 280
320x180 15 140 420 280
240X180 15 120 360 240
180x180 15 100 300 200
160x120 15 60 180 120
120x120 15 50 150 100

Supported Players:

Platform Player mixedVideoAudio=false mixedVideoAudio=true
Linux Default Player Supported Supported
Linux VLC Media Player Supported Supported
Linux ffplay Supported Supported
Windows Media Player Supported Audio Supported
Windows KMPlayer Supported Supported
Windows VLC Player Supported Supported
macOS QuickTime Player Supported Audio Supported
macOS Movist Supported Supported
macOS MPlayerX Supported Supported
macOS KMPlayer Do not Support Do not Support
iOS iOS Default Player Supported Audio Supported
iOS VLC Do not Support Do not Support
iOS KMPlayer Supported Audio Supported
Android Android Default Player Supported Audio Supported
Android MXPlayer Supported Audio Supported
Android VLC for Android Supported Supported
Android KMPlayer Supported Supported

Set Video Mixing Layout(setVideoMixingLayout)

public virtual int setVideoMixingLayout(const VideoMixingLayout &layout);

This method sets the video mixing layout.

typedef struct VideoMixingLayout
{
 struct Region {
     uid_t uid;
     double x;
     double y;
     double width;
     double height;
     int zOrder;
     double alpha;
     int renderMode;

 };
 int canvasWidth;
 int canvasHeight;
 const char* backgroundColor;//e.g. "#C0C0C0" in RGB
 int regionCount;
 const Region* regions;
 const char* appData;
 int appDataLength;
Name Description
canvasWidth The width of the entire canvas(The display window or screen)
canvasHeight The height of the entire canvas(The display window or screen)
backgroundColor Enter any of the 6-digit symbols defined in RGB
regions

The array of AgoraRtcVideoCompositingRegion. Each host in the channel can have a region to display the video on the screen with the following parameters to be set:

  • uid: The user id of the user with the video to be displayed on the region.

    • x[0.0,1.0]: the horizontal position of the region on the screen.
    • y[0.0,1.0]: the vertical position of the region on the screen.
    • width[0.0, 1.0]: the actual width of the region.
    • height[0.0, 1.0]: the actual height of the region.
  • zOrder[0, 100]: 0 means the region is on the bottom, and 100 means the region is on the top.

  • alpha[0.0, 1.0]: 0 means the region is transparent, and 1 means the region is opaque.

  • renderMode:

    • RENDER_MODE_HIDDEN(1): Cropped
    • RENDER_MODE_FIT(2): Zoom to fit
appData The application defined data

Here is an example used to describe the position and size of the region:

../_images/sei_overview.png

Leave Channel (leaveChannel)

public virtual int leaveChannel();

The recording application leaves the channel and releases the occpuied thread resources.

Get Properties(getProperties)

virtual const RecordingEngineProperties* getProperties()

This method allows you to get a series of properties, and currently it only supports retrieving the information of the recording path. You can get the recording path immediately after you started the recording before you join any channel. The difference from onUserJoined is that onUserJoined returns the recording path information only when you are in a channel.

Release IRecordingEngine Object(release)

public virtual int release();

This method destroys the IRecordingEngine object.

Callback Methods(IRecordingEngineEventHandler)

Error Reported Callback(onError)

virtual void onError(int error, STAT_CODE_TYPE stat_code)

This callback indicates that an error occurred during the runtime of the SDK. In most cases reporting an error means that the SDK cannot fix the issue and resume running, and therefore requires actions from the application or simply informs the user on the issue.

Name Description
error error code
stat_code status code
enum ERROR_CODE_TYPE {
ERR_OK = 0,
//1~1000
ERR_FAILED = 1,
ERR_INVALID_ARGUMENT = 2,
ERR_INTERNAL_FAILED = 3,
};

enum STAT_CODE_TYPE {
  STAT_OK = 0,
  STAT_ERR_FROM_ENGINE = 1,
  STAT_ERR_ARS_JOIN_CHANNEL = 2,
  STAT_ERR_CREATE_PROCESS = 3,
  STAT_ERR_MIXED_INVALID_VIDEO_PARAM = 4,

  STAT_POLL_ERR = 0x8,
  STAT_POLL_HANG_UP = 0x10,
  STAT_POLL_NVAL = 0x20,
};

Warning Reported Callback(onWarning)

public virtual void onWarning(int warn);

This callback indicates that some warning occurred during the runtime of the SDK. In most cases the application can ignore the warnings reported by the SDK because the SDK usually can fix the issue and resume running.

Name Description
warn

Warning codes:

  • WARN_NO_AVAILABLE_CHANNEL = 103: No channel resources are available. Maybe because the server cannot allocate channel resources
  • WARN_LOOKUP_CHANNEL_TIMEOUT = 104: Timed-out when looking up the channel. When joining a channel, the SDK looks up the specified channel. The warning usually occurs when the network condition is too bad to connect to the server.
  • WARN_LOOKUP_CHANNEL_REJECTED = 105: The server rejected the request to look up the channel. The server cannot process this request or request is illegal.
  • WARN_OPEN_CHANNEL_TIMEOUT = 106: Timed-out when opening the channel. Once the specific channel is found, the SDK opens the channel. The warning usually occurs when the network condition is too bad to connect to the server.
  • WARN_OPEN_CHANNEL_TIMEOUT = 107: The server rejected the request to open the channel. The server cannot process this request or request is illegal.

Join Channel Callback (onJoinChannelSuccess)

public virtual void onJoinChannelSuccess(const char * channelId, uid_t uid);

This callback indicates that the user has successfully joined the specified channel.

Name Description
channelId The channel ID is assigned based on the channel name specified in joinChannel() API.
uid User ID. If the uid is specified in the joinChannel method, returns the specified ID; if not, returns an ID that is automatically allocated by the Agora server.

Leave Channel Callback (onLeaveChannel)

public virtual void onLeaveChannel(LEAVE_PATH_CODE code)

When the recording application calls the leaveChannel() method, the SDK uses this callback to notify the application that the user has successfully left the channel.

 enum LEAVE_PATH_CODE {
   LEAVE_CODE_INIT = 0,
   LEAVE_CODE_SIG = 1<<1,
   LEAVE_CODE_NO_USERS = 1<<2,
   LEAVE_CODE_TIMER_CATCH = 1<<3,
   LEAVE_CODE_CLIENT_LEAVE = 1 << 4,
};

Other User Joined Channel Callback (onUserJoined)

public virtual void onUserJoined(uid_t uid, UserJoinInfos &infos)

This callback method notifies the application that another user has joined the channel. If there are other users in the channel when that user joins, the SDK also reports to the application on the existing users who are already in the channel.

typedef struct UserJoinInfos {
 const char* recordingDir;
}
Name Description
uid The User ID
recordingDir The directory of the recorded files

The following is an example of a returned directory:

root@ubuntu:/home/workspace/7-21/samples# ./Recorder_local --appId 74a0b7bb5d3e47c7abca0533d17b0afa --uid 333 --channel video --appliteDir `pwd`/../bin

User 63720491 joined, RecordingDir:./20170721/video_085747/

Other User Offline Callback (onUserOffline)

public virtual void onUserOffline(uid_t uid, USER_OFFLINE_REASON_TYPE reason)

This callback notifies the application that a user has left the channel or gone offline.

The SDK reads the timeout data to determine if a user has left the channel (or has gone offline) or not. If no data package is received from the user in 15 seconds, the SDK takes it as the user being offline. Sometimes a weak network connection may lead to false detection, therefore we recommend using signaling for reliable offline detection.

Name Description
uid User ID
reason

Reasons for user going offline:

  • USER_OFFLINE_QUIT = 0: User has quit the call.
  • USER_OFFLINE_DROPPED = 1: The SDK is timeout and dropped offline because it hasn’t received data package for too long [5]
  • USER_OFFLINE_BECOME_AUDIENCE = 2: It is triggered when the host is switched to the audience role. It is only applicable when you set the channel profile as live broadcast scenario when calling the joinChannel() method

Footnotes

[5]Sometimes when the other user quits the call but the message is not passed to the SDK due to unreliable channel, the SDK may mistake it as the other user is timeout and dropped offline.

Audio Raw Data Received Callback(audioFrameReceived)

public virtual void audioFrameReceived(unsigned int uid, const AudioFrame *frame) const

This callback is triggered when the audio raw data is received.

Name Description
uid User ID
frame The received audio data in pcm or aac format
struct AudioFrame {
  AUDIO_FRAME_TYPE type;
  union {
    AudioPcmFrame *pcm;
    AudioAacFrame *aac;
  } frame;
};

AudioPcmFrame

The following is the struct of the received audio raw data in pcm format:

 ~AudioPcmFrame();

 public:

  uint_t frame_ms_;
  uint_t channels_; // 1
  uint_t sample_bits_; // 16
  uint_t sample_rates_; // 8k, 16k, 32k, 44k
  uint_t samples_;

  uchar_t *pcmBuf_;//
  uint_t pcmBufSize_;

 private:
  std::string buf_; // samples * sample_bits_ / CHAR_BIT * channels_
};
Name Description
frame_ms The timestamp of the frame
channels The number of the sound channels
sample_bits The sampling data width
sample_rates The sampling rate
samples The number of samples
pcmBuf The audio frame buffer
pcmBufSize The size of the audio frame buffer

AudioAacFrame

The following is the struct of the received audio file in aac format:

Name Description
frame_ms The timestamp of the frame

Video Raw Data Received Callback(videoFrameReceived)

public virtual void videoFrameReceived(unsigned int uid, const VideoFrame *frame) const

This callback is triggered when the video raw data is received. It does not only enable you of getting the video raw data, but also allows you to decide the frequency of capturing the data to perform porn detection if necessary. It is recommended that you only capture the i frames and ignore the rest frames, but the frequency is decided by yourself.

Name Description
uid User ID
frame The received video data in H264 or YUV format
struct VideoFrame {
  VIDEO_FRAME_TYPE type;
  union {
    VideoYuvFrame *yuv;
    VideoH264Frame *h264;
  } frame;

  int rotation; // 0, 90, 180, 270
};

VideoYuvFrame

The following is the struct of the received video raw data in yuv format:

 ~VideoYuvFrame();

 uint_t frame_ms_;

 uchar_t *ybuf_;
 uchar_t *ubuf_;
 uchar_t *vbuf_;

 uint_t width_;
 uint_t height_;

 uint_t ystride_;
 uint_t ustride_;
 uint_t vstride_;

 //all
 uchar_t *buf_;
 uint_t bufSize_;

private:
 std::string data_;

};

Name Description
frame_ms The frame timestamp
ybuf Pointer to the Y buffer pointer in the YUV data
ubuf Pointer to the U buffer pointer in the YUV data
vbuf Pointer to the V buffer pointer in the YUV data
width Video pixel width
height Video pixel height
ystride Line span of Y buffer in YUV data
ustride Line span of U buffer in YUV data
vstride Line span of V buffer in YUV data
buf The video frame buffer
bufSize The size of the video frame buffer

VideoH264Frame

The following is the struct of the received video raw data in H.264 format:

struct VideoH264Frame {
public:
  uint_t frame_ms;
  uint_t frame_num;

  //all
  uchar_t *buf_;
  uint_t bufSize_;

private:
  std::string payload;
};

This method gets the video raw data in H.264 format.

Name Description
frame_ms The frame timestamp
buf The video frame buffer
bufSize The size of the video frame buffer

VideoJpgFrame

The following is the struct of the received video raw data in H.264 format:

struct VideoJpgFrame {
    friend class RecordingEngineImpl;
  public:
    uint_t frame_ms;

    //all
    uchar_t *buf_;
    uint_t bufSize_;

  private:
    std::string payload;
};
Name Description
frame_ms The frame timestamp
buf The video frame buffer
bufSize The size of the video frame buffer