001/*
002 *   Copyright 2024 Vonage
003 *
004 *   Licensed under the Apache License, Version 2.0 (the "License");
005 *   you may not use this file except in compliance with the License.
006 *   You may obtain a copy of the License at
007 *
008 *        http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *   Unless required by applicable law or agreed to in writing, software
011 *   distributed under the License is distributed on an "AS IS" BASIS,
012 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *   See the License for the specific language governing permissions and
014 *   limitations under the License.
015 */
016package com.vonage.client.video;
017
018import com.fasterxml.jackson.annotation.JsonIgnore;
019import com.fasterxml.jackson.annotation.JsonProperty;
020import com.vonage.client.JsonableBaseObject;
021import java.time.Instant;
022import java.util.List;
023import java.util.Objects;
024import java.util.UUID;
025
026/**
027 * Base class for {@link Broadcast} and {@link Archive}.
028 * Represents the common features of a video call consisting of multiple streams.
029 */
030public abstract class StreamComposition extends JsonableBaseObject {
031        @JsonProperty("id") protected UUID id;
032        @JsonProperty("applicationId") protected UUID applicationId;
033        @JsonProperty("sessionId") protected String sessionId;
034        @JsonProperty("streamMode") protected StreamMode streamMode;
035        @JsonProperty("resolution") protected Resolution resolution;
036        @JsonProperty("layout") protected StreamCompositionLayout layout;
037        @JsonProperty("hasVideo") protected Boolean hasVideo;
038        @JsonProperty("hasAudio") protected Boolean hasAudio;
039        @JsonProperty("createdAt") protected Long createdAt;
040        @JsonProperty("streams") protected List<VideoStream> streams;
041        @JsonProperty("maxBitrate") protected Integer maxBitrate;
042
043        protected StreamComposition() {
044        }
045
046        protected StreamComposition(Builder builder) {
047                sessionId = Objects.requireNonNull(builder.sessionId, "Session ID is required");
048                streamMode = builder.streamMode;
049                resolution = builder.resolution;
050                hasAudio = builder.hasAudio;
051                hasVideo = builder.hasVideo;
052                layout = builder.layout;
053                maxBitrate = builder.maxBitrate;
054        }
055
056        /**
057         * Unique ID of the composition.
058         *
059         * @return The composition ID.
060         */
061        public UUID getId() {
062                return id;
063        }
064
065        /**
066         * Vonage video application ID (as used to create the client).
067         *
068         * @return The application ID.
069         */
070        public UUID getApplicationId() {
071                return applicationId;
072        }
073
074        /**
075         * The ID of the video session associated with this composition.
076         *
077         * @return The session ID.
078         */
079        public String getSessionId() {
080                return sessionId;
081        }
082
083        /**
084         * The video resolution of the composition.
085         *
086         * @return The resolution as an enum.
087         */
088        public Resolution getResolution() {
089                return resolution;
090        }
091
092        /**
093         * Whether the composition has a video track ({@code true}) or not ({@code false}).
094         *
095         * @return Whether this composition has video.
096         */
097        public Boolean hasVideo() {
098                return hasVideo;
099        }
100
101        /**
102         * Whether the archive has an audio track ({@code true}) or not ({@code false}).
103         *
104         * @return Whether this composition has sound.
105         */
106        public Boolean hasAudio() {
107                return hasAudio;
108        }
109
110        /**
111         * The stream mode to used for selecting streams to be included in this composition:
112         * {@link StreamMode#AUTO} or {@link StreamMode#MANUAL}.
113         *
114         * @return The {@linkplain StreamMode}.
115         */
116        public StreamMode getStreamMode() {
117                return streamMode;
118        }
119
120        /**
121         * Returns the streams associated with this composition. This is only set when the status is
122         * "started" and the stream mode is "manual".
123         *
124         * @return The details for each video stream, or {@code null} if not applicable.
125         */
126        public List<VideoStream> getStreams() {
127                return streams;
128        }
129
130        /**
131         * Describes how the streams in this composition are displayed.
132         *
133         * @return Layout information for the stream compositions.
134         */
135        protected StreamCompositionLayout getLayout() {
136                return layout;
137        }
138
139        /**
140         * The maximum bitrate for the stream in bits per second (if one was set).
141         *
142         * @return The maximum bits per second as an integer, or {@code null} if unset.
143         */
144        public Integer getMaxBitrate() {
145                return maxBitrate;
146        }
147
148        /**
149         * The time at which this composition was started or created, in milliseconds since the Unix epoch.
150         *
151         * @return The created time as a long, or {@code null} if absent / not applicable.
152         */
153        @JsonProperty("createdAt")
154        public Long getCreatedAtMillis() {
155                return createdAt;
156        }
157
158        /**
159         * The time at which this composition was started or created.
160         *
161         * @return The creation time, or {@code null} if absent / not applicable.
162         */
163        @JsonIgnore
164        public Instant getCreatedAt() {
165                return createdAt != null ? Instant.ofEpochMilli(createdAt) : null;
166        }
167
168        protected static abstract class Builder {
169                protected String sessionId;
170                protected Integer maxBitrate;
171                protected Boolean hasAudio, hasVideo;
172                protected Resolution resolution;
173                protected StreamMode streamMode;
174                protected StreamCompositionLayout layout;
175        }
176}