/*
 * Jellyfin API
 * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 *
 * The version of the OpenAPI document: 10.11.6
 * 
 *
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

package org.openhab.binding.jellyfin.internal.gen.current.model;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.StringJoiner;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;

/**
 * MediaSourceInfo
 */
@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "OpenAPI Generator")
public class MediaSourceInfo {
    public static final String JSON_PROPERTY_PROTOCOL = "Protocol";
    private @org.eclipse.jdt.annotation.Nullable MediaProtocol protocol;

    public static final String JSON_PROPERTY_ID = "Id";
    private @org.eclipse.jdt.annotation.Nullable String id;

    public static final String JSON_PROPERTY_PATH = "Path";
    private @org.eclipse.jdt.annotation.Nullable String path;

    public static final String JSON_PROPERTY_ENCODER_PATH = "EncoderPath";
    private @org.eclipse.jdt.annotation.Nullable String encoderPath;

    public static final String JSON_PROPERTY_ENCODER_PROTOCOL = "EncoderProtocol";
    private @org.eclipse.jdt.annotation.Nullable MediaProtocol encoderProtocol;

    public static final String JSON_PROPERTY_TYPE = "Type";
    private @org.eclipse.jdt.annotation.Nullable MediaSourceType type;

    public static final String JSON_PROPERTY_CONTAINER = "Container";
    private @org.eclipse.jdt.annotation.Nullable String container;

    public static final String JSON_PROPERTY_SIZE = "Size";
    private @org.eclipse.jdt.annotation.Nullable Long size;

    public static final String JSON_PROPERTY_NAME = "Name";
    private @org.eclipse.jdt.annotation.Nullable String name;

    public static final String JSON_PROPERTY_IS_REMOTE = "IsRemote";
    private @org.eclipse.jdt.annotation.Nullable Boolean isRemote;

    public static final String JSON_PROPERTY_ETAG = "ETag";
    private @org.eclipse.jdt.annotation.Nullable String etag;

    public static final String JSON_PROPERTY_RUN_TIME_TICKS = "RunTimeTicks";
    private @org.eclipse.jdt.annotation.Nullable Long runTimeTicks;

    public static final String JSON_PROPERTY_READ_AT_NATIVE_FRAMERATE = "ReadAtNativeFramerate";
    private @org.eclipse.jdt.annotation.Nullable Boolean readAtNativeFramerate;

    public static final String JSON_PROPERTY_IGNORE_DTS = "IgnoreDts";
    private @org.eclipse.jdt.annotation.Nullable Boolean ignoreDts;

    public static final String JSON_PROPERTY_IGNORE_INDEX = "IgnoreIndex";
    private @org.eclipse.jdt.annotation.Nullable Boolean ignoreIndex;

    public static final String JSON_PROPERTY_GEN_PTS_INPUT = "GenPtsInput";
    private @org.eclipse.jdt.annotation.Nullable Boolean genPtsInput;

    public static final String JSON_PROPERTY_SUPPORTS_TRANSCODING = "SupportsTranscoding";
    private @org.eclipse.jdt.annotation.Nullable Boolean supportsTranscoding;

    public static final String JSON_PROPERTY_SUPPORTS_DIRECT_STREAM = "SupportsDirectStream";
    private @org.eclipse.jdt.annotation.Nullable Boolean supportsDirectStream;

    public static final String JSON_PROPERTY_SUPPORTS_DIRECT_PLAY = "SupportsDirectPlay";
    private @org.eclipse.jdt.annotation.Nullable Boolean supportsDirectPlay;

    public static final String JSON_PROPERTY_IS_INFINITE_STREAM = "IsInfiniteStream";
    private @org.eclipse.jdt.annotation.Nullable Boolean isInfiniteStream;

    public static final String JSON_PROPERTY_USE_MOST_COMPATIBLE_TRANSCODING_PROFILE = "UseMostCompatibleTranscodingProfile";
    private @org.eclipse.jdt.annotation.Nullable Boolean useMostCompatibleTranscodingProfile = false;

    public static final String JSON_PROPERTY_REQUIRES_OPENING = "RequiresOpening";
    private @org.eclipse.jdt.annotation.Nullable Boolean requiresOpening;

    public static final String JSON_PROPERTY_OPEN_TOKEN = "OpenToken";
    private @org.eclipse.jdt.annotation.Nullable String openToken;

    public static final String JSON_PROPERTY_REQUIRES_CLOSING = "RequiresClosing";
    private @org.eclipse.jdt.annotation.Nullable Boolean requiresClosing;

    public static final String JSON_PROPERTY_LIVE_STREAM_ID = "LiveStreamId";
    private @org.eclipse.jdt.annotation.Nullable String liveStreamId;

    public static final String JSON_PROPERTY_BUFFER_MS = "BufferMs";
    private @org.eclipse.jdt.annotation.Nullable Integer bufferMs;

    public static final String JSON_PROPERTY_REQUIRES_LOOPING = "RequiresLooping";
    private @org.eclipse.jdt.annotation.Nullable Boolean requiresLooping;

    public static final String JSON_PROPERTY_SUPPORTS_PROBING = "SupportsProbing";
    private @org.eclipse.jdt.annotation.Nullable Boolean supportsProbing;

    public static final String JSON_PROPERTY_VIDEO_TYPE = "VideoType";
    private @org.eclipse.jdt.annotation.Nullable VideoType videoType;

    public static final String JSON_PROPERTY_ISO_TYPE = "IsoType";
    private @org.eclipse.jdt.annotation.Nullable IsoType isoType;

    public static final String JSON_PROPERTY_VIDEO3_D_FORMAT = "Video3DFormat";
    private @org.eclipse.jdt.annotation.Nullable Video3DFormat video3DFormat;

    public static final String JSON_PROPERTY_MEDIA_STREAMS = "MediaStreams";
    private @org.eclipse.jdt.annotation.Nullable List<MediaStream> mediaStreams;

    public static final String JSON_PROPERTY_MEDIA_ATTACHMENTS = "MediaAttachments";
    private @org.eclipse.jdt.annotation.Nullable List<MediaAttachment> mediaAttachments;

    public static final String JSON_PROPERTY_FORMATS = "Formats";
    private @org.eclipse.jdt.annotation.Nullable List<String> formats;

    public static final String JSON_PROPERTY_BITRATE = "Bitrate";
    private @org.eclipse.jdt.annotation.Nullable Integer bitrate;

    public static final String JSON_PROPERTY_FALLBACK_MAX_STREAMING_BITRATE = "FallbackMaxStreamingBitrate";
    private @org.eclipse.jdt.annotation.Nullable Integer fallbackMaxStreamingBitrate;

    public static final String JSON_PROPERTY_TIMESTAMP = "Timestamp";
    private @org.eclipse.jdt.annotation.Nullable TransportStreamTimestamp timestamp;

    public static final String JSON_PROPERTY_REQUIRED_HTTP_HEADERS = "RequiredHttpHeaders";
    private @org.eclipse.jdt.annotation.Nullable Map<String, String> requiredHttpHeaders;

    public static final String JSON_PROPERTY_TRANSCODING_URL = "TranscodingUrl";
    private @org.eclipse.jdt.annotation.Nullable String transcodingUrl;

    public static final String JSON_PROPERTY_TRANSCODING_SUB_PROTOCOL = "TranscodingSubProtocol";
    private @org.eclipse.jdt.annotation.Nullable MediaStreamProtocol transcodingSubProtocol;

    public static final String JSON_PROPERTY_TRANSCODING_CONTAINER = "TranscodingContainer";
    private @org.eclipse.jdt.annotation.Nullable String transcodingContainer;

    public static final String JSON_PROPERTY_ANALYZE_DURATION_MS = "AnalyzeDurationMs";
    private @org.eclipse.jdt.annotation.Nullable Integer analyzeDurationMs;

    public static final String JSON_PROPERTY_DEFAULT_AUDIO_STREAM_INDEX = "DefaultAudioStreamIndex";
    private @org.eclipse.jdt.annotation.Nullable Integer defaultAudioStreamIndex;

    public static final String JSON_PROPERTY_DEFAULT_SUBTITLE_STREAM_INDEX = "DefaultSubtitleStreamIndex";
    private @org.eclipse.jdt.annotation.Nullable Integer defaultSubtitleStreamIndex;

    public static final String JSON_PROPERTY_HAS_SEGMENTS = "HasSegments";
    private @org.eclipse.jdt.annotation.Nullable Boolean hasSegments;

    public MediaSourceInfo() {
    }

    public MediaSourceInfo protocol(@org.eclipse.jdt.annotation.Nullable MediaProtocol protocol) {
        this.protocol = protocol;
        return this;
    }

    /**
     * Get protocol
     * 
     * @return protocol
     */
    @JsonProperty(value = JSON_PROPERTY_PROTOCOL)
    public @org.eclipse.jdt.annotation.Nullable MediaProtocol getProtocol() {
        return protocol;
    }

