Springboot集成声网api接口

1、新增声网配置文件

#声网配置
sw:
    #白板相关 AK
    accessKey: 
    #白板相关 SK
    secretAccessKey: 
    #项目id
    appId: 
    #项目证书
    appCertificate: 

2、新增HttpUtils工具类文件

import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.*;
import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.Map;

/**
 * 通用http发送方法
 *
 * @author ruoyi
 */
public class HttpUtils {
    /**
     * 客户ID
     */
    private static String customerKey = "";

    /**
     * 客户密钥
     */
    private static String customerSecret = "";

    private static final Logger log = LoggerFactory.getLogger(HttpUtils.class);

    /**
     * 向指定 URL 发送GET方法的请求
     *
     * @param url 发送请求的 URL
     * @return 所代表远程资源的响应结果
     */
    public static String sendGet(String url) {
        return sendGet(url, StringUtils.EMPTY);
    }

    /**
     * 向指定 URL 发送GET方法的请求
     *
     * @param url   发送请求的 URL
     * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param) {
        return sendGet(url, param, Constants.UTF8);
    }

    /**
     * 向指定 URL 发送GET方法的请求
     *
     * @param url         发送请求的 URL
     * @param param       请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @param contentType 编码类型
     * @return 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param, String contentType) {
        StringBuilder result = new StringBuilder();
        BufferedReader in = null;
        try {
            String urlNameString = StringUtils.isNotBlank(param) ? url + "?" + param : url;
            log.info("sendGet - {}", urlNameString);
            URL realUrl = new URL(urlNameString);
            URLConnection connection = realUrl.openConnection();
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            connection.connect();
            in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
            log.info("recv - {}", result);
        } catch (ConnectException e) {
            log.error("调用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e);
        } catch (SocketTimeoutException e) {
            log.error("调用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e);
        } catch (IOException e) {
            log.error("调用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e);
        } catch (Exception e) {
            log.error("调用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e);
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception ex) {
                log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
            }
        }
        return result.toString();
    }

    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url   发送请求的 URL
     * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        try {
            log.info("sendPost - {}", url);
            URL realUrl = new URL(url);
            URLConnection conn = realUrl.openConnection();
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("contentType", "utf-8");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            out = new PrintWriter(conn.getOutputStream());
            out.print(param);
            out.flush();
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
            log.info("recv - {}", result);
        } catch (ConnectException e) {
            log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e);
        } catch (SocketTimeoutException e) {
            log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e);
        } catch (IOException e) {
            log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e);
        } catch (Exception e) {
            log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e);
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
            }
        }
        return result.toString();
    }

    /**
     * 向指定 URL 发送Get方法的请求 带有请求头参数
     *
     * @param url 发送请求的 URL
     * @return 所代表远程资源的响应结果
     */
    public static String sendCloudGetHeader(String url) {
        // 拼接客户 ID 和客户密钥并使用 base64 编码
        String plainCredentials = customerKey + ":" + customerSecret;
        String base64Credentials = new String(Base64.getEncoder().encode(plainCredentials.getBytes()));
        // 创建 authorization header
        String authorizationHeader = "Basic " + base64Credentials;
        String result2 = HttpRequest.get(url)
                .header(Header.CONTENT_TYPE, "application/json")//头信息,多个头信息多次调用此方法即可
                .header(Header.AUTHORIZATION, authorizationHeader)
                .timeout(20000)//超时,毫秒
                .execute().body();
        if (result2.startsWith("\"")) {
            result2 = result2.substring(1);
        }
        if (result2.endsWith("\"")) {
            result2 = result2.substring(0, result2.length() - 1);
        }
        return result2;
    }

    /**
     * 向指定 URL 发送POST方法的请求 带有请求头参数
     *
     * @param url  发送请求的 URL
     * @param json 请求参数。
     * @return 所代表远程资源的响应结果
     */
    public static String sendCloudPostHeader(String url, JSONObject json) {
        // 拼接客户 ID 和客户密钥并使用 base64 编码
        String plainCredentials = customerKey + ":" + customerSecret;
        String base64Credentials = new String(Base64.getEncoder().encode(plainCredentials.getBytes()));
        // 创建 authorization header
        String authorizationHeader = "Basic " + base64Credentials;
        String result2 = HttpRequest.post(url)
                .header(Header.CONTENT_TYPE, "application/json")//头信息,多个头信息多次调用此方法即可
                .header(Header.AUTHORIZATION, authorizationHeader)
                .body(String.valueOf(json))//表单内容
                .timeout(20000)//超时,毫秒
                .execute().body();
        if (result2.startsWith("\"")) {
            result2 = result2.substring(1);
        }
        if (result2.endsWith("\"")) {
            result2 = result2.substring(0, result2.length() - 1);
        }
        return result2;
    }

    /**
     * 向指定 URL 发送POST方法的请求 带有请求头参数
     *
     * @param url   发送请求的 URL
     * @param json  请求参数。
     * @param token 请求头部
     * @return 所代表远程资源的响应结果
     */
    public static String sendPostHeader(String url, JSONObject json, String token) {
        String result2;
        //链式构建请求
        if (StringUtils.isNotBlank(token)) {
            result2 = HttpRequest.post(url)
                    .header(Header.CONTENT_TYPE, "application/json")//头信息,多个头信息多次调用此方法即可
                    .header("region", "cn-hz")//头信息,多个头信息多次调用此方法即可
                    .header("token", token)//头信息,多个头信息多次调用此方法即可
                    .body(String.valueOf(json))//表单内容
                    .timeout(20000)//超时,毫秒
                    .execute().body();
        } else {
            result2 = HttpRequest.post(url)
                    .header(Header.CONTENT_TYPE, "application/json")//头信息,多个头信息多次调用此方法即可
                    .header("region", "cn-hz")//头信息,多个头信息多次调用此方法即可
                    .body(String.valueOf(json))//表单内容
                    .timeout(20000)//超时,毫秒
                    .execute().body();
        }
        if (result2.startsWith("\"")) {
            result2 = result2.substring(1);
        }
        if (result2.endsWith("\"")) {
            result2 = result2.substring(0, result2.length() - 1);
        }
        return result2;
    }

