Windows&Linux&Harmony

本文档将介绍如何在您的Windows、Linux、Harmony项目中集成 ARTC SDK, 快速实现一个简单的实时音视频互动App,适用于互动直播和视频通话等场景。

功能简介

在开始之前,了解以下几个关键概念会很有帮助:

  • ARTC SDK:这是阿里云的实时音视频产品,帮助开发者快速实现实时音视频互动的SDK。

  • GRTN:阿里云全球实时传输网络,提供超低延时、高音质、安全可靠的音视频通讯服务。

  • 频道:相当于一个虚拟的房间,所有加入同一频道的用户都可以进行实时音视频互动。

  • 主播:可在频道内发布音视频流,并可订阅其他主播发布的音视频流。

  • 观众:可在频道内订阅音视频流,不能发布音视频流。

实现实时音视频互动的基本流程如下:

image
  1. 用户需要设置频道场景,并加入频道:

    • 视频通话场景:所有用户都是主播角色,可以进行推流和拉流

    • 互动直播场景:需要在频道内推流的用户设置主播角色;如果用户只需要拉流,不需要推流,则设置观众角色。

  2. 加入频道后,不同角色的用户有不同的推拉流行为:

    • 所有加入频道内的用户都可以接收频道内的音视频流。

    • 主播角色可以在频道内推音视频流

    • 观众如果需要推流,需要将用户角色切换成主播,便可以推流。

创建应用

获取实时音视频应用的AppIDAppKey,详情请参见创建应用

服务器集成

  1. 将阿里云提供的鉴权代码集成到您的服务器端环境中,详情请参见Token鉴权

  2. 服务器端提供API,方便移动应用(APP)端调用。

功能实现

Windows

前提条件

  • Visual Studio 2015 或以上版本。

  • WIndows 7 或以上版本。

集成SDK

  1. SDK下载,获取最新的 ARTC SDK 文件。

  2. 解压 ARTC SDK 文件,并将目录下的文件拷贝到您的项目中。

  3. 配置项目属性:

    1. 在解决方案资源管理器窗口中,右键单击项目,进入“属性”界面。

      image.png

    2. 添加包含目录:选择配置属性(Configuration Properties) → C/C++ 常规(General),在附加包含目录(Additional Include Directories)中添加头文件路径。

      image.png

    3. 添加库目录:在 Properties 窗口中,选择配置属性(Configuration Properties) → 链接器( Linker)→ 常规(General),在附加库目录( Additional Library Directories) 中添加库文件(.lib)的路径,例如.../x64/Release

      image.png

    4. 指定链接库文件:在 Properties 窗口中,选择配置属性(Configuration Properties)→ 链接器( Linker)→ 输入(Input),在附加依赖项(Additional Dependencies)中添加需要链接的库文件名“AliRTCSdk.lib”。

实现步骤

1、初始化RTC引擎及回调注册

说明

SDK设计为在遇到异常情况时,首先尝试内部重试机制以恢复正常状态。对于那些SDK无法自行解决的错误,会通过明确定义的回调接口(API)通知到您的应用程序。

异常发生原因

回调及参数

解决方案

说明

鉴权失败

onJoinChannelResult回调中的result返回AliRtcErrJoinBadToken

发生错误时App需要检查Token是否正确。

在用户主动调用API时,若鉴权失败,系统将在调用API的回调中返回鉴权失败的错误信息。

鉴权将要过期

onWillAuthInfoExpire

发生该异常时App需要重新获取最新的鉴权信息后,再调用refreshAuthInfo刷新鉴权信息。

鉴权过期错误在两种情况下出现:用户调用API或程序执行期间。因此,错误反馈将通过API回调或通过独立的错误回调通知。

鉴权过期

onAuthInfoExpired

发生该异常时App需要重新入会。

鉴权过期错误在两种情况下出现:用户调用API或程序执行期间。因此,错误反馈将通过API回调或通过独立的错误回调通知。

网络连接异常

onConnectionStatusChange回调返回AliRtcConnectionStatusFailed。

发生该异常时APP需要重新入会。

SDK具备一定时间断网自动恢复能力,但若断线时间超出预设阈值,会触发超时并断开连接。此时,App应检查网络状态并指导用户重新加入会议。

被踢下线