    @JsonProperty(value = JSON_PROPERTY_PROTOCOL)
    public void setProtocol(@org.eclipse.jdt.annotation.Nullable MediaProtocol protocol) {
        this.protocol = protocol;
    }

    public MediaSourceInfo id(@org.eclipse.jdt.annotation.Nullable String id) {
        this.id = id;
        return this;
    }

    /**
     * Get id
     * 
     * @return id
     */
    @JsonProperty(value = JSON_PROPERTY_ID)
    public @org.eclipse.jdt.annotation.Nullable String getId() {
        return id;
    }

    @JsonProperty(value = JSON_PROPERTY_ID)
    public void setId(@org.eclipse.jdt.annotation.Nullable String id) {
        this.id = id;
    }

    public MediaSourceInfo path(@org.eclipse.jdt.annotation.Nullable String path) {
        this.path = path;
        return this;
    }

    /**
     * Get path
     * 
     * @return path
     */
    @JsonProperty(value = JSON_PROPERTY_PATH)
    public @org.eclipse.jdt.annotation.Nullable String getPath() {
        return path;
    }

    @JsonProperty(value = JSON_PROPERTY_PATH)
    public void setPath(@org.eclipse.jdt.annotation.Nullable String path) {
        this.path = path;
    }

    public MediaSourceInfo encoderPath(@org.eclipse.jdt.annotation.Nullable String encoderPath) {
        this.encoderPath = encoderPath;
        return this;
    }

    /**
     * Get encoderPath
     * 
     * @return encoderPath
     */
    @JsonProperty(value = JSON_PROPERTY_ENCODER_PATH)
    public @org.eclipse.jdt.annotation.Nullable String getEncoderPath() {
        return encoderPath;
    }

    @JsonProperty(value = JSON_PROPERTY_ENCODER_PATH)
    public void setEncoderPath(@org.eclipse.jdt.annotation.Nullable String encoderPath) {
        this.encoderPath = encoderPath;
    }

    public MediaSourceInfo encoderProtocol(@org.eclipse.jdt.annotation.Nullable MediaProtocol encoderProtocol) {
        this.encoderProtocol = encoderProtocol;
        return this;
    }

    /**
     * Get encoderProtocol
     * 
     * @return encoderProtocol
     */
    @JsonProperty(value = JSON_PROPERTY_ENCODER_PROTOCOL)
    public @org.eclipse.jdt.annotation.Nullable MediaProtocol getEncoderProtocol() {
        return encoderProtocol;
    }

    @JsonProperty(value = JSON_PROPERTY_ENCODER_PROTOCOL)
    public void setEncoderProtocol(@org.eclipse.jdt.annotation.Nullable MediaProtocol encoderProtocol) {
        this.encoderProtocol = encoderProtocol;
    }

    public MediaSourceInfo type(@org.eclipse.jdt.annotation.Nullable MediaSourceType type) {
        this.type = type;
        return this;
    }

    /**
     * Get type
     * 
     * @return type
     */
    @JsonProperty(value = JSON_PROPERTY_TYPE)
    public @org.eclipse.jdt.annotation.Nullable MediaSourceType getType() {
        return type;
    }

    @JsonProperty(value = JSON_PROPERTY_TYPE)
    public void setType(@org.eclipse.jdt.annotation.Nullable MediaSourceType type) {
        this.type = type;
    }

    public MediaSourceInfo container(@org.eclipse.jdt.annotation.Nullable String container) {
        this.container = container;
        return this;
    }

    /**
     * Get container
     * 
     * @return container
     */
    @JsonProperty(value = JSON_PROPERTY_CONTAINER)
    public @org.eclipse.jdt.annotation.Nullable String getContainer() {
        return container;
    }

    @JsonProperty(value = JSON_PROPERTY_CONTAINER)
    public void setContainer(@org.eclipse.jdt.annotation.Nullable String container) {
        this.container = container;
    }

    public MediaSourceInfo size(@org.eclipse.jdt.annotation.Nullable Long size) {
        this.size = size;
        return this;
    }

    /**
     * Get size
     * 
     * @return size
     */
    @JsonProperty(value = JSON_PROPERTY_SIZE)
    public @org.eclipse.jdt.annotation.Nullable Long getSize() {
        return size;
    }

    @JsonProperty(value = JSON_PROPERTY_SIZE)
    public void setSize(@org.eclipse.jdt.annotation.Nullable Long size) {
        this.size = size;
    }

    public MediaSourceInfo name(@org.eclipse.jdt.annotation.Nullable String name) {
        this.name = name;
        return this;
    }

    /**
     * Get name
     * 
     * @return name
     */
    @JsonProperty(value = JSON_PROPERTY_NAME)
    public @org.eclipse.jdt.annotation.Nullable String getName() {
        return name;
    }

    @JsonProperty(value = JSON_PROPERTY_NAME)
    public void setName(@org.eclipse.jdt.annotation.Nullable String name) {
        this.name = name;
    }

    public MediaSourceInfo isRemote(@org.eclipse.jdt.annotation.Nullable Boolean isRemote) {
        this.isRemote = isRemote;
        return this;
    }

    /**
     * Gets or sets a value indicating whether the media is remote. Differentiate internet url vs local network.
     * 
     * @return isRemote
     */
    @JsonProperty(value = JSON_PROPERTY_IS_REMOTE)
    public @org.eclipse.jdt.annotation.Nullable Boolean getIsRemote() {
        return isRemote;
    }

    @JsonProperty(value = JSON_PROPERTY_IS_REMOTE)
    public void setIsRemote(@org.eclipse.jdt.annotation.Nullable Boolean isRemote) {
        this.isRemote = isRemote;
    }

    public MediaSourceInfo etag(@org.eclipse.jdt.annotation.Nullable String etag) {
        this.etag = etag;
        return this;
    }

    /**
     * Get etag
     * 
     * @return etag
     */
    @JsonProperty(value = JSON_PROPERTY_ETAG)
    public @org.eclipse.jdt.annotation.Nullable String getEtag() {
        return etag;
    }

    @JsonProperty(value = JSON_PROPERTY_ETAG)
    public void setEtag(@org.eclipse.jdt.annotation.Nullable String etag) {
        this.etag = etag;
    }

    public MediaSourceInfo runTimeTicks(@org.eclipse.jdt.annotation.Nullable Long runTimeTicks) {
        this.runTimeTicks = runTimeTicks;
        return this;
    }

    /**
     * Get runTimeTicks
     * 
     * @return runTimeTicks
     */
    @JsonProperty(value = JSON_PROPERTY_RUN_TIME_TICKS)
    public @org.eclipse.jdt.annotation.Nullable Long getRunTimeTicks() {
        return runTimeTicks;
    }

    @JsonProperty(value = JSON_PROPERTY_RUN_TIME_TICKS)
    public void setRunTimeTicks(@org.eclipse.jdt.annotation.Nullable Long runTimeTicks) {
        this.runTimeTicks = runTimeTicks;
    }

    public MediaSourceInfo readAtNativeFramerate(@org.eclipse.jdt.annotation.Nullable Boolean readAtNativeFramerate) {
        this.readAtNativeFramerate = readAtNativeFramerate;
        return this;
    }

    /**
     * Get readAtNativeFramerate
     * 
     * @return readAtNativeFramerate
     */
    @JsonProperty(value = JSON_PROPERTY_READ_AT_NATIVE_FRAMERATE)
    public @org.eclipse.jdt.annotation.Nullable Boolean getReadAtNativeFramerate() {
        return readAtNativeFramerate;
    }

    @JsonProperty(value = JSON_PROPERTY_READ_AT_NATIVE_FRAMERATE)
    public void setReadAtNativeFramerate(@org.eclipse.jdt.annotation.Nullable Boolean readAtNativeFramerate) {
        this.readAtNativeFramerate = readAtNativeFramerate;
    }

    public MediaSourceInfo ignoreDts(@org.eclipse.jdt.annotation.Nullable Boolean ignoreDts) {
        this.ignoreDts = ignoreDts;
        return this;
    }

    /**
     * Get ignoreDts
     * 
     * @return ignoreDts
     */
    @JsonProperty(value = JSON_PROPERTY_IGNORE_DTS)
    public @org.eclipse.jdt.annotation.Nullable Boolean getIgnoreDts() {
        return ignoreDts;
    }

    @JsonProperty(value = JSON_PROPERTY_IGNORE_DTS)
    public void setIgnoreDts(@org.eclipse.jdt.annotation.Nullable Boolean ignoreDts) {
        this.ignoreDts = ignoreDts;
    }

    public MediaSourceInfo ignoreIndex(@org.eclipse.jdt.annotation.Nullable Boolean ignoreIndex) {
        this.ignoreIndex = ignoreIndex;
        return this;
    }

    /**
     * Get ignoreIndex
     * 
     * @return ignoreIndex
     */
    @JsonProperty(value = JSON_PROPERTY_IGNORE_INDEX)
    public @org.eclipse.jdt.annotation.Nullable Boolean getIgnoreIndex() {
        return ignoreIndex;
    }

