Cloud Recording Callback

This document describes the callback events of the updated cloud recording feature.

Configuration Information

On the Tencent RTC Console, you can configure callback information. Upon configuration completion, you can receive event callback notifications.



Note:
You need to prepare the following information in advance and complete the Callback Configuration in the console.
Required: the HTTP/HTTPS server address to receive callback notifications.
Optional: Key for signature computation. You can customize a key of up to 32 characters, composed of uppercase and lowercase letters and numbers.

Timeout Retry

If your server does not respond within 5 seconds after the event callback server sends the message notification, it is deemed as a failed notification. If the initial notification fails, an immediate retry is performed. If the notification fails again, retry will be performed at an interval of 10 seconds until the message has been kept for 1 minute, after which retries will not be performed.

Callback API

You can assign an HTTP/HTTPS service gateway for subscribing to callback messages. When any related event happens, the cloud recording system calls back the event notification to your message receiving server.

Format of the Event Callback Message

Event callback messages are sent to your server via HTTP/HTTPS POST requests, in which:
Character Encoding Format: UTF-8.
Request: The body is in the JSON format.
Response: HTTP STATUS CODE = 200. The server ignores the specific content of the response package. To ensure protocol friendliness, it is recommended that the customer put the following in the response content: JSON: {"code":0}.

Parameter Description

The Header of the Event Callback Message Contains the Following Fields:

Field name
Value
Content-Type
application/json
Sign
Signature value
SdkAppId
sdk application id

The Body of the Event Callback Message Includes the Following Fields:

Field Name
Type
Description
EventGroupId
Number
Event group ID, fixed at 3 for cloud recording
EventType
Number
Event type for callback notification
CallbackTs
Number
The Unix timestamp (in milliseconds) when the event callback server sends a callback request to your server
EventInfo
JSON Object
The event information

Event Type Description:

Field Name
Type
Description
EVENT_TYPE_CLOUD_RECORDING_RECORDER_START
301
The cloud recording module starts.
EVENT_TYPE_CLOUD_RECORDING_RECORDER_STOP
302
The cloud recording module exits.
EVENT_TYPE_CLOUD_RECORDING_UPLOAD_START
303
The cloud recording file upload task starts, and it is called back only when COS is chosen.
EVENT_TYPE_CLOUD_RECORDING_FILE_INFO
Cloud recording: Generating the M3U8 index file. After the first successful generation and upload, it is called back only when COS is chosen through API recording.
EVENT_TYPE_CLOUD_RECORDING_UPLOAD_STOP
The cloud recording file upload is complete. It is called back only when COS is chosen.
EVENT_TYPE_CLOUD_RECORDING_FAILOVER
Cloud recording migration occurs. It is triggered when the existing recording task is migrated to a new load.
EVENT_TYPE_CLOUD_RECORDING_FILE_SLICE
Cloud recording: Generating the M3U8 index file (generating the first ts slice). After generation, it is called back only when COS is chosen through API recording.
EVENT_TYPE_CLOUD_RECORDING_DOWNLOAD_IMAGE_ERROR
An error occurs when the cloud recording attempts to download and decode the image file.
EVENT_TYPE_CLOUD_RECORDING_MP4_STOP
The MP4 recording task of cloud recording stops, and it is called back only when COS is chosen via API recording (when automatic recording is turned on in the console and the authorized VOD COS is selected as storage, please pay attention to event 311).
EVENT_TYPE_CLOUD_RECORDING_VOD_COMMIT
The cloud recording VOD recording task has completed the upload of media resources, and it is called back when you select Video on Demand and automatically recording to COS via the console (after file recording ends, the VOD index information is carried. Please subscribe to this type of callback event).
EVENT_TYPE_CLOUD_RECORDING_VOD_STOP
312
The cloud recording VOD task stops, and it is called back only when VOD is chosen.
Note:
The callback statuses from event types 301 to 309 are intermediate states of real-time recording, for you to better understand the recording process and keep track of the status. The successful upload of the actual recording file to video on demand will trigger an event 311 callback, and the overall task is completed and an event 312 is called back.