onBye

  • AliRtcOnByeUserReplaced:当发生该异常时排查用户userid是否相同。

  • AliRtcOnByeBeKickedOut:当发生该异常时,表示被业务踢下线,需要重新入会。

  • AliRtcOnByeChannelTerminated:当发生该异常时,表示房间被销毁,需要重新入会。

RTC服务提供了管理员可以主动移除参与者的功能。

本地设备异常

onLocalDeviceException

发生该异常时App需要检测权限、设备硬件是否正常。

RTC服务支持设备检测和异常诊断的能力;当本地设备发生异常时,RTC服务会通过回调的方式通知客户本地设备异常,此时,若SDK无法自行解决问题,则App需要介入以查看设备是否正常。

class AliEngineEventListenerImpl : public AliEngineEventListener {
public:
    AliEngineEventListenerImpl(AliEngine* engine, HWND hWnd) {
        mAliRtcEngine = engine;
        mHWnd = hWnd;
    };
    virtual AliEngineEventListenerImpl() {};

    virtual void OnConnectionStatusChange(int status, int reason) override {
        if (status == AliEngineConnectionFailed) {
            /* TODO: 务必处理;建议业务提示客户,此时SDK内部已经尝试了各种恢复策略已经无法继续使用时才会上报 */
        } else {
            /* TODO: 可选处理;增加业务代码,一般用于数据统计、UI变化 */
        }
    };

    virtual void OnLocalDeviceException(AliEngineLocalDeviceType deviceType, AliEngineLocalDeviceExceptionType exceptionType, const char* msg) override {
        /* TODO: 务必处理;建议业务提示客户错误,此时SDK内部已经尝试了各种恢复策略已经无法继续使用时才会上报 */
    };

    virtual void OnJoinChannelResult(int result, const char *channel, const char *userId, int elapsed) override {
        /* TODO: 可选处理;增加业务代码,一般用于数据统计、UI变化 */
    };

    virtual void OnLeaveChannelResult(int result, AliEngineStats stats) override {
        
    };

    virtual void OnAuthInfoWillExpire() override {
        /* TODO: 务必处理;业务触发重新获取当前channel,user的鉴权信息,然后设置refreshAuthInfo即可 */
    };

    virtual void OnBye(int code) override {
        /* TODO: 建议业务根据自己的场景,进行对应的处理 */
    };

    virtual void OnRemoteUserOnLineNotify(const char *uid, int elapsed) override {
        
    };

    virtual void OnRemoteUserOffLineNotify(const char *uid, AliEngineUserOfflineReason reason) override {
        
    };

    virtual void OnRemoteTrackAvailableNotify(const char *uid,
                                                  AliEngineAudioTrack audioTrack,
                                                  AliEngineVideoTrack videoTrack) {
        AliEngineVideoCanvas remote_canvas;
        if (videoTrack == AliEngineVideoTrackCamera
                            || videoTrack == AliEngineVideoTrackBoth) {
            RECT rect;
            ::GetWindowRect(mHWnd, &rect);
            remote_canvas.displayView = remoteView;
            remote_canvas.renderMode = AliEngineRenderModeAuto;
            mAliRtcEngine->SetRemoteViewConfig(remote_canvas,uid,AliEngineVideoTrackCamera);
        } else {
            mAliRtcEngine->SetRemoteViewConfig(remote_canvas, uid, AliEngineVideoTrackCamera);
        }
    }

private:
    AliEngine* mAliRtcEngine = nullptr;
    /* windows 窗口句柄 */
    HWND mHWnd;
};


private:
void createEngine() {
    mAliRtcEngine = AliRtcEngine.Create("");
    mLisenter = new AliEngineEventListenerImpl(mAliRtcEngine, mHWnd);
    mAliRtcEngine->SetEngineEventListener(mLisenter);
}

2、设置入会前的参数

说明
  • 在互动模式和主播角色设定下,SDK默认会自动推送本地音视频流,并接收其他主播的音视频流。

  • 在互动模式和观众角色设定下,SDK不会推送本地的音视频流,但会接收其他主播的音视频流。

  • SDK默认是自动推拉流模式,用户也可以关闭自动推拉流模式。