    @JsonProperty(value = JSON_PROPERTY_IGNORE_INDEX)
    public void setIgnoreIndex(@org.eclipse.jdt.annotation.Nullable Boolean ignoreIndex) {
        this.ignoreIndex = ignoreIndex;
    }

    public MediaSourceInfo genPtsInput(@org.eclipse.jdt.annotation.Nullable Boolean genPtsInput) {
        this.genPtsInput = genPtsInput;
        return this;
    }

    /**
     * Get genPtsInput
     * 
     * @return genPtsInput
     */
    @JsonProperty(value = JSON_PROPERTY_GEN_PTS_INPUT)
    public @org.eclipse.jdt.annotation.Nullable Boolean getGenPtsInput() {
        return genPtsInput;
    }

    @JsonProperty(value = JSON_PROPERTY_GEN_PTS_INPUT)
    public void setGenPtsInput(@org.eclipse.jdt.annotation.Nullable Boolean genPtsInput) {
        this.genPtsInput = genPtsInput;
    }

    public MediaSourceInfo supportsTranscoding(@org.eclipse.jdt.annotation.Nullable Boolean supportsTranscoding) {
        this.supportsTranscoding = supportsTranscoding;
        return this;
    }

    /**
     * Get supportsTranscoding
     * 
     * @return supportsTranscoding
     */
    @JsonProperty(value = JSON_PROPERTY_SUPPORTS_TRANSCODING)
    public @org.eclipse.jdt.annotation.Nullable Boolean getSupportsTranscoding() {
        return supportsTranscoding;
    }

    @JsonProperty(value = JSON_PROPERTY_SUPPORTS_TRANSCODING)
    public void setSupportsTranscoding(@org.eclipse.jdt.annotation.Nullable Boolean supportsTranscoding) {
        this.supportsTranscoding = supportsTranscoding;
    }

    public MediaSourceInfo supportsDirectStream(@org.eclipse.jdt.annotation.Nullable Boolean supportsDirectStream) {
        this.supportsDirectStream = supportsDirectStream;
        return this;
    }

    /**
     * Get supportsDirectStream
     * 
     * @return supportsDirectStream
     */
    @JsonProperty(value = JSON_PROPERTY_SUPPORTS_DIRECT_STREAM)
    public @org.eclipse.jdt.annotation.Nullable Boolean getSupportsDirectStream() {
        return supportsDirectStream;
    }

    @JsonProperty(value = JSON_PROPERTY_SUPPORTS_DIRECT_STREAM)
    public void setSupportsDirectStream(@org.eclipse.jdt.annotation.Nullable Boolean supportsDirectStream) {
        this.supportsDirectStream = supportsDirectStream;
    }

    public MediaSourceInfo supportsDirectPlay(@org.eclipse.jdt.annotation.Nullable Boolean supportsDirectPlay) {
        this.supportsDirectPlay = supportsDirectPlay;
        return this;
    }

    /**
     * Get supportsDirectPlay
     * 
     * @return supportsDirectPlay
     */
    @JsonProperty(value = JSON_PROPERTY_SUPPORTS_DIRECT_PLAY)
    public @org.eclipse.jdt.annotation.Nullable Boolean getSupportsDirectPlay() {
        return supportsDirectPlay;
    }

    @JsonProperty(value = JSON_PROPERTY_SUPPORTS_DIRECT_PLAY)
    public void setSupportsDirectPlay(@org.eclipse.jdt.annotation.Nullable Boolean supportsDirectPlay) {
        this.supportsDirectPlay = supportsDirectPlay;
    }

    public MediaSourceInfo isInfiniteStream(@org.eclipse.jdt.annotation.Nullable Boolean isInfiniteStream) {
        this.isInfiniteStream = isInfiniteStream;
        return this;
    }

    /**
     * Get isInfiniteStream
     * 
     * @return isInfiniteStream
     */
    @JsonProperty(value = JSON_PROPERTY_IS_INFINITE_STREAM)
    public @org.eclipse.jdt.annotation.Nullable Boolean getIsInfiniteStream() {
        return isInfiniteStream;
    }

    @JsonProperty(value = JSON_PROPERTY_IS_INFINITE_STREAM)
    public void setIsInfiniteStream(@org.eclipse.jdt.annotation.Nullable Boolean isInfiniteStream) {
        this.isInfiniteStream = isInfiniteStream;
    }

    public MediaSourceInfo useMostCompatibleTranscodingProfile(
            @org.eclipse.jdt.annotation.Nullable Boolean useMostCompatibleTranscodingProfile) {
        this.useMostCompatibleTranscodingProfile = useMostCompatibleTranscodingProfile;
        return this;
    }

    /**
     * Get useMostCompatibleTranscodingProfile
     * 
     * @return useMostCompatibleTranscodingProfile
     */
    @JsonProperty(value = JSON_PROPERTY_USE_MOST_COMPATIBLE_TRANSCODING_PROFILE)
    public @org.eclipse.jdt.annotation.Nullable Boolean getUseMostCompatibleTranscodingProfile() {
        return useMostCompatibleTranscodingProfile;
    }

    @JsonProperty(value = JSON_PROPERTY_USE_MOST_COMPATIBLE_TRANSCODING_PROFILE)
    public void setUseMostCompatibleTranscodingProfile(
            @org.eclipse.jdt.annotation.Nullable Boolean useMostCompatibleTranscodingProfile) {
        this.useMostCompatibleTranscodingProfile = useMostCompatibleTranscodingProfile;
    }

    public MediaSourceInfo requiresOpening(@org.eclipse.jdt.annotation.Nullable Boolean requiresOpening) {
        this.requiresOpening = requiresOpening;
        return this;
    }

    /**
     * Get requiresOpening
     * 
     * @return requiresOpening
     */
    @JsonProperty(value = JSON_PROPERTY_REQUIRES_OPENING)
    public @org.eclipse.jdt.annotation.Nullable Boolean getRequiresOpening() {
        return requiresOpening;
    }

    @JsonProperty(value = JSON_PROPERTY_REQUIRES_OPENING)
    public void setRequiresOpening(@org.eclipse.jdt.annotation.Nullable Boolean requiresOpening) {
        this.requiresOpening = requiresOpening;
    }

    public MediaSourceInfo openToken(@org.eclipse.jdt.annotation.Nullable String openToken) {
        this.openToken = openToken;
        return this;
    }

    /**
     * Get openToken
     * 
     * @return openToken
     */
    @JsonProperty(value = JSON_PROPERTY_OPEN_TOKEN)
    public @org.eclipse.jdt.annotation.Nullable String getOpenToken() {
        return openToken;
    }

    @JsonProperty(value = JSON_PROPERTY_OPEN_TOKEN)
    public void setOpenToken(@org.eclipse.jdt.annotation.Nullable String openToken) {
        this.openToken = openToken;
    }

    public MediaSourceInfo requiresClosing(@org.eclipse.jdt.annotation.Nullable Boolean requiresClosing) {
        this.requiresClosing = requiresClosing;
        return this;
    }

    /**
     * Get requiresClosing
     * 
     * @return requiresClosing
     */
    @JsonProperty(value = JSON_PROPERTY_REQUIRES_CLOSING)
    public @org.eclipse.jdt.annotation.Nullable Boolean getRequiresClosing() {
        return requiresClosing;
    }

    @JsonProperty(value = JSON_PROPERTY_REQUIRES_CLOSING)
    public void setRequiresClosing(@org.eclipse.jdt.annotation.Nullable Boolean requiresClosing) {
        this.requiresClosing = requiresClosing;
    }

    public MediaSourceInfo liveStreamId(@org.eclipse.jdt.annotation.Nullable String liveStreamId) {
        this.liveStreamId = liveStreamId;
        return this;
    }

    /**
     * Get liveStreamId
     * 
     * @return liveStreamId
     */
    @JsonProperty(value = JSON_PROPERTY_LIVE_STREAM_ID)
    public @org.eclipse.jdt.annotation.Nullable String getLiveStreamId() {
        return liveStreamId;
    }

    @JsonProperty(value = JSON_PROPERTY_LIVE_STREAM_ID)
    public void setLiveStreamId(@org.eclipse.jdt.annotation.Nullable String liveStreamId) {
        this.liveStreamId = liveStreamId;
    }

    public MediaSourceInfo bufferMs(@org.eclipse.jdt.annotation.Nullable Integer bufferMs) {
        this.bufferMs = bufferMs;
        return this;
    }

    /**
     * Get bufferMs
     * 
     * @return bufferMs
     */
    @JsonProperty(value = JSON_PROPERTY_BUFFER_MS)
    public @org.eclipse.jdt.annotation.Nullable Integer getBufferMs() {
        return bufferMs;
    }

    @JsonProperty(value = JSON_PROPERTY_BUFFER_MS)
    public void setBufferMs(@org.eclipse.jdt.annotation.Nullable Integer bufferMs) {
        this.bufferMs = bufferMs;
    }

    public MediaSourceInfo requiresLooping(@org.eclipse.jdt.annotation.Nullable Boolean requiresLooping) {
        this.requiresLooping = requiresLooping;
        return this;
    }