Event Information Description:

Field Name
Type
Description
RoomId
String/Number
The room name, consistent with the room ID type on the client side
EventTs
Number
The Unix timestamp of when the event occurred, in seconds (this field is not recommended. Instead, EventMsTs is recommended)
EventMsTs
Number
The Unix timestamp of when the event occurred, in milliseconds
UserId
String
The user ID of the recording robot
TaskId
String
The recording ID, which is a unique ID of a single cloud recording task
Payload
JsonObject
Defined based on various event types
When the event type is
301
(EVENT_TYPE_CLOUD_RECORDING_RECORDER_START), the definition of Payload is as follows:
Field Name
Type
Description
Status
Number
0: Indicates that the recording module successfully starts.
1: Indicates that the recording module fails to start.
{
"EventGroupId": 3,
"EventType": 301,
"CallbackTs": 1622186275913,
"EventInfo": {
"RoomId": "xx",
"EventTs": "1622186275",
"EventMsTs": 1622186275757,
"UserId": "xx",
"TaskId": "xx",
"Payload": {
"Status": 0
}
}
}
When the event type is
302
(EVENT_TYPE_CLOUD_RECORDING_RECORDER_STOP), the definition of Payload is as follows:
Field Name
Type
Description
LeaveCode
Number
0: The invocation of recording module normally stops and exits.
1: The customer kicks out the recording robot from the room.
2: The customer disbands the room.
3: The server kicks out the recording robot from the room.
4: The server disbands the room.
99: There is no other user flow in the room except for the recording robot, which will exit after a specified time.
100: Exit from the room due to timeout.
101: Repeated entry of the same user into the same room causes the robot to exit.
{
"EventGroupId": 3,
"EventType": 302,
"CallbackTs": 1622186354806,
"EventInfo": {
"RoomId": "xx",
"EventTs": "1622186354",
"EventMsTs": 1622186275757,
"UserId": "xx",
"TaskId": "xx",
"Payload": {
"LeaveCode": 0
}
}
}
When the event type is
303
(EVENT_TYPE_CLOUD_RECORDING_UPLOAD_START), the definition of Payload is as follows:
Field Name
Type
Description
Status
Number
0: Indicates that the upload module normally starts. 1: Indicates that the upload module fails to be initiated.
When the event type is
304
(EVENT_TYPE_CLOUD_RECORDING_FILE_INFO), the definition of Payload is as follows:
Field Name
Type
Description
FileList
String
The generated M3U8 filename
When the event type is
305
(EVENT_TYPE_CLOUD_RECORDING_UPLOAD_STOP), the definition of Payload is as follows:
Field Name
Type
Description
LeaveCode
Number
0: Indicates that this recording upload task has been completed, and all files have been uploaded to the specified third-party cloud storage. 1: Indicates that this recording upload task has been completed, but at least one file is lingering on the server or backup storage. 2: Indicates that files lingering on the server or backup storage have been restored and uploaded to the designated third-party cloud storage.
Note: 305 indicates the event that the HLS file upload is complete.
When the event type is
306
(EVENT_TYPE_CLOUD_RECORDING_FAILOVER), the definition of Payload is as follows:
Field Name
Type
Description
Status
Number
0: Indicates that this migration is completed.
{
"EventGroupId": 3,
"EventType": 306,
"CallbackTs": 1622191989674,
"EventInfo": {
"RoomId": "20015",
"EventTs": 1622191989,
"EventMsTs": 1622186275757,
"UserId": "xx",
"TaskId": "xx",
"Payload": {
"Status": 0
}
}
}
When the event type is
307
(EVENT_TYPE_CLOUD_RECORDING_FILE_SLICE), the definition of Payload is as follows:
Field Name
Type
Description
FileName
String
M3U8 filename
UserId
String
The user ID corresponding to the recorded file
TrackType
String
Audio/Video types: audio/video/audio_video
BeginTimeStamp
String
The Unix timestamp of the server when the recording starts (in milliseconds)
When the event type is
309
(EVENT_TYPE_CLOUD_RECORDING_DOWNLOAD_IMAGE_ERROR), the definition of Payload is as follows:
Field Name
Type
Description
Url
String
The URL of the failed download
{
"EventGroupId": 3,
"EventType": 309,
"CallbackTs": 1622191989674,
"EventInfo": {
"RoomId": "20015",
"EventTs": 1622191989,
"EventMsTs": 1622186275757,
"UserId": "xx",
"TaskId": "xx",
"Payload": {
"Url": "http://xx"
}
}
}
When the event type is
310
(EVENT_TYPE_CLOUD_RECORDING_MP4_STOP), the definition of Payload is as follows:
Note:
310 is a callback event after an MP4 file is uploaded to the user-specified third-party COS. A recording task may call back multiple events of 310 (each event corresponds to a recorded file information).
Field Name
Type
Description
Status
Number
0: Indicates that the MP4 recording task has exited normally, and all files have been uploaded to the designated third-party cloud storage.
1: Indicates that this MP4 recording task has exited normally, but at least one file lingers on the server or backup storage. 2: Indicates that this MP4 recording task exits abnormally (the possible reason is the failure of extracting HLS files from COS).
FileList
Array
All generated MP4 file names
FileMessage
Array
All generated MP4 file information
FileName
String
MP4 file name
UserId
String
The user ID corresponding to the MP4 file (this field is empty when the recording mode is set to mixed streaming mode)
TrackType
String
audio for audio / video for pure video / audio_video for audio and video
MediaId
String
The primary and auxiliary stream tag. main indicates the primary stream (camera), aux indicates the auxiliary streams (screen sharing), and mix indicates mixed stream recording.
StartTimeStamp
Number
The Unix timestamp at the beginning of the MP4 file (in milliseconds)
EndTimeStamp
Number
The UNIX timestamp at the end of the MP4 file (in milliseconds)
{
"EventGroupId": 3,
"EventType": 310,
"CallbackTs": 1622191965320,
"EventInfo": {
"RoomId": "20015",
"EventTs": 1622191989,
"EventMsTs": 1622186275757,
"UserId": "xx",
"TaskId": "xx",
"Payload": {
"Status": 0,
"FileList": ["xxxx1.mp4", "xxxx2.mp4"],
"FileMessage": [
{
"FileName": "xxxx1.mp4",
"UserId": "xxxx",
"TrackType": "audio_video",
"MediaId": "main",
"StartTimeStamp": 1622186279145,
"EndTimeStamp": 1622186282145
},
{
"FileName": "xxxx2.mp4",
"UserId": "xxxx",
"TrackType": "audio_video",
"MediaId": "main",
"StartTimeStamp": 1622186279153,
"EndTimeStamp": 1622186282153
}
]

}
}
}
When the event type is
311
(EVENT_TYPE_CLOUD_RECORDING_VOD_COMMIT), the definition of Payload is as follows:
Field Name
Type
Description
Status
Number
0: Indicates that the recorded file has been successfully uploaded to the VOD platform.
1: Indicates that the recorded file lingers on the server or backup storage.
2: Indicates that the upload and VOD task for this recorded file to is abnormal.
UserId
String
The user ID corresponding to this recorded file (this field is empty when the recording mode is set to mixed stream mode)
TrackType
String
audio for audio / video for pure video / audio_video for audio and video
MediaId
String
The primary and auxiliary stream tag. main indicates the primary stream (camera), aux indicates the auxiliary stream (screen sharing), and mix indicates mixed stream recording.
FileId
String
The unique ID of this recorded file in the VOD platform
VideoUrl
String
The playback address of this recorded file on the VOD platform
CacheFile
String
The filename corresponding to this MP4/HLS recording file
StartTimeStamp
Number
The Unix timestamp of the beginning of this recorded file (in milliseconds)
EndTimeStamp
Number
The Unix timestamp of the end of this recorded file (in milliseconds)
Errmsg
String
Corresponding error message when the status is not 0
Callback for successful upload:
{
"EventGroupId": 3,
"EventType": 311,
"CallbackTs": 1622191965320,
"EventInfo": {
"RoomId": "20015",
"EventTs": 1622191965,
"EventMsTs": 1622186275757,
"UserId": "xx",
"TaskId": "xx",
"Payload": {
"Status": 0,
"TencentVod": {
"UserId": "xx",
"TrackType": "audio_video",
"MediaId": "main",
"FileId": "xxxx",
"VideoUrl": "http://xxxx",
"CacheFile": "xxxx.mp4",
"StartTimeStamp": 1622186279153,
"EndTimeStamp": 1622186282153
}
}
}
}
Callback for upload failure:
{
"EventGroupId": 3,
"EventType": 311,
"CallbackTs": 1622191965320,
"EventInfo": {
"RoomId": "20015",
"EventTs": 1622191965,
"EventMsTs": 1622186275757,
"UserId": "xx",
"TaskId": "xx",
"Payload": {
"Status": 1,
"Errmsg": "xxx",
"TencentVod": {
"UserId": "123",
"TrackType": "audio_video",
"CacheFile": "xxx.mp4"
}
}
}
}
Note:
After the callback of 311 is received, the file upload is completed, and you need to wait for 30 seconds to 3 minutes for the file to be completely recorded, depending on the file size.
When the event type is
312
(EVENT_TYPE_CLOUD_RECORDING_VOD_STOP), the definition of Payload is as follows:
Field Name
Type
Description
Status
Number
0: Indicates that this VOD upload task has exited normally.
1: Indicates that this VOD upload task exits abnormally.
{
"EventGroupId": 3,
"EventType": 312,
"CallbackTs": 1622191965320,
"EventInfo": {
"RoomId": "20015",
"EventTs": 1622191965,
"EventMsTs": 1622186275757,
"UserId": "xx",
"TaskId": "xx",
"Payload": {
"Status": 0
}
}
}

