您可以阅读本文,了解服务端端互动直播课的集成操作。

前提条件

说明 当您启用旁路转推服务且超过10个并发量时,您需要和客户经理沟通或提交工单(选择视频直播)进行扩容申请。

操作步骤

  1. 获取AppKey和AppID
    • 您可以在控制台点击应用管理,点击查询AppKey,获取AppKey。
    • 您可以在控制台点击应用管理,复制您的AppID,如下图所示:AppID
  2. 获取AccessKey

    您可以为阿里云主账号和子账号创建一个访问密钥(AccessKey)。在调用阿里云ENS API时您需要使用AccessKey完成身份验证。

    AccessKey包括AccessKeyId和AccessKeySecret。
    • AccessKeyId:用于标识用户。
    • AccessKeySecret:用于验证用户的密钥。AccessKeySecret必须保密。
    警告 主账号Accesskey泄露会威胁您所有资源的安全。建议使用子账号(RAM用户)Accesskey进行操作,可有效降低Accesskey泄露的风险。

    具体操作步骤,请参见创建AccessKey

  3. 推流与播流域名鉴权

    添加经过备案的推流域名和播流域名,并完成域名解析、鉴权等操作,即可根据地址拼接规则手动拼接,以快速获取对应的推流地址和播流地址。

    具体操作步骤,请参见推流与播流配置

  4. 获取Demo
    如果您需要互动直播课开源示例项目,请添加钉钉群获取:顶顶群码
  5. 配置运行
    说明 服务端环境需要JDK 8及以上版本。
    1. 下载编译好的server,解压dist/rtc-api.zip。
    2. 修改配置文件BOOT-INF/classes/application.properties,如下图所示: 配置文件
      • 设置AK,需要添加AliyunRTCFullAccess权限 ,AccessKeyId和AccessKeySecret的生成请参考步骤二

        accessKeyID=*

        accessKeySecret=*

      • 修改RTC应用appId和appKey 。

        rtc.1v1audio.appId = *

        rtc.1v1audio.appKey = *

      • artp播流域名和url鉴权key。

        live_artp_play_domain = *

        live_artp_play_domain_auth_key = *

      • 播流域名和url鉴权key。

        live_play_domain = *

        live_play_domain_auth_key = *

      • 推流域名和url鉴权key。

        live_push_domain = *

        live_push_domain_auth_key = *

      • 布局ID。

        layout=*

    3. 执行restart.sh即可启动或重启Server。
    4. 访问http://127.0.0.1:8080/1v1-audio/index.html即可看到启动成功提示。

源码编译运行

命令行切换到项目所在磁盘的根目录执行命令:
mvn clean package -Dmaven.test.skip=true
出现BUILD SUCCESS则打包成功,可看到server/target/rtc-api-0.0.1-SNAPSHOT.jar文件。执行命名即可启动项目
nohup java -jar rtc-api-0.0.1-SNAPSHOT.jar &