    /**
     * Get requiresLooping
     * 
     * @return requiresLooping
     */
    @JsonProperty(value = JSON_PROPERTY_REQUIRES_LOOPING)
    public @org.eclipse.jdt.annotation.Nullable Boolean getRequiresLooping() {
        return requiresLooping;
    }

    @JsonProperty(value = JSON_PROPERTY_REQUIRES_LOOPING)
    public void setRequiresLooping(@org.eclipse.jdt.annotation.Nullable Boolean requiresLooping) {
        this.requiresLooping = requiresLooping;
    }

    public MediaSourceInfo supportsProbing(@org.eclipse.jdt.annotation.Nullable Boolean supportsProbing) {
        this.supportsProbing = supportsProbing;
        return this;
    }

    /**
     * Get supportsProbing
     * 
     * @return supportsProbing
     */
    @JsonProperty(value = JSON_PROPERTY_SUPPORTS_PROBING)
    public @org.eclipse.jdt.annotation.Nullable Boolean getSupportsProbing() {
        return supportsProbing;
    }

    @JsonProperty(value = JSON_PROPERTY_SUPPORTS_PROBING)
    public void setSupportsProbing(@org.eclipse.jdt.annotation.Nullable Boolean supportsProbing) {
        this.supportsProbing = supportsProbing;
    }

    public MediaSourceInfo videoType(@org.eclipse.jdt.annotation.Nullable VideoType videoType) {
        this.videoType = videoType;
        return this;
    }

    /**
     * Get videoType
     * 
     * @return videoType
     */
    @JsonProperty(value = JSON_PROPERTY_VIDEO_TYPE)
    public @org.eclipse.jdt.annotation.Nullable VideoType getVideoType() {
        return videoType;
    }

    @JsonProperty(value = JSON_PROPERTY_VIDEO_TYPE)
    public void setVideoType(@org.eclipse.jdt.annotation.Nullable VideoType videoType) {
        this.videoType = videoType;
    }

    public MediaSourceInfo isoType(@org.eclipse.jdt.annotation.Nullable IsoType isoType) {
        this.isoType = isoType;
        return this;
    }

    /**
     * Get isoType
     * 
     * @return isoType
     */
    @JsonProperty(value = JSON_PROPERTY_ISO_TYPE)
    public @org.eclipse.jdt.annotation.Nullable IsoType getIsoType() {
        return isoType;
    }

    @JsonProperty(value = JSON_PROPERTY_ISO_TYPE)
    public void setIsoType(@org.eclipse.jdt.annotation.Nullable IsoType isoType) {
        this.isoType = isoType;
    }

    public MediaSourceInfo video3DFormat(@org.eclipse.jdt.annotation.Nullable Video3DFormat video3DFormat) {
        this.video3DFormat = video3DFormat;
        return this;
    }

    /**
     * Get video3DFormat
     * 
     * @return video3DFormat
     */
    @JsonProperty(value = JSON_PROPERTY_VIDEO3_D_FORMAT)
    public @org.eclipse.jdt.annotation.Nullable Video3DFormat getVideo3DFormat() {
        return video3DFormat;
    }

    @JsonProperty(value = JSON_PROPERTY_VIDEO3_D_FORMAT)
    public void setVideo3DFormat(@org.eclipse.jdt.annotation.Nullable Video3DFormat video3DFormat) {
        this.video3DFormat = video3DFormat;
    }

    public MediaSourceInfo mediaStreams(@org.eclipse.jdt.annotation.Nullable List<MediaStream> mediaStreams) {
        this.mediaStreams = mediaStreams;
        return this;
    }

    public MediaSourceInfo addMediaStreamsItem(MediaStream mediaStreamsItem) {
        if (this.mediaStreams == null) {
            this.mediaStreams = new ArrayList<>();
        }
        this.mediaStreams.add(mediaStreamsItem);
        return this;
    }

    /**
     * Get mediaStreams
     * 
     * @return mediaStreams
     */
    @JsonProperty(value = JSON_PROPERTY_MEDIA_STREAMS)
    public @org.eclipse.jdt.annotation.Nullable List<MediaStream> getMediaStreams() {
        return mediaStreams;
    }

    @JsonProperty(value = JSON_PROPERTY_MEDIA_STREAMS)
    public void setMediaStreams(@org.eclipse.jdt.annotation.Nullable List<MediaStream> mediaStreams) {
        this.mediaStreams = mediaStreams;
    }

    public MediaSourceInfo mediaAttachments(
            @org.eclipse.jdt.annotation.Nullable List<MediaAttachment> mediaAttachments) {
        this.mediaAttachments = mediaAttachments;
        return this;
    }

    public MediaSourceInfo addMediaAttachmentsItem(MediaAttachment mediaAttachmentsItem) {
        if (this.mediaAttachments == null) {
            this.mediaAttachments = new ArrayList<>();
        }
        this.mediaAttachments.add(mediaAttachmentsItem);
        return this;
    }

    /**
     * Get mediaAttachments
     * 
     * @return mediaAttachments
     */
    @JsonProperty(value = JSON_PROPERTY_MEDIA_ATTACHMENTS)
    public @org.eclipse.jdt.annotation.Nullable List<MediaAttachment> getMediaAttachments() {
        return mediaAttachments;
    }

    @JsonProperty(value = JSON_PROPERTY_MEDIA_ATTACHMENTS)
    public void setMediaAttachments(@org.eclipse.jdt.annotation.Nullable List<MediaAttachment> mediaAttachments) {
        this.mediaAttachments = mediaAttachments;
    }

    public MediaSourceInfo formats(@org.eclipse.jdt.annotation.Nullable List<String> formats) {
        this.formats = formats;
        return this;
    }

    public MediaSourceInfo addFormatsItem(String formatsItem) {
        if (this.formats == null) {
            this.formats = new ArrayList<>();
        }
        this.formats.add(formatsItem);
        return this;
    }

    /**
     * Get formats
     * 
     * @return formats
     */
    @JsonProperty(value = JSON_PROPERTY_FORMATS)
    public @org.eclipse.jdt.annotation.Nullable List<String> getFormats() {
        return formats;
    }

    @JsonProperty(value = JSON_PROPERTY_FORMATS)
    public void setFormats(@org.eclipse.jdt.annotation.Nullable List<String> formats) {
        this.formats = formats;
    }

    public MediaSourceInfo bitrate(@org.eclipse.jdt.annotation.Nullable Integer bitrate) {
        this.bitrate = bitrate;
        return this;
    }

    /**
     * Get bitrate
     * 
     * @return bitrate
     */
    @JsonProperty(value = JSON_PROPERTY_BITRATE)
    public @org.eclipse.jdt.annotation.Nullable Integer getBitrate() {
        return bitrate;
    }

    @JsonProperty(value = JSON_PROPERTY_BITRATE)
    public void setBitrate(@org.eclipse.jdt.annotation.Nullable Integer bitrate) {
        this.bitrate = bitrate;
    }

    public MediaSourceInfo fallbackMaxStreamingBitrate(
            @org.eclipse.jdt.annotation.Nullable Integer fallbackMaxStreamingBitrate) {
        this.fallbackMaxStreamingBitrate = fallbackMaxStreamingBitrate;
        return this;
    }

    /**
     * Get fallbackMaxStreamingBitrate
     * 
     * @return fallbackMaxStreamingBitrate
     */
    @JsonProperty(value = JSON_PROPERTY_FALLBACK_MAX_STREAMING_BITRATE)
    public @org.eclipse.jdt.annotation.Nullable Integer getFallbackMaxStreamingBitrate() {
        return fallbackMaxStreamingBitrate;
    }

    @JsonProperty(value = JSON_PROPERTY_FALLBACK_MAX_STREAMING_BITRATE)
    public void setFallbackMaxStreamingBitrate(
            @org.eclipse.jdt.annotation.Nullable Integer fallbackMaxStreamingBitrate) {
        this.fallbackMaxStreamingBitrate = fallbackMaxStreamingBitrate;
    }

    public MediaSourceInfo timestamp(@org.eclipse.jdt.annotation.Nullable TransportStreamTimestamp timestamp) {
        this.timestamp = timestamp;
        return this;
    }

    /**
     * Get timestamp
     * 
     * @return timestamp
     */
    @JsonProperty(value = JSON_PROPERTY_TIMESTAMP)
    public @org.eclipse.jdt.annotation.Nullable TransportStreamTimestamp getTimestamp() {
        return timestamp;
    }

    @JsonProperty(value = JSON_PROPERTY_TIMESTAMP)
    public void setTimestamp(@org.eclipse.jdt.annotation.Nullable TransportStreamTimestamp timestamp) {
        this.timestamp = timestamp;
    }

    public MediaSourceInfo requiredHttpHeaders(
            @org.eclipse.jdt.annotation.Nullable Map<String, String> requiredHttpHeaders) {
        this.requiredHttpHeaders = requiredHttpHeaders;
        return this;
    }