Calculating a Signature

Signatures are calculated using the HMAC SHA256 encryption algorithm. After your event callback server receives the callback message, it calculates the signature in the same manner. If they match, it is an event callback from Tencent Real-Time Communication (TRTC), not a forged one. The signature calculation is as follows:
// In the signature Sign calculation formula, key is the encryption key used for calculating the signature Sign.
Sign = base64(hmacsha256(key, body))
Note:
The body is the original package body of the callback request received by you. Do not convert it. See the following example:
body="{\n\t\"EventGroupId\":\t1,\n\t\"EventType\":\t103,\n\t\"CallbackTs\":\t1615554923704,\n\t\"EventInfo\":\t{\n\t\t\"RoomId\":\t12345,\n\t\t\"EventTs\":\t1608441737,\n\t\t\"UserId\":\t\"test\",\n\t\t\"UniqueId\":\t1615554922656,\n\t\t\"Role\":\t20,\n\t\t\"Reason\":\t1\n\t}\n}"

Signature Verification Example

Java
Python
PHP
Golang
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
//# Function: Third-party callback sign verification
//# Parameters:
//# key: The key configured in the console
//#   body: The body returned in Tencent Cloud callback
//#   sign: Signature value of sign returned in Tencent Cloud callback
//# Returned values:
//# Status: OK indicates successful verification, and FAIL indicates verification failure. For specific reasons, see Info.
//#   Info: Success/Failure message

