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.JsonCreator;
019import com.fasterxml.jackson.annotation.JsonProperty;
020import com.fasterxml.jackson.annotation.JsonValue;
021import com.vonage.client.JsonableBaseObject;
022import java.net.URI;
023import java.util.*;
024
025/**
026 * Defines the properties in {@link ConnectRequest#getWebsocket()}.
027 *
028 * @since 8.5.0
029 */
030public final class Websocket extends JsonableBaseObject {
031    private URI uri;
032    private Collection<String> streams;
033    private Map<String, String> headers;
034    private AudioRate audioRate;
035
036    Websocket() {}
037
038    Websocket(ConnectRequest.Builder builder) {
039        String uriStr = Objects.requireNonNull(builder.uri, "WebSocket URI is required.");
040        if (uriStr.startsWith("ws://") || uriStr.startsWith("wss://")) {
041            uri = URI.create(builder.uri);
042        }
043        else {
044            throw new IllegalArgumentException("Invalid URI protocol: must start with ws:// or wss://");
045        }
046        if (builder.streams != null) {
047            streams = builder.streams instanceof List ? builder.streams : new ArrayList<>(builder.streams);
048        }
049        headers = builder.headers;
050        audioRate = builder.audioRate;
051    }
052
053    /**
054     * A publicly reachable WebSocket URI to be used for the destination of the audio stream.
055     *
056     * @return The WebSocket URI.
057     */
058    @JsonProperty("uri")
059    public URI getUri() {
060        return uri;
061    }
062
063    /**
064     * Stream IDs for the Vonage Video streams you want to include in the WebSocket audio.
065     * If you omitted, all streams in the session will be included.
066     *
067     * @return The collection of stream IDs to include, or {@code null} if not specified.
068     */
069    @JsonProperty("streams")
070    public Collection<String> getStreams() {
071        return streams;
072    }
073
074    /**
075     * Headers to be sent to your WebSocket server with each message, with a maximum length of 512 bytes.
076     *
077     * @return The header key-value pairs as a Map, or {@code null} if not specified.
078     */
079    @JsonProperty("headers")
080    public Map<String, String> getHeaders() {
081        return headers;
082    }
083
084    /**
085     * Audio sampling rate in Hz.
086     *
087     * @return The sample rate as an enum, or {@code null} if not specified.
088     */
089    @JsonProperty("audioRate")
090    public AudioRate getAudioRate() {
091        return audioRate;
092    }
093
094    /**
095     * Represents the possible audio sampling rate values for a WebSocket connection.
096     */
097    public enum AudioRate {
098        /**
099         * Linear 16-bit PCM at 8 Khz.
100         */
101        L16_8K,
102
103        /**
104         * Linear 16-bit PCM at 16 Khz.
105         */
106        L16_16K;
107
108        /**
109         * Converts the enum to an integer value representing the bitrate (Hz).
110         *
111         * @return The audio rate in Hertz as an int.
112         */
113        @JsonValue
114        public int getAudioRate() {
115            return this == L16_8K ? 8000 : 16_000;
116        }
117
118        /**
119         * Converts an integer sampling value into the appropriate enum representation.
120         *
121         * @param value The sampling rate in Hz or KHz.
122         *
123         * @return The corresponding enum representation.
124         */
125        @JsonCreator
126        public static AudioRate fromInt(int value) {
127            switch (value) {
128                case 8: case 8000: return L16_8K;
129                case 16: case 16_000: return L16_16K;
130                default: throw new IllegalArgumentException("Unsupported sample rate: "+value);
131            }
132        }
133    }
134}