    public MediaSourceInfo putRequiredHttpHeadersItem(String key, String requiredHttpHeadersItem) {
        if (this.requiredHttpHeaders == null) {
            this.requiredHttpHeaders = new HashMap<>();
        }
        this.requiredHttpHeaders.put(key, requiredHttpHeadersItem);
        return this;
    }

    /**
     * Get requiredHttpHeaders
     * 
     * @return requiredHttpHeaders
     */
    @JsonProperty(value = JSON_PROPERTY_REQUIRED_HTTP_HEADERS)
    @JsonInclude(content = JsonInclude.Include.ALWAYS)
    public @org.eclipse.jdt.annotation.Nullable Map<String, String> getRequiredHttpHeaders() {
        return requiredHttpHeaders;
    }

    @JsonProperty(value = JSON_PROPERTY_REQUIRED_HTTP_HEADERS)
    @JsonInclude(content = JsonInclude.Include.ALWAYS)
    public void setRequiredHttpHeaders(@org.eclipse.jdt.annotation.Nullable Map<String, String> requiredHttpHeaders) {
        this.requiredHttpHeaders = requiredHttpHeaders;
    }

    public MediaSourceInfo transcodingUrl(@org.eclipse.jdt.annotation.Nullable String transcodingUrl) {
        this.transcodingUrl = transcodingUrl;
        return this;
    }

    /**
     * Get transcodingUrl
     * 
     * @return transcodingUrl
     */
    @JsonProperty(value = JSON_PROPERTY_TRANSCODING_URL)
    public @org.eclipse.jdt.annotation.Nullable String getTranscodingUrl() {
        return transcodingUrl;
    }

    @JsonProperty(value = JSON_PROPERTY_TRANSCODING_URL)
    public void setTranscodingUrl(@org.eclipse.jdt.annotation.Nullable String transcodingUrl) {
        this.transcodingUrl = transcodingUrl;
    }

    public MediaSourceInfo transcodingSubProtocol(
            @org.eclipse.jdt.annotation.Nullable MediaStreamProtocol transcodingSubProtocol) {
        this.transcodingSubProtocol = transcodingSubProtocol;
        return this;
    }

    /**
     * Media streaming protocol. Lowercase for backwards compatibility.
     * 
     * @return transcodingSubProtocol
     */
    @JsonProperty(value = JSON_PROPERTY_TRANSCODING_SUB_PROTOCOL)
    public @org.eclipse.jdt.annotation.Nullable MediaStreamProtocol getTranscodingSubProtocol() {
        return transcodingSubProtocol;
    }

    @JsonProperty(value = JSON_PROPERTY_TRANSCODING_SUB_PROTOCOL)
    public void setTranscodingSubProtocol(
            @org.eclipse.jdt.annotation.Nullable MediaStreamProtocol transcodingSubProtocol) {
        this.transcodingSubProtocol = transcodingSubProtocol;
    }

    public MediaSourceInfo transcodingContainer(@org.eclipse.jdt.annotation.Nullable String transcodingContainer) {
        this.transcodingContainer = transcodingContainer;
        return this;
    }

    /**
     * Get transcodingContainer
     * 
     * @return transcodingContainer
     */
    @JsonProperty(value = JSON_PROPERTY_TRANSCODING_CONTAINER)
    public @org.eclipse.jdt.annotation.Nullable String getTranscodingContainer() {
        return transcodingContainer;
    }

    @JsonProperty(value = JSON_PROPERTY_TRANSCODING_CONTAINER)
    public void setTranscodingContainer(@org.eclipse.jdt.annotation.Nullable String transcodingContainer) {
        this.transcodingContainer = transcodingContainer;
    }

    public MediaSourceInfo analyzeDurationMs(@org.eclipse.jdt.annotation.Nullable Integer analyzeDurationMs) {
        this.analyzeDurationMs = analyzeDurationMs;
        return this;
    }

    /**
     * Get analyzeDurationMs
     * 
     * @return analyzeDurationMs
     */
    @JsonProperty(value = JSON_PROPERTY_ANALYZE_DURATION_MS)
    public @org.eclipse.jdt.annotation.Nullable Integer getAnalyzeDurationMs() {
        return analyzeDurationMs;
    }

    @JsonProperty(value = JSON_PROPERTY_ANALYZE_DURATION_MS)
    public void setAnalyzeDurationMs(@org.eclipse.jdt.annotation.Nullable Integer analyzeDurationMs) {
        this.analyzeDurationMs = analyzeDurationMs;
    }

    public MediaSourceInfo defaultAudioStreamIndex(
            @org.eclipse.jdt.annotation.Nullable Integer defaultAudioStreamIndex) {
        this.defaultAudioStreamIndex = defaultAudioStreamIndex;
        return this;
    }

    /**
     * Get defaultAudioStreamIndex
     * 
     * @return defaultAudioStreamIndex
     */
    @JsonProperty(value = JSON_PROPERTY_DEFAULT_AUDIO_STREAM_INDEX)
    public @org.eclipse.jdt.annotation.Nullable Integer getDefaultAudioStreamIndex() {
        return defaultAudioStreamIndex;
    }

    @JsonProperty(value = JSON_PROPERTY_DEFAULT_AUDIO_STREAM_INDEX)
    public void setDefaultAudioStreamIndex(@org.eclipse.jdt.annotation.Nullable Integer defaultAudioStreamIndex) {
        this.defaultAudioStreamIndex = defaultAudioStreamIndex;
    }

    public MediaSourceInfo defaultSubtitleStreamIndex(
            @org.eclipse.jdt.annotation.Nullable Integer defaultSubtitleStreamIndex) {
        this.defaultSubtitleStreamIndex = defaultSubtitleStreamIndex;
        return this;
    }

    /**
     * Get defaultSubtitleStreamIndex
     * 
     * @return defaultSubtitleStreamIndex
     */
    @JsonProperty(value = JSON_PROPERTY_DEFAULT_SUBTITLE_STREAM_INDEX)
    public @org.eclipse.jdt.annotation.Nullable Integer getDefaultSubtitleStreamIndex() {
        return defaultSubtitleStreamIndex;
    }

    @JsonProperty(value = JSON_PROPERTY_DEFAULT_SUBTITLE_STREAM_INDEX)
    public void setDefaultSubtitleStreamIndex(@org.eclipse.jdt.annotation.Nullable Integer defaultSubtitleStreamIndex) {
        this.defaultSubtitleStreamIndex = defaultSubtitleStreamIndex;
    }

    public MediaSourceInfo hasSegments(@org.eclipse.jdt.annotation.Nullable Boolean hasSegments) {
        this.hasSegments = hasSegments;
        return this;
    }

    /**
     * Get hasSegments
     * 
     * @return hasSegments
     */
    @JsonProperty(value = JSON_PROPERTY_HAS_SEGMENTS)
    public @org.eclipse.jdt.annotation.Nullable Boolean getHasSegments() {
        return hasSegments;
    }