public class checkSign {
    public static String secureFinalSign(String key, String entityBody) throws Exception {
        Mac hmacSha256 = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256");
        hmacSha256.initialize(secret_key);
        return Base64.getEncoder().encodeToString(hmacSha256.doFinal(body.getBytes()));
    }
    public static void main(String[] args) throws Exception {
        String key = "123654";
        String body = "{\n" + "\t\"EventGroupId\":\t2,\n" + "\t\"EventType\":\t204,\n" + "\t\"CallbackTs\":\t1664209748188,\n" + "\t\"EventInfo\":\t{\n" + "\t\t\"RoomId\":\t8489,\n" + "\t\t\"EventTs\":\t1664209748,\n" + "\t\t\"EventMsTs\":\t1664209748180,\n" + "\t\t\"UserId\":\t\"user_85034614\",\n" + "\t\t\"Reason\":\t0\n" + "\t}\n" + "}";
        String Sign = "kkoFeO3Oh2ZHnjtg8tEAQhtXK16/KI05W3BQff8IvGA=";
        String resultSign = obtainResultSignature(key, body);

        if (resultSign.equals(Sign)) {
            System.out.println("{'Status': 'OK', 'Info': 'Verification passed'}");
        } else {
            System.out.println("{'Status': 'FAIL', 'Info': 'Verification failed'}");
        }
    }
}
# -*- coding: utf8 -*-
import hmac
import base64
from hashlib import sha256