    /**
     * 向指定 URL 发送POST方法的请求 带有请求头参数
     *
     * @param url   发送请求的 URL
     * @param json  请求参数。
     * @param token 请求头部
     * @return 所代表远程资源的响应结果
     */
    public static String sendPostScreenHeader(String url, JSONObject json, String token) {
        String result2 = HttpRequest.post(url)
                .header(Header.CONTENT_TYPE, "application/json")//头信息,多个头信息多次调用此方法即可
                .header("region", "cn-hz")//头信息,多个头信息多次调用此方法即可
                .header("token", token)//头信息,多个头信息多次调用此方法即可
                .body(String.valueOf(json))//表单内容
                .timeout(20000)//超时,毫秒
                .execute().body();
        if (result2.startsWith("\"")) {
            result2 = result2.substring(1);
        }
        if (result2.endsWith("\"")) {
            result2 = result2.substring(0, result2.length() - 1);
        }
        return result2;
    }

    /**
     * 向指定 URL 发送Get方法的请求 带有请求头参数
     *
     * @param url   发送请求的 URL
     * @param token 请求头部
     * @return 所代表远程资源的响应结果
     */
    public static String sendGetHeader(String url, String token) {
        String result2;
        //链式构建请求
        if (StringUtils.isNotBlank(token)) {
            result2 = HttpRequest.get(url)
                    .header(Header.CONTENT_TYPE, "application/json;charset=UTF-8")//头信息,多个头信息多次调用此方法即可
                    .header("region", "cn-hz")//头信息,多个头信息多次调用此方法即可
                    .header("token", token)//头信息,多个头信息多次调用此方法即可
                    .timeout(20000)//超时,毫秒
                    .execute().body();
        } else {
            result2 = HttpRequest.get(url)
                    .header(Header.CONTENT_TYPE, "application/json;charset=UTF-8")//头信息,多个头信息多次调用此方法即可
                    .header("region", "cn-hz")//头信息,多个头信息多次调用此方法即可
                    .timeout(20000)//超时,毫秒
                    .execute().body();
        }
        if (result2.startsWith("\"")) {
            result2 = result2.substring(1);
        }
        if (result2.endsWith("\"")) {
            result2 = result2.substring(0, result2.length() - 1);
        }
        return result2;
    }

    /**
     * 向指定 URL 发送Patch方法的请求 带有请求头参数
     *
     * @param url   发送请求的 URL
     * @param token 请求头部
     * @return 所代表远程资源的响应结果
     */
    public static String sendPatchHeader(String url, String token) {
        String result2;
        //链式构建请求
        if (StringUtils.isNotBlank(token)) {
            result2 = HttpRequest.patch(url)
                    .header(Header.CONTENT_TYPE, "application/json;charset=UTF-8")//头信息,多个头信息多次调用此方法即可
                    .header("region", "cn-hz")//头信息,多个头信息多次调用此方法即可
                    .header("token", token)//头信息,多个头信息多次调用此方法即可
                    .timeout(20000)//超时,毫秒
                    .execute().body();
        } else {
            result2 = HttpRequest.patch(url)
                    .header(Header.CONTENT_TYPE, "application/json;charset=UTF-8")//头信息,多个头信息多次调用此方法即可
                    .header("region", "cn-hz")//头信息,多个头信息多次调用此方法即可
                    .timeout(20000)//超时,毫秒
                    .execute().body();
        }
        if (result2.startsWith("\"")) {
            result2 = result2.substring(1);
        }
        if (result2.endsWith("\"")) {
            result2 = result2.substring(0, result2.length() - 1);
        }
        return result2;
    }
}

3、新增token创建文件

public class RtmTokenBuilder {
    public enum Role {
        Rtm_User(1);

        int value;

        Role(int value) {
            this.value = value;
        }
    }

    public AccessToken mTokenCreator;

    public String buildToken(String appId, String appCertificate,
                             String uid, Role role, String channelName, int privilegeTs) throws Exception {
        mTokenCreator = new AccessToken(appId, appCertificate, channelName, uid);
        mTokenCreator.addPrivilege(AccessToken.Privileges.kRtmLogin, privilegeTs);
        return mTokenCreator.build();
    }

    public void setPrivilege(AccessToken.Privileges privilege, int expireTs) {
        mTokenCreator.addPrivilege(privilege, expireTs);
    }

    public boolean initTokenBuilder(String originToken) {
        mTokenCreator.fromString(originToken);
        return true;
    }
}

4、新增token2创建文件

public class RtcTokenBuilder2 {
    public enum Role {
        //(默认)用户有发流权限,即用户可在频道中发流
        ROLE_PUBLISHER(1),
        //用户有接收权限,即用户可在频道中接收,但不可发流
        ROLE_SUBSCRIBER(2);

        public int initValue;

        Role(int initValue) {
            this.initValue = initValue;
        }
    }

    /**
     * Build the RTC token with uid.
     *
     * @param appId:            The App ID issued to you by Agora. Apply for a new App ID from
     *                          Agora Dashboard if it is missing from your kit. See Get an App ID.
     * @param appCertificate:   Certificate of the application that you registered in
     *                          the Agora Dashboard. See Get an App Certificate.
     * @param channelName:      Unique channel name for the AgoraRTC session in the string format
     * @param uid:              User ID. A 32-bit unsigned integer with a value ranging from 1 to (2^32-1).
     *                          optionalUid must be unique.
     * @param role:             ROLE_PUBLISHER: A broadcaster/host in a live-broadcast profile.
     *                          ROLE_SUBSCRIBER: An audience(default) in a live-broadcast profile.
     * @param token_expire:     represented by the number of seconds elapsed since now. If, for example,
     *                          you want to access the Agora Service within 10 minutes after the token is generated,
     *                          set token_expire as 600(seconds).
     * @param privilege_expire: represented by the number of seconds elapsed since now. If, for example,
     *                          you want to enable your privilege for 10 minutes, set privilege_expire as 600(seconds).
     * @return The RTC token.
     */
    public String buildTokenWithUid(String appId, String appCertificate, String channelName, int uid, Role role, int token_expire, int privilege_expire) {
        return buildTokenWithUserAccount(appId, appCertificate, channelName, AccessToken2.getUidStr(uid), role, token_expire, privilege_expire);
    }

    public String buildTokenWithUid(String appId, String appCertificate, String channelName, String uid, Role role, int token_expire, int privilege_expire) {
        return buildTokenWithUserAccount(appId, appCertificate, channelName, uid, role, token_expire, privilege_expire);
    }