    @JsonProperty(value = JSON_PROPERTY_HAS_SEGMENTS)
    public void setHasSegments(@org.eclipse.jdt.annotation.Nullable Boolean hasSegments) {
        this.hasSegments = hasSegments;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        MediaSourceInfo mediaSourceInfo = (MediaSourceInfo) o;
        return Objects.equals(this.protocol, mediaSourceInfo.protocol) && Objects.equals(this.id, mediaSourceInfo.id)
                && Objects.equals(this.path, mediaSourceInfo.path)
                && Objects.equals(this.encoderPath, mediaSourceInfo.encoderPath)
                && Objects.equals(this.encoderProtocol, mediaSourceInfo.encoderProtocol)
                && Objects.equals(this.type, mediaSourceInfo.type)
                && Objects.equals(this.container, mediaSourceInfo.container)
                && Objects.equals(this.size, mediaSourceInfo.size) && Objects.equals(this.name, mediaSourceInfo.name)
                && Objects.equals(this.isRemote, mediaSourceInfo.isRemote)
                && Objects.equals(this.etag, mediaSourceInfo.etag)
                && Objects.equals(this.runTimeTicks, mediaSourceInfo.runTimeTicks)
                && Objects.equals(this.readAtNativeFramerate, mediaSourceInfo.readAtNativeFramerate)
                && Objects.equals(this.ignoreDts, mediaSourceInfo.ignoreDts)
                && Objects.equals(this.ignoreIndex, mediaSourceInfo.ignoreIndex)
                && Objects.equals(this.genPtsInput, mediaSourceInfo.genPtsInput)
                && Objects.equals(this.supportsTranscoding, mediaSourceInfo.supportsTranscoding)
                && Objects.equals(this.supportsDirectStream, mediaSourceInfo.supportsDirectStream)
                && Objects.equals(this.supportsDirectPlay, mediaSourceInfo.supportsDirectPlay)
                && Objects.equals(this.isInfiniteStream, mediaSourceInfo.isInfiniteStream)
                && Objects.equals(this.useMostCompatibleTranscodingProfile,
                        mediaSourceInfo.useMostCompatibleTranscodingProfile)
                && Objects.equals(this.requiresOpening, mediaSourceInfo.requiresOpening)
                && Objects.equals(this.openToken, mediaSourceInfo.openToken)
                && Objects.equals(this.requiresClosing, mediaSourceInfo.requiresClosing)
                && Objects.equals(this.liveStreamId, mediaSourceInfo.liveStreamId)
                && Objects.equals(this.bufferMs, mediaSourceInfo.bufferMs)
                && Objects.equals(this.requiresLooping, mediaSourceInfo.requiresLooping)
                && Objects.equals(this.supportsProbing, mediaSourceInfo.supportsProbing)
                && Objects.equals(this.videoType, mediaSourceInfo.videoType)
                && Objects.equals(this.isoType, mediaSourceInfo.isoType)
                && Objects.equals(this.video3DFormat, mediaSourceInfo.video3DFormat)
                && Objects.equals(this.mediaStreams, mediaSourceInfo.mediaStreams)
                && Objects.equals(this.mediaAttachments, mediaSourceInfo.mediaAttachments)
                && Objects.equals(this.formats, mediaSourceInfo.formats)
                && Objects.equals(this.bitrate, mediaSourceInfo.bitrate)
                && Objects.equals(this.fallbackMaxStreamingBitrate, mediaSourceInfo.fallbackMaxStreamingBitrate)
                && Objects.equals(this.timestamp, mediaSourceInfo.timestamp)
                && Objects.equals(this.requiredHttpHeaders, mediaSourceInfo.requiredHttpHeaders)
                && Objects.equals(this.transcodingUrl, mediaSourceInfo.transcodingUrl)
                && Objects.equals(this.transcodingSubProtocol, mediaSourceInfo.transcodingSubProtocol)
                && Objects.equals(this.transcodingContainer, mediaSourceInfo.transcodingContainer)
                && Objects.equals(this.analyzeDurationMs, mediaSourceInfo.analyzeDurationMs)
                && Objects.equals(this.defaultAudioStreamIndex, mediaSourceInfo.defaultAudioStreamIndex)
                && Objects.equals(this.defaultSubtitleStreamIndex, mediaSourceInfo.defaultSubtitleStreamIndex)
                && Objects.equals(this.hasSegments, mediaSourceInfo.hasSegments);
    }

    @Override
    public int hashCode() {
        return Objects.hash(protocol, id, path, encoderPath, encoderProtocol, type, container, size, name, isRemote,
                etag, runTimeTicks, readAtNativeFramerate, ignoreDts, ignoreIndex, genPtsInput, supportsTranscoding,
                supportsDirectStream, supportsDirectPlay, isInfiniteStream, useMostCompatibleTranscodingProfile,
                requiresOpening, openToken, requiresClosing, liveStreamId, bufferMs, requiresLooping, supportsProbing,
                videoType, isoType, video3DFormat, mediaStreams, mediaAttachments, formats, bitrate,
                fallbackMaxStreamingBitrate, timestamp, requiredHttpHeaders, transcodingUrl, transcodingSubProtocol,
                transcodingContainer, analyzeDurationMs, defaultAudioStreamIndex, defaultSubtitleStreamIndex,
                hasSegments);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("class MediaSourceInfo {\n");
        sb.append("    protocol: ").append(toIndentedString(protocol)).append("\n");
        sb.append("    id: ").append(toIndentedString(id)).append("\n");
        sb.append("    path: ").append(toIndentedString(path)).append("\n");
        sb.append("    encoderPath: ").append(toIndentedString(encoderPath)).append("\n");
        sb.append("    encoderProtocol: ").append(toIndentedString(encoderProtocol)).append("\n");
        sb.append("    type: ").append(toIndentedString(type)).append("\n");
        sb.append("    container: ").append(toIndentedString(container)).append("\n");
        sb.append("    size: ").append(toIndentedString(size)).append("\n");
        sb.append("    name: ").append(toIndentedString(name)).append("\n");
        sb.append("    isRemote: ").append(toIndentedString(isRemote)).append("\n");
        sb.append("    etag: ").append(toIndentedString(etag)).append("\n");
        sb.append("    runTimeTicks: ").append(toIndentedString(runTimeTicks)).append("\n");
        sb.append("    readAtNativeFramerate: ").append(toIndentedString(readAtNativeFramerate)).append("\n");
        sb.append("    ignoreDts: ").append(toIndentedString(ignoreDts)).append("\n");
        sb.append("    ignoreIndex: ").append(toIndentedString(ignoreIndex)).append("\n");
        sb.append("    genPtsInput: ").append(toIndentedString(genPtsInput)).append("\n");
        sb.append("    supportsTranscoding: ").append(toIndentedString(supportsTranscoding)).append("\n");
        sb.append("    supportsDirectStream: ").append(toIndentedString(supportsDirectStream)).append("\n");
        sb.append("    supportsDirectPlay: ").append(toIndentedString(supportsDirectPlay)).append("\n");
        sb.append("    isInfiniteStream: ").append(toIndentedString(isInfiniteStream)).append("\n");
        sb.append("    useMostCompatibleTranscodingProfile: ")
                .append(toIndentedString(useMostCompatibleTranscodingProfile)).append("\n");
        sb.append("    requiresOpening: ").append(toIndentedString(requiresOpening)).append("\n");
        sb.append("    openToken: ").append(toIndentedString(openToken)).append("\n");
        sb.append("    requiresClosing: ").append(toIndentedString(requiresClosing)).append("\n");
        sb.append("    liveStreamId: ").append(toIndentedString(liveStreamId)).append("\n");
        sb.append("    bufferMs: ").append(toIndentedString(bufferMs)).append("\n");
        sb.append("    requiresLooping: ").append(toIndentedString(requiresLooping)).append("\n");
        sb.append("    supportsProbing: ").append(toIndentedString(supportsProbing)).append("\n");
        sb.append("    videoType: ").append(toIndentedString(videoType)).append("\n");
        sb.append("    isoType: ").append(toIndentedString(isoType)).append("\n");
        sb.append("    video3DFormat: ").append(toIndentedString(video3DFormat)).append("\n");
        sb.append("    mediaStreams: ").append(toIndentedString(mediaStreams)).append("\n");
        sb.append("    mediaAttachments: ").append(toIndentedString(mediaAttachments)).append("\n");
        sb.append("    formats: ").append(toIndentedString(formats)).append("\n");
        sb.append("    bitrate: ").append(toIndentedString(bitrate)).append("\n");
        sb.append("    fallbackMaxStreamingBitrate: ").append(toIndentedString(fallbackMaxStreamingBitrate))
                .append("\n");
        sb.append("    timestamp: ").append(toIndentedString(timestamp)).append("\n");
        sb.append("    requiredHttpHeaders: ").append(toIndentedString(requiredHttpHeaders)).append("\n");
        sb.append("    transcodingUrl: ").append(toIndentedString(transcodingUrl)).append("\n");
        sb.append("    transcodingSubProtocol: ").append(toIndentedString(transcodingSubProtocol)).append("\n");
        sb.append("    transcodingContainer: ").append(toIndentedString(transcodingContainer)).append("\n");
        sb.append("    analyzeDurationMs: ").append(toIndentedString(analyzeDurationMs)).append("\n");
        sb.append("    defaultAudioStreamIndex: ").append(toIndentedString(defaultAudioStreamIndex)).append("\n");
        sb.append("    defaultSubtitleStreamIndex: ").append(toIndentedString(defaultSubtitleStreamIndex)).append("\n");
        sb.append("    hasSegments: ").append(toIndentedString(hasSegments)).append("\n");
        sb.append("}");
        return sb.toString();
    }

    /**
     * Convert the given object to string with each line indented by 4 spaces
     * (except the first line).
     */
    private String toIndentedString(Object o) {
        return o == null ? "null" : o.toString().replace("\n", "\n    ");
    }

    /**
     * Convert the instance into URL query string.
     *
     * @return URL query string
     */
    public String toUrlQueryString() {
        return toUrlQueryString(null);
    }

