# 快速开始

# 简介

菊风现在提供的乐鑫 ESP32-S3类型的SDK,将在本章节将指导您快速集成 SDK 到您的设备中,实现乐鑫 ESP32-S3设备间一对一音视频通话功能。

# 前提条件

  • 具有乐鑫 ESP32-S3的设备
  • 确保菊风账号具有 IoT 权限
  • 有效的菊风 AppKey

# 通话集成

# 流程图

乐鑫 ESP32-S3设备和其他设备通话时的流程图如下所示:

(实线部分为需要集成的内容,虚线部分为 SDK 实现的内容)

smart2smart

# 集成步骤

您可以一边参考时序图,一边按照以下步骤集成:

  1. 获取通讯秘钥,用于传入下文中的 jrtc_config 函数。

  2. 导入 IoT 账号,用于传入下文中的 jrtc_config 函数。

  3. 主叫和被叫调用 jrtc_config 配置环境,只需调用一次

  4. 主叫调用 jrtc_open 打开通话通道,返回 jrtc_t 对象(通话对象)。

  5. 主叫调用 jrtc_activate 激活设备的某种媒体功能,其中第二个参数将决定开启设备的功能类型:

    • 传 1 激活设备的扬声器功能;
    • 传 2 激活设备的麦克风功能;
    • 传 3 激活设备的扬声器和麦克风功能;
    • 传 4 激活设备的摄像头功能;
    • 传 7 激活设备的扬声器、麦克风和摄像头功能。

    该方法仅修改本地全局变量,并不会发送请求到服务器。

  6. 通过客户自己的服务器,主叫发起长连接通知被叫。

  7. 被叫在收到长连接通知的时候,调用 jrtc_openjrtc_activate

  8. 在通话通道状态变为 jrtc_joined 后,新建 UI 线程,不断渲染本地画面和远端画面。参考 渲染流程

  9. 调用 jrtc_close 关闭通话通道,通话通道状态将变为 JRTC_LEAVING 或 JRTC_CLOSED 。通过 jrtc_error 可以获取挂断的原因。

// 配置环境,只需调用一次
jrtc_config(appkey, uid, key[16], tokens); 

// (被叫)被叫在接收到长连接后,打开通话通道,获取通话对象 jc
// (主叫)主叫打开通话通道,获取通话对象 jc。并在此时发送长连接通知被叫
jc = jrtc_open("对方uid", ticket, video, camera); 

// 激活设备的麦克风和扬声器功能
jrtc_activate(jc,JRTC_AUDIO); 

// 激活设备的摄像头功能
// jrtc_activate(jc,JRTC_CAMERA); 

// 在通话通道状态变为 jrtc_joined 后。
// 新建 UI 线程,不断渲染本地画面和远端画面,参考下一章 渲染流程

//关闭通话通道, 并且等待网络线程结束
jrtc_close(jc, JRTC_EBYE); 

# 渲染流程

乐鑫 ESP32-S3设备端按照下列步骤进行视频渲染:

  1. 获取 jrtc_image_t 对象 (jrtc_open 中传入的最后两个参数均为 jrtc_image_t 对象):

    jrtc_image_t* img = "jrtc_open函数中传入的video或camera对象";
    
  2. 检查当前是否处于连接(JRTC_JOINED)状态,若不是,则无需渲染:

    if (jrtc_state(jc) <  JRTC_JOINED) break;
    
  3. 建立 UI 线程(App 界面层)负责绘制图像。在绘制前需要对 jrtc_image_t 对象的数据进行判断:

    if (img->get != img->put) {
      '界面绘制操作: 即使用img中的data, 更新界面控件'
        img->get = img->put;//增加读计数
    }
    

    利用 img->get != img->put 作为判断条件是因为:一旦发生数据传输,SDK 内部会不断修改 img 对象中的数据。所以当 img->get != img->put 的时候说明有新的数据产生。

    // 内部逻辑,非集成部分
    if (img->get == img->put) {
     //'更新图像内容: 即对img中的data, width, height, format 赋值'
     img->put++;//增加写计数
    }
    

    由于界面系统不同,界面绘制需要由开发者自行实现。例如 ASR 原生 LittlevGL 的 lv_watch 界面中, 界面绘制操作如下:

    //yuv420_2_rgb565 是内置的格式转换函数
    extern void yuv420_2_rgb565(int width, int height, const unsigned char *src, unsigned short *dst, unsigned semi);
    yuv420_2_rgb565(img->width, img->height, img->data, img_dsc->data, img->format);
    img->get = img->put;
    lv_img_set_src(img, img_dsc);//img, img_dsc 都是界面中的相应UI控件
    

# 主要函数

# jrtc_config

配置环境。会修改内部的全局变量,仅需在通话前调用一次

函数原型:

void jrtc_config (const char* appkey, const char* uid, const char key[16], const char* tokens);

参数详细如下:

WARNING

SDK 内部将直接引用该参数内存地址,需要由外部保证参数的内存地址的有效性。在通话结束前不允许将参数指向空,并且不能在通话过程中调用 jrtc_config。

参数 说明
appkey AppKey 是应用在 菊风云平台 中的唯一标识,类似应用的身份证。通过在控制台创建应用获取。
uid 自己的账号 id,需要自行导入,参考 导入 IoT 账号
key[] 通讯秘钥,在控制台获取,参考 获取通讯秘钥
token 用于鉴权的 token,默认设置为""。对于非token鉴权的用户使用默认值即可。

