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 a 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 The Agora Recording SDK notifies the application of its triggered events according to Callback Methods (IRecordingEngineEventHandler)

Join a Channel (joinChannel)

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

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

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

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

Channel mode:

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

Whether to record voice only:

  • True: Record voice only
  • False: Record both voice and video (default)
isVideoOnly

Whether to record video only:

  • True: Record video only
  • False: Record both voice 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 only.
  • If isAudioOnly is disabled, this parameter (true/false) sets whether to enable audio mixing and video mixing.
mixResolution [1] If you enabled video mixing, you can set the resolution in format: width, high, fps, and kbps. Namely, the width, height, frame rate, 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 real time:

  • False: Mix audio and video respectively.
  • True: Mix audio and video in real time. The format of the mixed audio and video is mp4, and the supported players are listed in Supported Players.
secret The decryption password after enabling the decryption mode
idleLimitSec

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

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

appliteDir Directory to store the Linux SDK built-in applite application
recordFileRootDir [4] Root directory to store the recording files
cfgFilePath [4]

File path of the configuration file. In the 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 and cannot be modified.

lowUdpPort [2] Lowest UDP port
highUdpPort [2] 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 Time interval of the captured screenshot, 1 second minimum, 5 seconds maximum
streamType The setting will only take effect if the Agora Native SDK enabled 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 tables for mixed resolutions.
[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) The raw data function does not support mixing videos. The web currently supports raw audio data, not raw video data.
[4](1, 2) Do not set recordFileRootDir and cfgFilePath at the same time.

Video Profile for Communication:

Resolution fps Minimum Bitrate Maximum Bitrate Recommended Bitrate
3840 x 2160 15 3000 9000 6000
2560 x 1440 15 1600 4800 3200
1920 x 1080 15 1000 3000 2000
1280 x 720 15 600 1800 1200
960 x 720 15 480 1440 960
848 x 480 15 300 900 600
640 x 480 15 250 750 500
480 x 480 15 200 600 400
640 x 360 15 200 600 400
360 x 360 15 130 390 260
424 x 240 15 110 330 220
320 x 240 15 90 270 180
240 x 240 15 70 210 140
320 x 180 15 70 210 140
240 X 180 15 60 180 120
180 x 180 15 50 150 100
160 x 120 15 30 90 60
120 x 120 15 25 75 50

Video Profile for Live Broadcast:

Resolution fps Minimum Bitrate Maximum Bitrate Recommended Bitrate
3840 x 2160 15 6000 18000 12000
2560 x 1440 15 3200 9600 6400
1920 x 1080 15 2000 6000 4000
1280 x 720 15 1200 3600 2400
960 x 720 15 960 2880 1920
848 x 480 15 600 1800 1200
640 x 480 15 500 1500 1000
480 x 480 15 400 1200 800
640 x 360 15 400 1200 800
360 x 360 15 260 780 520
424 x 240 15 220 660 440
320 x 240 15 180 540 360
240 x 240 15 140 420 280
320 x 180 15 140 420 280
240 X 180 15 120 360 240
180 x 180 15 100 300 200
160 x 120 15 60 180 120
120 x 120 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 the 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 Width of the entire canvas (display window or screen)
canvasHeight Height of the entire canvas (display window or screen)
backgroundColor Enter any of the 6-digit symbols defined in RGB
regions

Array of AgoraRtcVideoCompositingRegion. Each host in the channel has a region to display the video on the screen with the following parameters to be set:

  • uid: User ID of the user with the video to be displayed in the region.

    • x[0.0,1.0]: Horizontal position of the region on the screen.
    • y[0.0,1.0]: Vertical position of the region on the screen.
    • width[0.0, 1.0]: Actual width of the region.
    • height[0.0, 1.0]: Actual height of the region.
  • zOrder[0, 100]: 0 means the region is at the bottom, and 100 means the region is at 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 Application defined data

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

../_images/sei_overview.png

Leave a Channel (leaveChannel)

public virtual int leaveChannel();

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

Get the Properties (getProperties)

virtual const RecordingEngineProperties* getProperties()

This method allows you to get a series of properties, and only supports retrieving the information of the recording path. Before joining any channel, you can get the recording path immediately after you start the recording. The difference between onUserJoined is that onUserJoined returns the recording path information only when you are in a channel.

Release the 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 has occurred during SDK runtime. 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 about 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 SDK runtime. In most cases, the application can ignore the warnings reported by the SDK because the SDK can usually fix the issue and resume running.

Name Description
warn

Warning codes:

  • WARN_NO_AVAILABLE_CHANNEL = 103: No channel resources are available. For example, the server cannot allocate any channel resource.
  • WARN_LOOKUP_CHANNEL_TIMEOUT = 104: Timeout 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 poor 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 the request is illegal.
  • WARN_OPEN_CHANNEL_TIMEOUT = 106: Timeout when opening the channel. Once the specified channel is found, the SDK opens the channel. The warning usually occurs when the network condition is too poor 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 the 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 Channel ID assigned based on the channel name specified in the joinChannel() API.
uid User ID. If the uid is specified in the joinChannel method, it returns the specified ID; if not, it returns an ID that is automatically assigned 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 User ID
recordingDir 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). If no data package is received from the user in 15 seconds, the SDK assumes the user is offline. Sometimes a weak network connection may lead to false detections. 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 has timed out and dropped offline because it has not received any data package for a long time. [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 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 an unreliable channel, the SDK may assume the other user has timed out and dropped offline.

Raw Audio Data Received Callback (audioFrameReceived)

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

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

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

AudioPcmFrame

The struct of the received raw audio 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 Timestamp of the frame
channels Number of the sound channels
sample_bits Sampling data width
sample_rates Sampling rate
samples Number of samples
pcmBuf Audio frame buffer
pcmBufSize Size of the audio frame buffer

AudioAacFrame

The struct of the received audio file in aac format:

Name Description
frame_ms Timestamp of the frame

Raw Video Data Received Callback (videoFrameReceived)

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

This callback is triggered when the raw video data is received. It does not only allow getting the raw video data, but also deciding on the frequency of capturing the data to detect sexually explicit content, if necessary. It is recommended that you only capture the i frames and ignore the other frames, but you can decide on the frequency.

Name Description
uid User ID
frame 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 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 Timestamp of the frame
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 Width of the video pixel
height Height of the video pixel
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 Video frame buffer
bufSize Size of the video frame buffer

VideoH264Frame

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 raw video data in H.264 format.

Name Description
frame_ms Timestamp of the frame
buf Video frame buffer
bufSize Size of the video frame buffer

VideoJpgFrame

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 Timestamp of the frame
buf Video frame buffer
bufSize Size of the video frame buffer