    /**
     * Convert the instance into URL query string.
     *
     * @param prefix prefix of the query string
     * @return URL query string
     */
    public String toUrlQueryString(String prefix) {
        String suffix = "";
        String containerSuffix = "";
        String containerPrefix = "";
        if (prefix == null) {
            // style=form, explode=true, e.g. /pet?name=cat&type=manx
            prefix = "";
        } else {
            // deepObject style e.g. /pet?id[name]=cat&id[type]=manx
            prefix = prefix + "[";
            suffix = "]";
            containerSuffix = "]";
            containerPrefix = "[";
        }

        StringJoiner joiner = new StringJoiner("&");

        // add `Protocol` to the URL query string
        if (getProtocol() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sProtocol%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getProtocol()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `Id` to the URL query string
        if (getId() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sId%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getId()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `Path` to the URL query string
        if (getPath() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sPath%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getPath()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `EncoderPath` to the URL query string
        if (getEncoderPath() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sEncoderPath%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getEncoderPath()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `EncoderProtocol` to the URL query string
        if (getEncoderProtocol() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sEncoderProtocol%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getEncoderProtocol()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `Type` to the URL query string
        if (getType() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sType%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getType()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `Container` to the URL query string
        if (getContainer() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sContainer%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getContainer()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `Size` to the URL query string
        if (getSize() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sSize%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getSize()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `Name` to the URL query string
        if (getName() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sName%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getName()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `IsRemote` to the URL query string
        if (getIsRemote() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sIsRemote%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getIsRemote()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `ETag` to the URL query string
        if (getEtag() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sETag%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getEtag()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `RunTimeTicks` to the URL query string
        if (getRunTimeTicks() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sRunTimeTicks%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getRunTimeTicks()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `ReadAtNativeFramerate` to the URL query string
        if (getReadAtNativeFramerate() != null) {
            try {
                joiner.add(
                        String.format(java.util.Locale.ROOT, "%sReadAtNativeFramerate%s=%s", prefix, suffix, URLEncoder
                                .encode(String.valueOf(getReadAtNativeFramerate()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `IgnoreDts` to the URL query string
        if (getIgnoreDts() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sIgnoreDts%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getIgnoreDts()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `IgnoreIndex` to the URL query string
        if (getIgnoreIndex() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sIgnoreIndex%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getIgnoreIndex()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `GenPtsInput` to the URL query string
        if (getGenPtsInput() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sGenPtsInput%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getGenPtsInput()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `SupportsTranscoding` to the URL query string
        if (getSupportsTranscoding() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sSupportsTranscoding%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getSupportsTranscoding()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `SupportsDirectStream` to the URL query string
        if (getSupportsDirectStream() != null) {
            try {
                joiner.add(
                        String.format(java.util.Locale.ROOT, "%sSupportsDirectStream%s=%s", prefix, suffix, URLEncoder
                                .encode(String.valueOf(getSupportsDirectStream()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `SupportsDirectPlay` to the URL query string
        if (getSupportsDirectPlay() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sSupportsDirectPlay%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getSupportsDirectPlay()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `IsInfiniteStream` to the URL query string
        if (getIsInfiniteStream() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sIsInfiniteStream%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getIsInfiniteStream()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `UseMostCompatibleTranscodingProfile` to the URL query string
        if (getUseMostCompatibleTranscodingProfile() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sUseMostCompatibleTranscodingProfile%s=%s", prefix,
                        suffix, URLEncoder.encode(String.valueOf(getUseMostCompatibleTranscodingProfile()), "UTF-8")
                                .replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `RequiresOpening` to the URL query string
        if (getRequiresOpening() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sRequiresOpening%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getRequiresOpening()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `OpenToken` to the URL query string
        if (getOpenToken() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sOpenToken%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getOpenToken()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `RequiresClosing` to the URL query string
        if (getRequiresClosing() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sRequiresClosing%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getRequiresClosing()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `LiveStreamId` to the URL query string
        if (getLiveStreamId() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sLiveStreamId%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getLiveStreamId()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `BufferMs` to the URL query string
        if (getBufferMs() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sBufferMs%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getBufferMs()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `RequiresLooping` to the URL query string
        if (getRequiresLooping() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sRequiresLooping%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getRequiresLooping()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `SupportsProbing` to the URL query string
        if (getSupportsProbing() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sSupportsProbing%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getSupportsProbing()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `VideoType` to the URL query string
        if (getVideoType() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sVideoType%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getVideoType()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `IsoType` to the URL query string
        if (getIsoType() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sIsoType%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getIsoType()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `Video3DFormat` to the URL query string
        if (getVideo3DFormat() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sVideo3DFormat%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getVideo3DFormat()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `MediaStreams` to the URL query string
        if (getMediaStreams() != null) {
            for (int i = 0; i < getMediaStreams().size(); i++) {
                if (getMediaStreams().get(i) != null) {
                    joiner.add(getMediaStreams().get(i)
                            .toUrlQueryString(String.format(java.util.Locale.ROOT, "%sMediaStreams%s%s", prefix, suffix,
                                    "".equals(suffix) ? ""
                                            : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i,
                                                    containerSuffix))));
                }
            }
        }

        // add `MediaAttachments` to the URL query string
        if (getMediaAttachments() != null) {
            for (int i = 0; i < getMediaAttachments().size(); i++) {
                if (getMediaAttachments().get(i) != null) {
                    joiner.add(getMediaAttachments().get(i).toUrlQueryString(
                            String.format(java.util.Locale.ROOT, "%sMediaAttachments%s%s", prefix, suffix,
                                    "".equals(suffix) ? ""
                                            : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i,
                                                    containerSuffix))));
                }
            }
        }

        // add `Formats` to the URL query string
        if (getFormats() != null) {
            for (int i = 0; i < getFormats().size(); i++) {
                try {
                    joiner.add(String.format(java.util.Locale.ROOT, "%sFormats%s%s=%s", prefix, suffix,
                            "".equals(suffix) ? ""
                                    : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i,
                                            containerSuffix),
                            URLEncoder.encode(String.valueOf(getFormats().get(i)), "UTF-8").replaceAll("\\+", "%20")));
                } catch (UnsupportedEncodingException e) {
                    // Should never happen, UTF-8 is always supported
                    throw new RuntimeException(e);
                }
            }
        }

        // add `Bitrate` to the URL query string
        if (getBitrate() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sBitrate%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getBitrate()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `FallbackMaxStreamingBitrate` to the URL query string
        if (getFallbackMaxStreamingBitrate() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sFallbackMaxStreamingBitrate%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getFallbackMaxStreamingBitrate()), "UTF-8").replaceAll("\\+",
                                "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `Timestamp` to the URL query string
        if (getTimestamp() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sTimestamp%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getTimestamp()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `RequiredHttpHeaders` to the URL query string
        if (getRequiredHttpHeaders() != null) {
            for (String _key : getRequiredHttpHeaders().keySet()) {
                try {
                    joiner.add(String.format(java.util.Locale.ROOT, "%sRequiredHttpHeaders%s%s=%s", prefix, suffix,
                            "".equals(suffix) ? ""
                                    : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, _key,
                                            containerSuffix),
                            getRequiredHttpHeaders().get(_key),
                            URLEncoder.encode(String.valueOf(getRequiredHttpHeaders().get(_key)), "UTF-8")
                                    .replaceAll("\\+", "%20")));
                } catch (UnsupportedEncodingException e) {
                    // Should never happen, UTF-8 is always supported
                    throw new RuntimeException(e);
                }
            }
        }

        // add `TranscodingUrl` to the URL query string
        if (getTranscodingUrl() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sTranscodingUrl%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getTranscodingUrl()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `TranscodingSubProtocol` to the URL query string
        if (getTranscodingSubProtocol() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sTranscodingSubProtocol%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getTranscodingSubProtocol()), "UTF-8").replaceAll("\\+",
                                "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `TranscodingContainer` to the URL query string
        if (getTranscodingContainer() != null) {
            try {
                joiner.add(
                        String.format(java.util.Locale.ROOT, "%sTranscodingContainer%s=%s", prefix, suffix, URLEncoder
                                .encode(String.valueOf(getTranscodingContainer()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `AnalyzeDurationMs` to the URL query string
        if (getAnalyzeDurationMs() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sAnalyzeDurationMs%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getAnalyzeDurationMs()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `DefaultAudioStreamIndex` to the URL query string
        if (getDefaultAudioStreamIndex() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sDefaultAudioStreamIndex%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getDefaultAudioStreamIndex()), "UTF-8").replaceAll("\\+",
                                "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `DefaultSubtitleStreamIndex` to the URL query string
        if (getDefaultSubtitleStreamIndex() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sDefaultSubtitleStreamIndex%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getDefaultSubtitleStreamIndex()), "UTF-8").replaceAll("\\+",
                                "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `HasSegments` to the URL query string
        if (getHasSegments() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sHasSegments%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getHasSegments()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        return joiner.toString();
    }

    public static class Builder {

        private MediaSourceInfo instance;

        public Builder() {
            this(new MediaSourceInfo());
        }

        protected Builder(MediaSourceInfo instance) {
            this.instance = instance;
        }

        public MediaSourceInfo.Builder protocol(MediaProtocol protocol) {
            this.instance.protocol = protocol;
            return this;
        }

        public MediaSourceInfo.Builder id(String id) {
            this.instance.id = id;
            return this;
        }

        public MediaSourceInfo.Builder path(String path) {
            this.instance.path = path;
            return this;
        }

        public MediaSourceInfo.Builder encoderPath(String encoderPath) {
            this.instance.encoderPath = encoderPath;
            return this;
        }

        public MediaSourceInfo.Builder encoderProtocol(MediaProtocol encoderProtocol) {
            this.instance.encoderProtocol = encoderProtocol;
            return this;
        }

        public MediaSourceInfo.Builder type(MediaSourceType type) {
            this.instance.type = type;
            return this;
        }

        public MediaSourceInfo.Builder container(String container) {
            this.instance.container = container;
            return this;
        }

        public MediaSourceInfo.Builder size(Long size) {
            this.instance.size = size;
            return this;
        }

        public MediaSourceInfo.Builder name(String name) {
            this.instance.name = name;
            return this;
        }

        public MediaSourceInfo.Builder isRemote(Boolean isRemote) {
            this.instance.isRemote = isRemote;
            return this;
        }

        public MediaSourceInfo.Builder etag(String etag) {
            this.instance.etag = etag;
            return this;
        }

        public MediaSourceInfo.Builder runTimeTicks(Long runTimeTicks) {
            this.instance.runTimeTicks = runTimeTicks;
            return this;
        }

        public MediaSourceInfo.Builder readAtNativeFramerate(Boolean readAtNativeFramerate) {
            this.instance.readAtNativeFramerate = readAtNativeFramerate;
            return this;
        }

        public MediaSourceInfo.Builder ignoreDts(Boolean ignoreDts) {
            this.instance.ignoreDts = ignoreDts;
            return this;
        }

        public MediaSourceInfo.Builder ignoreIndex(Boolean ignoreIndex) {
            this.instance.ignoreIndex = ignoreIndex;
            return this;
        }

        public MediaSourceInfo.Builder genPtsInput(Boolean genPtsInput) {
            this.instance.genPtsInput = genPtsInput;
            return this;
        }

        public MediaSourceInfo.Builder supportsTranscoding(Boolean supportsTranscoding) {
            this.instance.supportsTranscoding = supportsTranscoding;
            return this;
        }

        public MediaSourceInfo.Builder supportsDirectStream(Boolean supportsDirectStream) {
            this.instance.supportsDirectStream = supportsDirectStream;
            return this;
        }

        public MediaSourceInfo.Builder supportsDirectPlay(Boolean supportsDirectPlay) {
            this.instance.supportsDirectPlay = supportsDirectPlay;
            return this;
        }

        public MediaSourceInfo.Builder isInfiniteStream(Boolean isInfiniteStream) {
            this.instance.isInfiniteStream = isInfiniteStream;
            return this;
        }

        public MediaSourceInfo.Builder useMostCompatibleTranscodingProfile(
                Boolean useMostCompatibleTranscodingProfile) {
            this.instance.useMostCompatibleTranscodingProfile = useMostCompatibleTranscodingProfile;
            return this;
        }

        public MediaSourceInfo.Builder requiresOpening(Boolean requiresOpening) {
            this.instance.requiresOpening = requiresOpening;
            return this;
        }

        public MediaSourceInfo.Builder openToken(String openToken) {
            this.instance.openToken = openToken;
            return this;
        }

        public MediaSourceInfo.Builder requiresClosing(Boolean requiresClosing) {
            this.instance.requiresClosing = requiresClosing;
            return this;
        }

        public MediaSourceInfo.Builder liveStreamId(String liveStreamId) {
            this.instance.liveStreamId = liveStreamId;
            return this;
        }

        public MediaSourceInfo.Builder bufferMs(Integer bufferMs) {
            this.instance.bufferMs = bufferMs;
            return this;
        }

        public MediaSourceInfo.Builder requiresLooping(Boolean requiresLooping) {
            this.instance.requiresLooping = requiresLooping;
            return this;
        }

        public MediaSourceInfo.Builder supportsProbing(Boolean supportsProbing) {
            this.instance.supportsProbing = supportsProbing;
            return this;
        }

        public MediaSourceInfo.Builder videoType(VideoType videoType) {
            this.instance.videoType = videoType;
            return this;
        }

        public MediaSourceInfo.Builder isoType(IsoType isoType) {
            this.instance.isoType = isoType;
            return this;
        }

        public MediaSourceInfo.Builder video3DFormat(Video3DFormat video3DFormat) {
            this.instance.video3DFormat = video3DFormat;
            return this;
        }

        public MediaSourceInfo.Builder mediaStreams(List<MediaStream> mediaStreams) {
            this.instance.mediaStreams = mediaStreams;
            return this;
        }

        public MediaSourceInfo.Builder mediaAttachments(List<MediaAttachment> mediaAttachments) {
            this.instance.mediaAttachments = mediaAttachments;
            return this;
        }

        public MediaSourceInfo.Builder formats(List<String> formats) {
            this.instance.formats = formats;
            return this;
        }

        public MediaSourceInfo.Builder bitrate(Integer bitrate) {
            this.instance.bitrate = bitrate;
            return this;
        }

        public MediaSourceInfo.Builder fallbackMaxStreamingBitrate(Integer fallbackMaxStreamingBitrate) {
            this.instance.fallbackMaxStreamingBitrate = fallbackMaxStreamingBitrate;
            return this;
        }

        public MediaSourceInfo.Builder timestamp(TransportStreamTimestamp timestamp) {
            this.instance.timestamp = timestamp;
            return this;
        }

        public MediaSourceInfo.Builder requiredHttpHeaders(Map<String, String> requiredHttpHeaders) {
            this.instance.requiredHttpHeaders = requiredHttpHeaders;
            return this;
        }

        public MediaSourceInfo.Builder transcodingUrl(String transcodingUrl) {
            this.instance.transcodingUrl = transcodingUrl;
            return this;
        }

        public MediaSourceInfo.Builder transcodingSubProtocol(MediaStreamProtocol transcodingSubProtocol) {
            this.instance.transcodingSubProtocol = transcodingSubProtocol;
            return this;
        }

        public MediaSourceInfo.Builder transcodingContainer(String transcodingContainer) {
            this.instance.transcodingContainer = transcodingContainer;
            return this;
        }

        public MediaSourceInfo.Builder analyzeDurationMs(Integer analyzeDurationMs) {
            this.instance.analyzeDurationMs = analyzeDurationMs;
            return this;
        }

        public MediaSourceInfo.Builder defaultAudioStreamIndex(Integer defaultAudioStreamIndex) {
            this.instance.defaultAudioStreamIndex = defaultAudioStreamIndex;
            return this;
        }

        public MediaSourceInfo.Builder defaultSubtitleStreamIndex(Integer defaultSubtitleStreamIndex) {
            this.instance.defaultSubtitleStreamIndex = defaultSubtitleStreamIndex;
            return this;
        }

        public MediaSourceInfo.Builder hasSegments(Boolean hasSegments) {
            this.instance.hasSegments = hasSegments;
            return this;
        }

        /**
         * returns a built MediaSourceInfo instance.
         *
         * The builder is not reusable.
         */
        public MediaSourceInfo build() {
            try {
                return this.instance;
            } finally {
                // ensure that this.instance is not reused
                this.instance = null;
            }
        }

        @Override
        public String toString() {
            return getClass() + "=(" + instance + ")";
        }
    }

    /**
     * Create a builder with no initialized field.
     */
    public static MediaSourceInfo.Builder builder() {
        return new MediaSourceInfo.Builder();
    }

    /**
     * Create a builder with a shallow copy of this instance.
     */
    public MediaSourceInfo.Builder toBuilder() {
        return new MediaSourceInfo.Builder().protocol(getProtocol()).id(getId()).path(getPath())
                .encoderPath(getEncoderPath()).encoderProtocol(getEncoderProtocol()).type(getType())
                .container(getContainer()).size(getSize()).name(getName()).isRemote(getIsRemote()).etag(getEtag())
                .runTimeTicks(getRunTimeTicks()).readAtNativeFramerate(getReadAtNativeFramerate())
                .ignoreDts(getIgnoreDts()).ignoreIndex(getIgnoreIndex()).genPtsInput(getGenPtsInput())
                .supportsTranscoding(getSupportsTranscoding()).supportsDirectStream(getSupportsDirectStream())
                .supportsDirectPlay(getSupportsDirectPlay()).isInfiniteStream(getIsInfiniteStream())
                .useMostCompatibleTranscodingProfile(getUseMostCompatibleTranscodingProfile())
                .requiresOpening(getRequiresOpening()).openToken(getOpenToken()).requiresClosing(getRequiresClosing())
                .liveStreamId(getLiveStreamId()).bufferMs(getBufferMs()).requiresLooping(getRequiresLooping())
                .supportsProbing(getSupportsProbing()).videoType(getVideoType()).isoType(getIsoType())
                .video3DFormat(getVideo3DFormat()).mediaStreams(getMediaStreams())
                .mediaAttachments(getMediaAttachments()).formats(getFormats()).bitrate(getBitrate())
                .fallbackMaxStreamingBitrate(getFallbackMaxStreamingBitrate()).timestamp(getTimestamp())
                .requiredHttpHeaders(getRequiredHttpHeaders()).transcodingUrl(getTranscodingUrl())
                .transcodingSubProtocol(getTranscodingSubProtocol()).transcodingContainer(getTranscodingContainer())
                .analyzeDurationMs(getAnalyzeDurationMs()).defaultAudioStreamIndex(getDefaultAudioStreamIndex())
                .defaultSubtitleStreamIndex(getDefaultSubtitleStreamIndex()).hasSegments(getHasSegments());
    }
}