# Function: Third-party callback sign verification
# Parameters:
#   key: The key configured in the console
#   body: The body returned in Tencent Cloud callback
#   Sign: The signature value sign returned in Tencent Cloud's callback
# Returned values:
# Status: OK indicates successful verification, and FAIL indicates verification failure. For specific reasons, see Info.
#   Info: Success/Failure Information

def checkSign(key, body, sign):
    temp_dict = {}
    computSign = base64.b64encode(hmac.new(key.encode('utf-8'), body.encode('utf-8'), digestmod=sha256).digest()).decode('utf-8')
    print(computSign)
    if computSign equals sign:
        temp_dict['Status'] = 'OK'
        temp_dict['Info'] = 'Verification passed'
        return temp_dict
    else:
        temp_dict['Status'] = 'FAIL'
        temp_dict['Info'] = 'Verification failed'
        return temp_dict

if __name__ == '__main__':
    key = '123654'
    body = "{\n" + "\t\"EventGroupId\":\t2,\n" + "\t\"EventType\":\t204,\n" + "\t\"CallbackTs\":\t1664209748188,\n" + "\t\"EventInfo\":\t{\n" + "\t\t\"RoomId\":\t8489,\n" + "\t\t\"EventTs\":\t1664209748,\n" + "\t\t\"EventMsTs\":\t1664209748180,\n" + "\t\t\"UserId\":\t\"user_85034614\",\n" + "\t\t\"Reason\":\t0\n" + "\t}\n" + "}"
    `sign` = 'kkoFeO3Oh2ZHnjtg8tEAQhtXK16/KI05W3BQff8IvGA='
    result = verifySignature(key, body, sign)
    print(result)
<?php

class TlsEventSig {
private $key = false;
private $body = false;
public function __construct( $key, $body ) {
$this->key = $key;
$this->body = $body;
}

private function __hmacsha256() {
$hash = hash_hmac( 'sha256', $this->body, $this->key, true );
return base64_encode( $hash);
}
public function genEventSig() {
return $this->__hmacsha256();
}
}

$key="789";
$data="{\n\t\"EventGroupId\":\t1,\n\t\"EventType\":\t101,\n\t\"CallbackTs\":\t1608086882372,\n\t\"EventInfo\":\t{\n\t\t\"RoomId\":\t20222,\n\t\t\"EventTs\":\t1608086882,\n\t\t\"UserId\":\t\"222222_phone\"\n\t}\n}";

$api = new TlsEventSig($key, $data);
echo $api->genEventSig();
package main
import "fmt"
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
)

func main () {
var data = "{\n\t\"EventGroupId\":\t1,\n\t\"EventType\":\t101,\n\t\"CallbackTs\":\t1608086882372,\n\t\"EventInfo\":\t{\n\t\t\"RoomId\":\t20222,\n\t\t\"EventTs\":\t1608086882,\n\t\t\"UserId\":\t\"222222_phone\"\n\t}\n}"
var key = "789"

//JSRUN engine 2.0, supporting up to 30 types of languages for online running, with full simulation of online interaction for input and output.
fmt.Println(hmacsha256(data,key))
}

func hmacsha256(data string, key string) string {
h := hmac.New(sha256.New, []byte(key))
h.Write([]byte(data))
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}