# jrtc_open

打开通话通道,分配通话资源,返回 jrtc_t 对象。如果希望仅发起一对一音频通话,那么将后两个参数设置为空即可。

函数原型:

struct jrtc_t* jrtc_open (const char* uid, const char* ticket, struct jrtc_image_t* video, struct jrtc_image_t* camera);

参数详细如下:

WARNING

SDK 内部将直接引用该参数内存地址,需要由外部保证参数的内存地址的有效性。在通话结束前不允许将参数指向空。

参数 类型 说明
uid char* 对方的账号 id
ticket char* 开发者自定义的唯一 ID 。对呼时, 必须使用相同的ticket, 以便服务器精确标识会话。注意:不能包含JSON需转义的字符。且不能超过 64 位
video struct jrtc_image_t* 期望接收的视频尺寸和帧速,码率. 若 NULL,则不接收视频
camera struct jrtc_image_t* 用于预览图像,建议的发送尺寸和帧速,码率. 若 NULL, 则不使用镜头

# jrtc_activate

激活设备的某个媒体功能,开启的功能类型取决于第二个参数的值:

  • 传 1 激活设备的扬声器功能;
  • 传 2 激活设备的麦克风功能;
  • 传 3 激活设备的扬声器和麦克风功能;
  • 传 4 激活设备的摄像头功能;
  • 传 7 激活设备的扬声器、麦克风和摄像头功能。

函数原型:

void jrtc_activate (struct jrtc_t* jc, int devices);

参数详细如下:

参数 类型 说明
jc struct jrtc_t* jrtc_t 对象,通过 jrtc_open 获取
devices int jrtc_device 的集合:
  • JRTC_SPEAKER = 1
  • JRTC_MICROPHONE = 2
  • JRTC_AUDIO = 3
  • JRTC_CAMERA = 4

# jrtc_close

关闭通话通道,释放通话资源。

调动该函数可能会出现停顿是因为正在关闭设备的通话资源。

函数原型:

void jrtc_close (struct jrtc_t* jc, enum jrtc_error err);

参数详细如下:

参数 类型 说明
jc struct jrtc_t* jrtc_t 对象,通过 jrtc_open 获取
err enum jrtc_error jrtc_error 的集合:
  • 关闭通话通道可设置为 JRTC_EBYE
  • 语音中断可设置为JRTC_EAUDIOCALL
  • 其他未知情况可设置为 JRTC_ENIL

# 次要函数

# jrtc_set_camera

动态设置前后镜头。传入 0 表示开启后镜头,传入1 表示开启前镜头。

函数原型:

void jrtc_set_camera (struct jrtc_t* jc, int camera);

TIP

  • ASR 设备通过 extern int mci_videocall_camera_get_sensor(void); (设备厂商自带的函数)获取当前摄像头。
  • 8910 设备无此接口。

# jrtc_deactivate

关闭设备的媒体功能。

函数原型:

void jrtc_deactivate (struct jrtc_t* jc, int devices);

# jrtc_state

获取通话通道状态。

函数原型:

enum jrtc_state jrtc_state  (const struct jrtc_t *jc);

# jrtc_error

返回最近的出错值。

函数原型:

enum jrtc_error jrtc_error  (const struct jrtc_t *jc);

# 枚举说明

# jrtc_state

通话通道状态。

参数 说明
JRTC_CLOSED = 0 初始状态
JRTC_LEAVING jrtc_leave 或内部出错后的状态
JRTC_OPENED 调用jrtc_open 后的状态
JRTC_JOINING 加入中的状态
JRTC_JOINED 成功加入会话
JRTC_TALKING 收到媒体后的状态

# jrtc_error

通话错误值。

参数 说明
JRTC_ENIL = 0 unknown error
JRTC_EPERM = 1 Operation not permitted
JRTC_ENONET = 64 Machine is not on the network
JRTC_EPROTO = 71 Protocol error
JRTC_EMSGSIZE = 90 Message too long
JRTC_ECONNRESET=104 Connection reset by peer
JRTC_ETIMEDOUT =101 Connection timed out
JRTC_ECONNREFUSED=111 Connection refused or closed
JRTC_EDECLINE = 129 Peer decline the call
JRTC_EINVOKETIMEOUT = 130 IoTUnit invoke timeout
JRTC_ECALLSERVERERROR = 131 Call server error
JRTC_EROOMNOTFND = 132 Room or callee not found
JRTC_ECALLTIMEOUT = 133 Call timeout
JRTC_ENOTREG = 134 device id not registered
JRTC_ELOGIN = 135 device id login failed
JRTC_EAUDIOCALL = 252 external audio call, don't close audio deivce
JRTC_EAUDIO=253 Audio device error
JRTC_EVIDEO=254 Video device error
JRTC_EBYE = 255 Success, Closed by peer leave

# jrtc_device

通话中的媒体设备。

参数 说明
JRTC_SPEAKER = 1 喇叭
JRTC_MICROPHONE = 2 麦克风
JRTC_AUDIO = 3 所有音频设备 包含JRTC_SPEAKER 和 JRTC_MICROPHONE
JRTC_CAMERA = 4 摄像头
最后更新时间: 2022/6/29 11:04:43