主要功能说明

  • 生成joinChannel所需鉴权信息

    访问地址:/app/token

    客户端调用RTC SDK加入房间的Token信息就是从这个接口获得。具体生成方式,请参见RTC帮助文档生成Token

            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            digest.update(appId.getBytes());
            digest.update(appKey.getBytes());
            digest.update(channelId.getBytes());
            digest.update(userId.getBytes());
            digest.update(nonce.getBytes());
            digest.update(Long.toString(timestamp).getBytes());
            String token = DatatypeConverter.printHexBinary(digest.digest()).toLowerCase();
            return token;
  • 查询频道实时在线用户列表

    访问地址:/app/descChannelUsers

    AppServer通过调用rtcOpenApi的DescribeChannelUsers接口查询频道的实时在线人数。

            DefaultAcsClient client = initVodClient();
            DescribeChannelUsersRequest request = new DescribeChannelUsersRequest();
            request.setAppId(appId);
            request.setChannelId(channelId);
            DescribeChannelUsersResponse response = client.getAcsResponse(request);
  • 查询房间开启时间

    访问地址:/app/descChannelStartTime

    生成RTC SDK加入房间所需token时查询当前房间人数,若房间人数为0,则记录房间id和当前时间为房间开启时间。

                DescribeChannelUsersResponse response = RtcOpenAPI.describeChannelUsers(appId, channelId);
                if (CollectionUtils.isEmpty(response.getUserList())) {
                    ImmutablePair<String, String> appChannel = new ImmutablePair<>(appId, channelId);
                    ScheduledFuture scheduledFuture = TASKS.getOrDefault(appChannel, new JSONObject()).getObject("scheduledFuture", ScheduledFuture.class);
    
                    TASKS.put(appChannel, channelInfo);
                }
    
    
                            JSONObject scheduledTask = ScheduledDeleteChannel.TASKS.get(ImmutablePair.of(appId, channelId));
  • 查询房间人数

    访问地址:/describeChannelUsers

            DefaultAcsClient client = initVodClient();
            DescribeChannelUsersRequest request = new DescribeChannelUsersRequest();
            request.setAppId(appId);
            request.setChannelId(channelId);
            DescribeChannelUsersResponse response = client.getAcsResponse(request);
  • 开启旁路直播

    访问地址:/startMPUTask

    API详细请参见StartMPUTask

    推流地址与播流地址生成。

    说明 旁路转推服务为单独计费项目,计费以StartMPUTask接口中TaskProfile参数为准,具体计费规则请参见旁路转推计费。源码中TaskProfile参数默认设置为9IN_1080P,如果您想修改TaskProfile参数,可在路径/src/main/java/com/alivc/base/RtcOpenAPI.java中修改TaskProfile参数。
            StartMPUTaskRequest request = new StartMPUTaskRequest();
            request.setAppId(appId);
            request.setChannelId(channelId);
    
            String layoutId;
            List layoutIdArr = new ArrayList();
    
            layoutId = ConfigMapUtil.getValueByKey("layout");
    
            layoutIdArr.add(Long.valueOf(layoutId));
    
            request.setLayoutIdss(layoutIdArr);
            request.setMediaEncode(30);
            request.setStreamURL(pushUrl);
            request.setTaskId(taskId);
    
            List<StartMPUTaskRequest.UserPanes> userPanesList = new ArrayList<>();
    
            StartMPUTaskRequest.UserPanes userPanes = new StartMPUTaskRequest.UserPanes();
            userPanes.setPaneId(0);
            userPanes.setSourceType("camera");
            userPanes.setUserId(userId);
            userPanesList.add(userPanes);
    
            request.setUserPaness(userPanesList);
    
            DefaultAcsClient client = initVodClient();
    
            StartMPUTaskResponse response = client.getAcsResponse(request);
  • 生成播流地址

    访问地址:/getPlayUrl

    API详细请参见StartMPUTask

    推流地址与播流地址生成。

            String livePushDomain = ConfigMapUtil.getValueByKey("live_push_domain");
            String livePushDomainAuthKey = ConfigMapUtil.getValueByKey("live_push_domain_auth_key");
    
            String livePlayDomain = ConfigMapUtil.getValueByKey("live_play_domain");
            String livePlayDomainAuthKey = ConfigMapUtil.getValueByKey("live_play_domain_auth_key");
    
            String liveArtpPlayDomain = ConfigMapUtil.getValueByKey("live_artp_play_domain");
            String liveArtpPlayDomainAuthKey = ConfigMapUtil.getValueByKey("live_artp_play_domain_auth_key");
    
            String appStream = ConfigMapUtil.getValueByKey("live_app_stream_name");
    
            Long timestamp = System.currentTimeMillis() / 1000;
            String rand = UUID.randomUUID().toString().replace("-", "");
    
            String pushUrl = "rtmp://" + livePushDomain + AuthKeyUrlUtil.getAuthedPath(appStream + channelId, livePushDomainAuthKey, timestamp, rand);
    
    
            log.debug(platform + "-" + channelId + "-" + userId + "-" + role);
    
            ResponseResult responseResult = new ResponseResult();
    
            // 原画
            String playUrlArtp = "artp://" + liveArtpPlayDomain + AuthKeyUrlUtil.getAuthedPath(appStream + channelId, liveArtpPlayDomainAuthKey, timestamp, rand);
            String playUrlFlv = "https://" + livePlayDomain + AuthKeyUrlUtil.getAuthedPath(appStream + channelId + ".flv", livePlayDomainAuthKey, timestamp, rand);
            String playUrlHls1 = "https://" + livePlayDomain + AuthKeyUrlUtil.getAuthedPath(appStream + channelId + ".m3u8", livePlayDomainAuthKey, timestamp, rand);
    
            JSONObject playUrl = new JSONObject();
            playUrl.put("rts", playUrlArtp);
            playUrl.put("flv", playUrlFlv);
            playUrl.put("hls", playUrlHls1);
    
            JSONObject data = new JSONObject();
            data.put("playUrl", playUrl);
  • 布局更新
    访问地址:/updateMPULayout
            UpdateMPULayoutRequest request = new UpdateMPULayoutRequest();
    
            String appId = ConfigMapUtil.getValueByKey("rtc.liveclass.appId");
    
            request.setAppId(appId);
    
            request.setTaskId(channelId);
    
            List<UpdateMPULayoutRequest.UserPanes> userPanesList = new LinkedList<>();
    
            UpdateMPULayoutRequest.UserPanes userPanes = new UpdateMPULayoutRequest.UserPanes();
            userPanes.setUserId(userId);
            userPanes.setPaneId(0);
            userPanes.setSourceType(sourceType);
    
            userPanesList.add(userPanes);
    
            String layoutId = ConfigMapUtil.getValueByKey("layout");
            List layoutIdArr = new ArrayList();
    
            layoutIdArr.add(layoutId);
    
            request.setLayoutIdss(layoutIdArr);
    
            request.setUserPaness(userPanesList);
    
            log.debug(platform + "-" + channelId + "-" + userId + "-" + role);
    
            ResponseResult responseResult = new ResponseResult();
    
                UpdateMPULayoutResponse response = RtcOpenAPI.updateMPULayout(request);
  • 停止旁路直播任务
    访问地址:/stopMPUTask
            StopMPUTaskRequest request = new StopMPUTaskRequest();
    
            String appId = ConfigMapUtil.getValueByKey("rtc.liveclass.appId");
    
            request.setAppId(appId);
            request.setTaskId(channelId);
    
            log.debug(platform + "-" + channelId + "-" + userId + "-" + role);
    
            ResponseResult responseResult = new ResponseResult();
    
            StopMPUTaskResponse response = RtcOpenAPI.stopMPUTaskRequest(request);