diff --git a/agora-rest-client-core/LICENSE b/agora-rest-client-core/LICENSE new file mode 100644 index 0000000..e4589a2 --- /dev/null +++ b/agora-rest-client-core/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Agora Community + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/agora-rest-client-core/pom.xml b/agora-rest-client-core/pom.xml index c2cc864..84dcdd4 100644 --- a/agora-rest-client-core/pom.xml +++ b/agora-rest-client-core/pom.xml @@ -125,11 +125,7 @@ - .. - - LICENSE - - META-INF + src/main/resources src @@ -239,6 +235,39 @@ + + org.apache.maven.plugins + maven-resources-plugin + 3.3.1 + + UTF-8 + + pdf + swf + + + + + copy-license + process-resources + + copy-resources + + + ${project.build.outputDirectory}/META-INF + + + ${project.basedir} + + LICENSE + + false + + + + + + diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/CloudRecordingClient.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/CloudRecordingClient.java index abe7a56..3e62a66 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/CloudRecordingClient.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/CloudRecordingClient.java @@ -1,9 +1,7 @@ package io.agora.rest.services.cloudrecording; import io.agora.rest.core.AgoraConfig; -import io.agora.rest.core.Context; import io.agora.rest.core.DefaultContext; -import io.agora.rest.services.cloudrecording.api.*; import io.agora.rest.services.cloudrecording.api.req.*; import io.agora.rest.services.cloudrecording.api.res.*; import io.agora.rest.services.cloudrecording.enums.CloudRecordingModeEnum; @@ -12,79 +10,64 @@ import io.agora.rest.services.cloudrecording.scenario.web.WebScenario; import reactor.core.publisher.Mono; -public class CloudRecordingClient { - - private final AcquireResourceAPI acquireResourceAPI; - - private final QueryResourceAPI queryResourceAPI; - - private final StartResourceAPI startResourceAPI; - - private final UpdateResourceAPI updateResourceAPI; - - private final StopResourceAPI stopResourceAPI; - - private final IndividualScenario individualScenario; - - private final WebScenario webScenario; - - private final MixScenario mixScenario; - - public static CloudRecordingClient create(AgoraConfig agoraConfig) { - return new CloudRecordingClient(new DefaultContext(agoraConfig)); +public abstract class CloudRecordingClient { + + private static CloudRecordingClient mInstance; + + /** + * @param cloudRecordingConfig Instance of {@link CloudRecordingConfig}. + * @return Returns the Cloud Recording client instance. + * @brief Creates a Cloud Recording client with the specified configuration. + * @since v0.4.0 + */ + public static synchronized CloudRecordingClient create(CloudRecordingConfig cloudRecordingConfig) { + if (mInstance == null) { + AgoraConfig agoraConfig = AgoraConfig.builder() + .appId(cloudRecordingConfig.getAppId()) + .credential(cloudRecordingConfig.getCredential()) + .domainArea(cloudRecordingConfig.getDomainArea()) + .httpProperty(cloudRecordingConfig.getHttpProperty()) + .build(); + mInstance=new CloudRecordingClientImpl(new DefaultContext(agoraConfig)); + } + + return mInstance; } - protected CloudRecordingClient(Context context) { - this.acquireResourceAPI = new AcquireResourceAPI(context); - this.queryResourceAPI = new QueryResourceAPI(context); - this.startResourceAPI = new StartResourceAPI(context); - this.stopResourceAPI = new StopResourceAPI(context); - this.updateResourceAPI = new UpdateResourceAPI(context); - - this.individualScenario = new IndividualScenario(acquireResourceAPI, queryResourceAPI, startResourceAPI, - updateResourceAPI, stopResourceAPI); - this.webScenario = new WebScenario(acquireResourceAPI, queryResourceAPI, startResourceAPI, updateResourceAPI, - stopResourceAPI); - this.mixScenario = new MixScenario(acquireResourceAPI, queryResourceAPI, startResourceAPI, updateResourceAPI, - stopResourceAPI); - } - public Mono acquire(AcquireResourceReq request) { - return acquireResourceAPI.handle(request); - } + public abstract Mono acquire(AcquireResourceReq request); - public Mono start(String resourceId, CloudRecordingModeEnum mode, StartResourceReq request) { - return startResourceAPI.handle(resourceId, mode, request); - } + public abstract Mono start(String resourceId, CloudRecordingModeEnum mode, StartResourceReq request); - public Mono query(String resourceId, String sid, CloudRecordingModeEnum mode) { - return queryResourceAPI.handle(resourceId, sid, mode); - } + public abstract Mono query(String resourceId, String sid, CloudRecordingModeEnum mode); - public Mono stop(String resourceId, String sid, CloudRecordingModeEnum mode, - StopResourceReq request) { - return stopResourceAPI.handle(resourceId, sid, mode, request); - } + public abstract Mono stop(String resourceId, String sid, CloudRecordingModeEnum mode, + StopResourceReq request); - public Mono update(String resourceId, String sid, CloudRecordingModeEnum mode, - UpdateResourceReq request) { - return updateResourceAPI.handle(resourceId, sid, mode, request); - } + public abstract Mono update(String resourceId, String sid, CloudRecordingModeEnum mode, + UpdateResourceReq request); - public Mono updateLayout(String resourceId, String sid, CloudRecordingModeEnum mode, - UpdateLayoutResourceReq request) { - return updateResourceAPI.handleLayout(resourceId, sid, mode, request); - } + public abstract Mono updateLayout(String resourceId, String sid, CloudRecordingModeEnum mode, + UpdateLayoutResourceReq request); - public IndividualScenario individualScenario() { - return individualScenario; - } + /** + * @brief Returns the individual scenario instance. + * @return Returns the individual scenario instance. + * @since v0.4.0 + */ + public abstract IndividualScenario individualScenario(); - public WebScenario webScenario() { - return webScenario; - } + /** + * @brief Returns the web scenario instance. + * @return Returns the web scenario instance. + * @since v0.4.0 + */ + public abstract WebScenario webScenario(); - public MixScenario mixScenario() { - return mixScenario; - } + /** + * @brief Returns the mix scenario instance. + * @return Returns the mix scenario instance. + * @since v0.4.0 + */ + public abstract MixScenario mixScenario(); } diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/CloudRecordingClientImpl.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/CloudRecordingClientImpl.java new file mode 100644 index 0000000..1ac4e9b --- /dev/null +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/CloudRecordingClientImpl.java @@ -0,0 +1,87 @@ +package io.agora.rest.services.cloudrecording; + +import io.agora.rest.core.Context; +import io.agora.rest.services.cloudrecording.api.*; +import io.agora.rest.services.cloudrecording.api.req.*; +import io.agora.rest.services.cloudrecording.api.res.*; +import io.agora.rest.services.cloudrecording.enums.CloudRecordingModeEnum; +import io.agora.rest.services.cloudrecording.scenario.individual.IndividualScenario; +import io.agora.rest.services.cloudrecording.scenario.individual.IndividualScenarioImpl; +import io.agora.rest.services.cloudrecording.scenario.mix.MixScenario; +import io.agora.rest.services.cloudrecording.scenario.mix.MixScenarioImpl; +import io.agora.rest.services.cloudrecording.scenario.web.WebScenario; +import io.agora.rest.services.cloudrecording.scenario.web.WebScenarioImpl; +import reactor.core.publisher.Mono; + +public class CloudRecordingClientImpl extends CloudRecordingClient { + + private final AcquireResourceAPI acquireResourceAPI; + + private final QueryResourceAPI queryResourceAPI; + + private final StartResourceAPI startResourceAPI; + + private final UpdateResourceAPI updateResourceAPI; + + private final StopResourceAPI stopResourceAPI; + + private final IndividualScenario individualScenario; + + private final WebScenario webScenario; + + private final MixScenario mixScenario; + + protected CloudRecordingClientImpl(Context context) { + this.acquireResourceAPI = new AcquireResourceAPI(context); + this.queryResourceAPI = new QueryResourceAPI(context); + this.startResourceAPI = new StartResourceAPI(context); + this.stopResourceAPI = new StopResourceAPI(context); + this.updateResourceAPI = new UpdateResourceAPI(context); + + this.individualScenario = new IndividualScenarioImpl(acquireResourceAPI, queryResourceAPI, startResourceAPI, + updateResourceAPI, stopResourceAPI); + this.webScenario = new WebScenarioImpl(acquireResourceAPI, queryResourceAPI, startResourceAPI, updateResourceAPI, + stopResourceAPI); + this.mixScenario = new MixScenarioImpl(acquireResourceAPI, queryResourceAPI, startResourceAPI, updateResourceAPI, + stopResourceAPI); + } + + public Mono acquire(AcquireResourceReq request) { + return acquireResourceAPI.handle(request); + } + + public Mono start(String resourceId, CloudRecordingModeEnum mode, StartResourceReq request) { + return startResourceAPI.handle(resourceId, mode, request); + } + + public Mono query(String resourceId, String sid, CloudRecordingModeEnum mode) { + return queryResourceAPI.handle(resourceId, sid, mode); + } + + public Mono stop(String resourceId, String sid, CloudRecordingModeEnum mode, + StopResourceReq request) { + return stopResourceAPI.handle(resourceId, sid, mode, request); + } + + public Mono update(String resourceId, String sid, CloudRecordingModeEnum mode, + UpdateResourceReq request) { + return updateResourceAPI.handle(resourceId, sid, mode, request); + } + + public Mono updateLayout(String resourceId, String sid, CloudRecordingModeEnum mode, + UpdateLayoutResourceReq request) { + return updateResourceAPI.handleLayout(resourceId, sid, mode, request); + } + + public IndividualScenario individualScenario() { + return individualScenario; + } + + public WebScenario webScenario() { + return webScenario; + } + + public MixScenario mixScenario() { + return mixScenario; + } +} diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/CloudRecordingConfig.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/CloudRecordingConfig.java new file mode 100644 index 0000000..f35a5d5 --- /dev/null +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/CloudRecordingConfig.java @@ -0,0 +1,109 @@ +package io.agora.rest.services.cloudrecording; + +import io.agora.rest.core.Credential; +import io.agora.rest.core.DomainArea; +import io.agora.rest.core.HttpProperty; + +/** + * @brief Defines the configuration for the Cloud Recording client + * @since v0.4.0 + */ +public class CloudRecordingConfig { + /** + * Agora AppID + */ + private final String appId; + + /** + * Credential for accessing the Agora service. + *

+ * Available credential types: + *

+ * - BasicAuthCredential: See {@link io.agora.rest.core.BasicAuthCredential} + */ + private final Credential credential; + + /** + * Domain area for the REST Client. See {@link DomainArea} + */ + private final DomainArea domainArea; + + /** + * HTTP properties for the REST Client. See {@link HttpProperty} + */ + private final HttpProperty httpProperty; + + private CloudRecordingConfig(Builder builder) { + this.appId = builder.appId; + this.credential = builder.credential; + this.domainArea = builder.domainArea; + this.httpProperty = builder.httpProperty; + } + + public static Builder builder() { + return new Builder(); + } + + public String getAppId() { + return appId; + } + + public Credential getCredential() { + return credential; + } + + public DomainArea getDomainArea() { + return domainArea; + } + + public HttpProperty getHttpProperty() { + return httpProperty; + } + + @Override + public String toString() { + return "CloudRecordingConfig{" + + "appId='" + appId + '\'' + + ", credential=" + credential + + ", domainArea=" + domainArea + + ", httpProperty=" + httpProperty + + '}'; + } + + public static class Builder { + + private String appId; + + private Credential credential; + + private DomainArea domainArea; + + private HttpProperty httpProperty; + + private Builder() { + } + + public Builder appId(String appId) { + this.appId = appId; + return this; + } + + public Builder credential(Credential credential) { + this.credential = credential; + return this; + } + + public Builder domainArea(DomainArea domainArea) { + this.domainArea = domainArea; + return this; + } + + + public CloudRecordingConfig build() { + if (httpProperty == null) { + this.httpProperty = HttpProperty.builder().build(); + } + return new CloudRecordingConfig(this); + } + } +} diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/req/StartResourceReq.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/req/StartResourceReq.java index 1018159..0ed1756 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/req/StartResourceReq.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/req/StartResourceReq.java @@ -245,8 +245,23 @@ public StartClientRequest build() { } } + /** + * @brief Configuration for the application. + * @since v0.4.0 + */ public static class AppsCollection { + /** + * The combination of cloud recording applications.(Optional) + *

+ * The combination policy can be set to: + *

+ * - "default": Use this policy except for postponed transcoding and audio + * mixing.(Default) + *

+ * - "postpone_transcoding": Use this policy if you need to postpone transcoding + * or audio mixing. + */ @JsonProperty("combinationPolicy") private String combinationPolicy; @@ -295,50 +310,222 @@ public AppsCollection build() { } } + /** + * @brief Configuration for recorded audio and video streams. + * @since v0.4.0 + */ public static class RecordingConfig { + /** + * The channel type.(Required) + * + * The channel type can be set to: + *

+ * - 0: The communication use-case (Default) + *

+ * - 1: Live streaming scene + */ @JsonProperty("channelType") private Integer channelType; + /** + * Subscribed media stream type.(Optional) + *

+ * The stream type can be set to: + *

+ * - 0: Subscribes to audio streams only. Suitable for smart voice review + * use-cases. + *

+ * - 1: Subscribes to video streams only. + *

+ * - 2: Subscribes to both audio and video streams.(Default) + */ @JsonProperty("streamTypes") private Integer streamTypes; + /** + * Output mode of media stream.(Optional) + *

+ * The stream mode can be set to: + *

+ * - "default": Default mode. + * Recording with audio transcoding will separately generate an M3U8 audio index + * file and a video index file. + *

+ * - "standard": Standard mode. Agora recommends using this mode. + * Recording with audio transcoding will separately generate an M3U8 audio index + * file, a video index file, + * and a merged audio and video index file. If VP8 encoding is used on the Web + * client, a merged MPD audio-video index file will be generated. + *

+ * - "original": Original encoding mode. It is applicable to individual + * non-transcoding audio recording. + * This field only takes effect when subscribing to audio only (streamTypes is + * 0). + * During the recording process, the audio is not transcoded, and an M3U8 audio + * index file is generated. + */ @JsonProperty("streamMode") private String streamMode; + /** + * The decryption mode.(Optional) + *

+ * If you have set channel encryption in the SDK client, + * you need to set the same decryption mode for the cloud recording service. + *

+ * The decryption mode can be set to: + *

+ * - 0: Not encrypted.(Default) + *

+ * - 1: AES_128_XTS encryption mode. 128-bit AES encryption, XTS mode. + *

+ * - 2: AES_128_ECB encryption mode. 128-bit AES encryption, ECB mode. + *

+ * - 3: AES_256_XTS encryption mode. 256-bit AES encryption, XTS mode. + *

+ * - 4: SM4_128_ECB encryption mode. 128-bit SM4 encryption, ECB mode. + *

+ * - 5: AES_128_GCM encryption mode. 128-bit AES encryption, GCM mode. + *

+ * - 6: AES_256_GCM encryption mode. 256-bit AES encryption, GCM mode. + *

+ * - 7: AES_128_GCM2 encryption mode. 128-bit AES encryption, GCM mode. + * Compared to AES_128_GCM encryption mode, AES_128_GCM2 encryption mode has + * higher security and requires setting a key and salt. + *

+ * - 8: AES_256_GCM2 encryption mode. 256-bit AES encryption, GCM mode. + * Compared to the AES_256_GCM encryption mode, the AES_256_GCM2 encryption mode + * is more secure and requires setting a key and salt. + */ @JsonProperty("decryptionMode") private Integer decryptionMode; + /** + * Keys related to encryption and decryption.(Optional) + *

+ * Only needs to be set when decryptionMode is not 0. + */ @JsonProperty("secret") private String secret; + /** + * Salt related to encryption and decryption.(Optional) + *

+ * Base64 encoding, 32-bit bytes. + *

+ * Only need to set when decryptionMode is 7 or 8. + */ @JsonProperty("salt") private String salt; + /** + * Set the sampling rate, bitrate, encoding mode, and number of channels for the + * output audio.(Optional) + *

+ * The audio profile can be set to: + *

+ * - 0: 48 kHz sampling rate, music encoding, mono audio channel, and the + * encoding bitrate is about 48 Kbps.(Default) + *

+ * - 1: 48 kHz sampling rate, music encoding, mono audio channel, and the + * encoding bitrate is approximately 128 Kbps. + *

+ * - 2: 48 kHz sampling rate, music encoding, stereo audio channel, and the + * encoding bitrate is approximately 192 Kbps. + */ @JsonProperty("audioProfile") private Integer audioProfile; + /** + * Sets the stream type of the remote video.(Optional) + *

+ * If you enable dual-stream mode in the SDK client, + * you can choose to subscribe to either the high-quality video stream or the + * low-quality video stream. + *

+ * The video stream type can be set to: + *

+ * - 0: High-quality video stream refers to high-resolution and high-bitrate + * video stream.(Default) + *

+ * - 1: Low-quality video stream refers to low-resolution and low-bitrate video + * stream. + */ @JsonProperty("videoStreamType") private Integer videoStreamType; + /** + * Maximum channel idle time.(Optional) + *

+ * The unit is seconds. + *

+ * The value range is [5,259200]. + *

+ * The default value is 30. + */ @JsonProperty("maxIdleTime") private Integer maxIdleTime; + /** + * Configurations for transcoded video output.(Optional) + */ @JsonProperty("transcodingConfig") private TranscodingConfig transcodingConfig; + /** + * Specify which UIDs' audio streams to subscribe to.(Optional) + *

+ * If you want to subscribe to the audio stream of all UIDs, no need to set this + * field. + */ @JsonProperty("subscribeAudioUids") private List subscribeAudioUIDs; + /** + * Specify which UIDs' audio streams not to subscribe to.(Optional) + *

+ * The cloud recording service will subscribe to the video streams of all UIDs + * except the specified ones. + */ @JsonProperty("unSubscribeAudioUids") private List unsubscribeAudioUIDs; + /** + * Specify which UIDs' video streams to subscribe to.(Optional) + *

+ * If you want to subscribe to the video streams of all UIDs, no need to set + * this field. + */ @JsonProperty("subscribeVideoUids") private List subscribeVideoUIDs; + /** + * Specify which UIDs' video streams not to subscribe to.(Optional) + *

+ * The cloud recording service will subscribe to the video streams of all UIDs + * except the specified ones. + */ @JsonProperty("unSubscribeVideoUids") private List unsubscribeVideoUIDs; + /** + * Estimated peak number of subscribers.(Optional) + *

+ * The subscription group can be set to: + *

+ * - 0: 1 to 2 UIDs. + *

+ * - 1: 3 to 7 UIDs. + *

+ * - 2: 8 to 12 UIDs + *

+ * - 3: 13 to 17 UIDs + *

+ * - 4: 18 to 32 UIDs. + *

+ * - 5: 33 to 49 UIDs. + */ @JsonProperty("subscribeUidGroup") private Integer subscribeUidGroup; @@ -607,8 +794,25 @@ public RecordingConfig build() { } } + /** + * @brief Container format. + * @since v0.4.0 + */ public static class Container { + /** + * The container format of the file.(Optional) + *

+ * The container format can be set to: + *

+ * - "mp4": the default format for the postponed transcoding. MP4 format. + *

+ * - "mp3": The default format for postponed audio mixing. MP3 format. + *

+ * - "m4a": M4A format. + *

+ * - "aac": AAC format. + */ @JsonProperty("format") private String format; @@ -653,14 +857,29 @@ public Container build() { } } + /** + * @brief Configurations for the recorded files generated under postponed + * transcoding or audio mixing. + * @since v0.4.0 + */ public static class TranscodeOptions { - + /** + * The container format of the recorded files.(Optional) See + * {@link TranscodeOptions.Container}. + */ @JsonProperty("container") private Container container; + /** + * The configuration for transcoding.(Required) See + * {@link TranscodeOptions.TransConfig}. + */ @JsonProperty("transConfig") private TransConfig transConfig; + /** + * Audio properties of the file. See {@link TranscodeOptions.Audio}. + */ @JsonProperty("audio") private Audio audio; @@ -737,8 +956,21 @@ public TranscodeOptions build() { } } + /** + * @brief Configuration for transcoding. + * @since v0.4.0 + */ public static class TransConfig { + /** + * The transcoding mode.(Required) + *

+ * The transcoding mode can be set to: + *

+ * - "postponeTranscoding": Postponed transcoding. + *

+ * - "audioMix": Postponed audio mixing. + */ @JsonProperty("transMode") private String transMode; @@ -783,14 +1015,43 @@ public TransConfig build() { } } + /** + * @brief Audio properties of the file. + * @since v0.4.0 + */ public static class Audio { + /** + * Audio sampling rate.(Optional) + *

+ * The sampling rate can be set to: + *

+ * - "48000": 48 kHz.(Default) + *

+ * - "32000": 32 kHz. + *

+ * - "16000": 16 kHz. + */ @JsonProperty("sampleRate") private String sampleRate; + /** + * Audio bitrate(Kbps).(Optional) + *

+ * It supports a customized value and the default value is "48000". + */ @JsonProperty("bitrate") private String bitRate; + /** + * Audio channels.(Optional) + *

+ * The channels can be set to: + *

+ * - "1": Mono. + *

+ * - "2": Stereo.(Default) + */ @JsonProperty("channels") private String channels; @@ -869,38 +1130,130 @@ public Audio build() { } } + /** + * @brief Configurations for transcoded video output. + * @since v0.4.0 + */ public static class TranscodingConfig { + /** + * The width of the video (pixels).(Optional) + *

+ * Width × Height cannot exceed 1920 × 1080. + *

+ * The default value is 360. + */ @JsonProperty("width") private Integer width; + /** + * The height of the video (pixels).(Optional) + *

+ * width × height cannot exceed 1920 × 1080. + *

+ * The default value is 640. + */ @JsonProperty("height") private Integer height; + /** + * The frame rate of the video (fps).(Optional) + *

+ * The default value is 15. + */ @JsonProperty("fps") private Integer fps; + /** + * The bitrate of the video (Kbps).(Optional) + *

+ * The default value is 1500. + */ @JsonProperty("bitrate") private Integer bitrate; + /** + * Only need to set it in vertical layout.(Optional) + *

+ * Specify the user ID of the large video window. + */ @JsonProperty("maxResolutionUid") private String maxResolutionUid; + /** + * Composite video layout.(Optional) + *

+ * The video layout can be set to: + *

+ * - 0: Floating layout(Default). + * The first user to join the channel will be displayed as a large window, + * filling the entire canvas. + * The video windows of other users will be displayed as small windows, arranged + * horizontally from bottom to top, + * up to 4 rows, each with 4 windows. It supports up to a total of 17 windows of + * different users' videos. + *

+ * - 1: Adaptive layout. + * Automatically adjust the size of each user's video window according to the + * number of users, + * each user's video window size is consistent, and supports up to 17 windows. + *

+ * - 2: Vertical layout. + * The maxResolutionUid is specified to display the large video window on the + * left side of the screen, + * and the small video windows of other users are vertically arranged on the + * right side, + * with a maximum of two columns, 8 windows per column, supporting up to 17 + * windows. + *

+ * - 3: Customized layout. + * Set the layoutConfig field to customize the mixed layout. + */ @JsonProperty("mixedVideoLayout") private Integer mixedVideoLayout; + /** + * The background color of the video canvas.(Optional) + *

+ * The RGB color table is supported, with strings formatted as a # sign and 6 + * hexadecimal digits. + *

+ * The default value is "#000000", representing the black color. + */ @JsonProperty("backgroundColor") private String backgroundColor; + /** + * The URL of the background image of the video canvas.(Optional) + *

+ * The display mode of the background image is set to cropped mode. + *

+ * Cropped mode: Will prioritize to ensure that the screen is filled. + *

+ * The background image size is scaled in equal proportion until the entire + * screen is filled with the background image. + *

+ * If the length and width of the background image differ from the video window, + * the background image will be peripherally cropped to fill the window. + */ @JsonProperty("backgroundImage") private String backgroundImage; + /** + * The URL of the default user screen background image.(Optional) + */ @JsonProperty("defaultUserBackgroundImage") private String defaultUserBackgroundImage; + /** + * Configurations of user's layout.(Optional) + */ @JsonProperty("layoutConfig") private List layoutConfig; + /** + * Configurations of user's background image.(Optional) + */ @JsonProperty("backgroundConfig") private List backgroundConfig; @@ -1115,26 +1468,102 @@ public TranscodingConfig build() { } } + /** + * @brief Configurations of user's layout. + * @since v0.4.0 + */ public static class LayoutConfig { + /** + * The content of the string is the UID of the user to be displayed in the area, + * 32-bit unsigned integer. + */ @JsonProperty("uid") private String uid; + /** + * The relative value of the horizontal coordinate of the upper-left corner of + * the screen, accurate to six decimal places. + *

+ * Layout from left to right, with 0.0 at the far left and 1.0 at the far right. + *

+ * This field can also be set to the integer 0 or 1. + *

+ * The value range is [0,1]. + */ @JsonProperty("x_axis") private Float xAxis; + /** + * The relative value of the vertical coordinate of the upper-left corner of + * this screen in the screen, accurate to six decimal places. + *

+ * Layout from top to bottom, with 0.0 at the top and 1.0 at the bottom. + *

+ * This field can also be set to the integer 0 or 1. + *

+ * The value range is [0,1]. + */ @JsonProperty("y_axis") private Float yAxis; + /** + * The relative value of the width of this screen, accurate to six decimal + * places. + *

+ * This field can also be set to the integer 0 or 1. + *

+ * The value range is [0,1]. + */ @JsonProperty("width") private Float width; + /** + * The relative value of the height of this screen, accurate to six decimal + * places. + *

+ * This field can also be set to the integer 0 or 1. + *

+ * The value range is [0,1]. + */ @JsonProperty("height") private Float height; + /** + * The transparency of the user's video window. Accurate to six decimal places. + *

+ * 0.0 means the user's video window is transparent, and 1.0 indicates that it + * is completely opaque. + *

+ * The value range is [0,1]. + *

+ * The default value is 1. + */ @JsonProperty("alpha") private Float alpha; + /** + * The display mode of users' video windows. + *

+ * The rendering mode can be set to: + *

+ * - 0: Cropped mode.(Default) + * Prioritize to ensure the screen is filled. + * The video window size is proportionally scaled until it fills the screen. + * If the video's length and width differ from the video window, + * the video stream will be cropped from its edges to fit the window, + * under the aspect ratio set for the video window. + *

+ * - 1: Fit mode. + * Prioritize to ensure that all video content is displayed. + * The video size is scaled proportionally until one side of the video window is + * aligned with the screen border. + * If the video scale does not comply with the window size, + * the video will be scaled to fill the screen while maintaining its aspect + * ratio. + *

+ * This scaling may result in a black border around the edges of the video. + */ @JsonProperty("render_mode") private Integer renderMode; @@ -1281,8 +1710,21 @@ public LayoutConfig build() { } } + /** + * @brief Configuration for the recorded files. + * @since v0.4.0 + */ public static class RecordingFileConfig { + /** + * Type of video files generated by recording.(Optional) + *

+ * The file type can be set to: + *

+ * - "hls": default value. M3U8 and TS files. + *

+ * - "mp4": MP4 files. + */ @JsonProperty("avFileType") private List avFileType; @@ -1327,11 +1769,30 @@ public RecordingFileConfig build() { } } + /** + * @brief Configuration for screenshot capture. + * @since v0.4.0 + */ public static class SnapshotConfig { + /** + * The cycle for regular screenshots in the cloud recording.(Optional) + *

+ * The unit is seconds. + *

+ * The value range is [5,3600]. + *

+ * The default value is 10. + */ @JsonProperty("captureInterval") private Integer captureInterval; + /** + * The file format of screenshots. + *

+ * Currently only ["jpg"] is supported, which generates screenshot files in JPG + * format. + */ @JsonProperty("fileType") private List fileType; @@ -1393,32 +1854,93 @@ public SnapshotConfig build() { } } + /** + * @brief Configuration for third-party cloud storage. + * @since v0.4.0 + */ public static class StorageConfig { - + /** + * Third-party cloud storage platforms.(Required) + *

+ * The vendor can be set to: + *

+ * - 1: Amazon S3 + *

+ * - 2: Alibaba Cloud + *

+ * - 3: Tencent Cloud + *

+ * - 5: Microsoft Azure + *

+ * - 6: Google Cloud + *

+ * - 7: Huawei Cloud + *

+ * - 8: Baidu IntelligentCloud + */ @JsonProperty("vendor") private Integer vendor; + /** + * The region information specified for the third-party cloud storage.(Required) + */ @JsonProperty("region") private Integer region; + /** + * Third-party cloud storage bucket.(Required) + */ @JsonProperty("bucket") private String bucket; + /** + * The access key of third-party cloud storage.(Required) + */ @JsonProperty("accessKey") private String accessKey; + /** + * The secret key of third-party cloud storage.(Required) + */ @JsonProperty("secretKey") private String secretKey; + /** + * The storage location of the recorded files in the third-party cloud is + * related to the prefix of the file name.(Optional) + */ @JsonProperty("fileNamePrefix") private List fileNamePrefix; + /** + * A temporary security token for third-party cloud storage. + *

+ * This token is issued by the cloud service provider's Security Token Service + * (STS) and used to grant limited access rights to third-party cloud storage + * resources. + *

+ * Currently supported cloud service providers include only the following: + *

+ * - 1: Amazon S3 + *

+ * - 2: Alibaba Cloud + *

+ * - 3: Tencent Cloud. + */ @JsonProperty("stsToken") private String stsToken; + /** + * The stsToken expiration timestamp used to mark UNIX time, in + * seconds.(Optional) + */ @JsonProperty("stsExpiration") private Integer stsExpiration; + /** + * Third-party cloud storage services will encrypt and tag the uploaded + * recording files according to this field.(Optional) + */ @JsonProperty("extensionParams") private ExtensionParams extensionParams; @@ -1599,11 +2121,34 @@ public StorageConfig build() { } } + /** + * @brief Third-party cloud storage services will encrypt and tag the uploaded + * recording files according to this field. + * @since v0.4.0 + */ public static class ExtensionParams { - + /** + * The encryption mode.(Required) + *

+ * This field is only applicable to Amazon S3, + * and the value can be set to: + *

+ * - "kms": KMS encryption. + *

+ * - "aes256": AES256 encryption. + */ @JsonProperty("sse") private String sse; + /** + * Tag content.(Required) + *

+ * After setting this field, the third-party cloud storage service + * will tag the uploaded recording files according to the content of this tag. + *

+ * This field is only applicable to Alibaba Cloud and Amazon S3. + * For other third-party cloud storage services, this field is not required. + */ @JsonProperty("tag") private String tag; @@ -1665,17 +2210,27 @@ public ExtensionParams build() { } } + /** + * @brief Configurations for extended services. + * @since v0.4.0 + */ public static class ExtensionServiceConfig { - + /** + * Error handling policy.(Optional) + *

+ * You can only set it to the default value, "error_abort", + * which means that once an error occurs to an extension service, + * all other non-extension services, such as stream subscription, also stop. + */ @JsonProperty("errorHandlePolicy") private String errorHandlePolicy; + /** + * Extended services.(Required) + */ @JsonProperty("extensionServices") private List extensionServices; - @JsonProperty("serviceParam") - private ServiceParam serviceParam; - public static Builder builder() { return new Builder(); } @@ -1683,7 +2238,6 @@ public static Builder builder() { private ExtensionServiceConfig(Builder builder) { setErrorHandlePolicy(builder.errorHandlePolicy); setExtensionServices(builder.extensionServices); - setServiceParam(builder.serviceParam); } public String getErrorHandlePolicy() { @@ -1702,20 +2256,11 @@ public void setExtensionServices(List extensionServices) { this.extensionServices = extensionServices; } - public ServiceParam getServiceParam() { - return serviceParam; - } - - public void setServiceParam(ServiceParam serviceParam) { - this.serviceParam = serviceParam; - } - @Override public String toString() { return "ExtensionServiceConfig{" + "errorHandlePolicy='" + errorHandlePolicy + '\'' + ", extensionServices=" + extensionServices + - ", serviceParam=" + serviceParam + '}'; } @@ -1725,8 +2270,6 @@ public static final class Builder { private List extensionServices; - private ServiceParam serviceParam; - private Builder() { } @@ -1740,25 +2283,58 @@ public Builder extensionServices(List val) { return this; } - public Builder serviceParam(ServiceParam val) { - serviceParam = val; - return this; - } - public ExtensionServiceConfig build() { return new ExtensionServiceConfig(this); } } } + /** + * @brief Configuration for extended services. + * @since v0.4.0 + */ public static class ExtensionService { - + /** + * Name of the extended service.(Required) + *

+ * The service name can be set to: + *

+ * - "web_recorder_service": Represents the extended service is web page + * recording. + *

+ * - "rtmp_publish_service": Represents the extended service is to push web page + * recording to the CDN. + */ @JsonProperty("serviceName") private String serviceName; + /** + * Error handling strategy within the extension service.(Optional) + *

+ * The error handling strategy can be set to: + *

+ * - "error_abort": the default and only value during web page recording. + * Stop other extension services when the current extension service encounters + * an error. + *

+ * - "error_ignore": The only default value when you push the web page recording + * to the CDN. + *

+ * Other extension services are not affected when the current extension service + * encounters an error. + */ @JsonProperty("errorHandlePolicy") private String errorHandlePolicy; + /** + * Specific configurations for extension services.(Required) + *

+ * - "WebRecordingServiceParam" for web page recording. See + * WebRecordingServiceParam for details. + *

+ * - "RtmpPublishServiceParam" for pushing web page recording to the CDN. See + * RtmpPublishServiceParam for details. + */ @JsonProperty("serviceParam") private ServiceParam serviceParam; @@ -1837,8 +2413,14 @@ public ExtensionService build() { } } - public static class Outputs { - + /** + * @brief The CDN address to which you push the stream. + * @since v0.4.0 + */ + public static class Output { + /** + * The CDN address to which you push the stream.(Required) + */ @JsonProperty("rtmpUrl") private String rtmpUrl; @@ -1846,7 +2428,7 @@ public static Builder builder() { return new Builder(); } - private Outputs(Builder builder) { + private Output(Builder builder) { setRtmpUrl(builder.rtmpUrl); } @@ -1876,44 +2458,142 @@ public Builder rtmpUrl(String val) { return this; } - public Outputs build() { - return new Outputs(this); + public Output build() { + return new Output(this); } } } + /** + * @brief Service parameter configuration for web page recording. + * @since v0.4.0 + */ public static class WebRecordingServiceParam implements ServiceParam { - + /** + * The address of the page to be recorded.(Required) + */ @JsonProperty("url") private String url; + /** + * The bitrate of the output video (Kbps).(Optional) + *

+ * For different output video resolutions, the default value of videoBitrate is + * different: + *

+ * - Output video resolution is greater than or equal to 1280 × 720, and the + * default value is 2000. + *

+ * - Output video resolution is less than 1280 × 720, and the default value is + * 1500. + */ @JsonProperty("VideoBitrate") private Integer videoBitRate; + /** + * The frame rate of the output video (fps).(Optional) + *

+ * The value range is [5,60]. + *

+ * The default value is 15. + */ @JsonProperty("videoFps") private Integer videoFPS; + /** + * Sampling rate, bitrate, encoding mode, and number of channels for the audio + * output.(Required) + *

+ * The audio profile can be set to: + *

+ * - 0: 48 kHz sampling rate, music encoding, mono audio channel, and the + * encoding bitrate is approximately 48 Kbps. + *

+ * - 1: 48 kHz sampling rate, music encoding, mono audio channel, and the + * encoding bitrate is approximately 128 Kbps. + *

+ * - 2: 48 kHz sampling rate, music encoding, stereo audio channel, and the + * encoding bitrate is approximately 192 Kbps. + */ @JsonProperty("audioProfile") private Integer audioProfile; + /** + * Whether to enable the mobile web mode.(Optional) + *

+ * - true: Enables the mode. After enabling, the recording service uses the + * mobile web rendering mode to record the current page. + *

+ * - false: Disables the mode.(Default) + */ @JsonProperty("mobile") private Boolean mobile; + /** + * The output video width (pixel).(Required) + *

+ * The product of videoWidth and videoHeight should be less than or equal to + * 1920 × 1080. + */ @JsonProperty("videoWidth") private Integer videoWidth; + /** + * The output video height (pixel).(Required) + *

+ * The product of videoWidth and videoHeight should be less than or equal to + * 1920 × 1080. + */ @JsonProperty("videoHeight") private Integer videoHeight; + /** + * The maximum duration of web page recording (hours). (Required) + *

+ * The web page recording will automatically stop after exceeding this value. + *

+ * The value range is [1,720]. + */ @JsonProperty("maxRecordingHour") private Integer maxRecordingHour; + /** + * Maximum length of MP4 slice file generated by web page recording, in + * minutes.(Optional) + *

+ * During the web page recording process, the recording service will create a + * new MP4 slice file when the current MP4 file duration exceeds the + * maxVideoDuration approximately. + *

+ * The value range is [30,240]. + *

+ * The default value is 120. + */ @JsonProperty("maxVideoDuration") private Integer maxVideoDuration; + /** + * Whether to pause page recording when starting a web page recording task. + * (Optional) + *

+ * - true: Pauses the web page recording that has been started. Immediately + * pause the recording after starting the web page recording task. The + * recording service will open and render the page to be recorded, but will + * not generate slice files. + *

+ * - false: Starts a web page recording task and performs web page + * recording.(Default) + */ @JsonProperty("onhold") private Boolean onhold; + /** + * Set the page load timeout in seconds.(Optional) + *

+ * The value range is [0,60]. + *

+ * The default value is 0. + */ @JsonProperty("readyTimeout") private Integer readyTimeout; @@ -2128,10 +2808,19 @@ public WebRecordingServiceParam build() { } } + /** + * @brief Service parameter configuration for pushing web page recording to the + * CDN. + * + * @since v0.4.0 + */ public static class RtmpPublishServiceParam implements ServiceParam { + /** + * The array of CDN addresses to which you push the stream.(Required) + */ @JsonProperty("outputs") - private List outputs; + private List outputs; public static Builder builder() { return new Builder(); @@ -2141,11 +2830,11 @@ private RtmpPublishServiceParam(Builder builder) { setOutputs(builder.outputs); } - public List getOutputs() { + public List getOutputs() { return outputs; } - public void setOutputs(List outputs) { + public void setOutputs(List outputs) { this.outputs = outputs; } @@ -2158,12 +2847,12 @@ public String toString() { public static final class Builder { - private List outputs; + private List outputs; private Builder() { } - public Builder outputs(List val) { + public Builder outputs(List val) { outputs = val; return this; } @@ -2174,14 +2863,57 @@ public RtmpPublishServiceParam build() { } } + /** + * @brief Configurations of user's background image. + * + * @since v0.4.0 + */ public static class BackgroundConfig { + /** + * The string content is the UID.(Required) + */ @JsonProperty("uid") private String uid; + /** + * The URL of the user's background image.(Required) + *

+ * After setting the background image, if the user stops sending the video + * stream for more than 3.5 seconds, + * the screen will switch to the background image. + *

+ * URL supports the HTTP and HTTPS protocols, and the image formats supported + * are JPG and BMP. + *

+ * The image size must not exceed 6 MB. + *

+ * The settings will only take effect after the recording service successfully + * downloads the image; + * if the download fails, the settings will not take effect. + *

+ * Different field settings may overlap each other. + */ @JsonProperty("image_url") private String imageUrl; + /** + * The display mode of users' video windows.(Optional) + *

+ * The value can be set to: + *

+ * - 0: cropped mode.(Default) + * Prioritize to ensure the screen is filled. + * The video window size is proportionally scaled until it fills the screen. + * If the video's length and width differ from the video window, + * the video stream will be cropped from its edges to fit the window, under the + * aspect ratio set for the video window. + *

+ * - 1: Fit mode. + * Prioritize to ensure that all video content is displayed. + * The video size is scaled proportionally until one side of the video window is + * aligned with the screen border. + */ @JsonProperty("render_mode") private Integer renderMode; diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/req/UpdateLayoutResourceReq.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/req/UpdateLayoutResourceReq.java index 5bb02f2..c9e2423 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/req/UpdateLayoutResourceReq.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/req/UpdateLayoutResourceReq.java @@ -246,26 +246,102 @@ public String toString() { } } + /** + * @brief Configurations of user's video window to be updated. + * @since v0.4.0 + */ public static class LayoutConfig { + /** + * The content of the string is the UID of the user to be displayed in the area, + * 32-bit unsigned integer. + */ @JsonProperty("uid") private String uid; + /** + * The relative value of the horizontal coordinate of the upper-left corner of + * the screen, accurate to six decimal places. + *

+ * Layout from left to right, with 0.0 at the far left and 1.0 at the far right. + *

+ * This field can also be set to the integer 0 or 1. + *

+ * The value range is [0,1]. + */ @JsonProperty("x_axis") private Float xAxis; + /** + * The relative value of the vertical coordinate of the upper-left corner of + * this screen in the screen, accurate to six decimal places. + *

+ * Layout from top to bottom, with 0.0 at the top and 1.0 at the bottom. + *

+ * This field can also be set to the integer 0 or 1. + *

+ * The value range is [0,1]. + */ @JsonProperty("y_axis") private Float yAxis; + /** + * The relative value of the width of this screen, accurate to six decimal + * places. + *

+ * This field can also be set to the integer 0 or 1. + *

+ * The value range is [0,1]. + */ @JsonProperty("width") private Float width; + /** + * The relative value of the height of this screen, accurate to six decimal + * places. + *

+ * This field can also be set to the integer 0 or 1. + *

+ * The value range is [0,1]. + */ @JsonProperty("height") private Float height; + /** + * The transparency of the user's video window. Accurate to six decimal places. + *

+ * 0.0 means the user's video window is transparent, and 1.0 indicates that it + * is completely opaque. + *

+ * The value range is [0,1]. + *

+ * The default value is 1. + */ @JsonProperty("alpha") private Float alpha; + /** + * The display mode of users' video windows. + *

+ * The rendering mode can be set to: + *

+ * - 0: Cropped mode.(Default) + * Prioritize to ensure the screen is filled. + * The video window size is proportionally scaled until it fills the screen. + * If the video's length and width differ from the video window, + * the video stream will be cropped from its edges to fit the window, + * under the aspect ratio set for the video window. + *

+ * - 1: Fit mode. + * Prioritize to ensure that all video content is displayed. + * The video size is scaled proportionally until one side of the video window is + * aligned with the screen border. + * If the video scale does not comply with the window size, + * the video will be scaled to fill the screen while maintaining its aspect + * ratio. + *

+ * This scaling may result in a black border around the edges of the video. + */ @JsonProperty("render_mode") private Integer renderMode; @@ -412,14 +488,56 @@ public String toString() { } } + /** + * @brief Configurations of user's background image to be updated. + * @since v0.4.0 + */ public static class BackgroundConfig { + /** + * The string content is the UID.(Required) + */ @JsonProperty("uid") private String uid; + /** + * The URL of the user's background image.(Required) + *

+ * After setting the background image, if the user stops sending the video + * stream for more than 3.5 seconds, + * the screen will switch to the background image. + *

+ * URL supports the HTTP and HTTPS protocols, and the image formats supported + * are JPG and BMP. + *

+ * The image size must not exceed 6 MB. + *

+ * The settings will only take effect after the recording service successfully + * downloads the image; + * if the download fails, the settings will not take effect. + *

+ * Different field settings may overlap each other. + */ @JsonProperty("image_url") private String imageURL; + /** + * The display mode of users' video windows.(Optional) + *

+ * The value can be set to: + *

+ * - 0: cropped mode.(Default) + * Prioritize to ensure the screen is filled. + * The video window size is proportionally scaled until it fills the screen. + * If the video's length and width differ from the video window, + * the video stream will be cropped from its edges to fit the window, under the + * aspect ratio set for the video window. + *

+ * - 1: Fit mode. + * Prioritize to ensure that all video content is displayed. + * The video size is scaled proportionally until one side of the video window is + * aligned with the screen border. + */ @JsonProperty("render_mode") private Integer renderMode; diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/req/UpdateResourceReq.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/req/UpdateResourceReq.java index 807e7ec..ee5262d 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/req/UpdateResourceReq.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/req/UpdateResourceReq.java @@ -144,11 +144,20 @@ public ClientRequest build() { } } + /** + * @brief Update subscription lists. + * @since v0.4.0 + */ public static class StreamSubscribe { - + /* + * The audio subscription list.(Optional) + */ @JsonProperty("audioUidList") private AudioUIDList audioUidList; + /** + * The video subscription list.(Optional) + */ @JsonProperty("videoUidList") private VideoUIDList videoUidList; @@ -210,11 +219,30 @@ public StreamSubscribe build() { } } + /** + * @brief Update audio subscription list. + * @since v0.4.0 + */ public static class AudioUIDList { + /** + * Specify which UIDs' audio streams to subscribe to. + * + * If you want to subscribe to the audio stream of all UIDs, no need to set + * this field. + * + * Set as ["#allstream#"] to subscribe to the audio streams of all UIDs in + * the channel. + */ @JsonProperty("subscribeAudioUids") private List subscribeAudioUIDs; + /** + * Specify which UIDs' audio streams not to subscribe to. + * + * The cloud recording service will subscribe to the audio streams of all other + * UIDs except the specified ones. + */ @JsonProperty("unSubscribeAudioUids") private List unsubscribeAudioUIDs; @@ -276,11 +304,30 @@ public AudioUIDList build() { } } + /** + * @brief Update video subscription list. + * @since v0.4.0 + */ public static class VideoUIDList { + /** + * Specify which UIDs' video streams to subscribe to. + * + * If you want to subscribe to the video stream of all UIDs, no need to set this + * field. + * + * Set as ["#allstream#"] to subscribe to the video streams of all UIDs in the + * channel. + */ @JsonProperty("subscribeVideoUids") private List subscribeVideoUIDs; + /* + * Specify which UIDs' video streams not to subscribe to. + * + * The cloud recording service will subscribe to the video streams of all other + * UIDs except the specified ones. + */ @JsonProperty("unSubscribeVideoUids") private List unsubscribeVideoUIDs; @@ -342,7 +389,22 @@ public VideoUIDList build() { } } + /** + * @brief Used to update the web page recording configurations. + * @since v0.4.0 + */ public static class WebRecordingConfig { + /** + * Set whether to pause the web page recording. + *

+ * - true: Pauses web page recording and generating recording files. + *

+ * - false: (Default) Continues web page recording and generates recording + * files. + *

+ * If you want to resume a paused web page recording, you can call the + * update method and set onhold to false. + */ @JsonProperty("onhold") private Boolean onHold; @@ -387,8 +449,16 @@ public WebRecordingConfig build() { } } + /** + * @brief Used to update the configurations for pushing web page recording to + * the CDN. + * @since v0.4.0 + */ public static class RtmpPublishConfig { + /** + * The output of pushing web page recording to the CDN. + */ @JsonProperty("outputs") private List outputs; @@ -433,8 +503,19 @@ public RtmpPublishConfig build() { } } + /** + * @brief Used to update the output of pushing web page recording to the CDN. + * @since v0.4.0 + */ public static class UpdateOutput { + /** + * The CDN URL where you push the stream to. + *

+ * URLs only support the RTMP and RTMPS protocols. + *

+ * The maximum number of streams being pushed to the CDN is 1. + */ @JsonProperty("rtmpUrl") private String rtmpURL; diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/AcquireResourceRes.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/AcquireResourceRes.java index 225c3e4..c45d5d9 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/AcquireResourceRes.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/AcquireResourceRes.java @@ -2,13 +2,27 @@ import com.fasterxml.jackson.annotation.JsonProperty; +/** + * @brief Returned by the various of cloud recording scenarios acquire API. + * @since v0.4.0 + */ public class AcquireResourceRes { + /** + * The name of the channel to be recorded. + */ @JsonProperty("cname") private String cname; + /** + * The user ID used by the cloud recording service in the RTC channel to + * identify the recording service in the channel. + */ @JsonProperty("uid") private String uid; + /** + * Unique identifier of the resource. + */ @JsonProperty("resourceId") private String resourceId; diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/QueryResourceRes.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/QueryResourceRes.java index a8494bd..f5d56e4 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/QueryResourceRes.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/QueryResourceRes.java @@ -10,16 +10,28 @@ import java.util.List; public class QueryResourceRes { + /** + * The name of the channel to be recorded. + */ @JsonProperty("cname") private String cname; + /** + * The user ID used by the cloud recording service in the RTC channel to + * identify the recording service in the channel. + */ @JsonProperty("uid") private String uid; + /** + * Unique identifier of the resource. + */ @JsonProperty("resourceId") private String resourceId; - @JsonProperty("sid") + /** + * Unique identifier of the recording session. + */ private String sid; @JsonProperty("serverResponse") @@ -43,13 +55,16 @@ public class QueryResourceRes { @JsonIgnore private WebRecordingServerResponse webRecordingServerResponse; + @JsonIgnore + private WebRecordingRtmpPublishServerResponse webRecordingRtmpPublishServerResponse; + + private static final ObjectMapper objectMapper = new ObjectMapper(); + @JsonIgnore public void setServerResponse(CloudRecordingModeEnum mode) throws Exception { JsonNode fileListModeNode = this.serverResponse.path("fileListMode"); this.serverResponseType = ServerResponseType.QUERY_SERVER_RESPONSE_UNKNOWN_TYPE; - ObjectMapper objectMapper = new ObjectMapper(); - switch (mode) { case INDIVIDUAL: if (fileListModeNode.isTextual() && "json".equals(fileListModeNode.asText())) { @@ -80,12 +95,35 @@ public void setServerResponse(CloudRecordingModeEnum mode) throws Exception { } break; case WEB: - this.serverResponseType = ServerResponseType.QUERY_WEB_RECORDING_SERVER_RESPONSE_TYPE; - this.webRecordingServerResponse = objectMapper.treeToValue(this.serverResponse, - WebRecordingServerResponse.class); + // Check for specific service types in WEB mode + JsonNode extensionServiceState = this.serverResponse.path("extensionServiceState"); + + if (extensionServiceState.isArray() && extensionServiceState.size() > 0) { + String serviceName = extensionServiceState.get(0).path("serviceName").asText(); + + switch (serviceName) { + case "rtmp_publish_service": + this.serverResponseType = ServerResponseType.QUERY_WEB_RECORDING_RTMP_PUBLISH_SERVER_RESPONSE_TYPE; + this.webRecordingRtmpPublishServerResponse = objectMapper.treeToValue(this.serverResponse, + WebRecordingRtmpPublishServerResponse.class); + break; + + case "web_recorder_service": + this.serverResponseType = ServerResponseType.QUERY_WEB_RECORDING_SERVER_RESPONSE_TYPE; + this.webRecordingServerResponse = objectMapper.treeToValue(this.serverResponse, + WebRecordingServerResponse.class); + break; + + default: + throw new AgoraJsonException("Unknown service name: " + serviceName); + } + } else { + this.serverResponseType = ServerResponseType.QUERY_WEB_RECORDING_SERVER_RESPONSE_TYPE; + this.webRecordingServerResponse = objectMapper.treeToValue(this.serverResponse, + WebRecordingServerResponse.class); + } break; } - } public String getCname() { @@ -140,7 +178,8 @@ public QueryIndividualRecordingServerResponse getQueryIndividualRecordingServerR return queryIndividualRecordingServerResponse; } - public void setQueryIndividualRecordingServerResponse(QueryIndividualRecordingServerResponse queryIndividualRecordingServerResponse) { + public void setQueryIndividualRecordingServerResponse( + QueryIndividualRecordingServerResponse queryIndividualRecordingServerResponse) { this.queryIndividualRecordingServerResponse = queryIndividualRecordingServerResponse; } @@ -148,7 +187,8 @@ public QueryIndividualVideoScreenshotServerResponse getQueryIndividualVideoScree return queryIndividualVideoScreenshotServerResponse; } - public void setQueryIndividualVideoScreenshotServerResponse(QueryIndividualVideoScreenshotServerResponse queryIndividualVideoScreenshotServerResponse) { + public void setQueryIndividualVideoScreenshotServerResponse( + QueryIndividualVideoScreenshotServerResponse queryIndividualVideoScreenshotServerResponse) { this.queryIndividualVideoScreenshotServerResponse = queryIndividualVideoScreenshotServerResponse; } @@ -164,7 +204,8 @@ public MixRecordingHLSAndMP4ServerResponse getMixRecordingHLSAndMP4ServerRespons return mixRecordingHLSAndMP4ServerResponse; } - public void setMixRecordingHLSAndMP4ServerResponse(MixRecordingHLSAndMP4ServerResponse mixRecordingHLSAndMP4ServerResponse) { + public void setMixRecordingHLSAndMP4ServerResponse( + MixRecordingHLSAndMP4ServerResponse mixRecordingHLSAndMP4ServerResponse) { this.mixRecordingHLSAndMP4ServerResponse = mixRecordingHLSAndMP4ServerResponse; } @@ -176,6 +217,15 @@ public void setWebRecordingServerResponse(WebRecordingServerResponse webRecordin this.webRecordingServerResponse = webRecordingServerResponse; } + public WebRecordingRtmpPublishServerResponse getWebRecordingRtmpPublishServerResponse() { + return webRecordingRtmpPublishServerResponse; + } + + public void setWebRecordingRtmpPublishServerResponse( + WebRecordingRtmpPublishServerResponse webRecordingRtmpPublishServerResponse) { + this.webRecordingRtmpPublishServerResponse = webRecordingRtmpPublishServerResponse; + } + @Override public String toString() { return "QueryResourceRes{" + @@ -199,19 +249,62 @@ public enum ServerResponseType { QUERY_INDIVIDUAL_VIDEO_SCREENSHOT_SERVER_RESPONSE_TYPE, QUERY_MIX_RECORDING_HLS_SERVER_RESPONSE_TYPE, QUERY_MIX_RECORDING_HLS_AND_MP4_SERVER_RESPONSE_TYPE, - QUERY_WEB_RECORDING_SERVER_RESPONSE_TYPE + QUERY_WEB_RECORDING_SERVER_RESPONSE_TYPE, + QUERY_WEB_RECORDING_RTMP_PUBLISH_SERVER_RESPONSE_TYPE } + /** + * @brief Server response returned by the individual recording query API. + * @since v0.4.0 + */ public static class QueryIndividualRecordingServerResponse { + /** + * Current status of the cloud service: + *

+ * - 0: Cloud service has not started. + *

+ * - 1: The cloud service initialization is complete. + *

+ * - 2: The cloud service components are starting. + *

+ * - 3: Some cloud service components are ready. + *

+ * - 4: All cloud service components are ready. + *

+ * - 5: The cloud service is in progress. + *

+ * - 6: The cloud service receives the request to stop. + *

+ * - 7: All components of the cloud service stop. + *

+ * - 8: The cloud service exits. + *

+ * - 20: The cloud service exits abnormally. + */ @JsonProperty("status") private Integer status; + /** + * The data format of the fileList field: + *

+ * - "string": fileList is of String type. In composite recording mode, + * if avFileType is set to ["hls"], fileListMode is "string". + *

+ * - "json": fileList is a JSON Array. When avFileType is set to ["hls","mp4"] + * in the individual or composite recording mode, fileListMode is set to "json". + */ @JsonProperty("fileListMode") private String fileListMode; + /* + * The file list. + */ @JsonProperty("fileList") private List fileList; + /** + * The recording start time of the file, the Unix timestamp, in seconds. + */ @JsonProperty("sliceStartTime") private Long sliceStartTime; @@ -257,22 +350,60 @@ public String toString() { '}'; } + /** + * @brief The file details of the M3U8 and MP4 files generated during recording. + * @since v0.4.0 + */ public static class FileDetail { + /** + * The file names of the M3U8 and MP4 files generated during recording. + */ @JsonProperty("fileName") private String fileName; + /** + * The recording file type. + *

+ * - "audio": Audio-only files. + *

+ * - "video": Video-only files. + *

+ * - "audio_and_video": audio and video files + */ @JsonProperty("trackType") private String trackType; + /** + * User UID, indicating which user's audio or video stream is being recorded. + *

+ * In composite recording mode, the uid is "0". + */ @JsonProperty("uid") private String uid; + /** + * Whether the users were recorded separately. + *

+ * - true: All users are recorded in a single file. + *

+ * - false: Each user is recorded separately. + */ @JsonProperty("mixedAllUser") private Boolean mixedAllUser; + /** + * Whether or not can be played online. + *

+ * - true: The file can be played online. + *

+ * - false: The file cannot be played online. + */ @JsonProperty("isPlayable") private Boolean isPlayable; + /** + * The recording start time of the file, the Unix timestamp, in seconds. + */ @JsonProperty("sliceStartTime") private Long sliceStartTime; @@ -338,10 +469,41 @@ public String toString() { } } + /** + * @brief Server response returned by the individual recording + * queryVideoScreenshot API. + * @since v0.4.0 + */ public static class QueryIndividualVideoScreenshotServerResponse { + /** + * Current status of the cloud service: + *

+ * - 0: Cloud service has not started. + *

+ * - 1: The cloud service initialization is complete. + *

+ * - 2: The cloud service components are starting. + *

+ * - 3: Some cloud service components are ready. + *

+ * - 4: All cloud service components are ready. + *

+ * - 5: The cloud service is in progress. + *

+ * - 6: The cloud service receives the request to stop. + *

+ * - 7: All components of the cloud service stop. + *

+ * - 8: The cloud service exits. + *

+ * - 20: The cloud service exits abnormally. + */ @JsonProperty("status") private Integer status; + /** + * The recording start time of the file, the Unix timestamp, in seconds. + */ @JsonProperty("sliceStartTime") private Long sliceStartTime; @@ -370,16 +532,58 @@ public String toString() { } } + /** + * @brief Server response returned by the mix recording queryHLS API. + * @since v0.4.0 + */ public static class MixRecordingHLSServerResponse { + /** + * Current status of the cloud service: + *

+ * - 0: Cloud service has not started. + *

+ * - 1: The cloud service initialization is complete. + *

+ * - 2: The cloud service components are starting. + *

+ * - 3: Some cloud service components are ready. + *

+ * - 4: All cloud service components are ready. + *

+ * - 5: The cloud service is in progress. + *

+ * - 6: The cloud service receives the request to stop. + *

+ * - 7: All components of the cloud service stop. + *

+ * - 8: The cloud service exits. + *

+ * - 20: The cloud service exits abnormally. + */ @JsonProperty("status") private Integer status; + /** + * The data format of the fileList field: + *

+ * - "string": fileList is of String type. In composite recording mode, + * if avFileType is set to ["hls"], fileListMode is "string". + *

+ * - "json": fileList is a JSON Array. When avFileType is set to ["hls","mp4"] + * in the individual or composite recording mode, fileListMode is set to "json". + */ @JsonProperty("fileListMode") private String fileListMode; + /* + * The file list. + */ @JsonProperty("fileList") private String fileList; + /** + * The recording start time of the file, the Unix timestamp, in seconds. + */ @JsonProperty("sliceStartTime") private Long sliceStartTime; @@ -426,16 +630,59 @@ public String toString() { } } + /** + * @brief Server response returned by the mix recording queryHLSAndMP4 API. + * @since v0.4.0 + */ public static class MixRecordingHLSAndMP4ServerResponse { + /** + * Current status of the cloud service: + *

+ * - 0: Cloud service has not started. + *

+ * - 1: The cloud service initialization is complete. + *

+ * - 2: The cloud service components are starting. + *

+ * - 3: Some cloud service components are ready. + *

+ * - 4: All cloud service components are ready. + *

+ * - 5: The cloud service is in progress. + *

+ * - 6: The cloud service receives the request to stop. + *

+ * - 7: All components of the cloud service stop. + *

+ * - 8: The cloud service exits. + *

+ * - 20: The cloud service exits abnormally. + */ @JsonProperty("status") private Integer status; + /** + * The data format of the fileList field: + *

+ * - "string": fileList is of String type. In composite recording mode, + * if avFileType is set to ["hls"], fileListMode is "string". + *

+ * - "json": fileList is a JSON Array. When avFileType is set to ["hls","mp4"] + * in the individual or composite recording mode, fileListMode is set to "json". + */ @JsonProperty("fileListMode") private String fileListMode; + /* + * The file list. + */ @JsonProperty("fileList") private List fileList; + /** + * The recording start time of the file, the Unix timestamp, in + * seconds. + */ @JsonProperty("sliceStartTime") private Long sliceStartTime; @@ -481,22 +728,61 @@ public String toString() { '}'; } + /** + * @brief The file details when the avFileType is set to ["hls","mp4"]. + * @since v0.4.0 + */ public static class FileDetail { + /** + * The file name of the M3U8 and MP4 files generated during recording. + * (Optional) + */ @JsonProperty("fileName") private String fileName; + /** + * The recording file type.(Optional) + *

+ * - "audio": Audio-only files. + *

+ * - "video": Video-only files. + *

+ * - "audio_and_video": audio and video files + */ @JsonProperty("trackType") private String trackType; + /** + * User UID, indicating which user's audio or video stream is being recorded. In + * composite recording mode, the uid is "0".(Optional) + */ @JsonProperty("uid") private String uid; + /** + * Whether the users were recorded separately.(Optional) + *

+ * - true: All users are recorded in a single file. + *

+ * - false: Each user is recorded separately. + */ @JsonProperty("mixedAllUser") private Boolean mixedAllUser; + /** + * Whether or not can be played online.(Optional) + *

+ * - true: The file can be played online. + *

+ * - false: The file cannot be played online. + */ @JsonProperty("isPlayable") private Boolean isPlayable; + /** + * The recording start time of the file, the Unix timestamp, in + * seconds.(Optional) + */ @JsonProperty("sliceStartTime") private Long sliceStartTime; @@ -562,10 +848,40 @@ public String toString() { } } + /** + * @brief Server response returned by the web recording query API. + * @since v0.4.0 + */ public static class WebRecordingServerResponse { + /** + * Current status of the cloud service: + *

+ * - 0: Cloud service has not started. + *

+ * - 1: The cloud service initialization is complete. + *

+ * - 2: The cloud service components are starting. + *

+ * - 3: Some cloud service components are ready. + *

+ * - 4: All cloud service components are ready. + *

+ * - 5: The cloud service is in progress. + *

+ * - 6: The cloud service receives the request to stop. + *

+ * - 7: All components of the cloud service stop. + *

+ * - 8: The cloud service exits. + *

+ * - 20: The cloud service exits abnormally. + */ @JsonProperty("status") private Integer status; + /** + * The extension service state. + */ @JsonProperty("extensionServiceState") private List extensionServiceState; @@ -593,10 +909,26 @@ public String toString() { '}'; } + /** + * @brief The extension service state. + * @since v0.4.0 + */ public static class ExtensionServiceState { + /** + * Extension service payload + */ @JsonProperty("payload") private Payload payload; + /** + * Name of the extended service: + *

+ * - "web_recorder_service": Represents the extended service is web page + * recording. + *

+ * - "rtmp_publish_service": Represents the extended service is to push web page + * recording to the CDN. + */ @JsonProperty("serviceName") private String serviceName; @@ -608,125 +940,307 @@ public String toString() { '}'; } - public static class Payload { - @JsonProperty("fileList") - private List fileList; + } - @JsonProperty("onhold") - private Boolean onhold; + /** + * @brief Extended service payload. + * @since v0.4.0 + */ + public static class Payload { + /** + * The file list. + */ + @JsonProperty("fileList") + private List fileList; + + /** + * Whether the page recording is in pause state: + *

+ * - true: In pause state. + *

+ * - false: The page recording is running. + */ + @JsonProperty("onhold") + private Boolean onhold; + + /** + * The status of uploading subscription content to the extension service: + *

+ * - "init": The service is initializing. + *

+ * - "inProgress": The service has started and is currently in progress. + *

+ * - "exit": Service exits. + */ + @JsonProperty("state") + private String state; + + public void setFileList(List fileList) { + this.fileList = fileList; + } - @JsonProperty("state") - private String state; + public Boolean getOnhold() { + return onhold; + } - @JsonProperty("outputs") - private List outputs; + public void setOnhold(Boolean onhold) { + this.onhold = onhold; + } - public List getFileList() { - return fileList; - } + public String getState() { + return state; + } - public void setFileList(List fileList) { - this.fileList = fileList; - } + public void setState(String state) { + this.state = state; + } - public Boolean getOnhold() { - return onhold; - } + @Override + public String toString() { + return "Payload{" + + "fileList=" + fileList + + ", onhold=" + onhold + + ", state='" + state + '\'' + + '}'; + } - public void setOnhold(Boolean onhold) { - this.onhold = onhold; - } + } - public String getState() { - return state; - } + /** + * @brief The file detail. + * @since v0.4.0 + */ + public static class FileDetail { + /** + * The file name. + */ + @JsonProperty("filename") + private String filename; + + /** + * The recording start time of the file, the Unix timestamp, in seconds. + */ + @JsonProperty("sliceStartTime") + private Long sliceStartTime; - public void setState(String state) { - this.state = state; - } + public String getFilename() { + return filename; + } - public List getOutputs() { - return outputs; - } + public void setFilename(String filename) { + this.filename = filename; + } - public void setOutputs(List outputs) { - this.outputs = outputs; - } + public Long getSliceStartTime() { + return sliceStartTime; + } - @Override - public String toString() { - return "Payload{" + - "fileList=" + fileList + - ", onhold=" + onhold + - ", state='" + state + '\'' + - ", outputs=" + outputs + - '}'; - } + public void setSliceStartTime(Long sliceStartTime) { + this.sliceStartTime = sliceStartTime; + } - public static class FileDetail { - @JsonProperty("filename") - private String filename; + @Override + public String toString() { + return "FileDetail{" + + "filename='" + filename + '\'' + + ", sliceStartTime=" + sliceStartTime + + '}'; + } + } + } - @JsonProperty("sliceStartTime") - private Long sliceStartTime; + /** + * @brief Server response returned by the web recording queryRtmpPublish API. + * @since v0.4.0 + */ + public static class WebRecordingRtmpPublishServerResponse { + /** + * Current status of the cloud service: + *

+ * - 0: Cloud service has not started. + *

+ * - 1: The cloud service initialization is complete. + *

+ * - 2: The cloud service components are starting. + *

+ * - 3: Some cloud service components are ready. + *

+ * - 4: All cloud service components are ready. + *

+ * - 5: The cloud service is in progress. + *

+ * - 6: The cloud service receives the request to stop. + *

+ * - 7: All components of the cloud service stop. + *

+ * - 8: The cloud service exits. + *

+ * - 20: The cloud service exits abnormally. + */ + @JsonProperty("status") + private Integer status; - public String getFilename() { - return filename; - } + /** + * The extension service state. + */ + @JsonProperty("extensionServiceState") + private List extensionServiceState; - public void setFilename(String filename) { - this.filename = filename; - } + public Integer getStatus() { + return status; + } - public Long getSliceStartTime() { - return sliceStartTime; - } + public void setStatus(Integer status) { + this.status = status; + } - public void setSliceStartTime(Long sliceStartTime) { - this.sliceStartTime = sliceStartTime; - } + public List getExtensionServiceState() { + return extensionServiceState; + } - @Override - public String toString() { - return "FileDetail{" + - "filename='" + filename + '\'' + - ", sliceStartTime=" + sliceStartTime + - '}'; - } - } + public void setExtensionServiceState(List extensionServiceState) { + this.extensionServiceState = extensionServiceState; + } - public static class Output { - @JsonProperty("rtmpUrl") - private String rtmpUrl; + @Override + public String toString() { + return "WebRecordingServerResponse{" + + "status=" + status + + ", extensionServiceState=" + extensionServiceState + + '}'; + } - @JsonProperty("status") - private String status; + /** + * @brief The extension service state. + * @since v0.4.0 + */ + public static class ExtensionServiceState { + /** + * Extension service payload + */ + @JsonProperty("payload") + private Payload payload; - public String getRtmpUrl() { - return rtmpUrl; - } + /** + * Name of the extended service: + *

+ * - "web_recorder_service": Represents the extended service is web page + * recording. + *

+ * - "rtmp_publish_service": Represents the extended service is to push web page + * recording to the CDN. + */ + @JsonProperty("serviceName") + private String serviceName; - public void setRtmpUrl(String rtmpUrl) { - this.rtmpUrl = rtmpUrl; - } + @Override + public String toString() { + return "ExtensionServiceState{" + + "payload=" + payload + + ", serviceName='" + serviceName + '\'' + + '}'; + } + } - public String getStatus() { - return status; - } + /** + * @brief Extended service payload. + * @since v0.4.0 + */ + public static class Payload { + + /** + * The status of uploading subscription content to the extension service: + *

+ * - "init": The service is initializing. + *

+ * - "inProgress": The service has started and is currently in progress. + *

+ * - "exit": Service exits. + */ + @JsonProperty("state") + private String state; + + /** + * The status of the push stream to the CDN. + */ + @JsonProperty("outputs") + private List outputs; + + public String getState() { + return state; + } - public void setStatus(String status) { - this.status = status; - } + public void setState(String state) { + this.state = state; + } - @Override - public String toString() { - return "Output{" + - "rtmpUrl='" + rtmpUrl + '\'' + - ", status='" + status + '\'' + - '}'; - } - } + public List getOutputs() { + return outputs; + } + + public void setOutputs(List outputs) { + this.outputs = outputs; + } + + @Override + public String toString() { + return "Payload{" + + "state='" + state + '\'' + + ", outputs=" + outputs + + '}'; + } + + } + + /** + * @brief The push stream to the CDN output. + * @since v0.4.0 + */ + public static class Output { + /** + * The CDN address to which you push the stream. + */ + @JsonProperty("rtmpUrl") + private String rtmpUrl; + + /** + * The current status of stream pushing of the web page recording: + *

+ * - "connecting": Connecting to the CDN server. + *

+ * - "publishing": The stream pushing is going on. + *

+ * - "onhold": Set whether to pause the stream pushing. + *

+ * - "disconnected": Failed to connect to the CDN server. Agora recommends + * that you change the CDN address to push the stream. + */ + @JsonProperty("status") + private String status; + + public String getRtmpUrl() { + return rtmpUrl; + } + + public void setRtmpUrl(String rtmpUrl) { + this.rtmpUrl = rtmpUrl; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + @Override + public String toString() { + return "Output{" + + "rtmpUrl='" + rtmpUrl + '\'' + + ", status='" + status + '\'' + + '}'; } } } -} +} \ No newline at end of file diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/StartResourceRes.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/StartResourceRes.java index 521dd06..895e553 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/StartResourceRes.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/StartResourceRes.java @@ -2,16 +2,33 @@ import com.fasterxml.jackson.annotation.JsonProperty; +/** + * @brief Returned by the various of cloud recording scenarios start API. + * @since v0.4.0 + */ public class StartResourceRes { + /** + * The name of the channel to be recorded. + */ @JsonProperty("cname") private String cname; + /** + * The user ID used by the cloud recording service in the RTC channel to + * identify the recording service in the channel. + */ @JsonProperty("uid") private String uid; + /** + * Unique identifier of the resource. + */ @JsonProperty("resourceId") private String resourceId; + /** + * Unique identifier of the recording session. + */ @JsonProperty("sid") private String sid; diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/StopResourceRes.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/StopResourceRes.java index 72fff3e..590502a 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/StopResourceRes.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/StopResourceRes.java @@ -2,16 +2,33 @@ import com.fasterxml.jackson.annotation.JsonProperty; +/** + * @brief Returned by the various of cloud recording scenarios stop API. + * @since v0.4.0 + */ public class StopResourceRes { + /** + * The name of the channel to be recorded. + */ @JsonProperty("cname") private String cname; + /** + * The user ID used by the cloud recording service in the RTC channel to + * identify the recording service in the channel. + */ @JsonProperty("uid") private String uid; + /** + * Unique identifier of the resource. + */ @JsonProperty("resourceId") private String resourceId; + /** + * Unique identifier of the recording session. + */ @JsonProperty("sid") private String sid; diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/UpdateLayoutResourceRes.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/UpdateLayoutResourceRes.java index 6b42726..496b514 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/UpdateLayoutResourceRes.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/UpdateLayoutResourceRes.java @@ -2,16 +2,33 @@ import com.fasterxml.jackson.annotation.JsonProperty; +/** + * @brief Returned by the mix recording updateLayout API. + * @since v0.4.0 + */ public class UpdateLayoutResourceRes { + /** + * The name of the channel to be recorded. + */ @JsonProperty("cname") private String cname; + /** + * The user ID used by the cloud recording service in the RTC channel to + * identify the recording service in the channel. + */ @JsonProperty("uid") private String uid; + /** + * Unique identifier of the resource. + */ @JsonProperty("resourceId") private String resourceId; + /** + * Unique identifier of the recording session. + */ @JsonProperty("sid") private String sid; diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/UpdateResourceRes.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/UpdateResourceRes.java index 2a3893b..0d2467f 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/UpdateResourceRes.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/api/res/UpdateResourceRes.java @@ -2,16 +2,33 @@ import com.fasterxml.jackson.annotation.JsonProperty; +/** + * @brief Returned by the various of cloud recording scenarios update API. + * @since v0.4.0 + */ public class UpdateResourceRes { + /** + * The name of the channel to be recorded. + */ @JsonProperty("cname") private String cname; + /** + * The user ID used by the cloud recording service in the RTC channel to + * identify the recording service in the channel. + */ @JsonProperty("uid") private String uid; + /** + * Unique identifier of the resource. + */ @JsonProperty("resourceId") private String resourceId; + /** + * Unique identifier of the recording session. + */ @JsonProperty("sid") private String sid; diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/IndividualScenario.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/IndividualScenario.java index 66be84f..881b23f 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/IndividualScenario.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/IndividualScenario.java @@ -1,15 +1,9 @@ package io.agora.rest.services.cloudrecording.scenario.individual; -import io.agora.rest.services.cloudrecording.api.*; -import io.agora.rest.services.cloudrecording.api.req.AcquireResourceReq; -import io.agora.rest.services.cloudrecording.api.req.StartResourceReq; -import io.agora.rest.services.cloudrecording.api.req.StopResourceReq; -import io.agora.rest.services.cloudrecording.api.req.UpdateResourceReq; import io.agora.rest.services.cloudrecording.api.res.AcquireResourceRes; import io.agora.rest.services.cloudrecording.api.res.StartResourceRes; import io.agora.rest.services.cloudrecording.api.res.StopResourceRes; import io.agora.rest.services.cloudrecording.api.res.UpdateResourceRes; -import io.agora.rest.services.cloudrecording.enums.CloudRecordingModeEnum; import io.agora.rest.services.cloudrecording.scenario.individual.req.AcquireIndividualResourceClientReq; import io.agora.rest.services.cloudrecording.scenario.individual.req.StartIndividualRecordingClientReq; import io.agora.rest.services.cloudrecording.scenario.individual.req.UpdateIndividualRecordingResourceClientReq; @@ -17,142 +11,103 @@ import io.agora.rest.services.cloudrecording.scenario.individual.res.QueryIndividualRecordingVideoScreenshotResourceRes; import reactor.core.publisher.Mono; -public class IndividualScenario { - - private final AcquireResourceAPI acquireResourceAPI; - - private final QueryResourceAPI queryResourceAPI; - - private final StartResourceAPI startResourceAPI; - - private final UpdateResourceAPI updateResourceAPI; - - private final StopResourceAPI stopResourceAPI; - - public IndividualScenario(AcquireResourceAPI acquireResourceAPI, - QueryResourceAPI queryResourceAPI, - StartResourceAPI startResourceAPI, - UpdateResourceAPI updateResourceAPI, - StopResourceAPI stopResourceAPI) { - this.acquireResourceAPI = acquireResourceAPI; - this.queryResourceAPI = queryResourceAPI; - this.startResourceAPI = startResourceAPI; - this.updateResourceAPI = updateResourceAPI; - this.stopResourceAPI = stopResourceAPI; - } - - public Mono acquire(String cname, String uid, boolean enablePostpone, - AcquireIndividualResourceClientReq clientRequest) { - int scene = 0; - - if (enablePostpone) { - scene = 2; - } - - StartResourceReq.StartClientRequest startParameter = null; - if (clientRequest.getStartParameter() != null) { - startParameter = StartResourceReq.StartClientRequest.builder() - .token(clientRequest.getStartParameter().getToken()) - .storageConfig(clientRequest.getStartParameter() - .getStorageConfig()) - .recordingConfig(clientRequest.getStartParameter() - .getRecordingConfig()) - .recordingFileConfig(clientRequest.getStartParameter() - .getRecordingFileConfig()) - .snapshotConfig(clientRequest.getStartParameter() - .getSnapshotConfig()) - .appsCollection(clientRequest.getStartParameter() - .getAppsCollection()) - .transcodeOptions(clientRequest.getStartParameter() - .getTranscodeOptions()) - .build(); - } - - AcquireResourceReq req = AcquireResourceReq.builder() - .cname(cname) - .uid(uid) - .clientRequest(AcquireResourceReq.ClientRequest.builder() - .scene(scene) - .resourceExpiredHour(clientRequest.getResourceExpiredHour()) - .regionAffinity(clientRequest.getRegionAffinity()) - .excludeResourceIds(clientRequest.getExcludeResourceIds()) - .startParameter(startParameter) - .build()) - .build(); - - return this.acquireResourceAPI.handle(req); - } - - public Mono start(String cname, String uid, String resourceId, - StartIndividualRecordingClientReq clientRequest) { - return this.startResourceAPI.handle(resourceId, CloudRecordingModeEnum.INDIVIDUAL, StartResourceReq - .builder() - .cname(cname) - .uid(uid) - .clientRequest(StartResourceReq.StartClientRequest.builder() - .token(clientRequest.getToken()) - .storageConfig(clientRequest.getStorageConfig()) - .recordingConfig(clientRequest.getRecordingConfig()) - .recordingFileConfig(clientRequest.getRecordingFileConfig()) - .snapshotConfig(clientRequest.getSnapshotConfig()) - .appsCollection(clientRequest.getAppsCollection()) - .transcodeOptions(clientRequest.getTranscodeOptions()) - .build()) - .build()); - } - - public Mono query(String resourceId, String sid) { - return this.queryResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.INDIVIDUAL) - .handle((res, sink) -> { - sink.next(QueryIndividualRecordingResourceRes.builder() - .cname(res.getCname()) - .uid(res.getUid()) - .resourceId(res.getResourceId()) - .sid(res.getSid()) - .serverResponse(res.getQueryIndividualRecordingServerResponse()) - .build()); - - sink.complete(); - }); - } - - public Mono queryVideoScreenshot(String resourceId, - String sid) { - return this.queryResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.INDIVIDUAL) - .handle((res, sink) -> { - sink.next(QueryIndividualRecordingVideoScreenshotResourceRes.builder() - .cname(res.getCname()) - .uid(res.getUid()) - .resourceId(res.getResourceId()) - .sid(res.getSid()) - .serverResponse(res - .getQueryIndividualVideoScreenshotServerResponse()) - .build()); - - sink.complete(); - }); - } - - public Mono update(String cname, String uid, String resourceId, String sid, - UpdateIndividualRecordingResourceClientReq clientRequest) { - return this.updateResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.INDIVIDUAL, - UpdateResourceReq.builder() - .cname(cname) - .uid(uid) - .clientRequest(UpdateResourceReq.ClientRequest.builder() - .streamSubscribe(clientRequest.getStreamSubscribe()) - .build()) - .build()); - } - - public Mono stop(String cname, String uid, String resourceId, String sid, boolean asyncStop) { - return this.stopResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.INDIVIDUAL, - StopResourceReq.builder() - .cname(cname) - .uid(uid) - .clientRequest(StopResourceReq.StopClientRequest.builder() - .asyncStop(asyncStop) - .build()) - .build()); - } +public abstract class IndividualScenario { + + /** + * @brief Get a resource ID for individual cloud recording. + * @since v0.4.0 + * @post After receiving the resource ID, call the start API to start cloud + * recording. + * @param cname The name of the channel to be recorded. + * @param uid The user ID used by the cloud recording service in the + * RTC channel to identify the recording service in the + * channel. + * @param enablePostpone Whether to postpone the recording. + * - true: Postpone the recording. + * - false: Start the recording immediately. + * @param clientRequest The request body. See + * {@link AcquireIndividualResourceClientReq} for + * details. + * @return Returns the acquire resource result. See + * {@link AcquireResourceRes} for details. + */ + public abstract Mono acquire(String cname, String uid, boolean enablePostpone, + AcquireIndividualResourceClientReq clientRequest); + + /** + * @brief Start individual cloud recording. + * @since v0.4.0 + * @param cname Channel name. + * @param uid User ID. + * @param resourceId The resource ID. + * @param clientRequest The request body. See + * {@link StartIndividualRecordingClientReq} for + * details. + * @return Returns the start resource result. See + * {@link StartResourceRes} for details. + */ + public abstract Mono start(String cname, String uid, String resourceId, + StartIndividualRecordingClientReq clientRequest); + + /** + * @brief Query the status of individual cloud recording when video screenshot + * capture is turned off. + * @since v0.4.0 + * @param resourceId The resource ID. + * @param sid The recording ID, identifying a recording cycle. + * @return Returns the query recording resource result. See + * {@link QueryIndividualRecordingResourceRes} for details. + */ + public abstract Mono query(String resourceId, String sid); + + /** + * @brief Query the status of individual cloud recording when video screenshot + * capture is turned on. + * @since v0.4.0 + * @param resourceId The resource ID. + * @param sid The recording ID, identifying a recording cycle. + * @return Returns the query recording resource result when video screenshot + * capture is turned on. See + * {@link QueryIndividualRecordingVideoScreenshotResourceRes} for + * details. + */ + public abstract Mono queryVideoScreenshot(String resourceId, + String sid); + + /** + * @brief Update the individual cloud recording configuration. + * @since v0.4.0 + * @param cname The name of the channel to be recorded. + * @param uid The user ID used by the cloud recording service in the + * RTC channel to identify the recording service in the + * channel. + * @param resourceId The resource ID. + * @param sid The recording ID, identifying a recording cycle. + * @param clientRequest The request body. See + * {@link UpdateIndividualRecordingResourceClientReq} for + * details. + * @return Returns the update resource result. See + * {@link UpdateResourceRes} for details. + */ + public abstract Mono update(String cname, String uid, String resourceId, String sid, + UpdateIndividualRecordingResourceClientReq clientRequest); + + /** + * @brief Stop individual cloud recording. + * @since v0.4.0 + * @param cname The name of the channel to be recorded. + * @param uid The user ID used by the cloud recording service in the RTC + * channel to identify the recording service in the channel. + * @param resourceId The resource ID. + * @param sid The recording ID, identifying a recording cycle. + * @param asyncStop Whether to stop the recording asynchronously. + *

+ * - true: Stop the recording asynchronously. + *

+ * - false: Stop the recording synchronously. + * @return Returns the stop resource result. See {@link StopResourceRes} for + * details. + */ + public abstract Mono stop(String cname, String uid, String resourceId, String sid, + boolean asyncStop); } diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/IndividualScenarioImpl.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/IndividualScenarioImpl.java new file mode 100644 index 0000000..543017d --- /dev/null +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/IndividualScenarioImpl.java @@ -0,0 +1,164 @@ +package io.agora.rest.services.cloudrecording.scenario.individual; + +import io.agora.rest.services.cloudrecording.api.*; +import io.agora.rest.services.cloudrecording.api.req.AcquireResourceReq; +import io.agora.rest.services.cloudrecording.api.req.StartResourceReq; +import io.agora.rest.services.cloudrecording.api.req.StopResourceReq; +import io.agora.rest.services.cloudrecording.api.req.UpdateResourceReq; +import io.agora.rest.services.cloudrecording.api.res.AcquireResourceRes; +import io.agora.rest.services.cloudrecording.api.res.StartResourceRes; +import io.agora.rest.services.cloudrecording.api.res.StopResourceRes; +import io.agora.rest.services.cloudrecording.api.res.UpdateResourceRes; +import io.agora.rest.services.cloudrecording.enums.CloudRecordingModeEnum; +import io.agora.rest.services.cloudrecording.scenario.individual.req.AcquireIndividualResourceClientReq; +import io.agora.rest.services.cloudrecording.scenario.individual.req.StartIndividualRecordingClientReq; +import io.agora.rest.services.cloudrecording.scenario.individual.req.UpdateIndividualRecordingResourceClientReq; +import io.agora.rest.services.cloudrecording.scenario.individual.res.QueryIndividualRecordingResourceRes; +import io.agora.rest.services.cloudrecording.scenario.individual.res.QueryIndividualRecordingVideoScreenshotResourceRes; +import reactor.core.publisher.Mono; + +public class IndividualScenarioImpl extends IndividualScenario { + + private final AcquireResourceAPI acquireResourceAPI; + + private final QueryResourceAPI queryResourceAPI; + + private final StartResourceAPI startResourceAPI; + + private final UpdateResourceAPI updateResourceAPI; + + private final StopResourceAPI stopResourceAPI; + + public IndividualScenarioImpl(AcquireResourceAPI acquireResourceAPI, + QueryResourceAPI queryResourceAPI, + StartResourceAPI startResourceAPI, + UpdateResourceAPI updateResourceAPI, + StopResourceAPI stopResourceAPI) { + this.acquireResourceAPI = acquireResourceAPI; + this.queryResourceAPI = queryResourceAPI; + this.startResourceAPI = startResourceAPI; + this.updateResourceAPI = updateResourceAPI; + this.stopResourceAPI = stopResourceAPI; + } + + @Override + public Mono acquire(String cname, String uid, boolean enablePostpone, + AcquireIndividualResourceClientReq clientRequest) { + int scene = 0; + + if (enablePostpone) { + scene = 2; + } + + StartResourceReq.StartClientRequest startParameter = null; + if (clientRequest.getStartParameter() != null) { + startParameter = StartResourceReq.StartClientRequest.builder() + .token(clientRequest.getStartParameter().getToken()) + .storageConfig(clientRequest.getStartParameter() + .getStorageConfig()) + .recordingConfig(clientRequest.getStartParameter() + .getRecordingConfig()) + .recordingFileConfig(clientRequest.getStartParameter() + .getRecordingFileConfig()) + .snapshotConfig(clientRequest.getStartParameter() + .getSnapshotConfig()) + .appsCollection(clientRequest.getStartParameter() + .getAppsCollection()) + .transcodeOptions(clientRequest.getStartParameter() + .getTranscodeOptions()) + .build(); + } + + AcquireResourceReq req = AcquireResourceReq.builder() + .cname(cname) + .uid(uid) + .clientRequest(AcquireResourceReq.ClientRequest.builder() + .scene(scene) + .resourceExpiredHour(clientRequest.getResourceExpiredHour()) + .regionAffinity(clientRequest.getRegionAffinity()) + .excludeResourceIds(clientRequest.getExcludeResourceIds()) + .startParameter(startParameter) + .build()) + .build(); + + return this.acquireResourceAPI.handle(req); + } + + @Override + public Mono start(String cname, String uid, String resourceId, + StartIndividualRecordingClientReq clientRequest) { + return this.startResourceAPI.handle(resourceId, CloudRecordingModeEnum.INDIVIDUAL, StartResourceReq + .builder() + .cname(cname) + .uid(uid) + .clientRequest(StartResourceReq.StartClientRequest.builder() + .token(clientRequest.getToken()) + .storageConfig(clientRequest.getStorageConfig()) + .recordingConfig(clientRequest.getRecordingConfig()) + .recordingFileConfig(clientRequest.getRecordingFileConfig()) + .snapshotConfig(clientRequest.getSnapshotConfig()) + .appsCollection(clientRequest.getAppsCollection()) + .transcodeOptions(clientRequest.getTranscodeOptions()) + .build()) + .build()); + } + + @Override + public Mono query(String resourceId, String sid) { + return this.queryResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.INDIVIDUAL) + .handle((res, sink) -> { + sink.next(QueryIndividualRecordingResourceRes.builder() + .cname(res.getCname()) + .uid(res.getUid()) + .resourceId(res.getResourceId()) + .sid(res.getSid()) + .serverResponse(res.getQueryIndividualRecordingServerResponse()) + .build()); + + sink.complete(); + }); + } + + @Override + public Mono queryVideoScreenshot(String resourceId, + String sid) { + return this.queryResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.INDIVIDUAL) + .handle((res, sink) -> { + sink.next(QueryIndividualRecordingVideoScreenshotResourceRes.builder() + .cname(res.getCname()) + .uid(res.getUid()) + .resourceId(res.getResourceId()) + .sid(res.getSid()) + .serverResponse(res + .getQueryIndividualVideoScreenshotServerResponse()) + .build()); + + sink.complete(); + }); + } + + @Override + public Mono update(String cname, String uid, String resourceId, String sid, + UpdateIndividualRecordingResourceClientReq clientRequest) { + return this.updateResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.INDIVIDUAL, + UpdateResourceReq.builder() + .cname(cname) + .uid(uid) + .clientRequest(UpdateResourceReq.ClientRequest.builder() + .streamSubscribe(clientRequest.getStreamSubscribe()) + .build()) + .build()); + } + + @Override + public Mono stop(String cname, String uid, String resourceId, String sid, boolean asyncStop) { + return this.stopResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.INDIVIDUAL, + StopResourceReq.builder() + .cname(cname) + .uid(uid) + .clientRequest(StopResourceReq.StopClientRequest.builder() + .asyncStop(asyncStop) + .build()) + .build()); + } +} diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/req/AcquireIndividualResourceClientReq.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/req/AcquireIndividualResourceClientReq.java index 0f9056b..53adce6 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/req/AcquireIndividualResourceClientReq.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/req/AcquireIndividualResourceClientReq.java @@ -2,14 +2,50 @@ import java.util.List; +/** + * @brief Client request for acquiring individual cloud recording resources. + * @since v0.4.0 + */ public class AcquireIndividualResourceClientReq { + /** + * The validity period for calling the cloud recording RESTful API. + *

+ * Start calculating after you successfully initiate the cloud recording service + * and obtain the sid (Recording ID). + *

+ * The calculation unit is hours. + *

+ * The value range is [1,720]. The default value is 72. + */ private Integer resourceExpiredHour; + /** + * The resourceId of another or several other recording tasks. + */ private List excludeResourceIds; + /** + * Specify regions that the cloud recording service can access. + *

+ * The region can be set to: + *

+ * - 0: Closest to request origin (default) + *

+ * - 1: China + *

+ * - 2: Southeast Asia + *

+ * - 3: Europe + *

+ * - 4: North America + */ private Integer regionAffinity; + /** + * The start parameter improves availability and optimizes load balancing. See + * {@link StartIndividualRecordingClientReq}. + */ private StartIndividualRecordingClientReq startParameter; public static Builder builder() { diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/req/StartIndividualRecordingClientReq.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/req/StartIndividualRecordingClientReq.java index 0f976b2..6a1435c 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/req/StartIndividualRecordingClientReq.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/req/StartIndividualRecordingClientReq.java @@ -2,20 +2,51 @@ import io.agora.rest.services.cloudrecording.api.req.StartResourceReq; +/** + * @brief Client request for starting individual recording. + * @since v0.4.0 + */ public class StartIndividualRecordingClientReq { + /** + * Agora App Token.(Optional) + */ private String token; + /** + * Configuration for the application.(Optional) See + * {@link StartResourceReq.AppsCollection}. + */ private StartResourceReq.AppsCollection appsCollection; + /** + * Configuration for recorded audio and video streams.(Optional) See + * {@link StartResourceReq.RecordingConfig}. + */ private StartResourceReq.RecordingConfig recordingConfig; + /** + * Configurations for the recorded files generated under postponed transcoding + * or audio mixing.(Optional) See {@link StartResourceReq.TranscodeOptions}. + */ private StartResourceReq.TranscodeOptions transcodeOptions; + /** + * Configuration for recorded files.(Optional) See + * {@link StartResourceReq.RecordingFileConfig}. + */ private StartResourceReq.RecordingFileConfig recordingFileConfig; + /** + * Configurations for screenshot capture.(Optional) See + * {@link StartResourceReq.SnapshotConfig}. + */ private StartResourceReq.SnapshotConfig snapshotConfig; + /** + * Configuration for third-party cloud storage.(Required) See + * {@link StartResourceReq.StorageConfig}. + */ private StartResourceReq.StorageConfig storageConfig; public static Builder builder() { diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/req/UpdateIndividualRecordingResourceClientReq.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/req/UpdateIndividualRecordingResourceClientReq.java index 8241814..94968d2 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/req/UpdateIndividualRecordingResourceClientReq.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/req/UpdateIndividualRecordingResourceClientReq.java @@ -2,8 +2,15 @@ import io.agora.rest.services.cloudrecording.api.req.UpdateResourceReq; +/** + * @brief Client request for updating individual recording. + * @since v0.4.0 + */ public class UpdateIndividualRecordingResourceClientReq { - + /** + * Update subscription lists.(Optional) See + * {@link UpdateResourceReq.StreamSubscribe}. + */ private UpdateResourceReq.StreamSubscribe streamSubscribe; public static Builder builder() { diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/res/QueryIndividualRecordingResourceRes.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/res/QueryIndividualRecordingResourceRes.java index 850e8ec..0d68066 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/res/QueryIndividualRecordingResourceRes.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/res/QueryIndividualRecordingResourceRes.java @@ -2,16 +2,36 @@ import io.agora.rest.services.cloudrecording.api.res.QueryResourceRes; +/** + * @brief Response returned by the individual recording query API. + * @since v0.4.0 + */ public class QueryIndividualRecordingResourceRes { - + /** + * The name of the channel to be recorded. + */ private String cname; + /** + * The user ID used by the cloud recording service in the RTC channel to + * identify the recording service in the channel. + */ private String uid; + /** + * Unique identifier of the resource. + */ private String resourceId; + /** + * Unique identifier of the recording session. + */ private String sid; + /** + * Server response. See + * {@link QueryResourceRes.QueryIndividualRecordingServerResponse}. + */ private QueryResourceRes.QueryIndividualRecordingServerResponse serverResponse; public static Builder builder() { diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/res/QueryIndividualRecordingVideoScreenshotResourceRes.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/res/QueryIndividualRecordingVideoScreenshotResourceRes.java index f4face4..62114ed 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/res/QueryIndividualRecordingVideoScreenshotResourceRes.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/individual/res/QueryIndividualRecordingVideoScreenshotResourceRes.java @@ -2,16 +2,37 @@ import io.agora.rest.services.cloudrecording.api.res.QueryResourceRes; +/** + * @brief Response returned by the individual recording queryVideoScreenshot + * API. + * @since v0.4.0 + */ public class QueryIndividualRecordingVideoScreenshotResourceRes { - + /** + * The name of the channel to be recorded. + */ private String cname; + /** + * The user ID used by the cloud recording service in the RTC channel to + * identify the recording service in the channel. + */ private String uid; + /** + * Unique identifier of the resource. + */ private String resourceId; + /** + * Unique identifier of the recording session. + */ private String sid; + /** + * Server response. See + * {@link QueryResourceRes.QueryIndividualVideoScreenshotServerResponse}. + */ private QueryResourceRes.QueryIndividualVideoScreenshotServerResponse serverResponse; public static Builder builder() { diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/MixScenario.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/MixScenario.java index c325d1a..870799a 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/MixScenario.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/MixScenario.java @@ -1,9 +1,6 @@ package io.agora.rest.services.cloudrecording.scenario.mix; -import io.agora.rest.services.cloudrecording.api.*; -import io.agora.rest.services.cloudrecording.api.req.*; import io.agora.rest.services.cloudrecording.api.res.*; -import io.agora.rest.services.cloudrecording.enums.CloudRecordingModeEnum; import io.agora.rest.services.cloudrecording.scenario.mix.req.AcquireMixRecordingResourceClientReq; import io.agora.rest.services.cloudrecording.scenario.mix.req.StartMixRecordingResourceClientReq; import io.agora.rest.services.cloudrecording.scenario.mix.req.UpdateLayoutMixRecordingResourceClientReq; @@ -12,138 +9,120 @@ import io.agora.rest.services.cloudrecording.scenario.mix.res.QueryMixHLSRecordingResourceRes; import reactor.core.publisher.Mono; -public class MixScenario { - - private final AcquireResourceAPI acquireResourceAPI; - - private final QueryResourceAPI queryResourceAPI; - - private final StartResourceAPI startResourceAPI; - - private final UpdateResourceAPI updateResourceAPI; - - private final StopResourceAPI stopResourceAPI; - - public MixScenario(AcquireResourceAPI acquireResourceAPI, - QueryResourceAPI queryResourceAPI, - StartResourceAPI startResourceAPI, - UpdateResourceAPI updateResourceAPI, - StopResourceAPI stopResourceAPI) { - this.acquireResourceAPI = acquireResourceAPI; - this.queryResourceAPI = queryResourceAPI; - this.startResourceAPI = startResourceAPI; - this.updateResourceAPI = updateResourceAPI; - this.stopResourceAPI = stopResourceAPI; - } - - public Mono acquire(String cname, String uid, - AcquireMixRecordingResourceClientReq clientRequest) { - - StartResourceReq.StartClientRequest startParameter = null; - if (clientRequest.getStartParameter() != null) { - startParameter = StartResourceReq.StartClientRequest.builder() - .token(clientRequest.getStartParameter().getToken()) - .storageConfig(clientRequest.getStartParameter().getStorageConfig()) - .recordingConfig(clientRequest.getStartParameter().getRecordingConfig()) - .recordingFileConfig(clientRequest.getStartParameter().getRecordingFileConfig()) - .build(); - } - - - return this.acquireResourceAPI.handle(AcquireResourceReq.builder() - .cname(cname) - .uid(uid) - .clientRequest(AcquireResourceReq.ClientRequest.builder() - .scene(0) - .resourceExpiredHour(clientRequest.getResourceExpiredHour()) - .regionAffinity(clientRequest.getRegionAffinity()) - .excludeResourceIds(clientRequest.getExcludeResourceIds()) - .startParameter(startParameter) - .build()) - .build()); - } - - public Mono start(String cname, String uid, String resourceId, - StartMixRecordingResourceClientReq clientRequest) { - return this.startResourceAPI.handle(resourceId, CloudRecordingModeEnum.MIX, StartResourceReq.builder() - .cname(cname) - .uid(uid) - .clientRequest(StartResourceReq.StartClientRequest.builder() - .token(clientRequest.getToken()) - .storageConfig(clientRequest.getStorageConfig()) - .recordingConfig(clientRequest.getRecordingConfig()) - .recordingFileConfig(clientRequest.getRecordingFileConfig()) - .build()) - .build()); - } - - public Mono queryHLS(String resourceId, String sid) { - return this.queryResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.MIX).handle((res, sink) -> { - sink.next(QueryMixHLSRecordingResourceRes.builder() - .cname(res.getCname()) - .uid(res.getUid()) - .resourceId(res.getResourceId()) - .sid(res.getSid()) - .serverResponse(res.getMixRecordingHLSServerResponse()) - .build()); - - sink.complete(); - }); - } - - public Mono queryHLSAndMP4(String resourceId, String sid) { - return this.queryResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.MIX).handle((res, sink) -> { - sink.next(QueryMixHLSAndMP4RecordingResourceRes.builder() - .cname(res.getCname()) - .uid(res.getUid()) - .resourceId(res.getResourceId()) - .sid(res.getSid()) - .serverResponse(res.getMixRecordingHLSAndMP4ServerResponse()) - .build()); - - sink.complete(); - }); - } - - public Mono updateLayout(String cname, String uid, String resourceId, String sid, - UpdateLayoutMixRecordingResourceClientReq clientRequest) { - return this.updateResourceAPI.handleLayout(resourceId, sid, CloudRecordingModeEnum.MIX, - UpdateLayoutResourceReq.builder() - .cname(cname) - .uid(uid) - .clientRequest(UpdateLayoutResourceReq.ClientRequest.builder() - .maxResolutionUID(clientRequest.getMaxResolutionUID()) - .mixedVideoLayout(clientRequest.getMixedVideoLayout()) - .backgroundColor(clientRequest.getBackgroundColor()) - .defaultUserBackgroundImage(clientRequest - .getDefaultUserBackgroundImage()) - .layoutConfig(clientRequest.getLayoutConfig()) - .backgroundImage(clientRequest.getBackgroundImage()) - .backgroundConfig(clientRequest.getBackgroundConfig()) - .build()) - .build()); - } - - public Mono update(String cname, String uid, String resourceId, String sid, - UpdateMixRecordingResourceClientReq clientRequest) { - return this.updateResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.MIX, - UpdateResourceReq.builder() - .cname(cname) - .uid(uid) - .clientRequest(UpdateResourceReq.ClientRequest.builder() - .streamSubscribe(clientRequest.getStreamSubscribe()) - .build()) - .build()); - } - - public Mono stop(String cname, String uid, String resourceId, String sid, boolean asyncStop) { - return this.stopResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.MIX, - StopResourceReq.builder() - .cname(cname) - .uid(uid) - .clientRequest(StopResourceReq.StopClientRequest.builder() - .asyncStop(asyncStop) - .build()) - .build()); - } +public abstract class MixScenario { + + /** + * @brief Get a resource ID for mix cloud recording. + * @since v0.4.0 + * @post After receiving the resource ID, call the start API to start cloud + * recording. + * @param cname The name of the channel to be recorded. + * @param uid The user ID used by the cloud recording service in the + * RTC channel to identify the recording service in the + * channel. + * @param clientRequest The request body. See + * {@link AcquireMixRecordingResourceClientReq} for + * details. + * @return Returns the acquire resource result. See + * {@link AcquireResourceRes} for details. + */ + public abstract Mono acquire(String cname, String uid, + AcquireMixRecordingResourceClientReq clientRequest); + + /** + * @brief Start mix cloud recording. + * @since v0.4.0 + * @param cname The name of the channel to be recorded. + * @param uid The user ID used by the cloud recording service in the + * RTC channel to identify the recording service in the + * channel. + * @param resourceId The resource ID. + * @param clientRequest The request body. See + * {@link StartMixRecordingResourceClientReq} for + * details. + * @return Returns the start resource result. See + * {@link StartResourceRes} for details. + */ + public abstract Mono start(String cname, String uid, String resourceId, + StartMixRecordingResourceClientReq clientRequest); + + /** + * @brief Query the status of mix cloud recording when the video file format is + * hls. + * @since v0.4.0 + * @param resourceId The resource ID. + * @param sid The recording ID, identifying a recording cycle. + * @return Returns the query mix recording resource result when the video file + * format is hls. See {@link QueryMixHLSRecordingResourceRes} for + * details. + */ + public abstract Mono queryHLS(String resourceId, String sid); + + /** + * @brief Query the status of mix cloud recording when the video file format is + * hls and mp4. + * @since v0.4.0 + * @param resourceId The resource ID. + * @param sid The recording ID, identifying a recording cycle. + * @return Returns the query mix recording resource result when the video file + * format is hls and mp4. See + * {@link QueryMixHLSAndMP4RecordingResourceRes} for details. + */ + public abstract Mono queryHLSAndMP4(String resourceId, String sid); + + /** + * @brief Update the mix cloud recording layout. + * @since v0.4.0 + * @param cname The name of the channel to be recorded. + * @param uid The user ID used by the cloud recording service in the + * RTC channel to identify the recording service in the + * channel. + * @param resourceId The resource ID. + * @param sid The recording ID, identifying a recording cycle. + * @param clientRequest The request body. See + * {@link UpdateLayoutMixRecordingResourceClientReq} for + * details. + * @return Returns the update layout resource result. See + * {@link UpdateLayoutResourceRes} for details. + */ + public abstract Mono updateLayout(String cname, String uid, String resourceId, + String sid, + UpdateLayoutMixRecordingResourceClientReq clientRequest); + + /** + * @brief Update the mix cloud recording configuration. + * @since v0.4.0 + * @param cname The name of the channel to be recorded. + * @param uid The user ID used by the cloud recording service in the + * RTC channel to identify the recording service in the + * channel. + * @param resourceId The resource ID. + * @param sid The recording ID, identifying a recording cycle. + * @param clientRequest The request body. See + * {@link UpdateMixRecordingResourceClientReq} for + * details. + * @return Returns the update resource result. See + * {@link UpdateResourceRes} for details. + */ + public abstract Mono update(String cname, String uid, String resourceId, String sid, + UpdateMixRecordingResourceClientReq clientRequest); + + /** + * @brief Stop mix cloud recording. + * @since v0.4.0 + * @param cname The name of the channel to be recorded. + * @param uid The user ID used by the cloud recording service in the RTC + * channel to identify the recording service in the channel. + * @param resourceId The resource ID. + * @param sid The recording ID, identifying a recording cycle. + * @param asyncStop Whether to stop the recording asynchronously. + *

+ * - true: Stop the recording asynchronously. + *

+ * - false: Stop the recording synchronously. + * @return Returns the stop resource result. See {@link StopResourceRes} for + * details. + */ + public abstract Mono stop(String cname, String uid, String resourceId, String sid, + boolean asyncStop); } diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/MixScenarioImpl.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/MixScenarioImpl.java new file mode 100644 index 0000000..05e6703 --- /dev/null +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/MixScenarioImpl.java @@ -0,0 +1,156 @@ +package io.agora.rest.services.cloudrecording.scenario.mix; + +import io.agora.rest.services.cloudrecording.api.*; +import io.agora.rest.services.cloudrecording.api.req.*; +import io.agora.rest.services.cloudrecording.api.res.*; +import io.agora.rest.services.cloudrecording.enums.CloudRecordingModeEnum; +import io.agora.rest.services.cloudrecording.scenario.mix.req.AcquireMixRecordingResourceClientReq; +import io.agora.rest.services.cloudrecording.scenario.mix.req.StartMixRecordingResourceClientReq; +import io.agora.rest.services.cloudrecording.scenario.mix.req.UpdateLayoutMixRecordingResourceClientReq; +import io.agora.rest.services.cloudrecording.scenario.mix.req.UpdateMixRecordingResourceClientReq; +import io.agora.rest.services.cloudrecording.scenario.mix.res.QueryMixHLSAndMP4RecordingResourceRes; +import io.agora.rest.services.cloudrecording.scenario.mix.res.QueryMixHLSRecordingResourceRes; +import reactor.core.publisher.Mono; + +public class MixScenarioImpl extends MixScenario { + + private final AcquireResourceAPI acquireResourceAPI; + + private final QueryResourceAPI queryResourceAPI; + + private final StartResourceAPI startResourceAPI; + + private final UpdateResourceAPI updateResourceAPI; + + private final StopResourceAPI stopResourceAPI; + + public MixScenarioImpl(AcquireResourceAPI acquireResourceAPI, + QueryResourceAPI queryResourceAPI, + StartResourceAPI startResourceAPI, + UpdateResourceAPI updateResourceAPI, + StopResourceAPI stopResourceAPI) { + this.acquireResourceAPI = acquireResourceAPI; + this.queryResourceAPI = queryResourceAPI; + this.startResourceAPI = startResourceAPI; + this.updateResourceAPI = updateResourceAPI; + this.stopResourceAPI = stopResourceAPI; + } + + @Override + public Mono acquire(String cname, String uid, + AcquireMixRecordingResourceClientReq clientRequest) { + + StartResourceReq.StartClientRequest startParameter = null; + if (clientRequest.getStartParameter() != null) { + startParameter = StartResourceReq.StartClientRequest.builder() + .token(clientRequest.getStartParameter().getToken()) + .storageConfig(clientRequest.getStartParameter().getStorageConfig()) + .recordingConfig(clientRequest.getStartParameter().getRecordingConfig()) + .recordingFileConfig(clientRequest.getStartParameter().getRecordingFileConfig()) + .build(); + } + + + return this.acquireResourceAPI.handle(AcquireResourceReq.builder() + .cname(cname) + .uid(uid) + .clientRequest(AcquireResourceReq.ClientRequest.builder() + .scene(0) + .resourceExpiredHour(clientRequest.getResourceExpiredHour()) + .regionAffinity(clientRequest.getRegionAffinity()) + .excludeResourceIds(clientRequest.getExcludeResourceIds()) + .startParameter(startParameter) + .build()) + .build()); + } + + @Override + public Mono start(String cname, String uid, String resourceId, + StartMixRecordingResourceClientReq clientRequest) { + return this.startResourceAPI.handle(resourceId, CloudRecordingModeEnum.MIX, StartResourceReq.builder() + .cname(cname) + .uid(uid) + .clientRequest(StartResourceReq.StartClientRequest.builder() + .token(clientRequest.getToken()) + .storageConfig(clientRequest.getStorageConfig()) + .recordingConfig(clientRequest.getRecordingConfig()) + .recordingFileConfig(clientRequest.getRecordingFileConfig()) + .build()) + .build()); + } + + @Override + public Mono queryHLS(String resourceId, String sid) { + return this.queryResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.MIX).handle((res, sink) -> { + sink.next(QueryMixHLSRecordingResourceRes.builder() + .cname(res.getCname()) + .uid(res.getUid()) + .resourceId(res.getResourceId()) + .sid(res.getSid()) + .serverResponse(res.getMixRecordingHLSServerResponse()) + .build()); + + sink.complete(); + }); + } + + @Override + public Mono queryHLSAndMP4(String resourceId, String sid) { + return this.queryResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.MIX).handle((res, sink) -> { + sink.next(QueryMixHLSAndMP4RecordingResourceRes.builder() + .cname(res.getCname()) + .uid(res.getUid()) + .resourceId(res.getResourceId()) + .sid(res.getSid()) + .serverResponse(res.getMixRecordingHLSAndMP4ServerResponse()) + .build()); + + sink.complete(); + }); + } + + @Override + public Mono updateLayout(String cname, String uid, String resourceId, String sid, + UpdateLayoutMixRecordingResourceClientReq clientRequest) { + return this.updateResourceAPI.handleLayout(resourceId, sid, CloudRecordingModeEnum.MIX, + UpdateLayoutResourceReq.builder() + .cname(cname) + .uid(uid) + .clientRequest(UpdateLayoutResourceReq.ClientRequest.builder() + .maxResolutionUID(clientRequest.getMaxResolutionUID()) + .mixedVideoLayout(clientRequest.getMixedVideoLayout()) + .backgroundColor(clientRequest.getBackgroundColor()) + .defaultUserBackgroundImage(clientRequest + .getDefaultUserBackgroundImage()) + .layoutConfig(clientRequest.getLayoutConfig()) + .backgroundImage(clientRequest.getBackgroundImage()) + .backgroundConfig(clientRequest.getBackgroundConfig()) + .build()) + .build()); + } + + @Override + public Mono update(String cname, String uid, String resourceId, String sid, + UpdateMixRecordingResourceClientReq clientRequest) { + return this.updateResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.MIX, + UpdateResourceReq.builder() + .cname(cname) + .uid(uid) + .clientRequest(UpdateResourceReq.ClientRequest.builder() + .streamSubscribe(clientRequest.getStreamSubscribe()) + .build()) + .build()); + } + + @Override + public Mono stop(String cname, String uid, String resourceId, String sid, boolean asyncStop) { + return this.stopResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.MIX, + StopResourceReq.builder() + .cname(cname) + .uid(uid) + .clientRequest(StopResourceReq.StopClientRequest.builder() + .asyncStop(asyncStop) + .build()) + .build()); + } +} diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/req/AcquireMixRecordingResourceClientReq.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/req/AcquireMixRecordingResourceClientReq.java index 96a732c..847965a 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/req/AcquireMixRecordingResourceClientReq.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/req/AcquireMixRecordingResourceClientReq.java @@ -2,14 +2,49 @@ import java.util.List; +/** + * @brief Client request for acquiring mix cloud recording resources. + * @since v0.4.0 + */ public class AcquireMixRecordingResourceClientReq { + /** + * The validity period for calling the cloud recording RESTful API. + *

+ * Start calculating after you successfully initiate the cloud recording service + * and obtain the sid (Recording ID). + *

+ * The calculation unit is hours. + *

+ * The value range is [1,720]. The default value is 72. + */ private Integer resourceExpiredHour; + /** + * The resourceId of another or several other recording tasks. + */ private List excludeResourceIds; + /** + * Specify regions that the cloud recording service can access. + *

+ * The region can be set to: + *

+ * - 0: Closest to request origin (default) + *

+ * - 1: China + *

+ * - 2: Southeast Asia + *

+ * - 3: Europe + *

+ * - 4: North America + */ private Integer regionAffinity; + /** + * The start parameter improves availability and optimizes load balancing. + */ private StartMixRecordingResourceClientReq startParameter; public static Builder builder() { diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/req/StartMixRecordingResourceClientReq.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/req/StartMixRecordingResourceClientReq.java index b474383..f73ff61 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/req/StartMixRecordingResourceClientReq.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/req/StartMixRecordingResourceClientReq.java @@ -2,14 +2,30 @@ import io.agora.rest.services.cloudrecording.api.req.StartResourceReq; +/** + * @brief Client request for starting mix recording. + * @since v0.4.0 + */ public class StartMixRecordingResourceClientReq { + /** + * Agora App Token.(Optional) + */ private String token; + /** + * Configuration for recorded audio and video streams.(Optional) + */ private StartResourceReq.RecordingConfig recordingConfig; + /** + * Configuration for recorded files.(Optional) + */ private StartResourceReq.RecordingFileConfig recordingFileConfig; + /** + * Configuration for third-party cloud storage.(Required) + */ private StartResourceReq.StorageConfig storageConfig; public static Builder builder() { diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/req/UpdateLayoutMixRecordingResourceClientReq.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/req/UpdateLayoutMixRecordingResourceClientReq.java index da226e3..cbc26be 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/req/UpdateLayoutMixRecordingResourceClientReq.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/req/UpdateLayoutMixRecordingResourceClientReq.java @@ -4,20 +4,79 @@ import java.util.List; +/** + * @brief Client request for updating the layout of mix recording. + * @since v0.4.0 + */ public class UpdateLayoutMixRecordingResourceClientReq { + /** + * Only need to set it in vertical layout.(Optional) + * + * Specify the user ID of the large video window. + */ private String maxResolutionUID; + /** + * Composite video layout.(Optional) + * + * The value can be set to: + * + * - 0: (Default) Floating layout. + * The first user to join the channel will be displayed as a large window, filling the entire canvas. + * The video windows of other users will be displayed as small windows, arranged horizontally from bottom to top, up to 4 rows, each with 4 windows. + * It supports up to a total of 17 windows of different users' videos. + * - 1: Adaptive layout. + * Automatically adjust the size of each user's video window according to the number of users, each user's video window size is consistent, and supports up to 17 windows. + * - 2: Vertical layout. + * The maxResolutionUid is specified to display the large video window on the left side of the screen, and the small video windows of other users are vertically arranged on the right side, with a maximum of two columns, 8 windows per column, supporting up to 17 windows. + * - 3: Customized layout. + * Set the layoutConfig field to customize the mixed layout. + */ private int mixedVideoLayout; + /** + * The background color of the video canvas.(Optional) + * + * The RGB color table is supported, with strings formatted as a # sign and 6 hexadecimal digits. + * + * The default value is "#000000", representing the black color. + */ private String backgroundColor; + /** + * The background image of the video canvas.(Optional) + * + * The display mode of the background image is set to cropped mode. + * + * Cropped mode: Will prioritize to ensure that the screen is filled. + * The background image size is scaled in equal proportion until the entire screen is filled with the background image. + * If the length and width of the background image differ from the video window, + * the background image will be peripherally cropped to fill the window. + */ private String backgroundImage; + /** + * The URL of the default user screen background image.(Optional) + * + * After configuring this field, when any user stops sending the video streams for more than 3.5 seconds, + * the screen will switch to the background image; + * this setting will be overridden if the background image is set separately for a UID. + */ private String defaultUserBackgroundImage; + /** + * The mixed video layout of users.(Optional) + * + * An array of screen layout settings for each user, supporting up to 17 users. + */ private List layoutConfig; + /** + * The background configuration.(Optional) + * + * The backgroundConfig field is used to set the background of the video windows. + */ private List backgroundConfig; public static Builder builder() { diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/req/UpdateMixRecordingResourceClientReq.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/req/UpdateMixRecordingResourceClientReq.java index 104a9f7..bf8c16c 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/req/UpdateMixRecordingResourceClientReq.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/req/UpdateMixRecordingResourceClientReq.java @@ -2,8 +2,15 @@ import io.agora.rest.services.cloudrecording.api.req.UpdateResourceReq; +/** + * @brief Client request for updating mix recording. + * @since v0.4.0 + */ public class UpdateMixRecordingResourceClientReq { + /** + * Update subscription lists.(Optional) + */ private UpdateResourceReq.StreamSubscribe streamSubscribe; public static Builder builder() { diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/res/QueryMixHLSAndMP4RecordingResourceRes.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/res/QueryMixHLSAndMP4RecordingResourceRes.java index 67d3082..37378d3 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/res/QueryMixHLSAndMP4RecordingResourceRes.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/res/QueryMixHLSAndMP4RecordingResourceRes.java @@ -2,16 +2,36 @@ import io.agora.rest.services.cloudrecording.api.res.QueryResourceRes; +/** + * @brief Response returned by the mix recording queryHLSAndMP4 API. + * @since v0.4.0 + */ public class QueryMixHLSAndMP4RecordingResourceRes { - + /** + * The name of the channel to be recorded. + */ private String cname; + /** + * The user ID used by the cloud recording service in the RTC channel to + * identify the recording service in the channel. + */ private String uid; + /** + * Unique identifier of the resource. + */ private String resourceId; + /** + * Unique identifier of the recording session. + */ private String sid; + /** + * Server response. See + * {@link QueryResourceRes.MixRecordingHLSAndMP4ServerResponse}. + */ private QueryResourceRes.MixRecordingHLSAndMP4ServerResponse serverResponse; public static Builder builder() { diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/res/QueryMixHLSRecordingResourceRes.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/res/QueryMixHLSRecordingResourceRes.java index 8841f93..e1e4f2c 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/res/QueryMixHLSRecordingResourceRes.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/mix/res/QueryMixHLSRecordingResourceRes.java @@ -2,16 +2,35 @@ import io.agora.rest.services.cloudrecording.api.res.QueryResourceRes; +/** + * @brief Response returned by the mix recording queryHLS API. + * @since v0.4.0 + */ public class QueryMixHLSRecordingResourceRes { - + /** + * The name of the channel to be recorded. + */ private String cname; + /** + * The user ID used by the cloud recording service in the RTC channel to + * identify the recording service in the channel. + */ private String uid; + /** + * Unique identifier of the resource. + */ private String resourceId; + /** + * Unique identifier of the recording session. + */ private String sid; + /** + * Server response. See {@link QueryResourceRes.MixRecordingHLSServerResponse}. + */ private QueryResourceRes.MixRecordingHLSServerResponse serverResponse; public static Builder builder() { diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/WebScenario.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/WebScenario.java index 6df0b22..5633de0 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/WebScenario.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/WebScenario.java @@ -1,116 +1,106 @@ package io.agora.rest.services.cloudrecording.scenario.web; -import io.agora.rest.services.cloudrecording.api.*; -import io.agora.rest.services.cloudrecording.api.req.AcquireResourceReq; -import io.agora.rest.services.cloudrecording.api.req.StartResourceReq; -import io.agora.rest.services.cloudrecording.api.req.StopResourceReq; -import io.agora.rest.services.cloudrecording.api.req.UpdateResourceReq; import io.agora.rest.services.cloudrecording.api.res.AcquireResourceRes; import io.agora.rest.services.cloudrecording.api.res.StartResourceRes; import io.agora.rest.services.cloudrecording.api.res.StopResourceRes; import io.agora.rest.services.cloudrecording.api.res.UpdateResourceRes; -import io.agora.rest.services.cloudrecording.enums.CloudRecordingModeEnum; import io.agora.rest.services.cloudrecording.scenario.web.req.AcquireWebRecordingResourceClientReq; import io.agora.rest.services.cloudrecording.scenario.web.req.StartWebRecordingResourceClientReq; import io.agora.rest.services.cloudrecording.scenario.web.req.UpdateWebRecordingResourceClientReq; import io.agora.rest.services.cloudrecording.scenario.web.res.QueryWebRecordingResourceRes; +import io.agora.rest.services.cloudrecording.scenario.web.res.QueryWebRecordingRtmpPublishResourceRes; import reactor.core.publisher.Mono; -public class WebScenario { - - private final AcquireResourceAPI acquireResourceAPI; +public abstract class WebScenario { - private final QueryResourceAPI queryResourceAPI; + /** + * @brief Get a resource ID for web cloud recording. + * @since v0.4.0 + * @post After receiving the resource ID, call the start API to start cloud + * recording. + * @param cname The name of the channel to be recorded. + * @param uid The user ID used by the cloud recording service in the + * RTC channel to identify the recording service in the + * channel. + * @param clientRequest The request body. See + * {@link AcquireWebRecordingResourceClientReq} for + * details. + * @return Returns the acquire resource result. See {@link AcquireResourceRes} + * for details. + */ + public abstract Mono acquire(String cname, String uid, + AcquireWebRecordingResourceClientReq clientRequest); - private final StartResourceAPI startResourceAPI; + /** + * @brief Start web recording. + * @since v0.4.0 + * @param cname The name of the channel to be recorded. + * @param uid The user ID used by the cloud recording service in the + * RTC channel to identify the recording service in the + * channel. + * @param resourceId The resource ID. + * @param clientRequest The request body. See + * {@link StartWebRecordingResourceClientReq} for details. + * @return Returns the start resource result. See {@link StartResourceRes} + * for details. + */ + public abstract Mono start(String cname, String uid, String resourceId, + StartWebRecordingResourceClientReq clientRequest); - private final UpdateResourceAPI updateResourceAPI; + /** + * @brief Query the status of web recording. + * @since v0.4.0 + * @param resourceId The resource ID. + * @param sid The recording ID, identifying a recording cycle. + * @return Returns the query web recording resource result. See + * {@link QueryWebRecordingResourceRes} for details. + */ + public abstract Mono query(String resourceId, String sid); - private final StopResourceAPI stopResourceAPI; + /** + * @brief Query the status of pushing web page recording to the CDN. + * @since v0.4.0 + * @param resourceId The resource ID. + * @param sid The recording ID, identifying a recording cycle. + * @return Returns the query web recording rtmp publish resource result. See + * {@link QueryWebRecordingRtmpPublishResourceRes} for details. + */ + public abstract Mono queryRtmpPublish(String resourceId, String sid); - public WebScenario(AcquireResourceAPI acquireResourceAPI, - QueryResourceAPI queryResourceAPI, - StartResourceAPI startResourceAPI, - UpdateResourceAPI updateResourceAPI, - StopResourceAPI stopResourceAPI) { - this.acquireResourceAPI = acquireResourceAPI; - this.queryResourceAPI = queryResourceAPI; - this.startResourceAPI = startResourceAPI; - this.updateResourceAPI = updateResourceAPI; - this.stopResourceAPI = stopResourceAPI; - } + /** + * @brief Update the web recording configuration. + * @since v0.4.0 + * @param cname The name of the channel to be recorded. + * @param uid The user ID used by the cloud recording service in the + * RTC channel to identify the recording service in the + * channel. + * @param resourceId The resource ID. + * @param sid The recording ID, identifying a recording cycle. + * @param clientRequest The request body. See + * {@link UpdateWebRecordingResourceClientReq} for + * details. + * @return Returns the update resource result. See + * {@link UpdateResourceRes} for details. + */ + public abstract Mono update(String cname, String uid, String resourceId, String sid, + UpdateWebRecordingResourceClientReq clientRequest); - public Mono acquire(String cname, String uid, - AcquireWebRecordingResourceClientReq clientRequest) { - StartResourceReq.StartClientRequest startParameter = null; - - if (clientRequest.getStartParameter() != null) { - startParameter = StartResourceReq.StartClientRequest.builder() - .storageConfig(clientRequest.getStartParameter().getStorageConfig()) - .recordingFileConfig(clientRequest.getStartParameter().getRecordingFileConfig()) - .extensionServiceConfig(clientRequest.getStartParameter().getExtensionServiceConfig()) - .build(); - } - - return this.acquireResourceAPI.handle(AcquireResourceReq.builder() - .cname(cname) - .uid(uid) - .clientRequest(AcquireResourceReq.ClientRequest.builder() - .scene(1) - .resourceExpiredHour(clientRequest.getResourceExpiredHour()) - .regionAffinity(clientRequest.getRegionAffinity()) - .excludeResourceIds(clientRequest.getExcludeResourceIds()) - .startParameter(startParameter) - .build()) - .build()); - } - - public Mono start(String cname, String uid, String resourceId, - StartWebRecordingResourceClientReq clientRequest) { - return this.startResourceAPI.handle(resourceId, CloudRecordingModeEnum.WEB, StartResourceReq.builder() - .cname(cname) - .uid(uid) - .clientRequest(StartResourceReq.StartClientRequest.builder() - .storageConfig(clientRequest.getStorageConfig()) - .recordingFileConfig(clientRequest.getRecordingFileConfig()) - .extensionServiceConfig(clientRequest.getExtensionServiceConfig()) - .build()) - .build()); - } - - public Mono query(String resourceId, String sid) { - return this.queryResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.WEB).handle((res, sink) -> { - sink.next(QueryWebRecordingResourceRes.builder() - .cname(res.getCname()) - .uid(res.getUid()) - .resourceId(res.getResourceId()) - .sid(res.getSid()) - .serverResponse(res.getWebRecordingServerResponse()) - .build()); - - sink.complete(); - }); - } - - public Mono update(String cname, String uid, String resourceId, String sid, - UpdateWebRecordingResourceClientReq clientRequest) { - return this.updateResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.WEB, UpdateResourceReq.builder() - .cname(cname) - .uid(uid) - .clientRequest(UpdateResourceReq.ClientRequest.builder() - .webRecordingConfig(clientRequest.getWebRecordingConfig()) - .rtmpPublishConfig(clientRequest.getRtmpPublishConfig()) - .build()) - .build()); - } - - public Mono stop(String cname, String uid, String resourceId, String sid, boolean asyncStop) { - return this.stopResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.WEB, StopResourceReq.builder() - .cname(cname) - .uid(uid) - .clientRequest(StopResourceReq.StopClientRequest.builder() - .asyncStop(asyncStop) - .build()) - .build()); - } + /** + * @brief Stop web recording. + * @since v0.4.0 + * @param cname The name of the channel to be recorded. + * @param uid The user ID used by the cloud recording service in the RTC + * channel to identify the recording service in the channel. + * @param resourceId The resource ID. + * @param sid The recording ID, identifying a recording cycle. + * @param asyncStop Whether to stop the recording asynchronously. + *

+ * - true: Stop the recording asynchronously. + *

+ * - false: Stop the recording synchronously. + * @return Returns the stop resource result. See {@link StopResourceRes} for + * details. + */ + public abstract Mono stop(String cname, String uid, String resourceId, String sid, + boolean asyncStop); } diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/WebScenarioImpl.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/WebScenarioImpl.java new file mode 100644 index 0000000..e94d8fc --- /dev/null +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/WebScenarioImpl.java @@ -0,0 +1,140 @@ +package io.agora.rest.services.cloudrecording.scenario.web; + +import io.agora.rest.services.cloudrecording.api.*; +import io.agora.rest.services.cloudrecording.api.req.AcquireResourceReq; +import io.agora.rest.services.cloudrecording.api.req.StartResourceReq; +import io.agora.rest.services.cloudrecording.api.req.StopResourceReq; +import io.agora.rest.services.cloudrecording.api.req.UpdateResourceReq; +import io.agora.rest.services.cloudrecording.api.res.AcquireResourceRes; +import io.agora.rest.services.cloudrecording.api.res.StartResourceRes; +import io.agora.rest.services.cloudrecording.api.res.StopResourceRes; +import io.agora.rest.services.cloudrecording.api.res.UpdateResourceRes; +import io.agora.rest.services.cloudrecording.enums.CloudRecordingModeEnum; +import io.agora.rest.services.cloudrecording.scenario.web.req.AcquireWebRecordingResourceClientReq; +import io.agora.rest.services.cloudrecording.scenario.web.req.StartWebRecordingResourceClientReq; +import io.agora.rest.services.cloudrecording.scenario.web.req.UpdateWebRecordingResourceClientReq; +import io.agora.rest.services.cloudrecording.scenario.web.res.QueryWebRecordingResourceRes; +import io.agora.rest.services.cloudrecording.scenario.web.res.QueryWebRecordingRtmpPublishResourceRes; +import reactor.core.publisher.Mono; + +public class WebScenarioImpl extends WebScenario { + + private final AcquireResourceAPI acquireResourceAPI; + + private final QueryResourceAPI queryResourceAPI; + + private final StartResourceAPI startResourceAPI; + + private final UpdateResourceAPI updateResourceAPI; + + private final StopResourceAPI stopResourceAPI; + + public WebScenarioImpl(AcquireResourceAPI acquireResourceAPI, + QueryResourceAPI queryResourceAPI, + StartResourceAPI startResourceAPI, + UpdateResourceAPI updateResourceAPI, + StopResourceAPI stopResourceAPI) { + this.acquireResourceAPI = acquireResourceAPI; + this.queryResourceAPI = queryResourceAPI; + this.startResourceAPI = startResourceAPI; + this.updateResourceAPI = updateResourceAPI; + this.stopResourceAPI = stopResourceAPI; + } + + @Override + public Mono acquire(String cname, String uid, + AcquireWebRecordingResourceClientReq clientRequest) { + StartResourceReq.StartClientRequest startParameter = null; + + if (clientRequest.getStartParameter() != null) { + startParameter = StartResourceReq.StartClientRequest.builder() + .storageConfig(clientRequest.getStartParameter().getStorageConfig()) + .recordingFileConfig(clientRequest.getStartParameter().getRecordingFileConfig()) + .extensionServiceConfig( + clientRequest.getStartParameter().getExtensionServiceConfig()) + .build(); + } + + return this.acquireResourceAPI.handle(AcquireResourceReq.builder() + .cname(cname) + .uid(uid) + .clientRequest(AcquireResourceReq.ClientRequest.builder() + .scene(1) + .resourceExpiredHour(clientRequest.getResourceExpiredHour()) + .regionAffinity(clientRequest.getRegionAffinity()) + .excludeResourceIds(clientRequest.getExcludeResourceIds()) + .startParameter(startParameter) + .build()) + .build()); + } + + @Override + public Mono start(String cname, String uid, String resourceId, + StartWebRecordingResourceClientReq clientRequest) { + return this.startResourceAPI.handle(resourceId, CloudRecordingModeEnum.WEB, StartResourceReq.builder() + .cname(cname) + .uid(uid) + .clientRequest(StartResourceReq.StartClientRequest.builder() + .storageConfig(clientRequest.getStorageConfig()) + .recordingFileConfig(clientRequest.getRecordingFileConfig()) + .extensionServiceConfig(clientRequest.getExtensionServiceConfig()) + .build()) + .build()); + } + + @Override + public Mono query(String resourceId, String sid) { + return this.queryResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.WEB).handle((res, sink) -> { + sink.next(QueryWebRecordingResourceRes.builder() + .cname(res.getCname()) + .uid(res.getUid()) + .resourceId(res.getResourceId()) + .sid(res.getSid()) + .serverResponse(res.getWebRecordingServerResponse()) + .build()); + + sink.complete(); + }); + } + + @Override + public Mono update(String cname, String uid, String resourceId, String sid, + UpdateWebRecordingResourceClientReq clientRequest) { + return this.updateResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.WEB, UpdateResourceReq + .builder() + .cname(cname) + .uid(uid) + .clientRequest(UpdateResourceReq.ClientRequest.builder() + .webRecordingConfig(clientRequest.getWebRecordingConfig()) + .rtmpPublishConfig(clientRequest.getRtmpPublishConfig()) + .build()) + .build()); + } + + @Override + public Mono stop(String cname, String uid, String resourceId, String sid, boolean asyncStop) { + return this.stopResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.WEB, + StopResourceReq.builder() + .cname(cname) + .uid(uid) + .clientRequest(StopResourceReq.StopClientRequest.builder() + .asyncStop(asyncStop) + .build()) + .build()); + } + + @Override + public Mono queryRtmpPublish(String resourceId, String sid) { + return this.queryResourceAPI.handle(resourceId, sid, CloudRecordingModeEnum.WEB).handle((res, sink) -> { + sink.next(QueryWebRecordingRtmpPublishResourceRes.builder() + .cname(res.getCname()) + .uid(res.getUid()) + .resourceId(res.getResourceId()) + .sid(res.getSid()) + .serverResponse(res.getWebRecordingRtmpPublishServerResponse()) + .build()); + + sink.complete(); + }); + } +} diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/req/AcquireWebRecordingResourceClientReq.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/req/AcquireWebRecordingResourceClientReq.java index 2d8506e..1b51e87 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/req/AcquireWebRecordingResourceClientReq.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/req/AcquireWebRecordingResourceClientReq.java @@ -2,14 +2,49 @@ import java.util.List; +/** + * @brief Client request for acquiring web cloud recording resources. + * @since v0.4.0 + */ public class AcquireWebRecordingResourceClientReq { + /** + * The validity period for calling the cloud recording RESTful API. + *

+ * Start calculating after you successfully initiate the cloud recording service + * and obtain the sid (Recording ID). + *

+ * The calculation unit is hours. + *

+ * The value range is [1,720]. The default value is 72. + */ private Integer resourceExpiredHour; + /** + * The resourceId of another or several other recording tasks. + */ private List excludeResourceIds; + /** + * Specify regions that the cloud recording service can access. + *

+ * The region can be set to: + *

+ * - 0: Closest to request origin (default) + *

+ * - 1: China + *

+ * - 2: Southeast Asia + *

+ * - 3: Europe + *

+ * - 4: North America + */ private Integer regionAffinity; + /** + * The start parameter improves availability and optimizes load balancing. + */ private StartWebRecordingResourceClientReq startParameter; public static Builder builder() { diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/req/StartWebRecordingResourceClientReq.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/req/StartWebRecordingResourceClientReq.java index 556f4d3..1b0e7bc 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/req/StartWebRecordingResourceClientReq.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/req/StartWebRecordingResourceClientReq.java @@ -2,12 +2,25 @@ import io.agora.rest.services.cloudrecording.api.req.StartResourceReq; +/** + * @brief Client request for starting web recording. + * @since v0.4.0 + */ public class StartWebRecordingResourceClientReq { + /** + * Configuration for recorded files.(Optional) + */ private StartResourceReq.RecordingFileConfig recordingFileConfig; + /** + * Configuration for third-party cloud storage.(Required) + */ private StartResourceReq.StorageConfig storageConfig; + /** + * Configurations for extended services.(Optional) + */ private StartResourceReq.ExtensionServiceConfig extensionServiceConfig; public static Builder builder() { diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/req/UpdateWebRecordingResourceClientReq.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/req/UpdateWebRecordingResourceClientReq.java index 9c8155c..9fe2b11 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/req/UpdateWebRecordingResourceClientReq.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/req/UpdateWebRecordingResourceClientReq.java @@ -2,10 +2,21 @@ import io.agora.rest.services.cloudrecording.api.req.UpdateResourceReq; +/** + * @brief Client request for updating web page recording. + * @since v0.4.0 + */ public class UpdateWebRecordingResourceClientReq { + /** + * Used to update the web page recording configurations.(Optional) + */ private UpdateResourceReq.WebRecordingConfig webRecordingConfig; + /** + * Used to update the configurations for pushing web page recording to the + * CDN.(Optional) + */ private UpdateResourceReq.RtmpPublishConfig rtmpPublishConfig; public static Builder builder() { diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/res/QueryWebRecordingResourceRes.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/res/QueryWebRecordingResourceRes.java index 1d6c7f3..13ef272 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/res/QueryWebRecordingResourceRes.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/res/QueryWebRecordingResourceRes.java @@ -2,16 +2,35 @@ import io.agora.rest.services.cloudrecording.api.res.QueryResourceRes; +/** + * @brief Response returned by the web recording query API. + * @since v0.4.0 + */ public class QueryWebRecordingResourceRes { - + /** + * The name of the channel to be recorded. + */ private String cname; + /** + * The user ID used by the cloud recording service in the RTC channel to + * identify the recording service in the channel. + */ private String uid; + /** + * Unique identifier of the resource. + */ private String resourceId; + /** + * Unique identifier of the recording session. + */ private String sid; + /** + * Server response. See {@link QueryResourceRes.WebRecordingServerResponse}. + */ private QueryResourceRes.WebRecordingServerResponse serverResponse; public static Builder builder() { diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/res/QueryWebRecordingRtmpPublishResourceRes.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/res/QueryWebRecordingRtmpPublishResourceRes.java new file mode 100644 index 0000000..7693d45 --- /dev/null +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/cloudrecording/scenario/web/res/QueryWebRecordingRtmpPublishResourceRes.java @@ -0,0 +1,139 @@ +package io.agora.rest.services.cloudrecording.scenario.web.res; + +import io.agora.rest.services.cloudrecording.api.res.QueryResourceRes; + +/** + * @brief Response returned by the web recording queryRtmpPublish API. + * @since v0.4.0 + */ +public class QueryWebRecordingRtmpPublishResourceRes { + /** + * The name of the channel to be recorded. + */ + private String cname; + + /** + * The user ID used by the cloud recording service in the RTC channel to + * identify the recording service in the channel. + */ + private String uid; + + /** + * Unique identifier of the resource. + */ + private String resourceId; + + /** + * Unique identifier of the recording session. + */ + private String sid; + + /** + * Server response. See + * {@link QueryResourceRes.WebRecordingRtmpPublishServerResponse}. + */ + private QueryResourceRes.WebRecordingRtmpPublishServerResponse serverResponse; + + public static Builder builder() { + return new Builder(); + } + + private QueryWebRecordingRtmpPublishResourceRes(Builder builder) { + setCname(builder.cname); + setUid(builder.uid); + setResourceId(builder.resourceId); + setSid(builder.sid); + setServerResponse(builder.serverResponse); + } + + public String getCname() { + return cname; + } + + public void setCname(String cname) { + this.cname = cname; + } + + public String getUid() { + return uid; + } + + public void setUid(String uid) { + this.uid = uid; + } + + public String getResourceId() { + return resourceId; + } + + public void setResourceId(String resourceId) { + this.resourceId = resourceId; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + + public QueryResourceRes.WebRecordingRtmpPublishServerResponse getServerResponse() { + return serverResponse; + } + + public void setServerResponse(QueryResourceRes.WebRecordingRtmpPublishServerResponse serverResponse) { + this.serverResponse = serverResponse; + } + + @Override + public String toString() { + return "QueryWebRecordingResourceRes{" + + "cname='" + cname + '\'' + + ", uid='" + uid + '\'' + + ", resourceId='" + resourceId + '\'' + + ", sid='" + sid + '\'' + + ", serverResponse=" + serverResponse + + '}'; + } + + public static final class Builder { + private String cname; + private String uid; + private String resourceId; + private String sid; + private QueryResourceRes.WebRecordingRtmpPublishServerResponse serverResponse; + + private Builder() { + } + + public Builder cname(String val) { + cname = val; + return this; + } + + public Builder uid(String val) { + uid = val; + return this; + } + + public Builder resourceId(String val) { + resourceId = val; + return this; + } + + public Builder sid(String val) { + sid = val; + return this; + } + + public Builder serverResponse(QueryResourceRes.WebRecordingRtmpPublishServerResponse val) { + serverResponse = val; + return this; + } + + public QueryWebRecordingRtmpPublishResourceRes build() { + return new QueryWebRecordingRtmpPublishResourceRes(this); + } + } +} diff --git a/agora-rest-client-core/src/main/java/io/agora/rest/services/convoai/ConvoAIConfig.java b/agora-rest-client-core/src/main/java/io/agora/rest/services/convoai/ConvoAIConfig.java index 07e75a1..2114db3 100644 --- a/agora-rest-client-core/src/main/java/io/agora/rest/services/convoai/ConvoAIConfig.java +++ b/agora-rest-client-core/src/main/java/io/agora/rest/services/convoai/ConvoAIConfig.java @@ -4,7 +4,6 @@ import io.agora.rest.core.DomainArea; import io.agora.rest.core.HttpProperty; - /** * @brief Defines the configuration for the Conversational AI engine client * @since v0.3.0 @@ -36,7 +35,8 @@ public class ConvoAIConfig { private final HttpProperty httpProperty; /** - * Service region for the Conversational AI engine. See {@link ConvoAIServiceRegionEnum} + * Service region for the Conversational AI engine. See + * {@link ConvoAIServiceRegionEnum} */ private final ConvoAIServiceRegionEnum serviceRegion; @@ -113,11 +113,6 @@ public Builder domainArea(DomainArea domainArea) { return this; } - private Builder httpProperty(HttpProperty httpProperty) { - this.httpProperty = httpProperty; - return this; - } - public Builder serverRegion(ConvoAIServiceRegionEnum serverRegion) { this.serviceRegion = serverRegion; return this; diff --git a/examples/cloudrecording/src/main/java/io/agora/rest/examples/cloudrecording/scenario/BaseScenario.java b/examples/cloudrecording/src/main/java/io/agora/rest/examples/cloudrecording/scenario/BaseScenario.java index 6e363ea..969f4a2 100644 --- a/examples/cloudrecording/src/main/java/io/agora/rest/examples/cloudrecording/scenario/BaseScenario.java +++ b/examples/cloudrecording/src/main/java/io/agora/rest/examples/cloudrecording/scenario/BaseScenario.java @@ -1,9 +1,9 @@ package io.agora.rest.examples.cloudrecording.scenario; -import io.agora.rest.core.AgoraConfig; import io.agora.rest.core.Credential; import io.agora.rest.core.DomainArea; import io.agora.rest.services.cloudrecording.CloudRecordingClient; +import io.agora.rest.services.cloudrecording.CloudRecordingConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,13 +30,13 @@ public BaseScenario(DomainArea domainArea, String appId, String cname, String ui this.uid = uid; this.credential = credential; - AgoraConfig agoraConfig = AgoraConfig.builder() + CloudRecordingConfig agoraConfig = CloudRecordingConfig.builder() .appId(appId) .credential(credential) .domainArea(domainArea) .build(); - logger.info("AgoraConfig: {}", agoraConfig); + logger.info("CloudRecordingConfig: {}", agoraConfig); this.cloudRecordingClient = CloudRecordingClient.create(agoraConfig); } diff --git a/examples/cloudrecording/src/main/java/io/agora/rest/examples/cloudrecording/scenario/MixRecordingScenario.java b/examples/cloudrecording/src/main/java/io/agora/rest/examples/cloudrecording/scenario/MixRecordingScenario.java index e141015..aedfef2 100644 --- a/examples/cloudrecording/src/main/java/io/agora/rest/examples/cloudrecording/scenario/MixRecordingScenario.java +++ b/examples/cloudrecording/src/main/java/io/agora/rest/examples/cloudrecording/scenario/MixRecordingScenario.java @@ -35,7 +35,8 @@ public void runHLS(String token, StartResourceReq.StorageConfig storageConfig) { .mixScenario() .acquire(cname, uid, AcquireMixRecordingResourceClientReq.builder() .resourceExpiredHour(1) - .build()).block(); + .build()) + .block(); } catch (AgoraException e) { logger.error("Failed to acquire resource,err:{}", e.getMessage()); return; @@ -97,7 +98,6 @@ public void runHLS(String token, StartResourceReq.StorageConfig storageConfig) { logger.info("Start resource successfully,startResourceResp:{}", startResourceRes); - // query resource detail for (int i = 0; i < 3; i++) { QueryMixHLSRecordingResourceRes queryMixHLSRecordingResourceRes; @@ -118,7 +118,8 @@ public void runHLS(String token, StartResourceReq.StorageConfig storageConfig) { return; } - logger.info("Query resource successfully,queryMixHLSRecordingResourceResp:{}", queryMixHLSRecordingResourceRes); + logger.info("Query resource successfully,queryMixHLSRecordingResourceResp:{}", + queryMixHLSRecordingResourceRes); try { Thread.sleep(3000); } catch (InterruptedException e) { @@ -132,16 +133,18 @@ public void runHLS(String token, StartResourceReq.StorageConfig storageConfig) { try { updateResourceRes = this.cloudRecordingClient .mixScenario() - .update(cname, uid, acquireResourceRes.getResourceId(), startResourceRes.getSid(), UpdateMixRecordingResourceClientReq.builder() - .streamSubscribe(UpdateResourceReq.StreamSubscribe.builder() - .audioUidList(UpdateResourceReq.AudioUIDList.builder() - .subscribeAudioUIDs(Collections.singletonList("#allstream#")) - .build()) - .videoUidList(UpdateResourceReq.VideoUIDList.builder() - .subscribeVideoUIDs(Collections.singletonList("#allstream#")) + .update(cname, uid, acquireResourceRes.getResourceId(), startResourceRes.getSid(), + UpdateMixRecordingResourceClientReq.builder() + .streamSubscribe(UpdateResourceReq.StreamSubscribe.builder() + .audioUidList(UpdateResourceReq.AudioUIDList.builder() + .subscribeAudioUIDs(Collections.singletonList("#allstream#")) + .build()) + .videoUidList(UpdateResourceReq.VideoUIDList.builder() + .subscribeVideoUIDs(Collections.singletonList("#allstream#")) + .build()) .build()) .build()) - .build()).block(); + .block(); } catch (AgoraException e) { logger.error("Failed to update resource,err:{}", e.getMessage()); @@ -158,17 +161,18 @@ public void runHLS(String token, StartResourceReq.StorageConfig storageConfig) { logger.info("Update resource successfully,updateResourceResp:{}", updateResourceRes); - // update UpdateLayoutResourceRes updateLayoutResourceRes; try { updateLayoutResourceRes = this.cloudRecordingClient .mixScenario() - .updateLayout(cname, uid, acquireResourceRes.getResourceId(), startResourceRes.getSid(), UpdateLayoutMixRecordingResourceClientReq.builder() - .mixedVideoLayout(1) - .backgroundColor("#FF0000") - .build()).block(); + .updateLayout(cname, uid, acquireResourceRes.getResourceId(), startResourceRes.getSid(), + UpdateLayoutMixRecordingResourceClientReq.builder() + .mixedVideoLayout(1) + .backgroundColor("#FF0000") + .build()) + .block(); } catch (AgoraException e) { logger.error("Failed to update layout resource,err:{}", e.getMessage()); @@ -205,7 +209,8 @@ public void runHLS(String token, StartResourceReq.StorageConfig storageConfig) { return; } - logger.info("Query resource successfully,queryMixHLSRecordingResourceResp:{}", queryMixHLSRecordingResourceRes); + logger.info("Query resource successfully,queryMixHLSRecordingResourceResp:{}", + queryMixHLSRecordingResourceRes); try { Thread.sleep(3000); } catch (InterruptedException e) { @@ -245,7 +250,8 @@ public void runHLSAndMP4(String token, StartResourceReq.StorageConfig storageCon .mixScenario() .acquire(cname, uid, AcquireMixRecordingResourceClientReq.builder() .resourceExpiredHour(1) - .build()).block(); + .build()) + .block(); } catch (AgoraException e) { logger.error("Failed to acquire resource,err:{}", e.getMessage()); return; @@ -307,7 +313,6 @@ public void runHLSAndMP4(String token, StartResourceReq.StorageConfig storageCon logger.info("Start resource successfully,startResourceResp:{}", startResourceRes); - // query resource detail for (int i = 0; i < 3; i++) { QueryMixHLSAndMP4RecordingResourceRes queryMixHLSAndMP4RecordingResourceRes; @@ -328,7 +333,8 @@ public void runHLSAndMP4(String token, StartResourceReq.StorageConfig storageCon return; } - logger.info("Query resource successfully,queryMixHLSAndMP4RecordingResourceResp:{}", queryMixHLSAndMP4RecordingResourceRes); + logger.info("Query resource successfully,queryMixHLSAndMP4RecordingResourceResp:{}", + queryMixHLSAndMP4RecordingResourceRes); try { Thread.sleep(3000); } catch (InterruptedException e) { @@ -342,16 +348,18 @@ public void runHLSAndMP4(String token, StartResourceReq.StorageConfig storageCon try { updateResourceRes = this.cloudRecordingClient .mixScenario() - .update(cname, uid, acquireResourceRes.getResourceId(), startResourceRes.getSid(), UpdateMixRecordingResourceClientReq.builder() - .streamSubscribe(UpdateResourceReq.StreamSubscribe.builder() - .audioUidList(UpdateResourceReq.AudioUIDList.builder() - .subscribeAudioUIDs(Collections.singletonList("#allstream#")) - .build()) - .videoUidList(UpdateResourceReq.VideoUIDList.builder() - .subscribeVideoUIDs(Collections.singletonList("#allstream#")) + .update(cname, uid, acquireResourceRes.getResourceId(), startResourceRes.getSid(), + UpdateMixRecordingResourceClientReq.builder() + .streamSubscribe(UpdateResourceReq.StreamSubscribe.builder() + .audioUidList(UpdateResourceReq.AudioUIDList.builder() + .subscribeAudioUIDs(Collections.singletonList("#allstream#")) + .build()) + .videoUidList(UpdateResourceReq.VideoUIDList.builder() + .subscribeVideoUIDs(Collections.singletonList("#allstream#")) + .build()) .build()) .build()) - .build()).block(); + .block(); } catch (AgoraException e) { logger.error("Failed to update resource,err:{}", e.getMessage()); @@ -368,17 +376,18 @@ public void runHLSAndMP4(String token, StartResourceReq.StorageConfig storageCon logger.info("Update resource successfully,updateResourceResp:{}", updateResourceRes); - // update UpdateLayoutResourceRes updateLayoutResourceRes; try { updateLayoutResourceRes = this.cloudRecordingClient .mixScenario() - .updateLayout(cname, uid, acquireResourceRes.getResourceId(), startResourceRes.getSid(), UpdateLayoutMixRecordingResourceClientReq.builder() - .mixedVideoLayout(1) - .backgroundColor("#FF0000") - .build()).block(); + .updateLayout(cname, uid, acquireResourceRes.getResourceId(), startResourceRes.getSid(), + UpdateLayoutMixRecordingResourceClientReq.builder() + .mixedVideoLayout(1) + .backgroundColor("#FF0000") + .build()) + .block(); } catch (AgoraException e) { logger.error("Failed to update layout resource,err:{}", e.getMessage()); @@ -415,7 +424,8 @@ public void runHLSAndMP4(String token, StartResourceReq.StorageConfig storageCon return; } - logger.info("Query resource successfully,queryMixHLSAndMP4RecordingResourceResp:{}", queryMixHLSAndMP4RecordingResourceRes); + logger.info("Query resource successfully,queryMixHLSAndMP4RecordingResourceResp:{}", + queryMixHLSAndMP4RecordingResourceRes); try { Thread.sleep(3000); } catch (InterruptedException e) { diff --git a/examples/cloudrecording/src/main/java/io/agora/rest/examples/cloudrecording/scenario/WebRecordingScenario.java b/examples/cloudrecording/src/main/java/io/agora/rest/examples/cloudrecording/scenario/WebRecordingScenario.java index 468034f..4492a1c 100644 --- a/examples/cloudrecording/src/main/java/io/agora/rest/examples/cloudrecording/scenario/WebRecordingScenario.java +++ b/examples/cloudrecording/src/main/java/io/agora/rest/examples/cloudrecording/scenario/WebRecordingScenario.java @@ -36,7 +36,8 @@ public void runWebRecorder(StartResourceReq.StorageConfig storageConfig) { .webScenario() .acquire(cname, uid, AcquireWebRecordingResourceClientReq.builder() .resourceExpiredHour(1) - .build()).block(); + .build()) + .block(); } catch (AgoraException e) { logger.error("Failed to acquire resource,err:{}", e.getMessage()); return; @@ -66,17 +67,19 @@ public void runWebRecorder(StartResourceReq.StorageConfig storageConfig) { .storageConfig(storageConfig) .extensionServiceConfig(StartResourceReq.ExtensionServiceConfig.builder() .errorHandlePolicy("error_abort") - .extensionServices(Collections.singletonList(StartResourceReq.ExtensionService.builder() - .serviceName("web_recorder_service") - .errorHandlePolicy("error_abort") - .serviceParam(StartResourceReq.WebRecordingServiceParam.builder() - .url("https://live.bilibili.com/") - .audioProfile(2) - .videoWidth(1280) - .videoHeight(720) - .maxRecordingHour(1) - .build()) - .build())) + .extensionServices(Collections + .singletonList(StartResourceReq.ExtensionService.builder() + .serviceName("web_recorder_service") + .errorHandlePolicy("error_abort") + .serviceParam( + StartResourceReq.WebRecordingServiceParam.builder() + .url("https://live.bilibili.com/") + .audioProfile(2) + .videoWidth(1280) + .videoHeight(720) + .maxRecordingHour(1) + .build()) + .build())) .build()) .build()) .block(); @@ -96,7 +99,6 @@ public void runWebRecorder(StartResourceReq.StorageConfig storageConfig) { logger.info("Start resource successfully,startResourceResp:{}", startResourceRes); - // query resource detail for (int i = 0; i < 3; i++) { QueryWebRecordingResourceRes queryWebRecordingResourceRes; @@ -131,11 +133,13 @@ public void runWebRecorder(StartResourceReq.StorageConfig storageConfig) { try { updateResourceRes = this.cloudRecordingClient .webScenario() - .update(cname, uid, acquireResourceRes.getResourceId(), startResourceRes.getSid(), UpdateWebRecordingResourceClientReq.builder() - .webRecordingConfig(UpdateResourceReq.WebRecordingConfig.builder() - .onHold(false) + .update(cname, uid, acquireResourceRes.getResourceId(), startResourceRes.getSid(), + UpdateWebRecordingResourceClientReq.builder() + .webRecordingConfig(UpdateResourceReq.WebRecordingConfig.builder() + .onHold(false) + .build()) .build()) - .build()).block(); + .block(); } catch (AgoraException e) { logger.error("Failed to update resource,err:{}", e.getMessage()); @@ -212,7 +216,8 @@ public void runWebRecorderAndRtmpPublish(StartResourceReq.StorageConfig storageC .webScenario() .acquire(cname, uid, AcquireWebRecordingResourceClientReq.builder() .resourceExpiredHour(1) - .build()).block(); + .build()) + .block(); } catch (AgoraException e) { logger.error("Failed to acquire resource,err:{}", e.getMessage()); return; @@ -243,26 +248,28 @@ public void runWebRecorderAndRtmpPublish(StartResourceReq.StorageConfig storageC .extensionServiceConfig(StartResourceReq.ExtensionServiceConfig.builder() .errorHandlePolicy("error_abort") .extensionServices(Arrays.asList(StartResourceReq.ExtensionService.builder() - .serviceName("web_recorder_service") - .errorHandlePolicy("error_abort") - .serviceParam(StartResourceReq.WebRecordingServiceParam.builder() - .url("https://live.bilibili.com/") - .audioProfile(2) - .videoWidth(1280) - .videoHeight(720) - .maxRecordingHour(1) - .build()) - .build(), + .serviceName("web_recorder_service") + .errorHandlePolicy("error_abort") + .serviceParam(StartResourceReq.WebRecordingServiceParam.builder() + .url("https://live.bilibili.com/") + .audioProfile(2) + .videoWidth(1280) + .videoHeight(720) + .maxRecordingHour(1) + .build()) + .build(), StartResourceReq.ExtensionService.builder() .serviceName("rtmp_publish_service") .errorHandlePolicy("error_ignore") - .serviceParam(StartResourceReq.RtmpPublishServiceParam.builder() - .outputs(Collections.singletonList(StartResourceReq.Outputs.builder() - .rtmpUrl("rtmp://xxx.xxx.xxx.xxx:1935/live/test") - .build())) + .serviceParam(StartResourceReq.RtmpPublishServiceParam + .builder() + .outputs(Collections.singletonList( + StartResourceReq.Output.builder() + .rtmpUrl( + "rtmp://xxx.xxx.xxx.xxx:1935/live/test") + .build())) .build()) - .build() - )) + .build())) .build()) .build()) .block(); @@ -282,7 +289,6 @@ public void runWebRecorderAndRtmpPublish(StartResourceReq.StorageConfig storageC logger.info("Start resource successfully,startResourceResp:{}", startResourceRes); - // query resource detail for (int i = 0; i < 3; i++) { QueryWebRecordingResourceRes queryWebRecordingResourceRes; @@ -317,16 +323,17 @@ public void runWebRecorderAndRtmpPublish(StartResourceReq.StorageConfig storageC try { updateResourceRes = this.cloudRecordingClient .webScenario() - .update(cname, uid, acquireResourceRes.getResourceId(), startResourceRes.getSid(), UpdateWebRecordingResourceClientReq.builder() - .webRecordingConfig(UpdateResourceReq.WebRecordingConfig.builder() - .onHold(false) - .build()) - .rtmpPublishConfig(UpdateResourceReq.RtmpPublishConfig.builder() - .outputs(Collections.singletonList(UpdateResourceReq.UpdateOutput.builder() - .rtmpURL("rtmp://yyy.yyy.yyy.yyy:1935/live/test") + .update(cname, uid, acquireResourceRes.getResourceId(), startResourceRes.getSid(), + UpdateWebRecordingResourceClientReq.builder() + .webRecordingConfig(UpdateResourceReq.WebRecordingConfig.builder() + .onHold(false) .build()) - ).build()) - .build()) + .rtmpPublishConfig(UpdateResourceReq.RtmpPublishConfig.builder() + .outputs(Collections.singletonList(UpdateResourceReq.UpdateOutput.builder() + .rtmpURL("rtmp://yyy.yyy.yyy.yyy:1935/live/test") + .build())) + .build()) + .build()) .block(); } catch (AgoraException e) { diff --git a/examples/convoai/src/main/java/io/agora/rest/examples/convoai/service/Service.java b/examples/convoai/src/main/java/io/agora/rest/examples/convoai/service/Service.java index 9440667..5f835ba 100644 --- a/examples/convoai/src/main/java/io/agora/rest/examples/convoai/service/Service.java +++ b/examples/convoai/src/main/java/io/agora/rest/examples/convoai/service/Service.java @@ -20,10 +20,9 @@ public class Service extends BaseService { private static final Logger logger = LoggerFactory.getLogger(Service.class); - private JoinConvoAIReq req; - - public Service(DomainArea domainArea, String appId, String cname, String uid, Credential credential, ConvoAIServiceRegionEnum serviceRegion) { + public Service(DomainArea domainArea, String appId, String cname, String uid, Credential credential, + ConvoAIServiceRegionEnum serviceRegion) { super(domainArea, appId, cname, uid, credential, serviceRegion); } @@ -233,17 +232,9 @@ public void runBytedanceTTS() { throw new IllegalArgumentException("CONVOAI_TTS_BYTEDANCE_VOICE_TYPE is required"); } - JoinConvoAIReq.BytedanceTTSVendorParams ttsVendorParams = JoinConvoAIReq.BytedanceTTSVendorParams. - builder(). - token(ttsToken). - cluster(ttsCluster). - voiceType(ttsVoiceType). - appId(ttsAppId). - speedRatio(1.0F). - volumeRatio(1.0F). - pitchRatio(1.0F). - emotion("happy"). - build(); + JoinConvoAIReq.BytedanceTTSVendorParams ttsVendorParams = JoinConvoAIReq.BytedanceTTSVendorParams.builder() + .token(ttsToken).cluster(ttsCluster).voiceType(ttsVoiceType).appId(ttsAppId).speedRatio(1.0F) + .volumeRatio(1.0F).pitchRatio(1.0F).emotion("happy").build(); runCustomTTS(JoinConvoAIReq.TTSVendorEnum.BYTEDANCE, ttsVendorParams); } @@ -265,17 +256,9 @@ public void runTencentTTS() { throw new IllegalArgumentException("CONVOAI_TTS_TENCENT_SECRET_KEY is required"); } - JoinConvoAIReq.TencentTTSVendorParams ttsVendorParams = JoinConvoAIReq.TencentTTSVendorParams. - builder(). - appId(ttsAppId). - secretId(ttsSecretId). - secretKey(ttsSecretKey). - voiceType(601005). - volume(0). - speed(0). - emotionCategory("happy"). - emotionIntensity(100). - build(); + JoinConvoAIReq.TencentTTSVendorParams ttsVendorParams = JoinConvoAIReq.TencentTTSVendorParams.builder() + .appId(ttsAppId).secretId(ttsSecretId).secretKey(ttsSecretKey).voiceType(601005).volume(0).speed(0) + .emotionCategory("happy").emotionIntensity(100).build(); runCustomTTS(JoinConvoAIReq.TTSVendorEnum.TENCENT, ttsVendorParams); @@ -298,19 +281,11 @@ public void runMinimaxTTS() { throw new IllegalArgumentException("CONVOAI_TTS_MINIMAX_GROUP_MODEL is required"); } - JoinConvoAIReq.MinimaxTTSVendorParams ttsVendorParams = JoinConvoAIReq.MinimaxTTSVendorParams. - builder(). - groupId(ttsGroupId). - key(ttsGroupKey). - model(ttsGroupModel). - voiceSetting(JoinConvoAIReq.MinimaxTTSVendorVoiceSettingParam.builder(). - voiceId("female-shaonv"). - speed(1F). - vol(1F). - pitch(0). - emotion("happy"). - build()). - build(); + JoinConvoAIReq.MinimaxTTSVendorParams ttsVendorParams = JoinConvoAIReq.MinimaxTTSVendorParams.builder() + .groupId(ttsGroupId).key(ttsGroupKey).model(ttsGroupModel) + .voiceSetting(JoinConvoAIReq.MinimaxTTSVendorVoiceSettingParam.builder().voiceId("female-shaonv") + .speed(1F).vol(1F).pitch(0).emotion("happy").build()) + .build(); runCustomTTS(JoinConvoAIReq.TTSVendorEnum.MINIMAX, ttsVendorParams); @@ -333,14 +308,8 @@ public void runMicrosoftTTS() { throw new IllegalArgumentException("CONVOAI_TTS_MICROSOFT_VOICE_NAME is required"); } - JoinConvoAIReq.MicrosoftTTSVendorParams ttsVendorParams = JoinConvoAIReq.MicrosoftTTSVendorParams. - builder(). - key(ttsKey). - region(ttsRegion). - voiceName(ttsVoiceName). - rate(1.8F). - volume(70F). - build(); + JoinConvoAIReq.MicrosoftTTSVendorParams ttsVendorParams = JoinConvoAIReq.MicrosoftTTSVendorParams.builder() + .key(ttsKey).region(ttsRegion).voiceName(ttsVoiceName).rate(1.8F).volume(70F).build(); runCustomTTS(JoinConvoAIReq.TTSVendorEnum.MICROSOFT, ttsVendorParams); } @@ -362,12 +331,8 @@ public void runElevenlabsTTS() { throw new IllegalArgumentException("CONVOAI_TTS_ELEVENLABS_VOICE_ID is required"); } - JoinConvoAIReq.ElevenLabsTTSVendorParams ttsVendorParams = JoinConvoAIReq.ElevenLabsTTSVendorParams. - builder(). - apiKey(ttsApiKey). - modelId(ttsModelId). - voiceId(ttsVoiceId). - build(); + JoinConvoAIReq.ElevenLabsTTSVendorParams ttsVendorParams = JoinConvoAIReq.ElevenLabsTTSVendorParams.builder() + .apiKey(ttsApiKey).modelId(ttsModelId).voiceId(ttsVoiceId).build(); runCustomTTS(JoinConvoAIReq.TTSVendorEnum.ELEVENLABS, ttsVendorParams); }