private:
void initEngineBeforeJoin() {
    /* 可选:入会前的参数设置 */
    mAliRtcEngine->SetChannelProfile(AliEngineInteractiveLive);
    mAliRtcEngine->SetClientRole(AliEngineClientRoleInteractive);
    /* 设置音频的属性 */
    mAliRtcEngine->SetAudioProfile(AliEngineBasicQualityMode, AliEngineSceneMusicMode);

    /* 可选:摄像头预览,不设置也会进行推流 */
    AliEngineVideoCanvas canvas;
    /* windows 窗口句柄 */
    canvas.view = mHWnd;
    mAliRtcEngine.setLocalViewConfig(canvas, AliEngineVideoTrackCamera);
}

3、入会

说明
  • 入会后会按照入会前设定的参数执行相应的推流和拉流。

  • SDK默认会自动推拉流,以减少客户端需要调用的API数量。

initEngineBeforeJoin();
mAliRtcEngine->joinChannel("您的鉴权信息", null, null, "testUserName");

4、切换角色

说明
  • 当用户从主播角色转换到观众角色时(通常被称作“下麦”),系统将停止推送本地的音视频流,已经订阅的音视频流不受影响。

  • 当用户从观众播角色转换到主播角色时(通常被称作“上麦”),系统将会推送本地的音视频流,已经订阅的音视频流不受影响。

/* TODO: 根据业务设置角色 */
/* 设置参与互动角色(主播角色) */
mAliRtcEngine->SetClientRole(AliEngineClientRoleInteractive);
/* 设置观看角色(观众角色) */
mAliRtcEngine->SetClientRole(AliEngineClientRoleLive);

5、离会

mAliRtcEngine->LeaveChannel();

6、销毁引擎

mAliRtcEngine->Destroy();
mAliRtcEngine = nullptr;

效果展示

image

参考信息

Windows SDK

Linux

前提条件

Java准备工作

Python准备工作

C++准备工作

Golang准备工作

实现步骤

1、初始化RTC引擎及回调注册

Java初始化SDK

Python初始化SDK

C++初始化SDK

Golang初始化SDK

2、设置入会前的参数

说明
  • 在互动模式和主播角色设定下,SDK默认会自动推送本地音视频流,并接收其他主播的音视频流。

  • 在互动模式和观众角色设定下,SDK不会推送本地的音视频流,但会接收其他主播的音视频流。

  • SDK默认是自动推拉流模式,用户也可以关闭自动推拉流模式。

Java设置入会参数

Python设置入会参数

C++设置入会参数

Golang设置入会参数

3、入会

说明
  • 入会后会按照入会前设定的参数执行相应的推流和拉流。

  • SDK默认会自动推拉流,以减少客户端需要调用的API数量。

Java入会

Python入会

C++入会

Golang入会

4、切换角色

说明
  • 当用户从主播角色转换到观众角色时(通常被称作“下麦”),系统将停止推送本地的音视频流,已经订阅的音视频流不受影响。

  • 当用户从观众播角色转换到主播角色时(通常被称作“上麦”),系统将会推送本地的音视频流,已经订阅的音视频流不受影响。

Java切换角色

Python切换角色

C++切换角色

Golang切换角色

5、离会

Java离会

Python离会

C++离会

Golang离会

6、销毁引擎

Java销毁引擎

Python销毁引擎

C++销毁引擎

Golang销毁引擎

参考信息

Linux SDK

Harmony

前提条件

  • 已联系华为商务人员,签署合作计划,开通相关权限,获取 DevEco Studio 5.0.3.900 Release 或以上版本。

  • 获取配套 API Version 12的 HarmonyOS NEXT 5.0.0.102 操作系统或以上版本,支持音视频的鸿蒙设备,且已开启“允许调试”选项。

  • 如果需要使用真机调试,请参考 鸿蒙官网文档 进行配置。

  • 鸿蒙设备已经连接到 Internet。

  • 注册华为开发者账号 并完成实名认证。

集成SDK

ohpm自动集成(推荐)

在工程中配置:

"dependencies": {
    "@aliyun_video_cloud/alivcsdk_artc":"6.11.0-beta",
}

运行命令:

ohpm install @aliyun_video_cloud/alivcsdk_artc

下载SDK手动集成

SDK下载中下载最新版本的Harmony ARTC SDK ,放到工程libs中。在工程中配置引用:

"dependencies": {
    "@aliyun_video_cloud/alivcsdk_artc":"file:./libs/AliVCSDK_ARTC-6.11.0-beta.har",
  }

image

实现步骤

1、初始化RTC引擎及回调注册

this.rtcSdk = AliRtcEngine.getInstance(NULL, getContext(this));
this.engineEventListener: AliRtcEngineEventListener = new AliRtcEngineEventListener();
this.engineEventListener
      .onRemoteUserOnline((uid: string, elapsed: boolean)=> {
        //有人入会
      })
      .onRemoteUserOffline((uid:string, reason: AliRtcUserOfflineReason)=> {
        //有人离会
      })
      .onJoinChannel((result : number, channel : string, userId : string, elapsed : number)=> {
        // 入会时触发
      })
      .onLeaveChannel((result : number, stat : AliRtcStats)=> {
        //离会时触发
      })
      
      .onBye((code : AliRtcOnByeType)=> {
        // 被服务器踢出或者频道关闭时回调
      })
      .onOccurError((error : number, msg : string)=> {
        // 发生错误时回调
      })
      
      .onConnectionStatusChange((status : number, reason : number)=> {
        //网络连接变化时回调
      })
    ;

  this.rtcSdk?.setRtcEngineEventListener(this.engineEventListener);

2、设置入会前的参数

说明
  • 在互动模式和主播角色设定下,SDK默认会自动推送本地音视频流,并接收其他主播的音视频流。

  • 在互动模式和观众角色设定下,SDK不会推送本地的音视频流,但会接收其他主播的音视频流。

  • SDK默认是自动推拉流模式,用户也可以关闭自动推拉流模式。

initEngineBeforeJoin = (surfaceId: string) => {
 
  let encoderConfig : AliRtcVideoEncoderConfiguration = new AliRtcVideoEncoderConfiguration();
  encoderConfig.dimensions = new AliRtcVideoDimensions();
  encoderConfig.dimensions.width = 480
  encoderConfig.dimensions.height = 640
  encoderConfig.frameRate = AliRtcFrameRate.AliEngineFrameRateFps15
  this.rtcSdk?.setVideoEncoderConfiguration(encoderConfig)

  let profile : AliRtcChannelProfile = AliRtcChannelProfile.AliEngineInteractiveLive
  if (this.mainPageParams.interactive_mode == 0) {
    profile = AliRtcChannelProfile.AliEngineCommunication
  } else if (this.mainPageParams.interactive_mode == 2) {
    profile = AliRtcChannelProfile.AliEngineInteractiveWithLowLatencyLive
  }
  this.rtcSdk?.setChannelProfile(profile);
  this.rtcSdk?.setClientRole(this.mainPageParams.is_anchor ? AliRtcClientRole.AliEngineClientRoleInteractive : AliRtcClientRole.AliEngineClientRoleLive);


  this.localVideoCanvas.surfaceId = surfaceId;
  this.rtcSdk?.setLocalViewConfig(this.localVideoCanvas, this.componentController, AliRtcVideoTrack.AliEngineVideoTrackCamera);

}

3、入会

说明
  • 入会后会按照入会前设定的参数执行相应的推流和拉流。

  • SDK默认会自动推拉流,以减少客户端需要调用的API数量。

this.initEngineBeforeJoin();
this.rtcSdk?.joinChannel("您的鉴权信息", null, null, "testUserName");

4、切换角色

说明
  • 当用户从主播角色转换到观众角色时(通常被称作“下麦”),系统将停止推送本地的音视频流,已经订阅的音视频流不受影响。

  • 当用户从观众播角色转换到主播角色时(通常被称作“上麦”),系统将会推送本地的音视频流,已经订阅的音视频流不受影响。

/* TODO: 根据业务设置角色 */
/* 设置参与互动角色(主播角色) */
this.rtcSdk?.setClientRole(AliRtcClientRole.AliEngineClientRoleInteractive);
/* 设置观看角色(观众角色) */
this.rtcSdk?.setClientRole(AliRtcClientRole.AliEngineClientRoleLive);

5、离会

this.rtcSdk?.leaveChannel();

6、销毁引擎

AliRtcEngine.destroyInstance();
this.rtcSdk? = null;

参考信息

Harmony SDK