    /**
     * Build the RTC token with account.
     *
     * @param appId:            The App ID issued to you by Agora. Apply for a new App ID from
     *                          Agora Dashboard if it is missing from your kit. See Get an App ID.
     * @param appCertificate:   Certificate of the application that you registered in
     *                          the Agora Dashboard. See Get an App Certificate.
     * @param channelName:      Unique channel name for the AgoraRTC session in the string format
     * @param account:          The user's account, max length is 255 Bytes.
     * @param role:             ROLE_PUBLISHER: A broadcaster/host in a live-broadcast profile.
     *                          ROLE_SUBSCRIBER: An audience(default) in a live-broadcast profile.
     * @param token_expire:     represented by the number of seconds elapsed since now. If, for example,
     *                          you want to access the Agora Service within 10 minutes after the token is generated,
     *                          set token_expire as 600(seconds).
     * @param privilege_expire: represented by the number of seconds elapsed since now. If, for example,
     *                          you want to enable your privilege for 10 minutes, set privilege_expire as 600(seconds).
     * @return The RTC token.
     */
    public String buildTokenWithUserAccount(String appId, String appCertificate, String channelName, String account, Role role, int token_expire, int privilege_expire) {
        AccessToken2 accessToken = new AccessToken2(appId, appCertificate, token_expire);
        AccessToken2.Service serviceRtc = new AccessToken2.ServiceRtc(channelName, account);

        serviceRtc.addPrivilegeRtc(AccessToken2.PrivilegeRtc.PRIVILEGE_JOIN_CHANNEL, privilege_expire);
        if (role == Role.ROLE_PUBLISHER) {
            serviceRtc.addPrivilegeRtc(AccessToken2.PrivilegeRtc.PRIVILEGE_PUBLISH_AUDIO_STREAM, privilege_expire);
            serviceRtc.addPrivilegeRtc(AccessToken2.PrivilegeRtc.PRIVILEGE_PUBLISH_VIDEO_STREAM, privilege_expire);
            serviceRtc.addPrivilegeRtc(AccessToken2.PrivilegeRtc.PRIVILEGE_PUBLISH_DATA_STREAM, privilege_expire);
        }
        accessToken.addService(serviceRtc);

        try {
            return accessToken.build();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * Generates an RTC token with the specified privilege.
     * <p>
     * This method supports generating a token with the following privileges:
     * - Joining an RTC channel.
     * - Publishing audio in an RTC channel.
     * - Publishing video in an RTC channel.
     * - Publishing data streams in an RTC channel.
     * <p>
     * The privileges for publishing audio, video, and data streams in an RTC channel apply only if you have
     * enabled co-host authentication.
     * <p>
     * A user can have multiple privileges. Each privilege is valid for a maximum of 24 hours.
     * The SDK triggers the onTokenPrivilegeWillExpire and onRequestToken callbacks when the token is about to expire
     * or has expired. The callbacks do not report the specific privilege affected, and you need to maintain
     * the respective timestamp for each privilege in your app logic. After receiving the callback, you need
     * to generate a new token, and then call renewToken to pass the new token to the SDK, or call joinChannel to re-join
     * the channel.
     *
     * @param appId                        The App ID of your Agora project.
     * @param appCertificate               The App Certificate of your Agora project.
     * @param channelName                  The unique channel name for the Agora RTC session in string format. The string length must be less than 64 bytes. The channel name may contain the following characters:
     *                                     - All lowercase English letters: a to z.
     *                                     - All uppercase English letters: A to Z.
     *                                     - All numeric characters: 0 to 9.
     *                                     - The space character.
     *                                     - "!", "#", "$", "%", "&", "(", ")", "+", "-", ":", ";", "<", "=", ".", ">", "?", "@", "[", "]", "^", "_", " {", "}", "|", "~", ",".
     * @param uid                          The user ID. A 32-bit unsigned integer with a value range from 1 to (2^32 - 1). It must be unique. Set uid as 0, if you do not want to authenticate the user ID, that is, any uid from the app client can join the channel.
     * @param tokenExpire                  represented by the number of seconds elapsed since now. If, for example, you want to access the
     *                                     Agora Service within 10 minutes after the token is generated, set tokenExpire as 600(seconds).
     * @param joinChannelPrivilegeExpire   The Unix timestamp when the privilege for joining the channel expires, represented
     *                                     by the sum of the current timestamp plus the valid time period of the token. For example, if you set joinChannelPrivilegeExpire as the
     *                                     current timestamp plus 600 seconds, the token expires in 10 minutes.
     * @param pubAudioPrivilegeExpire      The Unix timestamp when the privilege for publishing audio expires, represented
     *                                     by the sum of the current timestamp plus the valid time period of the token. For example, if you set pubAudioPrivilegeExpire as the
     *                                     current timestamp plus 600 seconds, the token expires in 10 minutes. If you do not want to enable this privilege,
     *                                     set pubAudioPrivilegeExpire as the current Unix timestamp.
     * @param pubVideoPrivilegeExpire      The Unix timestamp when the privilege for publishing video expires, represented
     *                                     by the sum of the current timestamp plus the valid time period of the token. For example, if you set pubVideoPrivilegeExpire as the
     *                                     current timestamp plus 600 seconds, the token expires in 10 minutes. If you do not want to enable this privilege,
     *                                     set pubVideoPrivilegeExpire as the current Unix timestamp.
     * @param pubDataStreamPrivilegeExpire The Unix timestamp when the privilege for publishing data streams expires, represented
     *                                     by the sum of the current timestamp plus the valid time period of the token. For example, if you set pubDataStreamPrivilegeExpire as the
     *                                     current timestamp plus 600 seconds, the token expires in 10 minutes. If you do not want to enable this privilege,
     *                                     set pubDataStreamPrivilegeExpire as the current Unix timestamp.
     * @note Agora recommends setting a reasonable timestamp for each privilege according to your scenario.
     * Suppose the expiration timestamp for joining the channel is set earlier than that for publishing audio.
     * When the token for joining the channel expires, the user is immediately kicked off the RTC channel
     * and cannot publish any audio stream, even though the timestamp for publishing audio has not expired.
     */
    public String buildTokenWithUid(String appId, String appCertificate, String channelName, int uid,
                                    int tokenExpire, int joinChannelPrivilegeExpire, int pubAudioPrivilegeExpire,
                                    int pubVideoPrivilegeExpire, int pubDataStreamPrivilegeExpire) {
        return buildTokenWithUserAccount(appId, appCertificate, channelName, AccessToken2.getUidStr(uid),
                tokenExpire, joinChannelPrivilegeExpire, pubAudioPrivilegeExpire, pubVideoPrivilegeExpire, pubDataStreamPrivilegeExpire);
    }

    /**
     * Generates an RTC token with the specified privilege.
     * <p>
     * This method supports generating a token with the following privileges:
     * - Joining an RTC channel.
     * - Publishing audio in an RTC channel.
     * - Publishing video in an RTC channel.
     * - Publishing data streams in an RTC channel.
     * <p>
     * The privileges for publishing audio, video, and data streams in an RTC channel apply only if you have
     * enabled co-host authentication.
     * <p>
     * A user can have multiple privileges. Each privilege is valid for a maximum of 24 hours.
     * The SDK triggers the onTokenPrivilegeWillExpire and onRequestToken callbacks when the token is about to expire
     * or has expired. The callbacks do not report the specific privilege affected, and you need to maintain
     * the respective timestamp for each privilege in your app logic. After receiving the callback, you need
     * to generate a new token, and then call renewToken to pass the new token to the SDK, or call joinChannel to re-join
     * the channel.
     *
     * @param appId                        The App ID of your Agora project.
     * @param appCertificate               The App Certificate of your Agora project.
     * @param channelName                  The unique channel name for the Agora RTC session in string format. The string length must be less than 64 bytes. The channel name may contain the following characters:
     *                                     - All lowercase English letters: a to z.
     *                                     - All uppercase English letters: A to Z.
     *                                     - All numeric characters: 0 to 9.
     *                                     - The space character.
     *                                     - "!", "#", "$", "%", "&", "(", ")", "+", "-", ":", ";", "<", "=", ".", ">", "?", "@", "[", "]", "^", "_", " {", "}", "|", "~", ",".
     * @param account                      The user account.
     * @param tokenExpire                  represented by the number of seconds elapsed since now. If, for example, you want to access the
     *                                     Agora Service within 10 minutes after the token is generated, set tokenExpire as 600(seconds).
     * @param joinChannelPrivilegeExpire   The Unix timestamp when the privilege for joining the channel expires, represented
     *                                     by the sum of the current timestamp plus the valid time period of the token. For example, if you set joinChannelPrivilegeExpire as the
     *                                     current timestamp plus 600 seconds, the token expires in 10 minutes.
     * @param pubAudioPrivilegeExpire      The Unix timestamp when the privilege for publishing audio expires, represented
     *                                     by the sum of the current timestamp plus the valid time period of the token. For example, if you set pubAudioPrivilegeExpire as the
     *                                     current timestamp plus 600 seconds, the token expires in 10 minutes. If you do not want to enable this privilege,
     *                                     set pubAudioPrivilegeExpire as the current Unix timestamp.
     * @param pubVideoPrivilegeExpire      The Unix timestamp when the privilege for publishing video expires, represented
     *                                     by the sum of the current timestamp plus the valid time period of the token. For example, if you set pubVideoPrivilegeExpire as the
     *                                     current timestamp plus 600 seconds, the token expires in 10 minutes. If you do not want to enable this privilege,
     *                                     set pubVideoPrivilegeExpire as the current Unix timestamp.
     * @param pubDataStreamPrivilegeExpire The Unix timestamp when the privilege for publishing data streams expires, represented
     *                                     by the sum of the current timestamp plus the valid time period of the token. For example, if you set pubDataStreamPrivilegeExpire as the
     *                                     current timestamp plus 600 seconds, the token expires in 10 minutes. If you do not want to enable this privilege,
     *                                     set pubDataStreamPrivilegeExpire as the current Unix timestamp.
     * @note Agora recommends setting a reasonable timestamp for each privilege according to your scenario.
     * Suppose the expiration timestamp for joining the channel is set earlier than that for publishing audio.
     * When the token for joining the channel expires, the user is immediately kicked off the RTC channel
     * and cannot publish any audio stream, even though the timestamp for publishing audio has not expired.
     */
    public String buildTokenWithUserAccount(String appId, String appCertificate, String channelName, String account,
                                            int tokenExpire, int joinChannelPrivilegeExpire, int pubAudioPrivilegeExpire,
                                            int pubVideoPrivilegeExpire, int pubDataStreamPrivilegeExpire) {
        AccessToken2 accessToken = new AccessToken2(appId, appCertificate, tokenExpire);
        AccessToken2.Service serviceRtc = new AccessToken2.ServiceRtc(channelName, account);

        serviceRtc.addPrivilegeRtc(AccessToken2.PrivilegeRtc.PRIVILEGE_JOIN_CHANNEL, joinChannelPrivilegeExpire);
        serviceRtc.addPrivilegeRtc(AccessToken2.PrivilegeRtc.PRIVILEGE_PUBLISH_AUDIO_STREAM, pubAudioPrivilegeExpire);
        serviceRtc.addPrivilegeRtc(AccessToken2.PrivilegeRtc.PRIVILEGE_PUBLISH_VIDEO_STREAM, pubVideoPrivilegeExpire);
        serviceRtc.addPrivilegeRtc(AccessToken2.PrivilegeRtc.PRIVILEGE_PUBLISH_DATA_STREAM, pubDataStreamPrivilegeExpire);
        accessToken.addService(serviceRtc);

        try {
            return accessToken.build();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
}

5、新增方法类文件

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.media.RtcTokenBuilder2;
import com.ruoyi.media.RtmTokenBuilder;
import com.ruoyi.media.RtmTokenBuilder2;
import com.ruoyi.meeting.domain.Screen;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 声网Controller
 *
 */
@RestController
@RequestMapping("/shengWang")
public class ShengWangController {

    //AccessToken2 从生成到过期的时间长度,单位为秒。
    // 例如,如果你将 token_Expire 设为 600 ,则 AccessToken2 会在生成后 10 分钟过期。
    // AccessToken2 的最大有效期为 24 小时。
    // 如果你将此参数设为超过 24 小时的时间,AccessToken2 有效期依然为 24 小时。
    // 如果你将此参数设为 0,AccessToken2 立即过期。
    private static int tokenExpirationInSeconds = 3600;
    //从 AccessToken2 生成到所有权限过期的时间长度,单位为秒。
    // 例如,如果你将 privilege_Expire 设为 600 ,则权限会在生成后 10 分钟过期。如果你将此参数设为 0(默认值),则权限永不过期。
    private static int privilegeExpirationInSeconds = 3600;

    /**
     * 获取rtm-token
     *
     * @param appId          应用程序id
     * @param appCertificate 应用证书
     * @param channelName    频道名称
     * @param uid            uid
     */
    @GetMapping("/rtmToken")
    public AjaxResult getRtmToken(@RequestParam("appId") String appId,
                                  @RequestParam("appCertificate") String appCertificate,
                                  @RequestParam("channelName") String channelName,
                                  @RequestParam("uid") String uid) throws Exception {
        int privilegeExpirationInSeconds = 3600;
        RtmTokenBuilder token = new RtmTokenBuilder();
        String result = token.buildToken(appId, appCertificate, uid, RtmTokenBuilder.Role.Rtm_User, channelName, privilegeExpirationInSeconds);
        HashMap map = new HashMap();
        map.put("rtmToken", result);
        return AjaxResult.success(map);
    }

    /**
     * 获取rtm-token2
     *
     * @param appId          应用程序id 你在声网控制台创建项目时生成的 App ID
     * @param appCertificate 应用证书 你的项目的 App 证书
     * @param uid            uid RTM 用户 ID
     */
    @GetMapping("/rtmToken2")
    public AjaxResult getRtmToken2(@RequestParam("appId") String appId,
                                   @RequestParam("appCertificate") String appCertificate,
                                   @RequestParam("uid") String uid) {
        //RTM Token 过期的 Unix 时间戳
        int expire = 3600;
        RtmTokenBuilder2 token = new RtmTokenBuilder2();
        String result = token.buildToken(appId, appCertificate, uid, expire);
        HashMap map = new HashMap();
        map.put("rtmToken2", result);
        return AjaxResult.success(map);
    }

    /**
     * 获取rtc-token2
     *
     * @param appId          应用程序id 你在声网控制台创建项目时生成的 App ID
     * @param appCertificate 应用证书 你的项目的 App 证书
     * @param channelName    频道名称
     * @param uid            uid Rtc 用户 ID
     */
    @GetMapping("/rtcToken2")
    public AjaxResult getRtcToken2(@RequestParam("appId") String appId,
                                   @RequestParam("appCertificate") String appCertificate,
                                   @RequestParam("channelName") String channelName,
                                   @RequestParam("uid") String uid) {
        RtcTokenBuilder2 token = new RtcTokenBuilder2();
        //生成 AccessToken2,并设置 AccessToken2 和所有权限的过期时间
        String result = token.buildTokenWithUid(appId, appCertificate, channelName, uid, RtcTokenBuilder2.Role.ROLE_PUBLISHER, tokenExpirationInSeconds, privilegeExpirationInSeconds);
        HashMap map = new HashMap();
        map.put("rtcToken2", result);
        return AjaxResult.success(map);
    }

    /**
     * 获取rtc-token
     *
     * @param appId          应用程序id 你在声网控制台创建项目时生成的 App ID
     * @param appCertificate 应用证书 你的项目的 App 证书
     * @param channelName    频道名称
     * @param uid            uid Rtc 用户 ID
     */
    @GetMapping("/rtcToken")
    public AjaxResult getRtcToken(@RequestParam("appId") String appId,
                                  @RequestParam("appCertificate") String appCertificate,
                                  @RequestParam("channelName") String channelName,
                                  @RequestParam("uid") int uid) {
        RtcTokenBuilder2 token = new RtcTokenBuilder2();
        int tokenExpire = 3600;
        int joinChannelPrivilegeExpire = 3600;
        int pubAudioPrivilegeExpire = 3600;
        int pubVideoPrivilegeExpire = 3600;
        int pubDataStreamPrivilegeExpire = 3600;
        String result = token.buildTokenWithUid(appId, appCertificate, channelName, uid, tokenExpire, joinChannelPrivilegeExpire, pubAudioPrivilegeExpire, pubVideoPrivilegeExpire, pubDataStreamPrivilegeExpire);
        HashMap map = new HashMap();
        map.put("rtcToken", result);
        return AjaxResult.success(map);
    }

    /**
     * 互动白板请求sdkToken
     *
     * @param accessKey       访问密钥 Access Key (AK),可在声网控制台获取
     * @param secretAccessKey 私有访问密钥 Secret Access Key (SK),可在声网控制台获取
     * @return
     */
    @GetMapping("/sdkToken")
    public AjaxResult getSdkToken(@RequestParam("accessKey") String accessKey,
                                  @RequestParam("secretAccessKey") String secretAccessKey
    ) {
        JSONObject json = new JSONObject();
        json.put("accessKey", accessKey);
        json.put("secretAccessKey", secretAccessKey);
        json.put("lifespan", 0);
        json.put("role", "admin");
        return AjaxResult.success("操作成功", HttpUtils.sendPostHeader("https://api.netless.link/v5/tokens/teams", json, ""));
    }

    /**
     * 互动白板创建房间uuid
     *
     * @param sdkToken 互动白板请求sdkToken
     * @return
     */
    @GetMapping("/roomUUid")
    public AjaxResult getRoomUUid(@RequestParam("sdkToken") String sdkToken
    ) {
        JSONObject json = new JSONObject();
        json.put("limit", 0);
        String roomToken = HttpUtils.sendPostHeader("https://api.netless.link/v5/rooms", json, sdkToken);
        JSONObject jsonObject = JSONObject.parseObject(roomToken);
        return AjaxResult.success("操作成功", jsonObject);
    }

    /**
     * 互动白板生成RoomToken
     *
     * @return
     */
    @GetMapping("/roomToken")
    public AjaxResult getRoomToken(@RequestParam("roomUUid") String roomUUid,
                                   @RequestParam("sdkToken") String sdkToken
    ) {

        JSONObject json = new JSONObject();
        json.put("lifespan", 0);
        json.put("role", "admin");
        String roomToken = HttpUtils.sendPostHeader("https://api.netless.link/v5/tokens/rooms/" + roomUUid, json, sdkToken);
        JSONObject jsonObject = JSONObject.parseObject(roomToken);
        return AjaxResult.success("操作成功", jsonObject);
    }

    /**
     * 互动白板生成TaskToken
     *
     * @param uuid     转换任务的 UUID,即转换任务的全局唯一标识符
     * @param sdkToken 互动白板请求sdkToken
     * @return
     */
    @GetMapping("/taskToken")
    public AjaxResult getTaskToken(@RequestParam("uuid") String uuid,
                                   @RequestParam("sdkToken") String sdkToken
    ) {
        JSONObject json = new JSONObject();
        json.put("lifespan", 0);
        json.put("role", "admin");
        String body = HttpUtils.sendPostHeader("https://api.netless.link/v5/tokens/tasks/" + uuid, json, sdkToken);
        JSONObject jsonObject = JSONObject.parseObject(body);
        return AjaxResult.success("操作成功", jsonObject);
    }

    /**
     * 获取房间信息
     *
     * @param uuid     转换任务的 UUID,即转换任务的全局唯一标识符
     * @param sdkToken 互动白板请求sdkToken
     * @return
     */
    @GetMapping("/getRoomInfo")
    public AjaxResult getRoomInfo(@RequestParam("uuid") String uuid,
                                  @RequestParam("sdkToken") String sdkToken
    ) {
        String body = HttpUtils.sendGetHeader("https://api.netless.link/v5/rooms/" + uuid, sdkToken);
        JSONObject jsonObject = JSONObject.parseObject(body);
        return AjaxResult.success("操作成功", jsonObject);
    }

    /**
     * 封闭房间信息
     *
     * @param uuid     转换任务的 UUID,即转换任务的全局唯一标识符
     * @param sdkToken 互动白板请求sdkToken
     * @return
     */
    @GetMapping("/patchRoom")
    public AjaxResult patchRoom(@RequestParam("uuid") String uuid,
                                @RequestParam("sdkToken") String sdkToken
    ) {
        String body = HttpUtils.sendPatchHeader("https://api.netless.link/v5/rooms/" + uuid, sdkToken);
        JSONObject jsonObject = JSONObject.parseObject(body);
        return AjaxResult.success("操作成功", jsonObject);
    }


    /**
     * 生成场景截图
     */
    @PostMapping("/screenshots")
    public AjaxResult getScreenshots(@RequestBody Screen screen
    ) {
        JSONObject json = new JSONObject();
        json.put("width", screen.getWidth());
        json.put("height", screen.getHeight());
        json.put("path", screen.getPath());
        String body = HttpUtils.sendPostScreenHeader("https://api.netless.link/v5/rooms/" + screen.getUuid() + "/screenshots", json, screen.getToken());
        //转换为json对象
        JSONObject jsonObject = JSONObject.parseObject(body);
        return AjaxResult.success("操作成功", jsonObject);
    }

    /**
     * 互动白板生成场景截图列表
     */
    @PostMapping("/screenshotsList")
    public AjaxResult getScreenshotsList(@RequestBody Screen screen
    ) {
        JSONObject json = new JSONObject();
        json.put("width", screen.getWidth());
        json.put("height", screen.getHeight());
        json.put("path", screen.getPath());
        String body = HttpUtils.sendPostScreenHeader("https://api.netless.link/v5/rooms/" + screen.getUuid() + "/screenshot-list", json, screen.getToken());
        //转换为json数组
        JSONArray objects = JSONArray.parseArray(body);
        return AjaxResult.success("操作成功", objects);
    }

    /**
     * 云录制获取resource ID
     *
     * @param appid 你的项目使用的 App ID
     * @param cname 待录制的频道名
     * @param uid   云端录制服务在频道内使用的 UID
     * @return
     */
    @GetMapping("/cloudRecording/acquire")
    public AjaxResult patchRoom(@RequestParam("appid") String appid,
                                @RequestParam("cname") String cname,
                                @RequestParam("uid") String uid
    ) {
        JSONObject json = new JSONObject();
        json.put("cname", cname);
        json.put("uid", uid);
        JSONObject json2 = new JSONObject();
        json2.put("region", "CN");
        json2.put("resourceExpiredHour", 1);
        json2.put("scene", 1);
        json.put("clientRequest", json2);
        String body = HttpUtils.sendCloudPostHeader("https://api.agora.io/v1/apps/" + appid + "/cloud_recording/acquire", json);
        JSONObject jsonObject = JSONObject.parseObject(body);
        Object uuid = jsonObject.get("resourceId");
        return AjaxResult.success("操作成功", uuid);
    }

    /**
     * 云录制-页面录制开始录制
     *
     * @param appid      你的项目使用的 App ID。必须使用和待录制的频道相同的 App ID。
     * @param cname      待录制的频道名
     * @param uid        字符串内容为云端录制服务在频道内使用的 UID,用于标识该录制服务,需要和你在 acquire 请求中输入的 UID 相同
     * @param resourceId 通过 acquire 请求获取的 resource ID。
     * @param token      用于鉴权的动态密钥
     * @param url        页面录制url
     * @return
     */
    @PostMapping("/cloudRecording/webStart")
    public AjaxResult webStart(@RequestParam("appid") String appid,
                               @RequestParam("cname") String cname,
                               @RequestParam("uid") String uid,
                               @RequestParam("resourceId") String resourceId,
                               @RequestParam("token") String token,
                               @RequestParam("url") String url
    ) {
        JSONObject json = new JSONObject();
        json.put("cname", cname);
        json.put("uid", uid);
        //JSON Object。扩展服务的具体参数设置
        JSONObject serviceParam = new JSONObject();
        serviceParam.put("url", url);
        serviceParam.put("audioProfile", 0);
        serviceParam.put("videoWidth", 1280);
        serviceParam.put("videoHeight", 720);
        serviceParam.put("maxRecordingHour", 1);
        serviceParam.put("maxVideoDuration", 200);
        serviceParam.put("readyTimeout", 5);
        //JSONArray 类型,由每个扩展服务的设置组成的数组
        List<JSONObject> extensionServices = new ArrayList<>();
        JSONObject map = new JSONObject();
        map.put("serviceName", "web_recorder_service");
        map.put("errorHandlePolicy", "error_abort");
        map.put("serviceParam", serviceParam);
        extensionServices.add(map);
        //扩展服务设置
        JSONObject extensionServiceConfig = new JSONObject();
        extensionServiceConfig.put("errorHandlePolicy", "error_abort");
        extensionServiceConfig.put("extensionServices", extensionServices);
        //录制文件
        List<String> avFileType = new ArrayList<>();
        avFileType.add("hls");
        avFileType.add("mp4");
        JSONObject recordingFileConfig = new JSONObject();
        recordingFileConfig.put("avFileType", avFileType);
        //第三方云存储
        List<String> fileNamePrefix = new ArrayList<>();
        fileNamePrefix.add("");
        fileNamePrefix.add("");
        JSONObject storageConfig = new JSONObject();
        storageConfig.put("vendor", 7);
        storageConfig.put("region", 1);
        //第三方云存储的 bucket
        storageConfig.put("bucket", "");
        //第三方云存储的 access key
        storageConfig.put("accessKey", "");
        //第三方云存储的 secret key
        storageConfig.put("secretKey", "");
        storageConfig.put("fileNamePrefix", fileNamePrefix);
        JSONObject clientRequest = new JSONObject();
        clientRequest.put("token", token);
        clientRequest.put("extensionServiceConfig", extensionServiceConfig);
        clientRequest.put("recordingFileConfig", recordingFileConfig);
        clientRequest.put("storageConfig", storageConfig);
        json.put("clientRequest", clientRequest);
        String webStart = HttpUtils.sendCloudPostHeader("https://api.agora.io/v1/apps/" + appid + "/cloud_recording/resourceid/" + resourceId + "/mode/web/start", json);
        JSONObject jsonObject = JSONObject.parseObject(webStart);
        return AjaxResult.success("操作成功", jsonObject);
    }

    /**
     * 云录制-页面录制结束录制
     *
     * @param appid      你的项目使用的 App ID。必须使用和待录制的频道相同的 App ID。
     * @param cname      待录制的频道名
     * @param uid        字符串内容为云端录制服务在频道内使用的 UID,用于标识该录制服务,需要和你在 acquire 请求中输入的 UID 相同
     * @param resourceId 通过 acquire 请求获取的 resource ID。
     * @param sid        通过 start 请求获取的录制 ID
     * @return
     */
    @PostMapping("/cloudRecording/webStop")
    public AjaxResult webStop(@RequestParam("appid") String appid,
                              @RequestParam("cname") String cname,
                              @RequestParam("uid") String uid,
                              @RequestParam("resourceId") String resourceId,
                              @RequestParam("sid") String sid
    ) {
        JSONObject json = new JSONObject();
        json.put("cname", cname);
        json.put("uid", uid);
        JSONObject clientRequest = new JSONObject();
        clientRequest.put("async_stop", true);
        json.put("clientRequest", clientRequest);
        String webStop = HttpUtils.sendCloudPostHeader("https://api.agora.io/v1/apps/" + appid + "/cloud_recording/resourceid/" + resourceId + "/sid/" + sid + "/mode/web/stop", json);
        JSONObject jsonObject = JSONObject.parseObject(webStop);
        return AjaxResult.success("操作成功", jsonObject);
    }

    /**
     * 云录制-合流录制开始录制
     *
     * @param appid      你的项目使用的 App ID。必须使用和待录制的频道相同的 App ID。
     * @param cname      待录制的频道名
     * @param uid        字符串内容为云端录制服务在频道内使用的 UID,用于标识该录制服务,需要和你在 acquire 请求中输入的 UID 相同
     * @param resourceId 通过 acquire 请求获取的 resource ID。
     * @param token      用于鉴权的动态密钥
     * @return
     */
    @PostMapping("/cloudRecording/mixStart")
    public AjaxResult mixStart(@RequestParam("appid") String appid,
                               @RequestParam("cname") String cname,
                               @RequestParam("uid") String uid,
                               @RequestParam("resourceId") String resourceId,
                               @RequestParam("token") String token
    ) {
        JSONObject json = new JSONObject();
        json.put("cname", cname);
        json.put("uid", uid);
        //视频转码的详细设置。仅适用于合流模式,单流模式下不能设置该参数
        JSONObject transcodingConfig = new JSONObject();
        //视频的高度
        transcodingConfig.put("height", 640);
        //视频的宽度
        transcodingConfig.put("width", 360);
        //视频的码率
        transcodingConfig.put("bitrate", 500);
        //视频的帧率
        transcodingConfig.put("fps", 15);
        //设置视频合流布局 自适应布局
        transcodingConfig.put("mixedVideoLayout", 1);
        //视频画布的背景颜色 黑色
        transcodingConfig.put("backgroundColor", "#000000");
        //录制文件
        List<String> avFileType = new ArrayList<>();
        avFileType.add("hls");
        avFileType.add("mp4");
        JSONObject recordingFileConfig = new JSONObject();
        recordingFileConfig.put("avFileType", avFileType);
        //用于配置音频流订阅、转码、输出音频属性
        JSONObject recordingConfig = new JSONObject();
        //最长空闲频道时间,单位为秒。默认值为 30
        recordingConfig.put("maxIdleTime", 30);
        //(默认)订阅音频和视频
        recordingConfig.put("streamTypes", 2);
        //直播场景
        recordingConfig.put("channelType", 1);
        //设置订阅的视频流类型 视频小流,即低分辨率低码率的视频流
        recordingConfig.put("videoStreamType", 1);
        recordingConfig.put("transcodingConfig", transcodingConfig);
        //预估的订阅人数峰值 8 到 12 个 UID
        recordingConfig.put("subscribeUidGroup", 2);
        //第三方云存储
        List<String> fileNamePrefix = new ArrayList<>();
        fileNamePrefix.add("");
        fileNamePrefix.add("");
        JSONObject storageConfig = new JSONObject();
        storageConfig.put("vendor", 7);
        storageConfig.put("region", 1);
        //第三方云存储的 bucket
        storageConfig.put("bucket", "");
        //第三方云存储的 access key
        storageConfig.put("accessKey", "");
        //第三方云存储的 secret key
        storageConfig.put("secretKey", "");
        //指定录制文件在第三方云存储中的存储位置
        storageConfig.put("fileNamePrefix", fileNamePrefix);
        JSONObject clientRequest = new JSONObject();
        clientRequest.put("token", token);
        clientRequest.put("recordingConfig", recordingConfig);
        clientRequest.put("recordingFileConfig", recordingFileConfig);
        clientRequest.put("storageConfig", storageConfig);
        json.put("clientRequest", clientRequest);
        String mixStart = HttpUtils.sendCloudPostHeader("https://api.agora.io/v1/apps/" + appid + "/cloud_recording/resourceid/" + resourceId + "/mode/mix/start", json);
        JSONObject jsonObject = JSONObject.parseObject(mixStart);
        return AjaxResult.success("操作成功", jsonObject);
    }

    /**
     * 云录制-合流录制结束录制
     *
     * @param appid      你的项目使用的 App ID。必须使用和待录制的频道相同的 App ID。
     * @param cname      待录制的频道名
     * @param uid        字符串内容为云端录制服务在频道内使用的 UID,用于标识该录制服务,需要和你在 acquire 请求中输入的 UID 相同
     * @param resourceId 通过 acquire 请求获取的 resource ID。
     * @param sid        用于鉴权的动态密钥
     * @return
     */
    @PostMapping("/cloudRecording/mixStop")
    public AjaxResult mixStop(@RequestParam("appid") String appid,
                              @RequestParam("cname") String cname,
                              @RequestParam("uid") String uid,
                              @RequestParam("resourceId") String resourceId,
                              @RequestParam("sid") String sid
    ) {
        JSONObject json = new JSONObject();
        json.put("cname", cname);
        json.put("uid", uid);
        json.put("clientRequest", new JSONObject());
        String mixStop = HttpUtils.sendCloudPostHeader("https://api.agora.io/v1/apps/" + appid + "/cloud_recording/resourceid/" + resourceId + "/sid/" + sid + "/mode/mix/stop", json);
        JSONObject jsonObject = JSONObject.parseObject(mixStop);
        return AjaxResult.success("操作成功", jsonObject);
    }

    /**
     * 云录制-查询云端录制状态
     *
     * @param appid      你的项目使用的 App ID。必须使用和待录制的频道相同的 App ID。
     * @param resourceId 通过 acquire 请求获取的 resource ID。
     * @param sid        通过 start 请求获取的录制 ID。
     * @param mode       录制模式,支持单流模式 individual 、合流模式 mix (默认模式)和页面录制模式 web。
     * @return
     */
    @GetMapping("/cloudRecording/query")
    public AjaxResult query(@RequestParam("appid") String appid,
                            @RequestParam("resourceId") String resourceId,
                            @RequestParam("sid") String sid,
                            @RequestParam("mode") String mode
    ) {
        String query = HttpUtils.sendCloudGetHeader("https://api.agora.io/v1/apps/" + appid + "/cloud_recording/resourceid/" + resourceId + "/sid/" + sid + "/mode/" + mode + "/query");
        JSONObject jsonObject = JSONObject.parseObject(query);
        return AjaxResult.success("操作成功", jsonObject);
    }

    /**
     * 云录制-更新云端录制
     *
     * @param appid      你的项目使用的 App ID。必须使用和待录制的频道相同的 App ID。
     * @param resourceId 通过 acquire 请求获取的 resource ID。
     * @param sid        通过 start 请求获取的录制 ID。
     * @param mode       录制模式,支持单流模式 individual 、合流模式 mix (默认模式)和页面录制模式 web。
     * @param cname      待录制的频道名
     * @param uid        字符串内容为云端录制服务在频道内使用的 UID,用于标识该录制服务,需要和你在 acquire 请求中输入的 UID 相同
     * @return
     */
    @PostMapping("/cloudRecording/update")
    public AjaxResult update(@RequestParam("appid") String appid,
                             @RequestParam("resourceId") String resourceId,
                             @RequestParam("sid") String sid,
                             @RequestParam("mode") String mode,
                             @RequestParam("cname") String cname,
                             @RequestParam("uid") String uid
    ) {
        JSONObject json = new JSONObject();
        json.put("cname", cname);
        json.put("uid", uid);
        JSONObject webRecordingConfig = new JSONObject();
        webRecordingConfig.put("onhold", true);
        json.put("clientRequest", webRecordingConfig);
        String update = HttpUtils.sendCloudPostHeader("https://api.agora.io/v1/apps/" + appid + "/cloud_recording/resourceid/" + resourceId + "/sid/" + sid + "/mode/" + mode + "/update", json);
        JSONObject jsonObject = JSONObject.parseObject(update);
        return AjaxResult.success("操作成功", jsonObject);
    }

    /**
     * 云录制-视频截图
     *
     * @param appid      你的项目使用的 App ID。必须使用和待录制的频道相同的 App ID。
     * @param cname      待录制的频道名
     * @param uid        字符串内容为云端录制服务在频道内使用的 UID,用于标识该录制服务,需要和你在 acquire 请求中输入的 UID 相同
     * @param resourceId 通过 acquire 请求获取的 resource ID。
     * @param token      用于鉴权的动态密钥
     * @return
     */
    @PostMapping("/cloudRecording/jpgStart")
    public AjaxResult jpgStart(@RequestParam("appid") String appid,
                               @RequestParam("cname") String cname,
                               @RequestParam("uid") String uid,
                               @RequestParam("resourceId") String resourceId,
                               @RequestParam("token") String token
    ) {
        JSONObject json = new JSONObject();
        json.put("cname", cname);
        json.put("uid", uid);
        //JSON Object。媒体流订阅、转码、输出音视频属性
        JSONObject recordingConfig = new JSONObject();
        recordingConfig.put("maxIdleTime", 30);
        recordingConfig.put("streamTypes", 1);
        recordingConfig.put("channelType", 0);
        //截图周期、截图文件
        List<String> fileType = new ArrayList<>();
        fileType.add("jpg");
        JSONObject snapshotConfig = new JSONObject();
        snapshotConfig.put("captureInterval", 5);
        snapshotConfig.put("fileType", fileType);
        //录制文件
        List<String> avFileType = new ArrayList<>();
        avFileType.add("hls");
        avFileType.add("mp4");
        JSONObject recordingFileConfig = new JSONObject();
        recordingFileConfig.put("avFileType", avFileType);
        //第三方云存储
        List<String> fileNamePrefix = new ArrayList<>();
        fileNamePrefix.add("");
        fileNamePrefix.add("");
        JSONObject storageConfig = new JSONObject();
        storageConfig.put("vendor", 7);
        storageConfig.put("region", 1);
        //第三方云存储的 bucket
        storageConfig.put("bucket", "");
        //第三方云存储的 access key
        storageConfig.put("accessKey", "");
        //第三方云存储的 secret key
        storageConfig.put("secretKey", "");
        storageConfig.put("fileNamePrefix", fileNamePrefix);
        JSONObject clientRequest = new JSONObject();
        clientRequest.put("token", token);
        clientRequest.put("recordingConfig", recordingConfig);
        clientRequest.put("snapshotConfig", snapshotConfig);
        clientRequest.put("recordingFileConfig", recordingFileConfig);
        clientRequest.put("storageConfig", storageConfig);
        json.put("clientRequest", clientRequest);
        String webStart = HttpUtils.sendCloudPostHeader("https://api.agora.io/v1/apps/" + appid + "/cloud_recording/resourceid/" + resourceId + "/mode/individual/start", json);
        JSONObject jsonObject = JSONObject.parseObject(webStart);
        return AjaxResult.success("操作成功", jsonObject);
    }

}
  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

灬涛声依旧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值