diff --git a/conference-to-stream/.env.example b/conference-to-stream/.env.example new file mode 100644 index 0000000..0104e3b --- /dev/null +++ b/conference-to-stream/.env.example @@ -0,0 +1,14 @@ +# Fishjam ID or full URL (e.g. your-id or https://fishjam.io/api/v1/connect/your-id) +FISHJAM_ID=your-fishjam-id + +# Fishjam management token +FISHJAM_MANAGEMENT_TOKEN=your-management-token + +# Composition API base URL (default: https://sandbox-rtc.fishjam.io) +COMPOSITION_API_URL=https://sandbox-rtc.fishjam.io + +# Backend port (default: 8080) +PORT=8080 + +# Frontend: backend URL +VITE_BACKEND_URL=http://localhost:8080 diff --git a/conference-to-stream/.gitignore b/conference-to-stream/.gitignore new file mode 100644 index 0000000..abbbc77 --- /dev/null +++ b/conference-to-stream/.gitignore @@ -0,0 +1,2 @@ +# Env file +.env diff --git a/conference-to-stream/README.md b/conference-to-stream/README.md new file mode 100644 index 0000000..c5e033e --- /dev/null +++ b/conference-to-stream/README.md @@ -0,0 +1,281 @@ +# Go API client for openapi + +Real-time video compositing + +## Overview +This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the [OpenAPI-spec](https://www.openapis.org/) from a remote server, you can easily generate an API client. + +- API version: 0.1.0 +- Package version: 1.0.0 +- Generator version: 7.20.0 +- Build package: org.openapitools.codegen.languages.GoClientCodegen + +## Installation + +Install the following dependencies: + +```sh +go get github.com/stretchr/testify/assert +go get golang.org/x/net/context +``` + +Put the package under your project folder and add the following in import: + +```go +import openapi "github.com/GIT_USER_ID/GIT_REPO_ID" +``` + +To use a proxy, set the environment variable `HTTP_PROXY`: + +```go +os.Setenv("HTTP_PROXY", "http://proxy_name:proxy_port") +``` + +## Configuration of Server URL + +Default configuration comes with `Servers` field that contains server objects as defined in the OpenAPI specification. + +### Select Server Configuration + +For using other server than the one defined on index 0 set context value `openapi.ContextServerIndex` of type `int`. + +```go +ctx := context.WithValue(context.Background(), openapi.ContextServerIndex, 1) +``` + +### Templated Server URL + +Templated server URL is formatted using default variables from configuration or from context value `openapi.ContextServerVariables` of type `map[string]string`. + +```go +ctx := context.WithValue(context.Background(), openapi.ContextServerVariables, map[string]string{ + "basePath": "v2", +}) +``` + +Note, enum values are always validated and all unused variables are silently ignored. + +### URLs Configuration per Operation + +Each operation can use different server URL defined using `OperationServers` map in the `Configuration`. +An operation is uniquely identified by `"{classname}Service.{nickname}"` string. +Similar rules for overriding default operation server index and variables applies by using `openapi.ContextOperationServerIndices` and `openapi.ContextOperationServerVariables` context maps. + +```go +ctx := context.WithValue(context.Background(), openapi.ContextOperationServerIndices, map[string]int{ + "{classname}Service.{nickname}": 2, +}) +ctx = context.WithValue(context.Background(), openapi.ContextOperationServerVariables, map[string]map[string]string{ + "{classname}Service.{nickname}": { + "port": "8443", + }, +}) +``` + +## Documentation for API Endpoints + +All URIs are relative to *https://rtc.fishjam.io* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*CompositionAPI* | [**CreateComposition**](docs/CompositionAPI.md#createcomposition) | **Post** /api/composition | +*CompositionAPI* | [**DeleteComposition**](docs/CompositionAPI.md#deletecomposition) | **Delete** /api/composition/{composition_id} | +*ControlRequestAPI* | [**Reset**](docs/ControlRequestAPI.md#reset) | **Post** /api/composition/{composition_id}/reset | +*ControlRequestAPI* | [**Start**](docs/ControlRequestAPI.md#start) | **Post** /api/composition/{composition_id}/start | +*RegisterRequestAPI* | [**RegisterFont**](docs/RegisterRequestAPI.md#registerfont) | **Post** /api/composition/{composition_id}/font/register | +*RegisterRequestAPI* | [**RegisterImage**](docs/RegisterRequestAPI.md#registerimage) | **Post** /api/composition/{composition_id}/image/{image_id}/register | +*RegisterRequestAPI* | [**RegisterInput**](docs/RegisterRequestAPI.md#registerinput) | **Post** /api/composition/{composition_id}/input/{input_id}/register | +*RegisterRequestAPI* | [**RegisterOutput**](docs/RegisterRequestAPI.md#registeroutput) | **Post** /api/composition/{composition_id}/output/{output_id}/register | +*UnregisterRequestAPI* | [**UnregisterImage**](docs/UnregisterRequestAPI.md#unregisterimage) | **Post** /api/composition/{composition_id}/image/{image_id}/unregister | +*UnregisterRequestAPI* | [**UnregisterInput**](docs/UnregisterRequestAPI.md#unregisterinput) | **Post** /api/composition/{composition_id}/input/{input_id}/unregister | +*UnregisterRequestAPI* | [**UnregisterOutput**](docs/UnregisterRequestAPI.md#unregisteroutput) | **Post** /api/composition/{composition_id}/output/{output_id}/unregister | +*UpdateRequestAPI* | [**RequestKeyframe**](docs/UpdateRequestAPI.md#requestkeyframe) | **Post** /api/composition/{composition_id}/output/{output_id}/request_keyframe | +*UpdateRequestAPI* | [**UpdateOutput**](docs/UpdateRequestAPI.md#updateoutput) | **Post** /api/composition/{composition_id}/output/{output_id}/update | +*WhipWhepAPI* | [**WhepOffer**](docs/WhipWhepAPI.md#whepoffer) | **Post** /api/composition/{composition_id}/whep/{output_id} | +*WhipWhepAPI* | [**WhipOffer**](docs/WhipWhepAPI.md#whipoffer) | **Post** /api/composition/{composition_id}/whip/{input_id} | + + +## Documentation For Models + + - [AacRtpMode](docs/AacRtpMode.md) + - [ApiError](docs/ApiError.md) + - [AudioChannels](docs/AudioChannels.md) + - [AudioMixingStrategy](docs/AudioMixingStrategy.md) + - [AudioScene](docs/AudioScene.md) + - [AudioSceneInput](docs/AudioSceneInput.md) + - [BoxShadow](docs/BoxShadow.md) + - [Component](docs/Component.md) + - [ComponentOneOf](docs/ComponentOneOf.md) + - [ComponentOneOf1](docs/ComponentOneOf1.md) + - [ComponentOneOf2](docs/ComponentOneOf2.md) + - [ComponentOneOf3](docs/ComponentOneOf3.md) + - [ComponentOneOf4](docs/ComponentOneOf4.md) + - [CompositionCreatedResponse](docs/CompositionCreatedResponse.md) + - [CreateCompositionRequest](docs/CreateCompositionRequest.md) + - [EasingFunction](docs/EasingFunction.md) + - [EasingFunctionOneOf](docs/EasingFunctionOneOf.md) + - [EasingFunctionOneOf1](docs/EasingFunctionOneOf1.md) + - [EasingFunctionOneOf2](docs/EasingFunctionOneOf2.md) + - [FontUpload](docs/FontUpload.md) + - [Framerate](docs/Framerate.md) + - [H264EncoderPreset](docs/H264EncoderPreset.md) + - [HlsAudioEncoderOptions](docs/HlsAudioEncoderOptions.md) + - [HlsInput](docs/HlsInput.md) + - [HlsOutput](docs/HlsOutput.md) + - [HlsVideoDecoderOptions](docs/HlsVideoDecoderOptions.md) + - [HlsVideoEncoderOptions](docs/HlsVideoEncoderOptions.md) + - [HlsVideoEncoderOptionsOneOf](docs/HlsVideoEncoderOptionsOneOf.md) + - [HlsVideoEncoderOptionsOneOf1](docs/HlsVideoEncoderOptionsOneOf1.md) + - [HorizontalAlign](docs/HorizontalAlign.md) + - [ImageSpec](docs/ImageSpec.md) + - [ImageSpecOneOf](docs/ImageSpecOneOf.md) + - [ImageSpecOneOf1](docs/ImageSpecOneOf1.md) + - [ImageSpecOneOf2](docs/ImageSpecOneOf2.md) + - [ImageSpecOneOf3](docs/ImageSpecOneOf3.md) + - [ImageSpecOneOf4](docs/ImageSpecOneOf4.md) + - [InputHlsCodec](docs/InputHlsCodec.md) + - [InputMp4Codec](docs/InputMp4Codec.md) + - [InputRtmpCodec](docs/InputRtmpCodec.md) + - [InputRtpAudioOptions](docs/InputRtpAudioOptions.md) + - [InputRtpAudioOptionsOneOf](docs/InputRtpAudioOptionsOneOf.md) + - [InputRtpAudioOptionsOneOf1](docs/InputRtpAudioOptionsOneOf1.md) + - [InputRtpVideoOptions](docs/InputRtpVideoOptions.md) + - [InputStream](docs/InputStream.md) + - [InputWhepVideoOptions](docs/InputWhepVideoOptions.md) + - [InputWhipVideoOptions](docs/InputWhipVideoOptions.md) + - [Interpolation](docs/Interpolation.md) + - [Mp4AudioEncoderOptions](docs/Mp4AudioEncoderOptions.md) + - [Mp4Input](docs/Mp4Input.md) + - [Mp4Output](docs/Mp4Output.md) + - [Mp4VideoDecoderOptions](docs/Mp4VideoDecoderOptions.md) + - [Mp4VideoEncoderOptions](docs/Mp4VideoEncoderOptions.md) + - [Mp4VideoEncoderOptionsOneOf](docs/Mp4VideoEncoderOptionsOneOf.md) + - [OpusEncoderPreset](docs/OpusEncoderPreset.md) + - [OutputEndCondition](docs/OutputEndCondition.md) + - [OutputHlsAudioOptions](docs/OutputHlsAudioOptions.md) + - [OutputHlsVideoOptions](docs/OutputHlsVideoOptions.md) + - [OutputMp4AudioOptions](docs/OutputMp4AudioOptions.md) + - [OutputMp4VideoOptions](docs/OutputMp4VideoOptions.md) + - [OutputRtmpClientAudioOptions](docs/OutputRtmpClientAudioOptions.md) + - [OutputRtmpClientVideoOptions](docs/OutputRtmpClientVideoOptions.md) + - [OutputRtpAudioOptions](docs/OutputRtpAudioOptions.md) + - [OutputRtpVideoOptions](docs/OutputRtpVideoOptions.md) + - [OutputWhepAudioOptions](docs/OutputWhepAudioOptions.md) + - [OutputWhepVideoOptions](docs/OutputWhepVideoOptions.md) + - [OutputWhipAudioOptions](docs/OutputWhipAudioOptions.md) + - [OutputWhipVideoOptions](docs/OutputWhipVideoOptions.md) + - [Overflow](docs/Overflow.md) + - [PixelFormat](docs/PixelFormat.md) + - [PortOrPortRange](docs/PortOrPortRange.md) + - [RegisterInput](docs/RegisterInput.md) + - [RegisterInputOneOf](docs/RegisterInputOneOf.md) + - [RegisterInputOneOf1](docs/RegisterInputOneOf1.md) + - [RegisterInputOneOf2](docs/RegisterInputOneOf2.md) + - [RegisterInputOneOf3](docs/RegisterInputOneOf3.md) + - [RegisterInputOneOf4](docs/RegisterInputOneOf4.md) + - [RegisterInputOneOf5](docs/RegisterInputOneOf5.md) + - [RegisterOutput](docs/RegisterOutput.md) + - [RegisterOutputOneOf](docs/RegisterOutputOneOf.md) + - [RegisterOutputOneOf1](docs/RegisterOutputOneOf1.md) + - [RegisterOutputOneOf2](docs/RegisterOutputOneOf2.md) + - [RegisterOutputOneOf3](docs/RegisterOutputOneOf3.md) + - [RegisterOutputOneOf4](docs/RegisterOutputOneOf4.md) + - [RegisterOutputOneOf5](docs/RegisterOutputOneOf5.md) + - [RescaleMode](docs/RescaleMode.md) + - [Rescaler](docs/Rescaler.md) + - [Resolution](docs/Resolution.md) + - [Response](docs/Response.md) + - [ResponseOneOf](docs/ResponseOneOf.md) + - [ResponseOneOf1](docs/ResponseOneOf1.md) + - [ResponseOneOf2](docs/ResponseOneOf2.md) + - [RtmpClientAudioEncoderOptions](docs/RtmpClientAudioEncoderOptions.md) + - [RtmpClientVideoEncoderOptions](docs/RtmpClientVideoEncoderOptions.md) + - [RtmpInput](docs/RtmpInput.md) + - [RtmpOutput](docs/RtmpOutput.md) + - [RtmpVideoDecoderOptions](docs/RtmpVideoDecoderOptions.md) + - [RtpAudioEncoderOptions](docs/RtpAudioEncoderOptions.md) + - [RtpInput](docs/RtpInput.md) + - [RtpOutput](docs/RtpOutput.md) + - [RtpVideoDecoderOptions](docs/RtpVideoDecoderOptions.md) + - [RtpVideoEncoderOptions](docs/RtpVideoEncoderOptions.md) + - [RtpVideoEncoderOptionsOneOf](docs/RtpVideoEncoderOptionsOneOf.md) + - [RtpVideoEncoderOptionsOneOf1](docs/RtpVideoEncoderOptionsOneOf1.md) + - [RtpVideoEncoderOptionsOneOf2](docs/RtpVideoEncoderOptionsOneOf2.md) + - [ShaderParam](docs/ShaderParam.md) + - [ShaderParamOneOf](docs/ShaderParamOneOf.md) + - [ShaderParamOneOf1](docs/ShaderParamOneOf1.md) + - [ShaderParamOneOf2](docs/ShaderParamOneOf2.md) + - [ShaderParamOneOf3](docs/ShaderParamOneOf3.md) + - [ShaderParamOneOf4](docs/ShaderParamOneOf4.md) + - [ShaderParamStructField](docs/ShaderParamStructField.md) + - [ShaderSpec](docs/ShaderSpec.md) + - [Text](docs/Text.md) + - [TextStyle](docs/TextStyle.md) + - [TextWeight](docs/TextWeight.md) + - [TextWrapMode](docs/TextWrapMode.md) + - [Tiles](docs/Tiles.md) + - [Transition](docs/Transition.md) + - [TransportProtocol](docs/TransportProtocol.md) + - [UnregisterInput](docs/UnregisterInput.md) + - [UnregisterOutput](docs/UnregisterOutput.md) + - [UnregisterRenderer](docs/UnregisterRenderer.md) + - [UpdateOutputRequest](docs/UpdateOutputRequest.md) + - [VerticalAlign](docs/VerticalAlign.md) + - [VideoEncoderBitrate](docs/VideoEncoderBitrate.md) + - [VideoEncoderBitrateOneOf](docs/VideoEncoderBitrateOneOf.md) + - [VideoScene](docs/VideoScene.md) + - [View](docs/View.md) + - [ViewDirection](docs/ViewDirection.md) + - [WhepAudioEncoderOptions](docs/WhepAudioEncoderOptions.md) + - [WhepInput](docs/WhepInput.md) + - [WhepOutput](docs/WhepOutput.md) + - [WhepVideoDecoderOptions](docs/WhepVideoDecoderOptions.md) + - [WhepVideoEncoderOptions](docs/WhepVideoEncoderOptions.md) + - [WhipAudioEncoderOptions](docs/WhipAudioEncoderOptions.md) + - [WhipAudioEncoderOptionsOneOf](docs/WhipAudioEncoderOptionsOneOf.md) + - [WhipAudioEncoderOptionsOneOf1](docs/WhipAudioEncoderOptionsOneOf1.md) + - [WhipInput](docs/WhipInput.md) + - [WhipOutput](docs/WhipOutput.md) + - [WhipVideoDecoderOptions](docs/WhipVideoDecoderOptions.md) + - [WhipVideoEncoderOptions](docs/WhipVideoEncoderOptions.md) + - [WhipVideoEncoderOptionsOneOf](docs/WhipVideoEncoderOptionsOneOf.md) + - [WhipVideoEncoderOptionsOneOf1](docs/WhipVideoEncoderOptionsOneOf1.md) + - [WhipVideoEncoderOptionsOneOf2](docs/WhipVideoEncoderOptionsOneOf2.md) + + +## Documentation For Authorization + + +Authentication schemes defined for the API: +### BearerAuth + +- **Type**: HTTP Bearer token authentication + +Example + +```go +auth := context.WithValue(context.Background(), openapi.ContextAccessToken, "BEARER_TOKEN_STRING") +r, err := client.Service.Operation(auth, args) +``` + + +## Documentation for Utility Methods + +Due to the fact that model structure members are all pointers, this package contains +a number of utility functions to easily obtain pointers to values of basic types. +Each of these functions takes a value of the given basic type and returns a pointer to it: + +* `PtrBool` +* `PtrInt` +* `PtrInt32` +* `PtrInt64` +* `PtrFloat` +* `PtrFloat32` +* `PtrFloat64` +* `PtrString` +* `PtrTime` + +## Author + + + diff --git a/conference-to-stream/api/openapi.yaml b/conference-to-stream/api/openapi.yaml new file mode 100644 index 0000000..646a397 --- /dev/null +++ b/conference-to-stream/api/openapi.yaml @@ -0,0 +1,3255 @@ +openapi: 3.1.0 +info: + description: Real-time video compositing + license: + name: Apache 2.0 + title: Composition API + version: 0.1.0 +servers: +- url: https://rtc.fishjam.io +paths: + /api/composition: + post: + operationId: create_composition + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/CreateCompositionRequest" + description: Composition creation options. + required: true + responses: + "201": + content: + application/json: + schema: + $ref: "#/components/schemas/CompositionCreatedResponse" + description: Composition created. + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Internal server error. + tags: + - composition + /api/composition/{composition_id}: + delete: + operationId: delete_composition + parameters: + - description: Composition ID. + explode: false + in: path + name: composition_id + required: true + schema: + type: string + style: simple + responses: + "200": + description: Composition deleted. + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Composition not found. + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Internal server error. + tags: + - composition + /api/composition/{composition_id}/start: + post: + operationId: start + parameters: + - description: Composition ID. + explode: false + in: path + name: composition_id + required: true + schema: + type: string + style: simple + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Response" + description: Composition started. + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Composition not found. + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Internal server error. + tags: + - control_request + /api/composition/{composition_id}/reset: + post: + operationId: reset + parameters: + - description: Composition ID. + explode: false + in: path + name: composition_id + required: true + schema: + type: string + style: simple + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Response" + description: Composition reset. + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Composition not found. + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Internal server error. + tags: + - control_request + /api/composition/{composition_id}/input/{input_id}/register: + post: + operationId: register_input + parameters: + - description: Composition ID. + explode: false + in: path + name: composition_id + required: true + schema: + type: string + style: simple + - description: Input ID. + explode: false + in: path + name: input_id + required: true + schema: + type: string + style: simple + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/RegisterInput" + required: true + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Response" + description: Input registered successfully. + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Bad request. + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Composition not found. + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Internal server error. + tags: + - register_request + /api/composition/{composition_id}/output/{output_id}/register: + post: + operationId: register_output + parameters: + - description: Composition ID. + explode: false + in: path + name: composition_id + required: true + schema: + type: string + style: simple + - description: Output ID. + explode: false + in: path + name: output_id + required: true + schema: + type: string + style: simple + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/RegisterOutput" + required: true + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Response" + description: Output registered successfully. + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Bad request. + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Composition not found. + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Internal server error. + tags: + - register_request + /api/composition/{composition_id}/image/{image_id}/register: + post: + operationId: register_image + parameters: + - description: Composition ID. + explode: false + in: path + name: composition_id + required: true + schema: + type: string + style: simple + - description: Image ID. + explode: false + in: path + name: image_id + required: true + schema: + type: string + style: simple + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/ImageSpec" + required: true + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Response" + description: Image registered successfully. + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Bad request. + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Composition not found. + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Internal server error. + tags: + - register_request + /api/composition/{composition_id}/font/register: + post: + operationId: register_font + parameters: + - description: Composition ID. + explode: false + in: path + name: composition_id + required: true + schema: + type: string + style: simple + requestBody: + content: + multipart/form-data: + schema: + $ref: "#/components/schemas/register_font_request" + required: true + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Response" + description: Font registered successfully. + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Bad request. + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Composition not found. + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Internal server error. + tags: + - register_request + /api/composition/{composition_id}/input/{input_id}/unregister: + post: + operationId: unregister_input + parameters: + - description: Composition ID. + explode: false + in: path + name: composition_id + required: true + schema: + type: string + style: simple + - description: Input ID. + explode: false + in: path + name: input_id + required: true + schema: + type: string + style: simple + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/UnregisterInput" + required: true + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Response" + description: Input unregistered successfully. + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Bad request. + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Input not found. + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Internal server error. + tags: + - unregister_request + /api/composition/{composition_id}/output/{output_id}/unregister: + post: + operationId: unregister_output + parameters: + - description: Composition ID. + explode: false + in: path + name: composition_id + required: true + schema: + type: string + style: simple + - description: Output ID. + explode: false + in: path + name: output_id + required: true + schema: + type: string + style: simple + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/UnregisterOutput" + required: true + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Response" + description: Output unregistered successfully. + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Bad request. + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Output not found. + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Internal server error. + tags: + - unregister_request + /api/composition/{composition_id}/image/{image_id}/unregister: + post: + operationId: unregister_image + parameters: + - description: Composition ID. + explode: false + in: path + name: composition_id + required: true + schema: + type: string + style: simple + - description: Image ID. + explode: false + in: path + name: image_id + required: true + schema: + type: string + style: simple + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/UnregisterRenderer" + required: true + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Response" + description: Image unregistered successfully. + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Bad request. + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Image not found. + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Internal server error. + tags: + - unregister_request + /api/composition/{composition_id}/output/{output_id}/update: + post: + operationId: update_output + parameters: + - description: Composition ID. + explode: false + in: path + name: composition_id + required: true + schema: + type: string + style: simple + - description: Output ID. + explode: false + in: path + name: output_id + required: true + schema: + type: string + style: simple + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/UpdateOutputRequest" + required: true + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Response" + description: Output updated successfully. + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Bad request. + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Composition not found. + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Internal server error. + tags: + - update_request + /api/composition/{composition_id}/output/{output_id}/request_keyframe: + post: + operationId: request_keyframe + parameters: + - description: Composition ID. + explode: false + in: path + name: composition_id + required: true + schema: + type: string + style: simple + - description: Output ID. + explode: false + in: path + name: output_id + required: true + schema: + type: string + style: simple + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Response" + description: Keyframe request successful. + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Bad request. + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Composition not found. + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Internal server error. + tags: + - update_request + /api/composition/{composition_id}/whip/{input_id}: + post: + operationId: whip_offer + parameters: + - description: Composition ID. + explode: false + in: path + name: composition_id + required: true + schema: + type: string + style: simple + - description: Input ID. + explode: false + in: path + name: input_id + required: true + schema: + type: string + style: simple + requestBody: + content: + application/sdp: + schema: + type: string + description: SDP offer. + required: true + responses: + "201": + content: + application/sdp: + schema: + type: string + description: Session created. + headers: + location: + description: Session URL. + explode: false + schema: + type: string + style: simple + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Bad request. + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Unauthorized. + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Composition or input not found. + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Internal server error. + security: + - BearerAuth: [] + tags: + - whip_whep + /api/composition/{composition_id}/whep/{output_id}: + post: + operationId: whep_offer + parameters: + - description: Composition ID. + explode: false + in: path + name: composition_id + required: true + schema: + type: string + style: simple + - description: Output ID. + explode: false + in: path + name: output_id + required: true + schema: + type: string + style: simple + requestBody: + content: + application/sdp: + schema: + type: string + description: SDP offer. + required: true + responses: + "201": + content: + application/sdp: + schema: + type: string + description: Session created. + headers: + location: + description: Session URL. + explode: false + schema: + type: string + style: simple + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Bad request. + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Unauthorized. + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Composition or output not found. + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiError" + description: Internal server error. + security: + - {} + - BearerAuth: [] + tags: + - whip_whep +components: + schemas: + AacRtpMode: + enum: + - low_bitrate + - high_bitrate + type: string + ApiError: + example: + http_status_code: 0 + message: message + properties: + message: + type: string + http_status_code: + format: int32 + minimum: 0 + type: integer + required: + - http_status_code + - message + AspectRatio: + type: string + AudioChannels: + enum: + - mono + - stereo + type: string + AudioMixingStrategy: + enum: + - sum_clip + - sum_scale + type: string + AudioScene: + additionalProperties: false + properties: + inputs: + items: + $ref: "#/components/schemas/AudioSceneInput" + type: array + required: + - inputs + AudioSceneInput: + additionalProperties: false + properties: + input_id: + type: string + volume: + description: "(**default=`1.0`**) float in `[0, 2]` range representing input\ + \ volume" + format: float + nullable: true + type: number + required: + - input_id + BoxShadow: + additionalProperties: false + properties: + offset_x: + format: float + nullable: true + type: number + offset_y: + format: float + nullable: true + type: number + color: + allOf: + - $ref: "#/components/schemas/RGBAColor" + nullable: true + blur_radius: + format: float + nullable: true + type: number + Component: + oneOf: + - $ref: "#/components/schemas/Component_oneOf" + - $ref: "#/components/schemas/Component_oneOf_1" + - $ref: "#/components/schemas/Component_oneOf_2" + - $ref: "#/components/schemas/Component_oneOf_3" + - $ref: "#/components/schemas/Component_oneOf_4" + ComponentId: + type: string + CompositionCreatedResponse: + example: + api_url: api_url + composition_id: composition_id + properties: + composition_id: + type: string + api_url: + type: string + required: + - api_url + - composition_id + CompositionId: + type: string + CreateCompositionRequest: + example: + autostart: true + properties: + autostart: + default: true + description: |- + If true, outputs will immediately start producing audio and video. + If false, call `POST /api/composition/{composition_id}/start` to start the composition. + type: boolean + EasingFunction: + description: |- + Easing functions are used to interpolate between two values over time. + + Custom easing functions can be implemented with cubic Bézier. + The control points are defined with `points` field by providing four numerical values: `x1`, `y1`, `x2` and `y2`. The `x1` and `x2` values have to be in the range `[0; 1]`. The cubic Bézier result is clamped to the range `[0; 1]`. + You can find example control point configurations [here](https://easings.net/). + oneOf: + - $ref: "#/components/schemas/EasingFunction_oneOf" + - $ref: "#/components/schemas/EasingFunction_oneOf_1" + - $ref: "#/components/schemas/EasingFunction_oneOf_2" + FontUpload: + properties: + font: + format: binary + type: string + required: + - font + Framerate: + oneOf: + - type: string + - format: int32 + minimum: 0 + type: integer + H264EncoderPreset: + enum: + - ultrafast + - superfast + - veryfast + - faster + - fast + - medium + - slow + - slower + - veryslow + - placebo + type: string + HlsAudioEncoderOptions: + properties: + sample_rate: + description: "(**default=`44100`**) Sample rate. Allowed values: [8000,\ + \ 16000, 24000, 44100, 48000]." + format: int32 + minimum: 0 + nullable: true + type: integer + type: + enum: + - aac + type: string + required: + - type + HlsInput: + additionalProperties: false + description: Parameters for an input stream from HLS source. + properties: + url: + description: URL to HLS playlist + type: string + required: + description: |- + (**default=`false`**) If input is required and the stream is not delivered + on time, then Smelter will delay producing output frames. + nullable: true + type: boolean + offset_ms: + description: |- + Offset in milliseconds relative to the pipeline start (start request). If the offset is + not defined then the stream will be synchronized based on the delivery time of the initial + frames. + format: double + nullable: true + type: number + required: + - url + HlsOutput: + additionalProperties: false + properties: + path: + description: Path to output HLS playlist. + type: string + max_playlist_size: + description: |- + Number of segments kept in the playlist. When the limit is reached the oldest segment is removed. + If not specified, no segments will removed. + minimum: 0 + nullable: true + type: integer + video: + allOf: + - $ref: "#/components/schemas/OutputHlsVideoOptions" + description: Video track configuration. + nullable: true + audio: + allOf: + - $ref: "#/components/schemas/OutputHlsAudioOptions" + description: Audio track configuration. + nullable: true + required: + - path + HlsVideoDecoderOptions: + enum: + - ffmpeg_h264 + - vulkan_h264 + type: string + HlsVideoEncoderOptions: + oneOf: + - $ref: "#/components/schemas/HlsVideoEncoderOptions_oneOf" + - $ref: "#/components/schemas/HlsVideoEncoderOptions_oneOf_1" + HorizontalAlign: + enum: + - left + - right + - justified + - center + type: string + ImageSpec: + oneOf: + - $ref: "#/components/schemas/ImageSpec_oneOf" + - $ref: "#/components/schemas/ImageSpec_oneOf_1" + - $ref: "#/components/schemas/ImageSpec_oneOf_2" + - $ref: "#/components/schemas/ImageSpec_oneOf_3" + - $ref: "#/components/schemas/ImageSpec_oneOf_4" + InputHlsCodec: + enum: + - h264 + type: string + InputId: + type: string + InputMp4Codec: + enum: + - h264 + type: string + InputRtmpCodec: + enum: + - h264 + type: string + InputRtpAudioOptions: + oneOf: + - $ref: "#/components/schemas/InputRtpAudioOptions_oneOf" + - $ref: "#/components/schemas/InputRtpAudioOptions_oneOf_1" + InputRtpVideoOptions: + additionalProperties: false + properties: + decoder: + $ref: "#/components/schemas/RtpVideoDecoderOptions" + required: + - decoder + InputStream: + additionalProperties: false + properties: + id: + allOf: + - $ref: "#/components/schemas/ComponentId" + description: Id of a component. + nullable: true + input_id: + allOf: + - $ref: "#/components/schemas/InputId" + description: "Id of an input. It identifies a stream registered using a\ + \ [`RegisterInputStream`](../routes.md#register-input) request." + required: + - input_id + InputWhepVideoOptions: + additionalProperties: false + properties: + decoder_preferences: + items: + $ref: "#/components/schemas/WhepVideoDecoderOptions" + nullable: true + type: array + InputWhipVideoOptions: + additionalProperties: false + properties: + decoder_preferences: + items: + $ref: "#/components/schemas/WhipVideoDecoderOptions" + nullable: true + type: array + Interpolation: + enum: + - linear + - spring + type: string + Mp4AudioEncoderOptions: + properties: + sample_rate: + description: "(**default=`44100`**) Sample rate. Allowed values: [8000,\ + \ 16000, 24000, 44100, 48000]." + format: int32 + minimum: 0 + nullable: true + type: integer + type: + enum: + - aac + type: string + required: + - type + Mp4Input: + additionalProperties: false + description: |- + Input stream from MP4 file. + Exactly one of `url` and `path` has to be defined. + properties: + url: + description: URL of the MP4 file. + nullable: true + type: string + loop: + description: (**default=`false`**) If input should be played in the loop. + Added in v0.4.0 + nullable: true + type: boolean + required: + description: |- + (**default=`false`**) If input is required and frames are not processed + on time, then Smelter will delay producing output frames. + nullable: true + type: boolean + offset_ms: + description: |- + Offset in milliseconds relative to the pipeline start (start request). If offset is + not defined then stream is synchronized based on the first frames delivery time. + format: double + nullable: true + type: number + Mp4Output: + additionalProperties: false + properties: + path: + description: Path to output MP4 file. + type: string + video: + allOf: + - $ref: "#/components/schemas/OutputMp4VideoOptions" + description: Video stream configuration. + nullable: true + audio: + allOf: + - $ref: "#/components/schemas/OutputMp4AudioOptions" + description: Audio stream configuration. + nullable: true + ffmpeg_options: + additionalProperties: + type: string + description: "Raw FFmpeg muxer options. See [docs](https://ffmpeg.org/ffmpeg-formats.html)\ + \ for more." + required: + - path + Mp4VideoDecoderOptions: + enum: + - ffmpeg_h264 + - vulkan_h264 + type: string + Mp4VideoEncoderOptions: + oneOf: + - $ref: "#/components/schemas/Mp4VideoEncoderOptions_oneOf" + - $ref: "#/components/schemas/HlsVideoEncoderOptions_oneOf_1" + OpusEncoderPreset: + enum: + - quality + - voip + - lowest_latency + type: string + OutputEndCondition: + additionalProperties: false + description: |- + This type defines when end of an input stream should trigger end of the output stream. Only one of those fields can be set at the time. + Unless specified otherwise the input stream is considered finished/ended when: + - TCP connection was dropped/closed. + - RTCP Goodbye packet (`BYE`) was received. + - Mp4 track has ended. + - Input was unregistered already (or never registered). + properties: + any_of: + description: Terminate output stream if any of the input streams from the + list are finished. + items: + $ref: "#/components/schemas/InputId" + nullable: true + type: array + all_of: + description: Terminate output stream if all the input streams from the list + are finished. + items: + $ref: "#/components/schemas/InputId" + nullable: true + type: array + any_input: + description: "Terminate output stream if any of the input streams ends.\ + \ This includes streams added after the output was registered. In particular,\ + \ output stream will **not be** terminated if no inputs were ever connected." + nullable: true + type: boolean + all_inputs: + description: "Terminate output stream if all the input streams finish. In\ + \ particular, output stream will **be** terminated if no inputs were ever\ + \ connected." + nullable: true + type: boolean + OutputHlsAudioOptions: + additionalProperties: false + properties: + mixing_strategy: + allOf: + - $ref: "#/components/schemas/AudioMixingStrategy" + description: (**default="sum_clip"**) Specifies how audio should be mixed. + nullable: true + send_eos_when: + allOf: + - $ref: "#/components/schemas/OutputEndCondition" + description: Condition for termination of output stream based on the input + streams states. + nullable: true + encoder: + allOf: + - $ref: "#/components/schemas/HlsAudioEncoderOptions" + description: Audio encoder options. + channels: + allOf: + - $ref: "#/components/schemas/AudioChannels" + description: Specifies channels configuration. + nullable: true + initial: + allOf: + - $ref: "#/components/schemas/AudioScene" + description: Initial audio mixer configuration for output. + required: + - encoder + - initial + OutputHlsVideoOptions: + additionalProperties: false + properties: + resolution: + allOf: + - $ref: "#/components/schemas/Resolution" + description: Output resolution in pixels. + send_eos_when: + allOf: + - $ref: "#/components/schemas/OutputEndCondition" + description: "Condition for termination of the output stream based on the\ + \ input streams states. If output includes both audio and video streams,\ + \ then EOS needs to be sent for every type." + nullable: true + encoder: + allOf: + - $ref: "#/components/schemas/HlsVideoEncoderOptions" + description: Video encoder options. + initial: + allOf: + - $ref: "#/components/schemas/VideoScene" + description: "Root of a component tree/scene that should be rendered for\ + \ the output. Use [`update_output` request](../routes.md#update-output)\ + \ to update this value after registration. [Learn more](../../concept/component.md)." + required: + - encoder + - initial + - resolution + OutputId: + type: string + OutputMp4AudioOptions: + additionalProperties: false + properties: + mixing_strategy: + allOf: + - $ref: "#/components/schemas/AudioMixingStrategy" + description: (**default="sum_clip"**) Specifies how audio should be mixed. + nullable: true + send_eos_when: + allOf: + - $ref: "#/components/schemas/OutputEndCondition" + description: Condition for termination of output stream based on the input + streams states. + nullable: true + encoder: + allOf: + - $ref: "#/components/schemas/Mp4AudioEncoderOptions" + description: Audio encoder options. + channels: + allOf: + - $ref: "#/components/schemas/AudioChannels" + description: Specifies channels configuration. + nullable: true + initial: + allOf: + - $ref: "#/components/schemas/AudioScene" + description: Initial audio mixer configuration for output. + required: + - encoder + - initial + OutputMp4VideoOptions: + additionalProperties: false + properties: + resolution: + allOf: + - $ref: "#/components/schemas/Resolution" + description: Output resolution in pixels. + send_eos_when: + allOf: + - $ref: "#/components/schemas/OutputEndCondition" + description: "Condition for termination of the output stream based on the\ + \ input streams states. If output includes both audio and video streams,\ + \ then EOS needs to be sent for every type." + nullable: true + encoder: + allOf: + - $ref: "#/components/schemas/Mp4VideoEncoderOptions" + description: Video encoder options. + initial: + allOf: + - $ref: "#/components/schemas/VideoScene" + description: "Root of a component tree/scene that should be rendered for\ + \ the output. Use [`update_output` request](../routes.md#update-output)\ + \ to update this value after registration. [Learn more](../../concept/component.md)." + required: + - encoder + - initial + - resolution + OutputRtmpClientAudioOptions: + additionalProperties: false + properties: + mixing_strategy: + allOf: + - $ref: "#/components/schemas/AudioMixingStrategy" + description: (**default="sum_clip"**) Specifies how audio should be mixed. + nullable: true + send_eos_when: + allOf: + - $ref: "#/components/schemas/OutputEndCondition" + description: "Condition for termination of the output stream based on the\ + \ input streams states. If output includes both audio and video streams,\ + \ then EOS needs to be sent for every type." + nullable: true + encoder: + allOf: + - $ref: "#/components/schemas/RtmpClientAudioEncoderOptions" + description: Audio encoder options. + channels: + allOf: + - $ref: "#/components/schemas/AudioChannels" + description: Channels configuration. + nullable: true + initial: + allOf: + - $ref: "#/components/schemas/AudioScene" + description: Initial audio mixer configuration for output. + required: + - encoder + - initial + OutputRtmpClientVideoOptions: + additionalProperties: false + properties: + resolution: + allOf: + - $ref: "#/components/schemas/Resolution" + description: Output resolution in pixels. + send_eos_when: + allOf: + - $ref: "#/components/schemas/OutputEndCondition" + description: "Condition for termination of the output stream based on the\ + \ input streams states. If output includes both audio and video streams,\ + \ then EOS needs to be sent for every type." + nullable: true + encoder: + allOf: + - $ref: "#/components/schemas/RtmpClientVideoEncoderOptions" + description: Video encoder options. + initial: + allOf: + - $ref: "#/components/schemas/VideoScene" + description: "Root of a component tree/scene that should be rendered for\ + \ the output. Use [`update_output` request](../routes.md#update-output)\ + \ to update this value after registration. [Learn more](../../concept/component.md)." + required: + - encoder + - initial + - resolution + OutputRtpAudioOptions: + additionalProperties: false + properties: + mixing_strategy: + allOf: + - $ref: "#/components/schemas/AudioMixingStrategy" + description: (**default="sum_clip"**) Specifies how audio should be mixed. + nullable: true + send_eos_when: + allOf: + - $ref: "#/components/schemas/OutputEndCondition" + description: "Condition for termination of output stream based on the input\ + \ streams states. If output includes both audio and video streams, then\ + \ EOS needs to be sent for every type." + nullable: true + encoder: + allOf: + - $ref: "#/components/schemas/RtpAudioEncoderOptions" + description: Audio encoder options. + channels: + allOf: + - $ref: "#/components/schemas/AudioChannels" + description: Channels configuration. + nullable: true + initial: + allOf: + - $ref: "#/components/schemas/AudioScene" + description: Initial audio mixer configuration for output. + required: + - encoder + - initial + OutputRtpVideoOptions: + additionalProperties: false + properties: + resolution: + allOf: + - $ref: "#/components/schemas/Resolution" + description: Output resolution in pixels. + send_eos_when: + allOf: + - $ref: "#/components/schemas/OutputEndCondition" + description: "Condition for termination of the output stream based on the\ + \ input streams states. If output includes both audio and video streams,\ + \ then EOS needs to be sent for every type." + nullable: true + encoder: + allOf: + - $ref: "#/components/schemas/RtpVideoEncoderOptions" + description: Video encoder options. + initial: + allOf: + - $ref: "#/components/schemas/VideoScene" + description: "Root of a component tree/scene that should be rendered for\ + \ the output. Use [`update_output` request](../routes.md#update-output)\ + \ to update this value after registration. [Learn more](../../concept/component.md)." + required: + - encoder + - initial + - resolution + OutputWhepAudioOptions: + additionalProperties: false + properties: + mixing_strategy: + allOf: + - $ref: "#/components/schemas/AudioMixingStrategy" + description: (**default="sum_clip"**) Specifies how audio should be mixed. + nullable: true + send_eos_when: + allOf: + - $ref: "#/components/schemas/OutputEndCondition" + description: Condition for termination of output stream based on the input + streams states. + nullable: true + encoder: + allOf: + - $ref: "#/components/schemas/WhepAudioEncoderOptions" + description: Audio encoder options. + channels: + allOf: + - $ref: "#/components/schemas/AudioChannels" + description: Specifies channels configuration. + nullable: true + initial: + allOf: + - $ref: "#/components/schemas/AudioScene" + description: Initial audio mixer configuration for output. + required: + - encoder + - initial + OutputWhepVideoOptions: + additionalProperties: false + properties: + resolution: + allOf: + - $ref: "#/components/schemas/Resolution" + description: Output resolution in pixels. + send_eos_when: + allOf: + - $ref: "#/components/schemas/OutputEndCondition" + description: "Condition for termination of the output stream based on the\ + \ input streams states. If output includes both audio and video streams,\ + \ then EOS needs to be sent for every type." + nullable: true + encoder: + allOf: + - $ref: "#/components/schemas/WhepVideoEncoderOptions" + description: Video encoder options. + initial: + allOf: + - $ref: "#/components/schemas/VideoScene" + description: "Root of a component tree/scene that should be rendered for\ + \ the output. Use [`update_output` request](../routes.md#update-output)\ + \ to update this value after registration. [Learn more](../../concept/component.md)." + required: + - encoder + - initial + - resolution + OutputWhipAudioOptions: + additionalProperties: false + properties: + mixing_strategy: + allOf: + - $ref: "#/components/schemas/AudioMixingStrategy" + description: (**default="sum_clip"**) Specifies how audio should be mixed. + nullable: true + send_eos_when: + allOf: + - $ref: "#/components/schemas/OutputEndCondition" + description: Condition for termination of output stream based on the input + streams states. + nullable: true + channels: + allOf: + - $ref: "#/components/schemas/AudioChannels" + description: Specifies channels configuration. + nullable: true + encoder_preferences: + description: Codec preferences list. + items: + $ref: "#/components/schemas/WhipAudioEncoderOptions" + nullable: true + type: array + initial: + allOf: + - $ref: "#/components/schemas/AudioScene" + description: Initial audio mixer configuration for output. + required: + - initial + OutputWhipVideoOptions: + additionalProperties: false + properties: + resolution: + allOf: + - $ref: "#/components/schemas/Resolution" + description: Output resolution in pixels. + send_eos_when: + allOf: + - $ref: "#/components/schemas/OutputEndCondition" + description: "Defines when output stream should end if some of the input\ + \ streams are finished. If output includes both audio and video streams,\ + \ then EOS needs to be sent on both." + nullable: true + encoder_preferences: + description: Codec preferences list. + items: + $ref: "#/components/schemas/WhipVideoEncoderOptions" + nullable: true + type: array + initial: + allOf: + - $ref: "#/components/schemas/VideoScene" + description: Root of a component tree/scene that should be rendered for + the output. + required: + - initial + - resolution + Overflow: + enum: + - visible + - hidden + - fit + type: string + PixelFormat: + enum: + - yuv420p + - yuv422p + - yuv444p + type: string + PortOrPortRange: + oneOf: + - type: string + - format: int32 + minimum: 0 + type: integer + RGBAColor: + type: string + RegisterInput: + oneOf: + - $ref: "#/components/schemas/RegisterInput_oneOf" + - $ref: "#/components/schemas/RegisterInput_oneOf_1" + - $ref: "#/components/schemas/RegisterInput_oneOf_2" + - $ref: "#/components/schemas/RegisterInput_oneOf_3" + - $ref: "#/components/schemas/RegisterInput_oneOf_4" + - $ref: "#/components/schemas/RegisterInput_oneOf_5" + RegisterOutput: + oneOf: + - $ref: "#/components/schemas/RegisterOutput_oneOf" + - $ref: "#/components/schemas/RegisterOutput_oneOf_1" + - $ref: "#/components/schemas/RegisterOutput_oneOf_2" + - $ref: "#/components/schemas/RegisterOutput_oneOf_3" + - $ref: "#/components/schemas/RegisterOutput_oneOf_4" + - $ref: "#/components/schemas/RegisterOutput_oneOf_5" + RescaleMode: + enum: + - fit + - fill + type: string + Rescaler: + additionalProperties: false + properties: + id: + allOf: + - $ref: "#/components/schemas/ComponentId" + description: Id of a component. + nullable: true + child: + allOf: + - $ref: "#/components/schemas/Component" + description: List of component's children. + mode: + allOf: + - $ref: "#/components/schemas/RescaleMode" + description: "(**default=`\"fit\"`**) Resize mode:" + nullable: true + horizontal_align: + allOf: + - $ref: "#/components/schemas/HorizontalAlign" + description: (**default=`"center"`**) Horizontal alignment. + nullable: true + vertical_align: + allOf: + - $ref: "#/components/schemas/VerticalAlign" + description: (**default=`"center"`**) Vertical alignment. + nullable: true + width: + description: |- + Width of a component in pixels (without a border). Exact behavior might be different + based on the parent component: + - If the parent component is a layout, check sections "Absolute positioning" and "Static + positioning" of that component. + - If the parent component is not a layout, then this field is required. + format: float + nullable: true + type: number + height: + description: |- + Height of a component in pixels (without a border). Exact behavior might be different + based on the parent component: + - If the parent component is a layout, check sections "Absolute positioning" and "Static + positioning" of that component. + - If the parent component is not a layout, then this field is required. + format: float + nullable: true + type: number + top: + description: |- + Distance in pixels between this component's top edge and its parent's top edge (including a border). + If this field is defined, then the component will ignore a layout defined by its parent. + format: float + nullable: true + type: number + left: + description: |- + Distance in pixels between this component's left edge and its parent's left edge (including a border). + If this field is defined, this element will be absolutely positioned, instead of being + laid out by its parent. + format: float + nullable: true + type: number + bottom: + description: |- + Distance in pixels between the bottom edge of this component and the bottom edge of its + parent (including a border). If this field is defined, this element will be absolutely + positioned, instead of being laid out by its parent. + format: float + nullable: true + type: number + right: + description: |- + Distance in pixels between this component's right edge and its parent's right edge. + If this field is defined, this element will be absolutely positioned, instead of being + laid out by its parent. + format: float + nullable: true + type: number + rotation: + description: |- + Rotation of a component in degrees. If this field is defined, this element will be + absolutely positioned, instead of being laid out by its parent. + format: float + nullable: true + type: number + transition: + allOf: + - $ref: "#/components/schemas/Transition" + description: |- + Defines how this component will behave during a scene update. This will only have an + effect if the previous scene already contained a `Rescaler` component with the same id. + nullable: true + border_radius: + description: (**default=`0.0`**) Radius of a rounded corner. + format: float + nullable: true + type: number + border_width: + description: (**default=`0.0`**) Border width. + format: float + nullable: true + type: number + border_color: + allOf: + - $ref: "#/components/schemas/RGBAColor" + description: (**default=`"#00000000"`**) Border color in a `"#RRGGBBAA"` + format. + nullable: true + box_shadow: + description: List of box shadows. + items: + $ref: "#/components/schemas/BoxShadow" + nullable: true + type: array + required: + - child + Resolution: + properties: + width: + description: Width in pixels. + minimum: 0 + type: integer + height: + description: Height in pixels. + minimum: 0 + type: integer + required: + - height + - width + Response: + oneOf: + - $ref: "#/components/schemas/Response_oneOf" + - $ref: "#/components/schemas/Response_oneOf_1" + - $ref: "#/components/schemas/Response_oneOf_2" + - type: object + RtmpClientAudioEncoderOptions: + properties: + sample_rate: + description: "(**default=`48000`**) Sample rate. Allowed values: [8000,\ + \ 16000, 24000, 44100, 48000]." + format: int32 + minimum: 0 + nullable: true + type: integer + type: + enum: + - aac + type: string + required: + - type + RtmpClientVideoEncoderOptions: + oneOf: + - $ref: "#/components/schemas/HlsVideoEncoderOptions_oneOf" + - $ref: "#/components/schemas/HlsVideoEncoderOptions_oneOf_1" + RtmpInput: + additionalProperties: false + properties: + app: + description: |- + The RTMP application name. + This is the first path segment of the RTMP stream URL that Smelter listens on for incoming streams. + Format: `rtmp://://://Added in v0.4.0" + }, + "required": { + "type": [ + "boolean", + "null" + ], + "description": "(**default=`false`**) If input is required and frames are not processed\non time, then Smelter will delay producing output frames." + }, + "offset_ms": { + "type": [ + "number", + "null" + ], + "format": "double", + "description": "Offset in milliseconds relative to the pipeline start (start request). If offset is\nnot defined then stream is synchronized based on the first frames delivery time." + } + }, + "additionalProperties": false + }, + "Mp4Output": { + "type": "object", + "required": [ + "path" + ], + "properties": { + "path": { + "type": "string", + "description": "Path to output MP4 file." + }, + "video": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/OutputMp4VideoOptions", + "description": "Video stream configuration." + } + ] + }, + "audio": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/OutputMp4AudioOptions", + "description": "Audio stream configuration." + } + ] + }, + "ffmpeg_options": { + "type": [ + "object", + "null" + ], + "description": "Raw FFmpeg muxer options. See [docs](https://ffmpeg.org/ffmpeg-formats.html) for more.", + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "Mp4VideoDecoderOptions": { + "type": "string", + "enum": [ + "ffmpeg_h264", + "vulkan_h264" + ] + }, + "Mp4VideoEncoderOptions": { + "oneOf": [ + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "preset": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/H264EncoderPreset", + "description": "(**default=`\"fast\"`**) Video output encoder preset. Visit `FFmpeg` [docs](https://trac.ffmpeg.org/wiki/Encode/H.264#Preset) to learn more." + } + ] + }, + "bitrate": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/VideoEncoderBitrate", + "description": "Encoding bitrate. Default value depends on chosen encoder." + } + ] + }, + "keyframe_interval_ms": { + "type": [ + "number", + "null" + ], + "format": "double", + "description": "(**default=`5000`**) Maximal interval between keyframes, in milliseconds." + }, + "pixel_format": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/PixelFormat", + "description": "(**default=`\"yuv420p\"`**) Encoder pixel format." + } + ] + }, + "ffmpeg_options": { + "type": [ + "object", + "null" + ], + "description": "Raw FFmpeg encoder options. See [docs](https://ffmpeg.org/ffmpeg-codecs.html) for more.", + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + } + }, + "type": { + "type": "string", + "enum": [ + "ffmpeg_h264" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "bitrate": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/VideoEncoderBitrate", + "description": "Encoding bitrate. If not provided, bitrate is calculated based on resolution and framerate.\nFor example at 1080p 30 FPS the average bitrate is 5000 kbit/s and max bitrate is 6250 kbit/s." + } + ] + }, + "keyframe_interval_ms": { + "type": [ + "number", + "null" + ], + "format": "double", + "description": "(**default=`5000`**) Interval between keyframes, in milliseconds." + }, + "type": { + "type": "string", + "enum": [ + "vulkan_h264" + ] + } + } + } + ] + }, + "OpusEncoderPreset": { + "type": "string", + "enum": [ + "quality", + "voip", + "lowest_latency" + ] + }, + "OutputEndCondition": { + "type": "object", + "description": "This type defines when end of an input stream should trigger end of the output stream. Only one of those fields can be set at the time.\nUnless specified otherwise the input stream is considered finished/ended when:\n- TCP connection was dropped/closed.\n- RTCP Goodbye packet (`BYE`) was received.\n- Mp4 track has ended.\n- Input was unregistered already (or never registered).", + "properties": { + "any_of": { + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/components/schemas/InputId" + }, + "description": "Terminate output stream if any of the input streams from the list are finished." + }, + "all_of": { + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/components/schemas/InputId" + }, + "description": "Terminate output stream if all the input streams from the list are finished." + }, + "any_input": { + "type": [ + "boolean", + "null" + ], + "description": "Terminate output stream if any of the input streams ends. This includes streams added after the output was registered. In particular, output stream will **not be** terminated if no inputs were ever connected." + }, + "all_inputs": { + "type": [ + "boolean", + "null" + ], + "description": "Terminate output stream if all the input streams finish. In particular, output stream will **be** terminated if no inputs were ever connected." + } + }, + "additionalProperties": false + }, + "OutputHlsAudioOptions": { + "type": "object", + "required": [ + "encoder", + "initial" + ], + "properties": { + "mixing_strategy": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/AudioMixingStrategy", + "description": "(**default=\"sum_clip\"**) Specifies how audio should be mixed." + } + ] + }, + "send_eos_when": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/OutputEndCondition", + "description": "Condition for termination of output stream based on the input streams states." + } + ] + }, + "encoder": { + "$ref": "#/components/schemas/HlsAudioEncoderOptions", + "description": "Audio encoder options." + }, + "channels": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/AudioChannels", + "description": "Specifies channels configuration." + } + ] + }, + "initial": { + "$ref": "#/components/schemas/AudioScene", + "description": "Initial audio mixer configuration for output." + } + }, + "additionalProperties": false + }, + "OutputHlsVideoOptions": { + "type": "object", + "required": [ + "resolution", + "encoder", + "initial" + ], + "properties": { + "resolution": { + "$ref": "#/components/schemas/Resolution", + "description": "Output resolution in pixels." + }, + "send_eos_when": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/OutputEndCondition", + "description": "Condition for termination of the output stream based on the input streams states. If output includes both audio and video streams, then EOS needs to be sent for every type." + } + ] + }, + "encoder": { + "$ref": "#/components/schemas/HlsVideoEncoderOptions", + "description": "Video encoder options." + }, + "initial": { + "$ref": "#/components/schemas/VideoScene", + "description": "Root of a component tree/scene that should be rendered for the output. Use [`update_output` request](../routes.md#update-output) to update this value after registration. [Learn more](../../concept/component.md)." + } + }, + "additionalProperties": false + }, + "OutputId": { + "type": "string" + }, + "OutputMp4AudioOptions": { + "type": "object", + "required": [ + "encoder", + "initial" + ], + "properties": { + "mixing_strategy": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/AudioMixingStrategy", + "description": "(**default=\"sum_clip\"**) Specifies how audio should be mixed." + } + ] + }, + "send_eos_when": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/OutputEndCondition", + "description": "Condition for termination of output stream based on the input streams states." + } + ] + }, + "encoder": { + "$ref": "#/components/schemas/Mp4AudioEncoderOptions", + "description": "Audio encoder options." + }, + "channels": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/AudioChannels", + "description": "Specifies channels configuration." + } + ] + }, + "initial": { + "$ref": "#/components/schemas/AudioScene", + "description": "Initial audio mixer configuration for output." + } + }, + "additionalProperties": false + }, + "OutputMp4VideoOptions": { + "type": "object", + "required": [ + "resolution", + "encoder", + "initial" + ], + "properties": { + "resolution": { + "$ref": "#/components/schemas/Resolution", + "description": "Output resolution in pixels." + }, + "send_eos_when": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/OutputEndCondition", + "description": "Condition for termination of the output stream based on the input streams states. If output includes both audio and video streams, then EOS needs to be sent for every type." + } + ] + }, + "encoder": { + "$ref": "#/components/schemas/Mp4VideoEncoderOptions", + "description": "Video encoder options." + }, + "initial": { + "$ref": "#/components/schemas/VideoScene", + "description": "Root of a component tree/scene that should be rendered for the output. Use [`update_output` request](../routes.md#update-output) to update this value after registration. [Learn more](../../concept/component.md)." + } + }, + "additionalProperties": false + }, + "OutputRtmpClientAudioOptions": { + "type": "object", + "required": [ + "encoder", + "initial" + ], + "properties": { + "mixing_strategy": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/AudioMixingStrategy", + "description": "(**default=\"sum_clip\"**) Specifies how audio should be mixed." + } + ] + }, + "send_eos_when": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/OutputEndCondition", + "description": "Condition for termination of the output stream based on the input streams states. If output includes both audio and video streams, then EOS needs to be sent for every type." + } + ] + }, + "encoder": { + "$ref": "#/components/schemas/RtmpClientAudioEncoderOptions", + "description": "Audio encoder options." + }, + "channels": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/AudioChannels", + "description": "Channels configuration." + } + ] + }, + "initial": { + "$ref": "#/components/schemas/AudioScene", + "description": "Initial audio mixer configuration for output." + } + }, + "additionalProperties": false + }, + "OutputRtmpClientVideoOptions": { + "type": "object", + "required": [ + "resolution", + "encoder", + "initial" + ], + "properties": { + "resolution": { + "$ref": "#/components/schemas/Resolution", + "description": "Output resolution in pixels." + }, + "send_eos_when": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/OutputEndCondition", + "description": "Condition for termination of the output stream based on the input streams states. If output includes both audio and video streams, then EOS needs to be sent for every type." + } + ] + }, + "encoder": { + "$ref": "#/components/schemas/RtmpClientVideoEncoderOptions", + "description": "Video encoder options." + }, + "initial": { + "$ref": "#/components/schemas/VideoScene", + "description": "Root of a component tree/scene that should be rendered for the output. Use [`update_output` request](../routes.md#update-output) to update this value after registration. [Learn more](../../concept/component.md)." + } + }, + "additionalProperties": false + }, + "OutputRtpAudioOptions": { + "type": "object", + "required": [ + "encoder", + "initial" + ], + "properties": { + "mixing_strategy": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/AudioMixingStrategy", + "description": "(**default=\"sum_clip\"**) Specifies how audio should be mixed." + } + ] + }, + "send_eos_when": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/OutputEndCondition", + "description": "Condition for termination of output stream based on the input streams states. If output includes both audio and video streams, then EOS needs to be sent for every type." + } + ] + }, + "encoder": { + "$ref": "#/components/schemas/RtpAudioEncoderOptions", + "description": "Audio encoder options." + }, + "channels": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/AudioChannels", + "description": "Channels configuration." + } + ] + }, + "initial": { + "$ref": "#/components/schemas/AudioScene", + "description": "Initial audio mixer configuration for output." + } + }, + "additionalProperties": false + }, + "OutputRtpVideoOptions": { + "type": "object", + "required": [ + "resolution", + "encoder", + "initial" + ], + "properties": { + "resolution": { + "$ref": "#/components/schemas/Resolution", + "description": "Output resolution in pixels." + }, + "send_eos_when": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/OutputEndCondition", + "description": "Condition for termination of the output stream based on the input streams states. If output includes both audio and video streams, then EOS needs to be sent for every type." + } + ] + }, + "encoder": { + "$ref": "#/components/schemas/RtpVideoEncoderOptions", + "description": "Video encoder options." + }, + "initial": { + "$ref": "#/components/schemas/VideoScene", + "description": "Root of a component tree/scene that should be rendered for the output. Use [`update_output` request](../routes.md#update-output) to update this value after registration. [Learn more](../../concept/component.md)." + } + }, + "additionalProperties": false + }, + "OutputWhepAudioOptions": { + "type": "object", + "required": [ + "encoder", + "initial" + ], + "properties": { + "mixing_strategy": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/AudioMixingStrategy", + "description": "(**default=\"sum_clip\"**) Specifies how audio should be mixed." + } + ] + }, + "send_eos_when": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/OutputEndCondition", + "description": "Condition for termination of output stream based on the input streams states." + } + ] + }, + "encoder": { + "$ref": "#/components/schemas/WhepAudioEncoderOptions", + "description": "Audio encoder options." + }, + "channels": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/AudioChannels", + "description": "Specifies channels configuration." + } + ] + }, + "initial": { + "$ref": "#/components/schemas/AudioScene", + "description": "Initial audio mixer configuration for output." + } + }, + "additionalProperties": false + }, + "OutputWhepVideoOptions": { + "type": "object", + "required": [ + "resolution", + "encoder", + "initial" + ], + "properties": { + "resolution": { + "$ref": "#/components/schemas/Resolution", + "description": "Output resolution in pixels." + }, + "send_eos_when": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/OutputEndCondition", + "description": "Condition for termination of the output stream based on the input streams states. If output includes both audio and video streams, then EOS needs to be sent for every type." + } + ] + }, + "encoder": { + "$ref": "#/components/schemas/WhepVideoEncoderOptions", + "description": "Video encoder options." + }, + "initial": { + "$ref": "#/components/schemas/VideoScene", + "description": "Root of a component tree/scene that should be rendered for the output. Use [`update_output` request](../routes.md#update-output) to update this value after registration. [Learn more](../../concept/component.md)." + } + }, + "additionalProperties": false + }, + "OutputWhipAudioOptions": { + "type": "object", + "required": [ + "initial" + ], + "properties": { + "mixing_strategy": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/AudioMixingStrategy", + "description": "(**default=\"sum_clip\"**) Specifies how audio should be mixed." + } + ] + }, + "send_eos_when": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/OutputEndCondition", + "description": "Condition for termination of output stream based on the input streams states." + } + ] + }, + "channels": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/AudioChannels", + "description": "Specifies channels configuration." + } + ] + }, + "encoder_preferences": { + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/components/schemas/WhipAudioEncoderOptions" + }, + "description": "Codec preferences list." + }, + "initial": { + "$ref": "#/components/schemas/AudioScene", + "description": "Initial audio mixer configuration for output." + } + }, + "additionalProperties": false + }, + "OutputWhipVideoOptions": { + "type": "object", + "required": [ + "resolution", + "initial" + ], + "properties": { + "resolution": { + "$ref": "#/components/schemas/Resolution", + "description": "Output resolution in pixels." + }, + "send_eos_when": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/OutputEndCondition", + "description": "Defines when output stream should end if some of the input streams are finished. If output includes both audio and video streams, then EOS needs to be sent on both." + } + ] + }, + "encoder_preferences": { + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/components/schemas/WhipVideoEncoderOptions" + }, + "description": "Codec preferences list." + }, + "initial": { + "$ref": "#/components/schemas/VideoScene", + "description": "Root of a component tree/scene that should be rendered for the output." + } + }, + "additionalProperties": false + }, + "Overflow": { + "type": "string", + "enum": [ + "visible", + "hidden", + "fit" + ] + }, + "PixelFormat": { + "type": "string", + "enum": [ + "yuv420p", + "yuv422p", + "yuv444p" + ] + }, + "PortOrPortRange": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "integer", + "format": "int32", + "minimum": 0 + } + ] + }, + "RGBAColor": { + "type": "string" + }, + "RegisterInput": { + "oneOf": [ + { + "$ref": "#/components/schemas/RtpInput" + }, + { + "$ref": "#/components/schemas/RtmpInput" + }, + { + "$ref": "#/components/schemas/Mp4Input" + }, + { + "$ref": "#/components/schemas/WhipInput" + }, + { + "$ref": "#/components/schemas/WhepInput" + }, + { + "$ref": "#/components/schemas/HlsInput" + } + ], + "discriminator": { + "propertyName": "type", + "mapping": { + "hls": "#/components/schemas/HlsInput", + "mp4": "#/components/schemas/Mp4Input", + "rtmp_server": "#/components/schemas/RtmpInput", + "rtp_stream": "#/components/schemas/RtpInput", + "whep_client": "#/components/schemas/WhepInput", + "whip_server": "#/components/schemas/WhipInput" + } + } + }, + "RegisterOutput": { + "oneOf": [ + { + "$ref": "#/components/schemas/RtpOutput" + }, + { + "$ref": "#/components/schemas/RtmpOutput" + }, + { + "$ref": "#/components/schemas/Mp4Output" + }, + { + "$ref": "#/components/schemas/WhipOutput" + }, + { + "$ref": "#/components/schemas/WhepOutput" + }, + { + "$ref": "#/components/schemas/HlsOutput" + } + ], + "discriminator": { + "propertyName": "type", + "mapping": { + "hls": "#/components/schemas/HlsOutput", + "mp4": "#/components/schemas/Mp4Output", + "rtmp_client": "#/components/schemas/RtmpOutput", + "rtp_stream": "#/components/schemas/RtpOutput", + "whep_server": "#/components/schemas/WhepOutput", + "whip_client": "#/components/schemas/WhipOutput" + } + } + }, + "RescaleMode": { + "type": "string", + "enum": [ + "fit", + "fill" + ] + }, + "Rescaler": { + "type": "object", + "required": [ + "child" + ], + "properties": { + "id": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/ComponentId", + "description": "Id of a component." + } + ] + }, + "child": { + "$ref": "#/components/schemas/Component", + "description": "List of component's children." + }, + "mode": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/RescaleMode", + "description": "(**default=`\"fit\"`**) Resize mode:" + } + ] + }, + "horizontal_align": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/HorizontalAlign", + "description": "(**default=`\"center\"`**) Horizontal alignment." + } + ] + }, + "vertical_align": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/VerticalAlign", + "description": "(**default=`\"center\"`**) Vertical alignment." + } + ] + }, + "width": { + "type": [ + "number", + "null" + ], + "format": "float", + "description": "Width of a component in pixels (without a border). Exact behavior might be different\nbased on the parent component:\n- If the parent component is a layout, check sections \"Absolute positioning\" and \"Static\n positioning\" of that component.\n- If the parent component is not a layout, then this field is required." + }, + "height": { + "type": [ + "number", + "null" + ], + "format": "float", + "description": "Height of a component in pixels (without a border). Exact behavior might be different\nbased on the parent component:\n- If the parent component is a layout, check sections \"Absolute positioning\" and \"Static\n positioning\" of that component.\n- If the parent component is not a layout, then this field is required." + }, + "top": { + "type": [ + "number", + "null" + ], + "format": "float", + "description": "Distance in pixels between this component's top edge and its parent's top edge (including a border).\nIf this field is defined, then the component will ignore a layout defined by its parent." + }, + "left": { + "type": [ + "number", + "null" + ], + "format": "float", + "description": "Distance in pixels between this component's left edge and its parent's left edge (including a border).\nIf this field is defined, this element will be absolutely positioned, instead of being\nlaid out by its parent." + }, + "bottom": { + "type": [ + "number", + "null" + ], + "format": "float", + "description": "Distance in pixels between the bottom edge of this component and the bottom edge of its\nparent (including a border). If this field is defined, this element will be absolutely\npositioned, instead of being laid out by its parent." + }, + "right": { + "type": [ + "number", + "null" + ], + "format": "float", + "description": "Distance in pixels between this component's right edge and its parent's right edge.\nIf this field is defined, this element will be absolutely positioned, instead of being\nlaid out by its parent." + }, + "rotation": { + "type": [ + "number", + "null" + ], + "format": "float", + "description": "Rotation of a component in degrees. If this field is defined, this element will be\nabsolutely positioned, instead of being laid out by its parent." + }, + "transition": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/Transition", + "description": "Defines how this component will behave during a scene update. This will only have an\neffect if the previous scene already contained a `Rescaler` component with the same id." + } + ] + }, + "border_radius": { + "type": [ + "number", + "null" + ], + "format": "float", + "description": "(**default=`0.0`**) Radius of a rounded corner." + }, + "border_width": { + "type": [ + "number", + "null" + ], + "format": "float", + "description": "(**default=`0.0`**) Border width." + }, + "border_color": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/RGBAColor", + "description": "(**default=`\"#00000000\"`**) Border color in a `\"#RRGGBBAA\"` format." + } + ] + }, + "box_shadow": { + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/components/schemas/BoxShadow" + }, + "description": "List of box shadows." + } + }, + "additionalProperties": false + }, + "Resolution": { + "type": "object", + "required": [ + "width", + "height" + ], + "properties": { + "width": { + "type": "integer", + "description": "Width in pixels.", + "minimum": 0 + }, + "height": { + "type": "integer", + "description": "Height in pixels.", + "minimum": 0 + } + } + }, + "Response": { + "oneOf": [ + { + "type": "object", + "required": [ + "bearer_token" + ], + "properties": { + "bearer_token": { + "type": "string" + } + } + }, + { + "type": "object", + "properties": { + "video_duration_ms": { + "type": [ + "integer", + "null" + ], + "format": "int64", + "minimum": 0 + }, + "audio_duration_ms": { + "type": [ + "integer", + "null" + ], + "format": "int64", + "minimum": 0 + } + } + }, + { + "type": "object", + "properties": { + "port": { + "type": [ + "integer", + "null" + ], + "format": "int32", + "minimum": 0 + } + } + }, + { + "type": "object" + } + ] + }, + "RtmpClientAudioEncoderOptions": { + "oneOf": [ + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "sample_rate": { + "type": [ + "integer", + "null" + ], + "format": "int32", + "description": "(**default=`48000`**) Sample rate. Allowed values: [8000, 16000, 24000, 44100, 48000].", + "minimum": 0 + }, + "type": { + "type": "string", + "enum": [ + "aac" + ] + } + } + } + ] + }, + "RtmpClientVideoEncoderOptions": { + "oneOf": [ + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "preset": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/H264EncoderPreset", + "description": "(**default=`\"fast\"`**) Video output encoder preset. Visit `FFmpeg` [docs](https://trac.ffmpeg.org/wiki/Encode/H.264#Preset) to learn more." + } + ] + }, + "bitrate": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/VideoEncoderBitrate", + "description": "Encoding bitrate. Default value depends on chosen encoder." + } + ] + }, + "keyframe_interval_ms": { + "type": [ + "number", + "null" + ], + "format": "double", + "description": "(**default=`5000`**) Maximal interval between keyframes, in milliseconds." + }, + "pixel_format": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/PixelFormat", + "description": "(**default=`\"yuv420p\"`**) Encoder pixel format" + } + ] + }, + "ffmpeg_options": { + "type": [ + "object", + "null" + ], + "description": "Raw FFmpeg encoder options. See [docs](https://ffmpeg.org/ffmpeg-codecs.html) for more.", + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + } + }, + "type": { + "type": "string", + "enum": [ + "ffmpeg_h264" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "bitrate": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/VideoEncoderBitrate", + "description": "Encoding bitrate. If not provided, bitrate is calculated based on resolution and framerate.\nFor example at 1080p 30 FPS the average bitrate is 5000 kbit/s and max bitrate is 6250 kbit/s." + } + ] + }, + "keyframe_interval_ms": { + "type": [ + "number", + "null" + ], + "format": "double", + "description": "(**default=`5000`**) Interval between keyframes, in milliseconds." + }, + "type": { + "type": "string", + "enum": [ + "vulkan_h264" + ] + } + } + } + ] + }, + "RtmpInput": { + "type": "object", + "required": [ + "app", + "stream_key" + ], + "properties": { + "app": { + "type": "string", + "description": "The RTMP application name.\nThis is the first path segment of the RTMP stream URL that Smelter listens on for incoming streams.\nFormat: `rtmp://://://= 300 { + return fmt.Errorf("start composition: unexpected status %d: %s", resp.StatusCode(), string(resp.Body)) + } + return nil +} + +// DeleteComposition deletes a composition by ID. +func (c *Client) DeleteComposition(apiURL, compositionID string) error { + cl, err := c.newAPI(apiURL) + if err != nil { + return err + } + resp, err := cl.DeleteCompositionWithResponse(context.Background(), compositionID) + if err != nil { + return fmt.Errorf("delete composition: %w", err) + } + if resp.StatusCode() < 200 || resp.StatusCode() >= 300 { + return fmt.Errorf("delete composition: unexpected status %d: %s", resp.StatusCode(), string(resp.Body)) + } + return nil +} + +// RegisterWhepOutput registers a WHEP server output on the composition. +func (c *Client) RegisterWhepOutput(apiURL, compositionID, outputID string) error { + cl, err := c.newAPI(apiURL) + if err != nil { + return err + } + + var videoEncoder api.WhepVideoEncoderOptions + if err := videoEncoder.FromWhepVideoEncoderOptions3(api.WhepVideoEncoderOptions3{ + Type: api.WhepVideoEncoderOptions3TypeVulkanH264, + }); err != nil { + return fmt.Errorf("build video encoder: %w", err) + } + var initialVideoRoot api.Component + if err := initialVideoRoot.FromView(api.View{}); err != nil { + return fmt.Errorf("build initial video root: %w", err) + } + + var audioEncoder api.WhepAudioEncoderOptions + if err := audioEncoder.FromWhepAudioEncoderOptions0(api.WhepAudioEncoderOptions0{ + Type: api.WhepAudioEncoderOptions0TypeOpus, + }); err != nil { + return fmt.Errorf("build audio encoder: %w", err) + } + stereo := api.Stereo + + var body api.RegisterOutput + if err := body.FromWhepOutput(api.WhepOutput{ + Video: &api.OutputWhepVideoOptions{ + Encoder: videoEncoder, + Resolution: api.Resolution{Width: 1280, Height: 720}, + Initial: api.VideoScene{Root: initialVideoRoot}, + }, + Audio: &api.OutputWhepAudioOptions{ + Encoder: audioEncoder, + Channels: &stereo, + Initial: api.AudioScene{Inputs: []api.AudioSceneInput{}}, + }, + }); err != nil { + return fmt.Errorf("build register output body: %w", err) + } + resp, err := cl.RegisterOutputWithResponse(context.Background(), compositionID, outputID, body) + if err != nil { + return fmt.Errorf("register whep output: %w", err) + } + if resp.StatusCode() < 200 || resp.StatusCode() >= 300 { + return fmt.Errorf("register whep output: unexpected status %d: %s", resp.StatusCode(), string(resp.Body)) + } + return nil +} + +// UpdateOutput updates a composition output with the given set of inputs. +func (c *Client) UpdateOutput(apiURL, compositionID, outputID string, inputs []InputEntry) error { + cl, err := c.newAPI(apiURL) + if err != nil { + return err + } + + var videoRoot api.Component + audioInputs := make([]api.AudioSceneInput, 0, len(inputs)) + + if len(inputs) == 0 { + if err := videoRoot.FromView(api.View{}); err != nil { + return fmt.Errorf("build video root: %w", err) + } + } else { + tileChildren := make([]api.Component, 0, len(inputs)) + for _, entry := range inputs { + tile, err := buildParticipantTile(entry) + if err != nil { + return err + } + tileChildren = append(tileChildren, tile) + audioInputs = append(audioInputs, api.AudioSceneInput{InputId: entry.InputID}) + } + bgColor := api.RGBAColor("#000000FF") + ratio := api.AspectRatio("16:9") + if err := videoRoot.FromTiles(api.Tiles{ + Children: &tileChildren, + BackgroundColor: &bgColor, + TileAspectRatio: &ratio, + }); err != nil { + return fmt.Errorf("build tiles component: %w", err) + } + } + + req := api.UpdateOutputRequest{ + Video: &api.VideoScene{Root: videoRoot}, + Audio: &api.AudioScene{Inputs: audioInputs}, + } + resp, err := cl.UpdateOutputWithResponse(context.Background(), compositionID, outputID, req) + if err != nil { + return fmt.Errorf("update output: %w", err) + } + if resp.StatusCode() < 200 || resp.StatusCode() >= 300 { + return fmt.Errorf("update output: unexpected status %d: %s", resp.StatusCode(), string(resp.Body)) + } + return nil +} + +// buildParticipantTile creates a Rescaler containing a View with the input stream +// and an optional name label overlay at the bottom. +func buildParticipantTile(entry InputEntry) (api.Component, error) { + // InputStream + var inputStream api.Component + if err := inputStream.FromInputStream(api.InputStream{ + InputId: entry.InputID, + }); err != nil { + return api.Component{}, fmt.Errorf("build input stream: %w", err) + } + + viewChildren := []api.Component{inputStream} + + // Name label overlay (only if name is non-empty) + if entry.PeerName != "" { + var textComp api.Component + fontSize := float32(24) + textColor := api.RGBAColor("#FFFFFFFF") + weight := api.TextWeightBold + align := api.HorizontalAlignCenter + labelWidth := float32(1280) + if err := textComp.FromText(api.Text{ + Text: entry.PeerName, + FontSize: fontSize, + Color: &textColor, + Weight: &weight, + Align: &align, + Width: &labelWidth, + }); err != nil { + return api.Component{}, fmt.Errorf("build text component: %w", err) + } + + labelChildren := []api.Component{textComp} + labelBg := api.RGBAColor("#00000088") + bottom := float32(0) + left := float32(0) + labelHeight := float32(40) + var labelView api.Component + if err := labelView.FromView(api.View{ + Children: &labelChildren, + Bottom: &bottom, + Left: &left, + Width: &labelWidth, + Height: &labelHeight, + BackgroundColor: &labelBg, + }); err != nil { + return api.Component{}, fmt.Errorf("build label view: %w", err) + } + + viewChildren = append(viewChildren, labelView) + } + + // Outer View wrapping input + label + overflow := api.OverflowHidden + viewWidth := float32(1280) + viewHeight := float32(720) + var outerView api.Component + if err := outerView.FromView(api.View{ + Children: &viewChildren, + Width: &viewWidth, + Height: &viewHeight, + Overflow: &overflow, + }); err != nil { + return api.Component{}, fmt.Errorf("build outer view: %w", err) + } + + // Rescaler + mode := api.RescaleModeFit + var rescaler api.Component + if err := rescaler.FromRescaler(api.Rescaler{ + Child: outerView, + Mode: &mode, + }); err != nil { + return api.Component{}, fmt.Errorf("build rescaler: %w", err) + } + + return rescaler, nil +} + +// WhepURL returns the WHEP playback URL for the given output. +func (c *Client) WhepURL(apiURL, compositionID, outputID string) string { + return fmt.Sprintf("%s/api/composition/%s/whep/%s", apiURL, compositionID, outputID) +} + +// CompositionBaseURL returns the composition base URL used for track forwarding. +func (c *Client) CompositionBaseURL(apiURL, compositionID string) string { + return fmt.Sprintf("%s/api/composition/%s", apiURL, compositionID) +} diff --git a/conference-to-stream/backend/composition/generated/composition.gen.go b/conference-to-stream/backend/composition/generated/composition.gen.go new file mode 100644 index 0000000..bb570cd --- /dev/null +++ b/conference-to-stream/backend/composition/generated/composition.gen.go @@ -0,0 +1,7362 @@ +// Package compositionapi provides primitives to interact with the openapi HTTP API. +// +// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.0.0 DO NOT EDIT. +package compositionapi + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "strings" + + "github.com/oapi-codegen/runtime" + openapi_types "github.com/oapi-codegen/runtime/types" +) + +const ( + BearerAuthScopes bearerAuthContextKey = "BearerAuth.Scopes" +) + +// Defines values for AacRtpMode. +const ( + HighBitrate AacRtpMode = "high_bitrate" + LowBitrate AacRtpMode = "low_bitrate" +) + +// Valid indicates whether the value is a known member of the AacRtpMode enum. +func (e AacRtpMode) Valid() bool { + switch e { + case HighBitrate: + return true + case LowBitrate: + return true + default: + return false + } +} + +// Defines values for AudioChannels. +const ( + Mono AudioChannels = "mono" + Stereo AudioChannels = "stereo" +) + +// Valid indicates whether the value is a known member of the AudioChannels enum. +func (e AudioChannels) Valid() bool { + switch e { + case Mono: + return true + case Stereo: + return true + default: + return false + } +} + +// Defines values for AudioMixingStrategy. +const ( + SumClip AudioMixingStrategy = "sum_clip" + SumScale AudioMixingStrategy = "sum_scale" +) + +// Valid indicates whether the value is a known member of the AudioMixingStrategy enum. +func (e AudioMixingStrategy) Valid() bool { + switch e { + case SumClip: + return true + case SumScale: + return true + default: + return false + } +} + +// Defines values for EasingFunction0FunctionName. +const ( + Linear EasingFunction0FunctionName = "linear" +) + +// Valid indicates whether the value is a known member of the EasingFunction0FunctionName enum. +func (e EasingFunction0FunctionName) Valid() bool { + switch e { + case Linear: + return true + default: + return false + } +} + +// Defines values for EasingFunction1FunctionName. +const ( + Bounce EasingFunction1FunctionName = "bounce" +) + +// Valid indicates whether the value is a known member of the EasingFunction1FunctionName enum. +func (e EasingFunction1FunctionName) Valid() bool { + switch e { + case Bounce: + return true + default: + return false + } +} + +// Defines values for EasingFunction2FunctionName. +const ( + CubicBezier EasingFunction2FunctionName = "cubic_bezier" +) + +// Valid indicates whether the value is a known member of the EasingFunction2FunctionName enum. +func (e EasingFunction2FunctionName) Valid() bool { + switch e { + case CubicBezier: + return true + default: + return false + } +} + +// Defines values for H264EncoderPreset. +const ( + H264EncoderPresetFast H264EncoderPreset = "fast" + H264EncoderPresetFaster H264EncoderPreset = "faster" + H264EncoderPresetMedium H264EncoderPreset = "medium" + H264EncoderPresetPlacebo H264EncoderPreset = "placebo" + H264EncoderPresetSlow H264EncoderPreset = "slow" + H264EncoderPresetSlower H264EncoderPreset = "slower" + H264EncoderPresetSuperfast H264EncoderPreset = "superfast" + H264EncoderPresetUltrafast H264EncoderPreset = "ultrafast" + H264EncoderPresetVeryfast H264EncoderPreset = "veryfast" + H264EncoderPresetVeryslow H264EncoderPreset = "veryslow" +) + +// Valid indicates whether the value is a known member of the H264EncoderPreset enum. +func (e H264EncoderPreset) Valid() bool { + switch e { + case H264EncoderPresetFast: + return true + case H264EncoderPresetFaster: + return true + case H264EncoderPresetMedium: + return true + case H264EncoderPresetPlacebo: + return true + case H264EncoderPresetSlow: + return true + case H264EncoderPresetSlower: + return true + case H264EncoderPresetSuperfast: + return true + case H264EncoderPresetUltrafast: + return true + case H264EncoderPresetVeryfast: + return true + case H264EncoderPresetVeryslow: + return true + default: + return false + } +} + +// Defines values for HlsAudioEncoderOptions0Type. +const ( + HlsAudioEncoderOptions0TypeAac HlsAudioEncoderOptions0Type = "aac" +) + +// Valid indicates whether the value is a known member of the HlsAudioEncoderOptions0Type enum. +func (e HlsAudioEncoderOptions0Type) Valid() bool { + switch e { + case HlsAudioEncoderOptions0TypeAac: + return true + default: + return false + } +} + +// Defines values for HlsVideoEncoderOptions0Type. +const ( + HlsVideoEncoderOptions0TypeFfmpegH264 HlsVideoEncoderOptions0Type = "ffmpeg_h264" +) + +// Valid indicates whether the value is a known member of the HlsVideoEncoderOptions0Type enum. +func (e HlsVideoEncoderOptions0Type) Valid() bool { + switch e { + case HlsVideoEncoderOptions0TypeFfmpegH264: + return true + default: + return false + } +} + +// Defines values for HlsVideoEncoderOptions1Type. +const ( + HlsVideoEncoderOptions1TypeVulkanH264 HlsVideoEncoderOptions1Type = "vulkan_h264" +) + +// Valid indicates whether the value is a known member of the HlsVideoEncoderOptions1Type enum. +func (e HlsVideoEncoderOptions1Type) Valid() bool { + switch e { + case HlsVideoEncoderOptions1TypeVulkanH264: + return true + default: + return false + } +} + +// Defines values for HorizontalAlign. +const ( + HorizontalAlignCenter HorizontalAlign = "center" + HorizontalAlignJustified HorizontalAlign = "justified" + HorizontalAlignLeft HorizontalAlign = "left" + HorizontalAlignRight HorizontalAlign = "right" +) + +// Valid indicates whether the value is a known member of the HorizontalAlign enum. +func (e HorizontalAlign) Valid() bool { + switch e { + case HorizontalAlignCenter: + return true + case HorizontalAlignJustified: + return true + case HorizontalAlignLeft: + return true + case HorizontalAlignRight: + return true + default: + return false + } +} + +// Defines values for ImageSpec0AssetType. +const ( + Png ImageSpec0AssetType = "png" +) + +// Valid indicates whether the value is a known member of the ImageSpec0AssetType enum. +func (e ImageSpec0AssetType) Valid() bool { + switch e { + case Png: + return true + default: + return false + } +} + +// Defines values for ImageSpec1AssetType. +const ( + Jpeg ImageSpec1AssetType = "jpeg" +) + +// Valid indicates whether the value is a known member of the ImageSpec1AssetType enum. +func (e ImageSpec1AssetType) Valid() bool { + switch e { + case Jpeg: + return true + default: + return false + } +} + +// Defines values for ImageSpec2AssetType. +const ( + Svg ImageSpec2AssetType = "svg" +) + +// Valid indicates whether the value is a known member of the ImageSpec2AssetType enum. +func (e ImageSpec2AssetType) Valid() bool { + switch e { + case Svg: + return true + default: + return false + } +} + +// Defines values for ImageSpec3AssetType. +const ( + Gif ImageSpec3AssetType = "gif" +) + +// Valid indicates whether the value is a known member of the ImageSpec3AssetType enum. +func (e ImageSpec3AssetType) Valid() bool { + switch e { + case Gif: + return true + default: + return false + } +} + +// Defines values for ImageSpec4AssetType. +const ( + Auto ImageSpec4AssetType = "auto" +) + +// Valid indicates whether the value is a known member of the ImageSpec4AssetType enum. +func (e ImageSpec4AssetType) Valid() bool { + switch e { + case Auto: + return true + default: + return false + } +} + +// Defines values for InputRtpAudioOptions0Decoder. +const ( + InputRtpAudioOptions0DecoderOpus InputRtpAudioOptions0Decoder = "opus" +) + +// Valid indicates whether the value is a known member of the InputRtpAudioOptions0Decoder enum. +func (e InputRtpAudioOptions0Decoder) Valid() bool { + switch e { + case InputRtpAudioOptions0DecoderOpus: + return true + default: + return false + } +} + +// Defines values for InputRtpAudioOptions1Decoder. +const ( + InputRtpAudioOptions1DecoderAac InputRtpAudioOptions1Decoder = "aac" +) + +// Valid indicates whether the value is a known member of the InputRtpAudioOptions1Decoder enum. +func (e InputRtpAudioOptions1Decoder) Valid() bool { + switch e { + case InputRtpAudioOptions1DecoderAac: + return true + default: + return false + } +} + +// Defines values for Mp4AudioEncoderOptions0Type. +const ( + Mp4AudioEncoderOptions0TypeAac Mp4AudioEncoderOptions0Type = "aac" +) + +// Valid indicates whether the value is a known member of the Mp4AudioEncoderOptions0Type enum. +func (e Mp4AudioEncoderOptions0Type) Valid() bool { + switch e { + case Mp4AudioEncoderOptions0TypeAac: + return true + default: + return false + } +} + +// Defines values for Mp4VideoEncoderOptions0Type. +const ( + Mp4VideoEncoderOptions0TypeFfmpegH264 Mp4VideoEncoderOptions0Type = "ffmpeg_h264" +) + +// Valid indicates whether the value is a known member of the Mp4VideoEncoderOptions0Type enum. +func (e Mp4VideoEncoderOptions0Type) Valid() bool { + switch e { + case Mp4VideoEncoderOptions0TypeFfmpegH264: + return true + default: + return false + } +} + +// Defines values for Mp4VideoEncoderOptions1Type. +const ( + Mp4VideoEncoderOptions1TypeVulkanH264 Mp4VideoEncoderOptions1Type = "vulkan_h264" +) + +// Valid indicates whether the value is a known member of the Mp4VideoEncoderOptions1Type enum. +func (e Mp4VideoEncoderOptions1Type) Valid() bool { + switch e { + case Mp4VideoEncoderOptions1TypeVulkanH264: + return true + default: + return false + } +} + +// Defines values for OpusEncoderPreset. +const ( + LowestLatency OpusEncoderPreset = "lowest_latency" + Quality OpusEncoderPreset = "quality" + Voip OpusEncoderPreset = "voip" +) + +// Valid indicates whether the value is a known member of the OpusEncoderPreset enum. +func (e OpusEncoderPreset) Valid() bool { + switch e { + case LowestLatency: + return true + case Quality: + return true + case Voip: + return true + default: + return false + } +} + +// Defines values for Overflow. +const ( + OverflowFit Overflow = "fit" + OverflowHidden Overflow = "hidden" + OverflowVisible Overflow = "visible" +) + +// Valid indicates whether the value is a known member of the Overflow enum. +func (e Overflow) Valid() bool { + switch e { + case OverflowFit: + return true + case OverflowHidden: + return true + case OverflowVisible: + return true + default: + return false + } +} + +// Defines values for PixelFormat. +const ( + Yuv420p PixelFormat = "yuv420p" + Yuv422p PixelFormat = "yuv422p" + Yuv444p PixelFormat = "yuv444p" +) + +// Valid indicates whether the value is a known member of the PixelFormat enum. +func (e PixelFormat) Valid() bool { + switch e { + case Yuv420p: + return true + case Yuv422p: + return true + case Yuv444p: + return true + default: + return false + } +} + +// Defines values for RescaleMode. +const ( + RescaleModeFill RescaleMode = "fill" + RescaleModeFit RescaleMode = "fit" +) + +// Valid indicates whether the value is a known member of the RescaleMode enum. +func (e RescaleMode) Valid() bool { + switch e { + case RescaleModeFill: + return true + case RescaleModeFit: + return true + default: + return false + } +} + +// Defines values for RtmpClientAudioEncoderOptions0Type. +const ( + RtmpClientAudioEncoderOptions0TypeAac RtmpClientAudioEncoderOptions0Type = "aac" +) + +// Valid indicates whether the value is a known member of the RtmpClientAudioEncoderOptions0Type enum. +func (e RtmpClientAudioEncoderOptions0Type) Valid() bool { + switch e { + case RtmpClientAudioEncoderOptions0TypeAac: + return true + default: + return false + } +} + +// Defines values for RtmpClientVideoEncoderOptions0Type. +const ( + RtmpClientVideoEncoderOptions0TypeFfmpegH264 RtmpClientVideoEncoderOptions0Type = "ffmpeg_h264" +) + +// Valid indicates whether the value is a known member of the RtmpClientVideoEncoderOptions0Type enum. +func (e RtmpClientVideoEncoderOptions0Type) Valid() bool { + switch e { + case RtmpClientVideoEncoderOptions0TypeFfmpegH264: + return true + default: + return false + } +} + +// Defines values for RtmpClientVideoEncoderOptions1Type. +const ( + RtmpClientVideoEncoderOptions1TypeVulkanH264 RtmpClientVideoEncoderOptions1Type = "vulkan_h264" +) + +// Valid indicates whether the value is a known member of the RtmpClientVideoEncoderOptions1Type enum. +func (e RtmpClientVideoEncoderOptions1Type) Valid() bool { + switch e { + case RtmpClientVideoEncoderOptions1TypeVulkanH264: + return true + default: + return false + } +} + +// Defines values for RtpAudioEncoderOptions0Type. +const ( + RtpAudioEncoderOptions0TypeOpus RtpAudioEncoderOptions0Type = "opus" +) + +// Valid indicates whether the value is a known member of the RtpAudioEncoderOptions0Type enum. +func (e RtpAudioEncoderOptions0Type) Valid() bool { + switch e { + case RtpAudioEncoderOptions0TypeOpus: + return true + default: + return false + } +} + +// Defines values for RtpVideoDecoderOptions. +const ( + RtpVideoDecoderOptionsFfmpegH264 RtpVideoDecoderOptions = "ffmpeg_h264" + RtpVideoDecoderOptionsFfmpegVp8 RtpVideoDecoderOptions = "ffmpeg_vp8" + RtpVideoDecoderOptionsFfmpegVp9 RtpVideoDecoderOptions = "ffmpeg_vp9" + RtpVideoDecoderOptionsVulkanH264 RtpVideoDecoderOptions = "vulkan_h264" +) + +// Valid indicates whether the value is a known member of the RtpVideoDecoderOptions enum. +func (e RtpVideoDecoderOptions) Valid() bool { + switch e { + case RtpVideoDecoderOptionsFfmpegH264: + return true + case RtpVideoDecoderOptionsFfmpegVp8: + return true + case RtpVideoDecoderOptionsFfmpegVp9: + return true + case RtpVideoDecoderOptionsVulkanH264: + return true + default: + return false + } +} + +// Defines values for RtpVideoEncoderOptions0Type. +const ( + RtpVideoEncoderOptions0TypeFfmpegH264 RtpVideoEncoderOptions0Type = "ffmpeg_h264" +) + +// Valid indicates whether the value is a known member of the RtpVideoEncoderOptions0Type enum. +func (e RtpVideoEncoderOptions0Type) Valid() bool { + switch e { + case RtpVideoEncoderOptions0TypeFfmpegH264: + return true + default: + return false + } +} + +// Defines values for RtpVideoEncoderOptions1Type. +const ( + RtpVideoEncoderOptions1TypeFfmpegVp8 RtpVideoEncoderOptions1Type = "ffmpeg_vp8" +) + +// Valid indicates whether the value is a known member of the RtpVideoEncoderOptions1Type enum. +func (e RtpVideoEncoderOptions1Type) Valid() bool { + switch e { + case RtpVideoEncoderOptions1TypeFfmpegVp8: + return true + default: + return false + } +} + +// Defines values for RtpVideoEncoderOptions2Type. +const ( + RtpVideoEncoderOptions2TypeFfmpegVp9 RtpVideoEncoderOptions2Type = "ffmpeg_vp9" +) + +// Valid indicates whether the value is a known member of the RtpVideoEncoderOptions2Type enum. +func (e RtpVideoEncoderOptions2Type) Valid() bool { + switch e { + case RtpVideoEncoderOptions2TypeFfmpegVp9: + return true + default: + return false + } +} + +// Defines values for RtpVideoEncoderOptions3Type. +const ( + RtpVideoEncoderOptions3TypeVulkanH264 RtpVideoEncoderOptions3Type = "vulkan_h264" +) + +// Valid indicates whether the value is a known member of the RtpVideoEncoderOptions3Type enum. +func (e RtpVideoEncoderOptions3Type) Valid() bool { + switch e { + case RtpVideoEncoderOptions3TypeVulkanH264: + return true + default: + return false + } +} + +// Defines values for ShaderParam0Type. +const ( + ShaderParam0TypeF32 ShaderParam0Type = "f32" +) + +// Valid indicates whether the value is a known member of the ShaderParam0Type enum. +func (e ShaderParam0Type) Valid() bool { + switch e { + case ShaderParam0TypeF32: + return true + default: + return false + } +} + +// Defines values for ShaderParam1Type. +const ( + ShaderParam1TypeU32 ShaderParam1Type = "u32" +) + +// Valid indicates whether the value is a known member of the ShaderParam1Type enum. +func (e ShaderParam1Type) Valid() bool { + switch e { + case ShaderParam1TypeU32: + return true + default: + return false + } +} + +// Defines values for ShaderParam2Type. +const ( + ShaderParam2TypeI32 ShaderParam2Type = "i32" +) + +// Valid indicates whether the value is a known member of the ShaderParam2Type enum. +func (e ShaderParam2Type) Valid() bool { + switch e { + case ShaderParam2TypeI32: + return true + default: + return false + } +} + +// Defines values for ShaderParam3Type. +const ( + ShaderParam3TypeList ShaderParam3Type = "list" +) + +// Valid indicates whether the value is a known member of the ShaderParam3Type enum. +func (e ShaderParam3Type) Valid() bool { + switch e { + case ShaderParam3TypeList: + return true + default: + return false + } +} + +// Defines values for ShaderParam4Type. +const ( + ShaderParam4TypeStruct ShaderParam4Type = "struct" +) + +// Valid indicates whether the value is a known member of the ShaderParam4Type enum. +func (e ShaderParam4Type) Valid() bool { + switch e { + case ShaderParam4TypeStruct: + return true + default: + return false + } +} + +// Defines values for ShaderParamStructField0Type. +const ( + ShaderParamStructField0TypeF32 ShaderParamStructField0Type = "f32" +) + +// Valid indicates whether the value is a known member of the ShaderParamStructField0Type enum. +func (e ShaderParamStructField0Type) Valid() bool { + switch e { + case ShaderParamStructField0TypeF32: + return true + default: + return false + } +} + +// Defines values for ShaderParamStructField1Type. +const ( + ShaderParamStructField1TypeU32 ShaderParamStructField1Type = "u32" +) + +// Valid indicates whether the value is a known member of the ShaderParamStructField1Type enum. +func (e ShaderParamStructField1Type) Valid() bool { + switch e { + case ShaderParamStructField1TypeU32: + return true + default: + return false + } +} + +// Defines values for ShaderParamStructField2Type. +const ( + ShaderParamStructField2TypeI32 ShaderParamStructField2Type = "i32" +) + +// Valid indicates whether the value is a known member of the ShaderParamStructField2Type enum. +func (e ShaderParamStructField2Type) Valid() bool { + switch e { + case ShaderParamStructField2TypeI32: + return true + default: + return false + } +} + +// Defines values for ShaderParamStructField3Type. +const ( + ShaderParamStructField3TypeList ShaderParamStructField3Type = "list" +) + +// Valid indicates whether the value is a known member of the ShaderParamStructField3Type enum. +func (e ShaderParamStructField3Type) Valid() bool { + switch e { + case ShaderParamStructField3TypeList: + return true + default: + return false + } +} + +// Defines values for ShaderParamStructField4Type. +const ( + ShaderParamStructField4TypeStruct ShaderParamStructField4Type = "struct" +) + +// Valid indicates whether the value is a known member of the ShaderParamStructField4Type enum. +func (e ShaderParamStructField4Type) Valid() bool { + switch e { + case ShaderParamStructField4TypeStruct: + return true + default: + return false + } +} + +// Defines values for TextStyle. +const ( + Italic TextStyle = "italic" + Normal TextStyle = "normal" + Oblique TextStyle = "oblique" +) + +// Valid indicates whether the value is a known member of the TextStyle enum. +func (e TextStyle) Valid() bool { + switch e { + case Italic: + return true + case Normal: + return true + case Oblique: + return true + default: + return false + } +} + +// Defines values for TextWeight. +const ( + TextWeightBlack TextWeight = "black" + TextWeightBold TextWeight = "bold" + TextWeightExtraBold TextWeight = "extra_bold" + TextWeightExtraLight TextWeight = "extra_light" + TextWeightLight TextWeight = "light" + TextWeightMedium TextWeight = "medium" + TextWeightNormal TextWeight = "normal" + TextWeightSemiBold TextWeight = "semi_bold" + TextWeightThin TextWeight = "thin" +) + +// Valid indicates whether the value is a known member of the TextWeight enum. +func (e TextWeight) Valid() bool { + switch e { + case TextWeightBlack: + return true + case TextWeightBold: + return true + case TextWeightExtraBold: + return true + case TextWeightExtraLight: + return true + case TextWeightLight: + return true + case TextWeightMedium: + return true + case TextWeightNormal: + return true + case TextWeightSemiBold: + return true + case TextWeightThin: + return true + default: + return false + } +} + +// Defines values for TextWrapMode. +const ( + Glyph TextWrapMode = "glyph" + None TextWrapMode = "none" + Word TextWrapMode = "word" +) + +// Valid indicates whether the value is a known member of the TextWrapMode enum. +func (e TextWrapMode) Valid() bool { + switch e { + case Glyph: + return true + case None: + return true + case Word: + return true + default: + return false + } +} + +// Defines values for TransportProtocol. +const ( + TcpServer TransportProtocol = "tcp_server" + Udp TransportProtocol = "udp" +) + +// Valid indicates whether the value is a known member of the TransportProtocol enum. +func (e TransportProtocol) Valid() bool { + switch e { + case TcpServer: + return true + case Udp: + return true + default: + return false + } +} + +// Defines values for VerticalAlign. +const ( + VerticalAlignBottom VerticalAlign = "bottom" + VerticalAlignCenter VerticalAlign = "center" + VerticalAlignJustified VerticalAlign = "justified" + VerticalAlignTop VerticalAlign = "top" +) + +// Valid indicates whether the value is a known member of the VerticalAlign enum. +func (e VerticalAlign) Valid() bool { + switch e { + case VerticalAlignBottom: + return true + case VerticalAlignCenter: + return true + case VerticalAlignJustified: + return true + case VerticalAlignTop: + return true + default: + return false + } +} + +// Defines values for ViewDirection. +const ( + Column ViewDirection = "column" + Row ViewDirection = "row" +) + +// Valid indicates whether the value is a known member of the ViewDirection enum. +func (e ViewDirection) Valid() bool { + switch e { + case Column: + return true + case Row: + return true + default: + return false + } +} + +// Defines values for WhepAudioEncoderOptions0Type. +const ( + WhepAudioEncoderOptions0TypeOpus WhepAudioEncoderOptions0Type = "opus" +) + +// Valid indicates whether the value is a known member of the WhepAudioEncoderOptions0Type enum. +func (e WhepAudioEncoderOptions0Type) Valid() bool { + switch e { + case WhepAudioEncoderOptions0TypeOpus: + return true + default: + return false + } +} + +// Defines values for WhepVideoDecoderOptions. +const ( + WhepVideoDecoderOptionsAny WhepVideoDecoderOptions = "any" + WhepVideoDecoderOptionsFfmpegH264 WhepVideoDecoderOptions = "ffmpeg_h264" + WhepVideoDecoderOptionsFfmpegVp8 WhepVideoDecoderOptions = "ffmpeg_vp8" + WhepVideoDecoderOptionsFfmpegVp9 WhepVideoDecoderOptions = "ffmpeg_vp9" + WhepVideoDecoderOptionsVulkanH264 WhepVideoDecoderOptions = "vulkan_h264" +) + +// Valid indicates whether the value is a known member of the WhepVideoDecoderOptions enum. +func (e WhepVideoDecoderOptions) Valid() bool { + switch e { + case WhepVideoDecoderOptionsAny: + return true + case WhepVideoDecoderOptionsFfmpegH264: + return true + case WhepVideoDecoderOptionsFfmpegVp8: + return true + case WhepVideoDecoderOptionsFfmpegVp9: + return true + case WhepVideoDecoderOptionsVulkanH264: + return true + default: + return false + } +} + +// Defines values for WhepVideoEncoderOptions0Type. +const ( + WhepVideoEncoderOptions0TypeFfmpegH264 WhepVideoEncoderOptions0Type = "ffmpeg_h264" +) + +// Valid indicates whether the value is a known member of the WhepVideoEncoderOptions0Type enum. +func (e WhepVideoEncoderOptions0Type) Valid() bool { + switch e { + case WhepVideoEncoderOptions0TypeFfmpegH264: + return true + default: + return false + } +} + +// Defines values for WhepVideoEncoderOptions1Type. +const ( + WhepVideoEncoderOptions1TypeFfmpegVp8 WhepVideoEncoderOptions1Type = "ffmpeg_vp8" +) + +// Valid indicates whether the value is a known member of the WhepVideoEncoderOptions1Type enum. +func (e WhepVideoEncoderOptions1Type) Valid() bool { + switch e { + case WhepVideoEncoderOptions1TypeFfmpegVp8: + return true + default: + return false + } +} + +// Defines values for WhepVideoEncoderOptions2Type. +const ( + WhepVideoEncoderOptions2TypeFfmpegVp9 WhepVideoEncoderOptions2Type = "ffmpeg_vp9" +) + +// Valid indicates whether the value is a known member of the WhepVideoEncoderOptions2Type enum. +func (e WhepVideoEncoderOptions2Type) Valid() bool { + switch e { + case WhepVideoEncoderOptions2TypeFfmpegVp9: + return true + default: + return false + } +} + +// Defines values for WhepVideoEncoderOptions3Type. +const ( + WhepVideoEncoderOptions3TypeVulkanH264 WhepVideoEncoderOptions3Type = "vulkan_h264" +) + +// Valid indicates whether the value is a known member of the WhepVideoEncoderOptions3Type enum. +func (e WhepVideoEncoderOptions3Type) Valid() bool { + switch e { + case WhepVideoEncoderOptions3TypeVulkanH264: + return true + default: + return false + } +} + +// Defines values for WhipAudioEncoderOptions0Type. +const ( + WhipAudioEncoderOptions0TypeOpus WhipAudioEncoderOptions0Type = "opus" +) + +// Valid indicates whether the value is a known member of the WhipAudioEncoderOptions0Type enum. +func (e WhipAudioEncoderOptions0Type) Valid() bool { + switch e { + case WhipAudioEncoderOptions0TypeOpus: + return true + default: + return false + } +} + +// Defines values for WhipAudioEncoderOptions1Type. +const ( + WhipAudioEncoderOptions1TypeAny WhipAudioEncoderOptions1Type = "any" +) + +// Valid indicates whether the value is a known member of the WhipAudioEncoderOptions1Type enum. +func (e WhipAudioEncoderOptions1Type) Valid() bool { + switch e { + case WhipAudioEncoderOptions1TypeAny: + return true + default: + return false + } +} + +// Defines values for WhipVideoDecoderOptions. +const ( + WhipVideoDecoderOptionsAny WhipVideoDecoderOptions = "any" + WhipVideoDecoderOptionsFfmpegH264 WhipVideoDecoderOptions = "ffmpeg_h264" + WhipVideoDecoderOptionsFfmpegVp8 WhipVideoDecoderOptions = "ffmpeg_vp8" + WhipVideoDecoderOptionsFfmpegVp9 WhipVideoDecoderOptions = "ffmpeg_vp9" + WhipVideoDecoderOptionsVulkanH264 WhipVideoDecoderOptions = "vulkan_h264" +) + +// Valid indicates whether the value is a known member of the WhipVideoDecoderOptions enum. +func (e WhipVideoDecoderOptions) Valid() bool { + switch e { + case WhipVideoDecoderOptionsAny: + return true + case WhipVideoDecoderOptionsFfmpegH264: + return true + case WhipVideoDecoderOptionsFfmpegVp8: + return true + case WhipVideoDecoderOptionsFfmpegVp9: + return true + case WhipVideoDecoderOptionsVulkanH264: + return true + default: + return false + } +} + +// Defines values for WhipVideoEncoderOptions0Type. +const ( + FfmpegH264 WhipVideoEncoderOptions0Type = "ffmpeg_h264" +) + +// Valid indicates whether the value is a known member of the WhipVideoEncoderOptions0Type enum. +func (e WhipVideoEncoderOptions0Type) Valid() bool { + switch e { + case FfmpegH264: + return true + default: + return false + } +} + +// Defines values for WhipVideoEncoderOptions1Type. +const ( + FfmpegVp8 WhipVideoEncoderOptions1Type = "ffmpeg_vp8" +) + +// Valid indicates whether the value is a known member of the WhipVideoEncoderOptions1Type enum. +func (e WhipVideoEncoderOptions1Type) Valid() bool { + switch e { + case FfmpegVp8: + return true + default: + return false + } +} + +// Defines values for WhipVideoEncoderOptions2Type. +const ( + FfmpegVp9 WhipVideoEncoderOptions2Type = "ffmpeg_vp9" +) + +// Valid indicates whether the value is a known member of the WhipVideoEncoderOptions2Type enum. +func (e WhipVideoEncoderOptions2Type) Valid() bool { + switch e { + case FfmpegVp9: + return true + default: + return false + } +} + +// Defines values for WhipVideoEncoderOptions3Type. +const ( + WhipVideoEncoderOptions3TypeVulkanH264 WhipVideoEncoderOptions3Type = "vulkan_h264" +) + +// Valid indicates whether the value is a known member of the WhipVideoEncoderOptions3Type enum. +func (e WhipVideoEncoderOptions3Type) Valid() bool { + switch e { + case WhipVideoEncoderOptions3TypeVulkanH264: + return true + default: + return false + } +} + +// Defines values for WhipVideoEncoderOptions4Type. +const ( + WhipVideoEncoderOptions4TypeAny WhipVideoEncoderOptions4Type = "any" +) + +// Valid indicates whether the value is a known member of the WhipVideoEncoderOptions4Type enum. +func (e WhipVideoEncoderOptions4Type) Valid() bool { + switch e { + case WhipVideoEncoderOptions4TypeAny: + return true + default: + return false + } +} + +// AacRtpMode defines model for AacRtpMode. +type AacRtpMode string + +// ApiError defines model for ApiError. +type ApiError struct { + HttpStatusCode int32 `json:"http_status_code"` + Message string `json:"message"` +} + +// AspectRatio defines model for AspectRatio. +type AspectRatio = string + +// AudioChannels defines model for AudioChannels. +type AudioChannels string + +// AudioMixingStrategy defines model for AudioMixingStrategy. +type AudioMixingStrategy string + +// AudioScene defines model for AudioScene. +type AudioScene struct { + Inputs []AudioSceneInput `json:"inputs"` +} + +// AudioSceneInput defines model for AudioSceneInput. +type AudioSceneInput struct { + InputId InputId `json:"input_id"` + + // Volume (**default=`1.0`**) float in `[0, 2]` range representing input volume + Volume *float32 `json:"volume,omitempty"` +} + +// BoxShadow defines model for BoxShadow. +type BoxShadow struct { + BlurRadius *float32 `json:"blur_radius,omitempty"` + Color *RGBAColor `json:"color,omitempty"` + OffsetX *float32 `json:"offset_x,omitempty"` + OffsetY *float32 `json:"offset_y,omitempty"` +} + +// Component defines model for Component. +type Component struct { + union json.RawMessage +} + +// ComponentId defines model for ComponentId. +type ComponentId = string + +// CompositionCreatedResponse defines model for CompositionCreatedResponse. +type CompositionCreatedResponse struct { + ApiUrl string `json:"api_url"` + CompositionId CompositionId `json:"composition_id"` +} + +// CompositionId defines model for CompositionId. +type CompositionId = string + +// CreateCompositionRequest defines model for CreateCompositionRequest. +type CreateCompositionRequest struct { + // Autostart If true, outputs will immediately start producing audio and video. + // If false, call `POST /api/composition/{composition_id}/start` to start the composition. + Autostart *bool `json:"autostart,omitempty"` +} + +// EasingFunction Easing functions are used to interpolate between two values over time. +// +// Custom easing functions can be implemented with cubic Bézier. +// The control points are defined with `points` field by providing four numerical values: `x1`, `y1`, `x2` and `y2`. The `x1` and `x2` values have to be in the range `[0; 1]`. The cubic Bézier result is clamped to the range `[0; 1]`. +// You can find example control point configurations [here](https://easings.net/). +type EasingFunction struct { + union json.RawMessage +} + +// EasingFunction0 defines model for . +type EasingFunction0 struct { + FunctionName EasingFunction0FunctionName `json:"function_name"` +} + +// EasingFunction0FunctionName defines model for EasingFunction.0.FunctionName. +type EasingFunction0FunctionName string + +// EasingFunction1 defines model for . +type EasingFunction1 struct { + FunctionName EasingFunction1FunctionName `json:"function_name"` +} + +// EasingFunction1FunctionName defines model for EasingFunction.1.FunctionName. +type EasingFunction1FunctionName string + +// EasingFunction2 defines model for . +type EasingFunction2 struct { + FunctionName EasingFunction2FunctionName `json:"function_name"` + Points []float64 `json:"points"` +} + +// EasingFunction2FunctionName defines model for EasingFunction.2.FunctionName. +type EasingFunction2FunctionName string + +// H264EncoderPreset defines model for H264EncoderPreset. +type H264EncoderPreset string + +// HlsAudioEncoderOptions defines model for HlsAudioEncoderOptions. +type HlsAudioEncoderOptions struct { + union json.RawMessage +} + +// HlsAudioEncoderOptions0 defines model for . +type HlsAudioEncoderOptions0 struct { + // SampleRate (**default=`44100`**) Sample rate. Allowed values: [8000, 16000, 24000, 44100, 48000]. + SampleRate *int32 `json:"sample_rate,omitempty"` + Type HlsAudioEncoderOptions0Type `json:"type"` +} + +// HlsAudioEncoderOptions0Type defines model for HlsAudioEncoderOptions.0.Type. +type HlsAudioEncoderOptions0Type string + +// HlsInput Parameters for an input stream from HLS source. +type HlsInput struct { + // OffsetMs Offset in milliseconds relative to the pipeline start (start request). If the offset is + // not defined then the stream will be synchronized based on the delivery time of the initial + // frames. + OffsetMs *float64 `json:"offset_ms,omitempty"` + + // Required (**default=`false`**) If input is required and the stream is not delivered + // on time, then Smelter will delay producing output frames. + Required *bool `json:"required,omitempty"` + + // Url URL to HLS playlist + Url string `json:"url"` +} + +// HlsOutput defines model for HlsOutput. +type HlsOutput struct { + Audio *OutputHlsAudioOptions `json:"audio,omitempty"` + + // MaxPlaylistSize Number of segments kept in the playlist. When the limit is reached the oldest segment is removed. + // If not specified, no segments will removed. + MaxPlaylistSize *int `json:"max_playlist_size,omitempty"` + + // Path Path to output HLS playlist. + Path string `json:"path"` + Video *OutputHlsVideoOptions `json:"video,omitempty"` +} + +// HlsVideoEncoderOptions defines model for HlsVideoEncoderOptions. +type HlsVideoEncoderOptions struct { + union json.RawMessage +} + +// HlsVideoEncoderOptions0 defines model for . +type HlsVideoEncoderOptions0 struct { + Bitrate *VideoEncoderBitrate `json:"bitrate,omitempty"` + + // FfmpegOptions Raw FFmpeg encoder options. See [docs](https://ffmpeg.org/ffmpeg-codecs.html) for more. + FfmpegOptions *map[string]string `json:"ffmpeg_options,omitempty"` + + // KeyframeIntervalMs (**default=`5000`**) Maximal interval between keyframes, in milliseconds. + KeyframeIntervalMs *float64 `json:"keyframe_interval_ms,omitempty"` + PixelFormat *PixelFormat `json:"pixel_format,omitempty"` + Preset *H264EncoderPreset `json:"preset,omitempty"` + Type HlsVideoEncoderOptions0Type `json:"type"` +} + +// HlsVideoEncoderOptions0Type defines model for HlsVideoEncoderOptions.0.Type. +type HlsVideoEncoderOptions0Type string + +// HlsVideoEncoderOptions1 defines model for . +type HlsVideoEncoderOptions1 struct { + Bitrate *VideoEncoderBitrate `json:"bitrate,omitempty"` + + // KeyframeIntervalMs (**default=`5000`**) Interval between keyframes, in milliseconds. + KeyframeIntervalMs *float64 `json:"keyframe_interval_ms,omitempty"` + Type HlsVideoEncoderOptions1Type `json:"type"` +} + +// HlsVideoEncoderOptions1Type defines model for HlsVideoEncoderOptions.1.Type. +type HlsVideoEncoderOptions1Type string + +// HorizontalAlign defines model for HorizontalAlign. +type HorizontalAlign string + +// ImageSpec defines model for ImageSpec. +type ImageSpec struct { + union json.RawMessage +} + +// ImageSpec0 defines model for . +type ImageSpec0 struct { + AssetType ImageSpec0AssetType `json:"asset_type"` + Url *string `json:"url,omitempty"` +} + +// ImageSpec0AssetType defines model for ImageSpec.0.AssetType. +type ImageSpec0AssetType string + +// ImageSpec1 defines model for . +type ImageSpec1 struct { + AssetType ImageSpec1AssetType `json:"asset_type"` + Url *string `json:"url,omitempty"` +} + +// ImageSpec1AssetType defines model for ImageSpec.1.AssetType. +type ImageSpec1AssetType string + +// ImageSpec2 defines model for . +type ImageSpec2 struct { + AssetType ImageSpec2AssetType `json:"asset_type"` + Resolution *Resolution `json:"resolution,omitempty"` + Url *string `json:"url,omitempty"` +} + +// ImageSpec2AssetType defines model for ImageSpec.2.AssetType. +type ImageSpec2AssetType string + +// ImageSpec3 defines model for . +type ImageSpec3 struct { + AssetType ImageSpec3AssetType `json:"asset_type"` + Url *string `json:"url,omitempty"` +} + +// ImageSpec3AssetType defines model for ImageSpec.3.AssetType. +type ImageSpec3AssetType string + +// ImageSpec4 defines model for . +type ImageSpec4 struct { + AssetType ImageSpec4AssetType `json:"asset_type"` + Url *string `json:"url,omitempty"` +} + +// ImageSpec4AssetType defines model for ImageSpec.4.AssetType. +type ImageSpec4AssetType string + +// InputId defines model for InputId. +type InputId = string + +// InputRtpAudioOptions defines model for InputRtpAudioOptions. +type InputRtpAudioOptions struct { + union json.RawMessage +} + +// InputRtpAudioOptions0 defines model for . +type InputRtpAudioOptions0 struct { + Decoder InputRtpAudioOptions0Decoder `json:"decoder"` +} + +// InputRtpAudioOptions0Decoder defines model for InputRtpAudioOptions.0.Decoder. +type InputRtpAudioOptions0Decoder string + +// InputRtpAudioOptions1 defines model for . +type InputRtpAudioOptions1 struct { + // AudioSpecificConfig AudioSpecificConfig as described in MPEG-4 part 3, section 1.6.2.1 + // The config should be encoded as described in [RFC 3640](https://datatracker.ietf.org/doc/html/rfc3640#section-4.1). + // + // The simplest way to obtain this value when using ffmpeg to stream to the compositor is + // to pass the additional `-sdp_file FILENAME` option to ffmpeg. This will cause it to + // write out an sdp file, which will contain this field. Programs which have the ability + // to stream AAC to the compositor should provide this information. + // + // In MP4 files, the ASC is embedded inside the esds box (note that it is not the whole + // box, only a part of it). This also applies to fragmented MP4s downloaded over HLS, if + // the playlist uses MP4s instead of MPEG Transport Streams + // + // In FLV files and the RTMP protocol, the ASC can be found in the `AACAUDIODATA` tag. + AudioSpecificConfig string `json:"audio_specific_config"` + Decoder InputRtpAudioOptions1Decoder `json:"decoder"` + RtpMode *AacRtpMode `json:"rtp_mode,omitempty"` +} + +// InputRtpAudioOptions1Decoder defines model for InputRtpAudioOptions.1.Decoder. +type InputRtpAudioOptions1Decoder string + +// InputRtpVideoOptions defines model for InputRtpVideoOptions. +type InputRtpVideoOptions struct { + Decoder RtpVideoDecoderOptions `json:"decoder"` +} + +// InputStream defines model for InputStream. +type InputStream struct { + Id *ComponentId `json:"id,omitempty"` + InputId InputId `json:"input_id"` +} + +// InputWhepVideoOptions defines model for InputWhepVideoOptions. +type InputWhepVideoOptions struct { + DecoderPreferences *[]WhepVideoDecoderOptions `json:"decoder_preferences,omitempty"` +} + +// InputWhipVideoOptions defines model for InputWhipVideoOptions. +type InputWhipVideoOptions struct { + DecoderPreferences *[]WhipVideoDecoderOptions `json:"decoder_preferences,omitempty"` +} + +// Mp4AudioEncoderOptions defines model for Mp4AudioEncoderOptions. +type Mp4AudioEncoderOptions struct { + union json.RawMessage +} + +// Mp4AudioEncoderOptions0 defines model for . +type Mp4AudioEncoderOptions0 struct { + // SampleRate (**default=`44100`**) Sample rate. Allowed values: [8000, 16000, 24000, 44100, 48000]. + SampleRate *int32 `json:"sample_rate,omitempty"` + Type Mp4AudioEncoderOptions0Type `json:"type"` +} + +// Mp4AudioEncoderOptions0Type defines model for Mp4AudioEncoderOptions.0.Type. +type Mp4AudioEncoderOptions0Type string + +// Mp4Input Input stream from MP4 file. +// Exactly one of `url` and `path` has to be defined. +type Mp4Input struct { + // Loop (**default=`false`**) If input should be played in the loop. Added in v0.4.0 + Loop *bool `json:"loop,omitempty"` + + // OffsetMs Offset in milliseconds relative to the pipeline start (start request). If offset is + // not defined then stream is synchronized based on the first frames delivery time. + OffsetMs *float64 `json:"offset_ms,omitempty"` + + // Required (**default=`false`**) If input is required and frames are not processed + // on time, then Smelter will delay producing output frames. + Required *bool `json:"required,omitempty"` + + // Url URL of the MP4 file. + Url *string `json:"url,omitempty"` +} + +// Mp4Output defines model for Mp4Output. +type Mp4Output struct { + Audio *OutputMp4AudioOptions `json:"audio,omitempty"` + + // FfmpegOptions Raw FFmpeg muxer options. See [docs](https://ffmpeg.org/ffmpeg-formats.html) for more. + FfmpegOptions *map[string]string `json:"ffmpeg_options,omitempty"` + + // Path Path to output MP4 file. + Path string `json:"path"` + Video *OutputMp4VideoOptions `json:"video,omitempty"` +} + +// Mp4VideoEncoderOptions defines model for Mp4VideoEncoderOptions. +type Mp4VideoEncoderOptions struct { + union json.RawMessage +} + +// Mp4VideoEncoderOptions0 defines model for . +type Mp4VideoEncoderOptions0 struct { + Bitrate *VideoEncoderBitrate `json:"bitrate,omitempty"` + + // FfmpegOptions Raw FFmpeg encoder options. See [docs](https://ffmpeg.org/ffmpeg-codecs.html) for more. + FfmpegOptions *map[string]string `json:"ffmpeg_options,omitempty"` + + // KeyframeIntervalMs (**default=`5000`**) Maximal interval between keyframes, in milliseconds. + KeyframeIntervalMs *float64 `json:"keyframe_interval_ms,omitempty"` + PixelFormat *PixelFormat `json:"pixel_format,omitempty"` + Preset *H264EncoderPreset `json:"preset,omitempty"` + Type Mp4VideoEncoderOptions0Type `json:"type"` +} + +// Mp4VideoEncoderOptions0Type defines model for Mp4VideoEncoderOptions.0.Type. +type Mp4VideoEncoderOptions0Type string + +// Mp4VideoEncoderOptions1 defines model for . +type Mp4VideoEncoderOptions1 struct { + Bitrate *VideoEncoderBitrate `json:"bitrate,omitempty"` + + // KeyframeIntervalMs (**default=`5000`**) Interval between keyframes, in milliseconds. + KeyframeIntervalMs *float64 `json:"keyframe_interval_ms,omitempty"` + Type Mp4VideoEncoderOptions1Type `json:"type"` +} + +// Mp4VideoEncoderOptions1Type defines model for Mp4VideoEncoderOptions.1.Type. +type Mp4VideoEncoderOptions1Type string + +// OpusEncoderPreset defines model for OpusEncoderPreset. +type OpusEncoderPreset string + +// OutputEndCondition This type defines when end of an input stream should trigger end of the output stream. Only one of those fields can be set at the time. +// Unless specified otherwise the input stream is considered finished/ended when: +// - TCP connection was dropped/closed. +// - RTCP Goodbye packet (`BYE`) was received. +// - Mp4 track has ended. +// - Input was unregistered already (or never registered). +type OutputEndCondition struct { + // AllInputs Terminate output stream if all the input streams finish. In particular, output stream will **be** terminated if no inputs were ever connected. + AllInputs *bool `json:"all_inputs,omitempty"` + + // AllOf Terminate output stream if all the input streams from the list are finished. + AllOf *[]InputId `json:"all_of,omitempty"` + + // AnyInput Terminate output stream if any of the input streams ends. This includes streams added after the output was registered. In particular, output stream will **not be** terminated if no inputs were ever connected. + AnyInput *bool `json:"any_input,omitempty"` + + // AnyOf Terminate output stream if any of the input streams from the list are finished. + AnyOf *[]InputId `json:"any_of,omitempty"` +} + +// OutputHlsAudioOptions defines model for OutputHlsAudioOptions. +type OutputHlsAudioOptions struct { + Channels *AudioChannels `json:"channels,omitempty"` + Encoder HlsAudioEncoderOptions `json:"encoder"` + Initial AudioScene `json:"initial"` + MixingStrategy *AudioMixingStrategy `json:"mixing_strategy,omitempty"` + SendEosWhen *OutputEndCondition `json:"send_eos_when,omitempty"` +} + +// OutputHlsVideoOptions defines model for OutputHlsVideoOptions. +type OutputHlsVideoOptions struct { + Encoder HlsVideoEncoderOptions `json:"encoder"` + Initial VideoScene `json:"initial"` + Resolution Resolution `json:"resolution"` + SendEosWhen *OutputEndCondition `json:"send_eos_when,omitempty"` +} + +// OutputMp4AudioOptions defines model for OutputMp4AudioOptions. +type OutputMp4AudioOptions struct { + Channels *AudioChannels `json:"channels,omitempty"` + Encoder Mp4AudioEncoderOptions `json:"encoder"` + Initial AudioScene `json:"initial"` + MixingStrategy *AudioMixingStrategy `json:"mixing_strategy,omitempty"` + SendEosWhen *OutputEndCondition `json:"send_eos_when,omitempty"` +} + +// OutputMp4VideoOptions defines model for OutputMp4VideoOptions. +type OutputMp4VideoOptions struct { + Encoder Mp4VideoEncoderOptions `json:"encoder"` + Initial VideoScene `json:"initial"` + Resolution Resolution `json:"resolution"` + SendEosWhen *OutputEndCondition `json:"send_eos_when,omitempty"` +} + +// OutputRtmpClientAudioOptions defines model for OutputRtmpClientAudioOptions. +type OutputRtmpClientAudioOptions struct { + Channels *AudioChannels `json:"channels,omitempty"` + Encoder RtmpClientAudioEncoderOptions `json:"encoder"` + Initial AudioScene `json:"initial"` + MixingStrategy *AudioMixingStrategy `json:"mixing_strategy,omitempty"` + SendEosWhen *OutputEndCondition `json:"send_eos_when,omitempty"` +} + +// OutputRtmpClientVideoOptions defines model for OutputRtmpClientVideoOptions. +type OutputRtmpClientVideoOptions struct { + Encoder RtmpClientVideoEncoderOptions `json:"encoder"` + Initial VideoScene `json:"initial"` + Resolution Resolution `json:"resolution"` + SendEosWhen *OutputEndCondition `json:"send_eos_when,omitempty"` +} + +// OutputRtpAudioOptions defines model for OutputRtpAudioOptions. +type OutputRtpAudioOptions struct { + Channels *AudioChannels `json:"channels,omitempty"` + Encoder RtpAudioEncoderOptions `json:"encoder"` + Initial AudioScene `json:"initial"` + MixingStrategy *AudioMixingStrategy `json:"mixing_strategy,omitempty"` + SendEosWhen *OutputEndCondition `json:"send_eos_when,omitempty"` +} + +// OutputRtpVideoOptions defines model for OutputRtpVideoOptions. +type OutputRtpVideoOptions struct { + Encoder RtpVideoEncoderOptions `json:"encoder"` + Initial VideoScene `json:"initial"` + Resolution Resolution `json:"resolution"` + SendEosWhen *OutputEndCondition `json:"send_eos_when,omitempty"` +} + +// OutputWhepAudioOptions defines model for OutputWhepAudioOptions. +type OutputWhepAudioOptions struct { + Channels *AudioChannels `json:"channels,omitempty"` + Encoder WhepAudioEncoderOptions `json:"encoder"` + Initial AudioScene `json:"initial"` + MixingStrategy *AudioMixingStrategy `json:"mixing_strategy,omitempty"` + SendEosWhen *OutputEndCondition `json:"send_eos_when,omitempty"` +} + +// OutputWhepVideoOptions defines model for OutputWhepVideoOptions. +type OutputWhepVideoOptions struct { + Encoder WhepVideoEncoderOptions `json:"encoder"` + Initial VideoScene `json:"initial"` + Resolution Resolution `json:"resolution"` + SendEosWhen *OutputEndCondition `json:"send_eos_when,omitempty"` +} + +// OutputWhipAudioOptions defines model for OutputWhipAudioOptions. +type OutputWhipAudioOptions struct { + Channels *AudioChannels `json:"channels,omitempty"` + + // EncoderPreferences Codec preferences list. + EncoderPreferences *[]WhipAudioEncoderOptions `json:"encoder_preferences,omitempty"` + Initial AudioScene `json:"initial"` + MixingStrategy *AudioMixingStrategy `json:"mixing_strategy,omitempty"` + SendEosWhen *OutputEndCondition `json:"send_eos_when,omitempty"` +} + +// OutputWhipVideoOptions defines model for OutputWhipVideoOptions. +type OutputWhipVideoOptions struct { + // EncoderPreferences Codec preferences list. + EncoderPreferences *[]WhipVideoEncoderOptions `json:"encoder_preferences,omitempty"` + Initial VideoScene `json:"initial"` + Resolution Resolution `json:"resolution"` + SendEosWhen *OutputEndCondition `json:"send_eos_when,omitempty"` +} + +// Overflow defines model for Overflow. +type Overflow string + +// PixelFormat defines model for PixelFormat. +type PixelFormat string + +// PortOrPortRange defines model for PortOrPortRange. +type PortOrPortRange struct { + union json.RawMessage +} + +// PortOrPortRange0 defines model for . +type PortOrPortRange0 = string + +// PortOrPortRange1 defines model for . +type PortOrPortRange1 = int32 + +// RGBAColor defines model for RGBAColor. +type RGBAColor = string + +// RegisterInput defines model for RegisterInput. +type RegisterInput struct { + union json.RawMessage +} + +// RegisterOutput defines model for RegisterOutput. +type RegisterOutput struct { + union json.RawMessage +} + +// RescaleMode defines model for RescaleMode. +type RescaleMode string + +// Rescaler defines model for Rescaler. +type Rescaler struct { + BorderColor *RGBAColor `json:"border_color,omitempty"` + + // BorderRadius (**default=`0.0`**) Radius of a rounded corner. + BorderRadius *float32 `json:"border_radius,omitempty"` + + // BorderWidth (**default=`0.0`**) Border width. + BorderWidth *float32 `json:"border_width,omitempty"` + + // Bottom Distance in pixels between the bottom edge of this component and the bottom edge of its + // parent (including a border). If this field is defined, this element will be absolutely + // positioned, instead of being laid out by its parent. + Bottom *float32 `json:"bottom,omitempty"` + + // BoxShadow List of box shadows. + BoxShadow *[]BoxShadow `json:"box_shadow,omitempty"` + Child Component `json:"child"` + + // Height Height of a component in pixels (without a border). Exact behavior might be different + // based on the parent component: + // - If the parent component is a layout, check sections "Absolute positioning" and "Static + // positioning" of that component. + // - If the parent component is not a layout, then this field is required. + Height *float32 `json:"height,omitempty"` + HorizontalAlign *HorizontalAlign `json:"horizontal_align,omitempty"` + Id *ComponentId `json:"id,omitempty"` + + // Left Distance in pixels between this component's left edge and its parent's left edge (including a border). + // If this field is defined, this element will be absolutely positioned, instead of being + // laid out by its parent. + Left *float32 `json:"left,omitempty"` + Mode *RescaleMode `json:"mode,omitempty"` + + // Right Distance in pixels between this component's right edge and its parent's right edge. + // If this field is defined, this element will be absolutely positioned, instead of being + // laid out by its parent. + Right *float32 `json:"right,omitempty"` + + // Rotation Rotation of a component in degrees. If this field is defined, this element will be + // absolutely positioned, instead of being laid out by its parent. + Rotation *float32 `json:"rotation,omitempty"` + + // Top Distance in pixels between this component's top edge and its parent's top edge (including a border). + // If this field is defined, then the component will ignore a layout defined by its parent. + Top *float32 `json:"top,omitempty"` + Transition *Transition `json:"transition,omitempty"` + VerticalAlign *VerticalAlign `json:"vertical_align,omitempty"` + + // Width Width of a component in pixels (without a border). Exact behavior might be different + // based on the parent component: + // - If the parent component is a layout, check sections "Absolute positioning" and "Static + // positioning" of that component. + // - If the parent component is not a layout, then this field is required. + Width *float32 `json:"width,omitempty"` +} + +// Resolution defines model for Resolution. +type Resolution struct { + // Height Height in pixels. + Height int `json:"height"` + + // Width Width in pixels. + Width int `json:"width"` +} + +// Response defines model for Response. +type Response struct { + union json.RawMessage +} + +// Response0 defines model for . +type Response0 struct { + BearerToken string `json:"bearer_token"` +} + +// Response1 defines model for . +type Response1 struct { + AudioDurationMs *int64 `json:"audio_duration_ms,omitempty"` + VideoDurationMs *int64 `json:"video_duration_ms,omitempty"` +} + +// Response2 defines model for . +type Response2 struct { + Port *int32 `json:"port,omitempty"` +} + +// Response3 defines model for . +type Response3 = map[string]interface{} + +// RtmpClientAudioEncoderOptions defines model for RtmpClientAudioEncoderOptions. +type RtmpClientAudioEncoderOptions struct { + union json.RawMessage +} + +// RtmpClientAudioEncoderOptions0 defines model for . +type RtmpClientAudioEncoderOptions0 struct { + // SampleRate (**default=`48000`**) Sample rate. Allowed values: [8000, 16000, 24000, 44100, 48000]. + SampleRate *int32 `json:"sample_rate,omitempty"` + Type RtmpClientAudioEncoderOptions0Type `json:"type"` +} + +// RtmpClientAudioEncoderOptions0Type defines model for RtmpClientAudioEncoderOptions.0.Type. +type RtmpClientAudioEncoderOptions0Type string + +// RtmpClientVideoEncoderOptions defines model for RtmpClientVideoEncoderOptions. +type RtmpClientVideoEncoderOptions struct { + union json.RawMessage +} + +// RtmpClientVideoEncoderOptions0 defines model for . +type RtmpClientVideoEncoderOptions0 struct { + Bitrate *VideoEncoderBitrate `json:"bitrate,omitempty"` + + // FfmpegOptions Raw FFmpeg encoder options. See [docs](https://ffmpeg.org/ffmpeg-codecs.html) for more. + FfmpegOptions *map[string]string `json:"ffmpeg_options,omitempty"` + + // KeyframeIntervalMs (**default=`5000`**) Maximal interval between keyframes, in milliseconds. + KeyframeIntervalMs *float64 `json:"keyframe_interval_ms,omitempty"` + PixelFormat *PixelFormat `json:"pixel_format,omitempty"` + Preset *H264EncoderPreset `json:"preset,omitempty"` + Type RtmpClientVideoEncoderOptions0Type `json:"type"` +} + +// RtmpClientVideoEncoderOptions0Type defines model for RtmpClientVideoEncoderOptions.0.Type. +type RtmpClientVideoEncoderOptions0Type string + +// RtmpClientVideoEncoderOptions1 defines model for . +type RtmpClientVideoEncoderOptions1 struct { + Bitrate *VideoEncoderBitrate `json:"bitrate,omitempty"` + + // KeyframeIntervalMs (**default=`5000`**) Interval between keyframes, in milliseconds. + KeyframeIntervalMs *float64 `json:"keyframe_interval_ms,omitempty"` + Type RtmpClientVideoEncoderOptions1Type `json:"type"` +} + +// RtmpClientVideoEncoderOptions1Type defines model for RtmpClientVideoEncoderOptions.1.Type. +type RtmpClientVideoEncoderOptions1Type string + +// RtmpInput defines model for RtmpInput. +type RtmpInput struct { + // App The RTMP application name. + // This is the first path segment of the RTMP stream URL that Smelter listens on for incoming streams. + // Format: `rtmp://://://= 300 { + return fmt.Errorf("create track forwarding: unexpected status %d: %s", resp.StatusCode(), string(resp.Body)) + } + return nil +} diff --git a/conference-to-stream/backend/fishjam/generated/fishjam.gen.go b/conference-to-stream/backend/fishjam/generated/fishjam.gen.go new file mode 100644 index 0000000..4959073 --- /dev/null +++ b/conference-to-stream/backend/fishjam/generated/fishjam.gen.go @@ -0,0 +1,3551 @@ +// Package fishjamapi provides primitives to interact with the openapi HTTP API. +// +// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.0.0 DO NOT EDIT. +package fishjamapi + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "strings" + + "github.com/oapi-codegen/runtime" +) + +const ( + AuthorizationScopes authorizationContextKey = "authorization.Scopes" +) + +// Defines values for AudioFormat. +const ( + Pcm16 AudioFormat = "pcm16" +) + +// Valid indicates whether the value is a known member of the AudioFormat enum. +func (e AudioFormat) Valid() bool { + switch e { + case Pcm16: + return true + default: + return false + } +} + +// Defines values for AudioSampleRate. +const ( + N16000 AudioSampleRate = 16000 + N24000 AudioSampleRate = 24000 +) + +// Valid indicates whether the value is a known member of the AudioSampleRate enum. +func (e AudioSampleRate) Valid() bool { + switch e { + case N16000: + return true + case N24000: + return true + default: + return false + } +} + +// Defines values for PeerStatus. +const ( + PeerStatusConnected PeerStatus = "connected" + PeerStatusDisconnected PeerStatus = "disconnected" +) + +// Valid indicates whether the value is a known member of the PeerStatus enum. +func (e PeerStatus) Valid() bool { + switch e { + case PeerStatusConnected: + return true + case PeerStatusDisconnected: + return true + default: + return false + } +} + +// Defines values for PeerType. +const ( + Agent PeerType = "agent" + Webrtc PeerType = "webrtc" +) + +// Valid indicates whether the value is a known member of the PeerType enum. +func (e PeerType) Valid() bool { + switch e { + case Agent: + return true + case Webrtc: + return true + default: + return false + } +} + +// Defines values for RoomType. +const ( + AudioOnly RoomType = "audio_only" + AudioOnlyLivestream RoomType = "audio_only_livestream" + Broadcaster RoomType = "broadcaster" + Conference RoomType = "conference" + FullFeature RoomType = "full_feature" + Livestream RoomType = "livestream" +) + +// Valid indicates whether the value is a known member of the RoomType enum. +func (e RoomType) Valid() bool { + switch e { + case AudioOnly: + return true + case AudioOnlyLivestream: + return true + case Broadcaster: + return true + case Conference: + return true + case FullFeature: + return true + case Livestream: + return true + default: + return false + } +} + +// Defines values for StreamerStatus. +const ( + StreamerStatusConnected StreamerStatus = "connected" + StreamerStatusDisconnected StreamerStatus = "disconnected" +) + +// Valid indicates whether the value is a known member of the StreamerStatus enum. +func (e StreamerStatus) Valid() bool { + switch e { + case StreamerStatusConnected: + return true + case StreamerStatusDisconnected: + return true + default: + return false + } +} + +// Defines values for SubscribeMode. +const ( + Auto SubscribeMode = "auto" + Manual SubscribeMode = "manual" +) + +// Valid indicates whether the value is a known member of the SubscribeMode enum. +func (e SubscribeMode) Valid() bool { + switch e { + case Auto: + return true + case Manual: + return true + default: + return false + } +} + +// Defines values for TrackType. +const ( + Audio TrackType = "audio" + Video TrackType = "video" +) + +// Valid indicates whether the value is a known member of the TrackType enum. +func (e TrackType) Valid() bool { + switch e { + case Audio: + return true + case Video: + return true + default: + return false + } +} + +// Defines values for VideoCodec. +const ( + H264 VideoCodec = "h264" + Vp8 VideoCodec = "vp8" +) + +// Valid indicates whether the value is a known member of the VideoCodec enum. +func (e VideoCodec) Valid() bool { + switch e { + case H264: + return true + case Vp8: + return true + default: + return false + } +} + +// Defines values for ViewerStatus. +const ( + Connected ViewerStatus = "connected" + Disconnected ViewerStatus = "disconnected" +) + +// Valid indicates whether the value is a known member of the ViewerStatus enum. +func (e ViewerStatus) Valid() bool { + switch e { + case Connected: + return true + case Disconnected: + return true + default: + return false + } +} + +// AgentOutput Output audio options +type AgentOutput struct { + // AudioFormat The format of the output audio + AudioFormat *AudioFormat `json:"audioFormat,omitempty"` + + // AudioSampleRate The sample rate of the output audio + AudioSampleRate *AudioSampleRate `json:"audioSampleRate,omitempty"` +} + +// AudioFormat The format of the output audio +type AudioFormat string + +// AudioSampleRate The sample rate of the output audio +type AudioSampleRate int + +// AuthToken Token for authorizing websocket connection +type AuthToken = string + +// Error Error message +type Error struct { + // Errors Error details + Errors string `json:"errors"` +} + +// Peer Describes peer status +type Peer struct { + // Id Assigned peer id + Id PeerID `json:"id"` + + // Metadata Custom metadata set by the peer + Metadata *PeerMetadata `json:"metadata"` + + // Status Informs about the peer status + Status PeerStatus `json:"status"` + + // SubscribeMode Configuration of peer's subscribing policy + SubscribeMode SubscribeMode `json:"subscribeMode"` + + // Subscriptions Describes peer's subscriptions in manual mode + Subscriptions Subscriptions `json:"subscriptions"` + + // Tracks List of all peer's tracks + Tracks []Track `json:"tracks"` + + // Type Peer type + Type PeerType `json:"type"` +} + +// PeerConfig Peer configuration +type PeerConfig struct { + // Options Peer-specific options + Options PeerOptions `json:"options"` + + // Type Peer type + Type PeerType `json:"type"` +} + +// PeerDetailsResponse Response containing peer details and their token +type PeerDetailsResponse struct { + Data struct { + // Peer Describes peer status + Peer Peer `json:"peer"` + + // PeerWebsocketUrl Websocket URL to which peer has to connect + PeerWebsocketUrl *WebsocketURL `json:"peer_websocket_url,omitempty"` + + // Token Token for authorizing websocket connection + Token AuthToken `json:"token"` + } `json:"data"` +} + +// PeerID Assigned peer id +type PeerID = string + +// PeerMetadata Custom metadata set by the peer +type PeerMetadata = map[string]interface{} + +// PeerOptions Peer-specific options +type PeerOptions struct { + union json.RawMessage +} + +// PeerOptionsAgent Options specific to the Agent peer +type PeerOptionsAgent struct { + // Output Output audio options + Output *AgentOutput `json:"output,omitempty"` + + // SubscribeMode Configuration of peer's subscribing policy + SubscribeMode *SubscribeMode `json:"subscribeMode,omitempty"` +} + +// PeerOptionsWebRTC Options specific to the WebRTC peer +type PeerOptionsWebRTC struct { + // Metadata Custom peer metadata + Metadata *WebRTCMetadata `json:"metadata,omitempty"` + + // SubscribeMode Configuration of peer's subscribing policy + SubscribeMode *SubscribeMode `json:"subscribeMode,omitempty"` +} + +// PeerRefreshTokenResponse Response containing new peer token +type PeerRefreshTokenResponse struct { + Data struct { + // Token Token for authorizing websocket connection + Token AuthToken `json:"token"` + } `json:"data"` +} + +// PeerStatus Informs about the peer status +type PeerStatus string + +// PeerType Peer type +type PeerType string + +// Room Description of the room state +type Room struct { + // Config Room configuration + Config RoomConfig `json:"config"` + + // Id Room ID + Id string `json:"id"` + + // Peers List of all peers + Peers []Peer `json:"peers"` +} + +// RoomConfig Room configuration +type RoomConfig struct { + // MaxPeers Maximum amount of peers allowed into the room + MaxPeers *int `json:"maxPeers,omitempty"` + + // Public True if livestream viewers can omit specifying a token. + Public *bool `json:"public,omitempty"` + + // RoomType The use-case of the room. If not provided, this defaults to conference. + RoomType *RoomType `json:"roomType,omitempty"` + + // VideoCodec Enforces video codec for each peer in the room + VideoCodec *VideoCodec `json:"videoCodec,omitempty"` + + // WebhookUrl URL where Fishjam notifications will be sent + WebhookUrl *string `json:"webhookUrl,omitempty"` +} + +// RoomCreateDetailsResponse Response containing room details +type RoomCreateDetailsResponse struct { + Data struct { + // Room Description of the room state + Room Room `json:"room"` + } `json:"data"` +} + +// RoomDetailsResponse Response containing room details +type RoomDetailsResponse struct { + // Data Description of the room state + Data Room `json:"data"` +} + +// RoomType The use-case of the room. If not provided, this defaults to conference. +type RoomType string + +// RoomsListingResponse Response containing list of all rooms +type RoomsListingResponse struct { + Data []Room `json:"data"` +} + +// Stream Describes stream status +type Stream struct { + // AudioOnly True if stream is restricted to audio only + AudioOnly *bool `json:"audioOnly,omitempty"` + + // Id Assigned stream id + Id string `json:"id"` + Public bool `json:"public"` + + // Streamers List of all streamers + Streamers []Streamer `json:"streamers"` + + // Viewers List of all viewers + Viewers []Viewer `json:"viewers"` +} + +// StreamConfig Stream configuration +type StreamConfig struct { + // AudioOnly Restrics stream to audio only + AudioOnly *bool `json:"audioOnly,omitempty"` + + // Public True if livestream viewers can omit specifying a token. + Public *bool `json:"public,omitempty"` + + // WebhookUrl Webhook URL for receiving server notifications + WebhookUrl *string `json:"webhookUrl,omitempty"` +} + +// Streamer Describes streamer status +type Streamer struct { + // Id Assigned streamer id + Id string `json:"id"` + Status StreamerStatus `json:"status"` + + // Token Token for authorizing broadcaster streamer connection + Token StreamerToken `json:"token"` +} + +// StreamerStatus defines model for Streamer.Status. +type StreamerStatus string + +// StreamerToken Token for authorizing broadcaster streamer connection +type StreamerToken struct { + Token string `json:"token"` +} + +// StreamsListingResponse Response containing list of all streams +type StreamsListingResponse struct { + Data []Stream `json:"data"` +} + +// SubscribeMode Configuration of peer's subscribing policy +type SubscribeMode string + +// Subscriptions Describes peer's subscriptions in manual mode +type Subscriptions struct { + // Peers List of peer IDs this peer subscribes to + Peers []PeerID `json:"peers"` + + // Tracks List of track IDs this peer subscribes to + Tracks []TrackID `json:"tracks"` +} + +// Track Describes media track of a Peer +type Track struct { + // Id Assigned track id + Id *TrackID `json:"id,omitempty"` + Metadata *TrackMetadata `json:"metadata,omitempty"` + Type *TrackType `json:"type,omitempty"` +} + +// TrackForwarding Track forwardings for a room +type TrackForwarding struct { + // CompositionURL URL for the composition + CompositionURL string `json:"compositionURL"` + + // Selector Selects tracks that should be forwarded, currently only "all" is supported + Selector *string `json:"selector,omitempty"` +} + +// TrackID Assigned track id +type TrackID = string + +// TrackMetadata defines model for TrackMetadata. +type TrackMetadata = map[string]interface{} + +// TrackType defines model for TrackType. +type TrackType string + +// VideoCodec Enforces video codec for each peer in the room +type VideoCodec string + +// Viewer Describes viewer status +type Viewer struct { + // Id Assigned viewer id + Id string `json:"id"` + Status ViewerStatus `json:"status"` + + // Token Token for authorizing broadcaster viewer connection + Token ViewerToken `json:"token"` +} + +// ViewerStatus defines model for Viewer.Status. +type ViewerStatus string + +// ViewerToken Token for authorizing broadcaster viewer connection +type ViewerToken struct { + Token string `json:"token"` +} + +// WebRTCMetadata Custom peer metadata +type WebRTCMetadata map[string]interface{} + +// WebsocketURL Websocket URL to which peer has to connect +type WebsocketURL = string + +// authorizationContextKey is the context key for authorization security scheme +type authorizationContextKey string + +// SubscribePeerParams defines parameters for SubscribePeer. +type SubscribePeerParams struct { + // PeerId ID of the peer that produces the track + PeerId *string `form:"peer_id,omitempty" json:"peer_id,omitempty"` +} + +// SubscribeTracksJSONBody defines parameters for SubscribeTracks. +type SubscribeTracksJSONBody struct { + // TrackIds List of track IDs to subscribe to + TrackIds []TrackID `json:"track_ids"` +} + +// CreateStreamJSONRequestBody defines body for CreateStream for application/json ContentType. +type CreateStreamJSONRequestBody = StreamConfig + +// CreateRoomJSONRequestBody defines body for CreateRoom for application/json ContentType. +type CreateRoomJSONRequestBody = RoomConfig + +// AddPeerJSONRequestBody defines body for AddPeer for application/json ContentType. +type AddPeerJSONRequestBody = PeerConfig + +// SubscribeTracksJSONRequestBody defines body for SubscribeTracks for application/json ContentType. +type SubscribeTracksJSONRequestBody SubscribeTracksJSONBody + +// CreateTrackForwardingJSONRequestBody defines body for CreateTrackForwarding for application/json ContentType. +type CreateTrackForwardingJSONRequestBody = TrackForwarding + +// AsPeerOptionsWebRTC returns the union data inside the PeerOptions as a PeerOptionsWebRTC +func (t PeerOptions) AsPeerOptionsWebRTC() (PeerOptionsWebRTC, error) { + var body PeerOptionsWebRTC + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromPeerOptionsWebRTC overwrites any union data inside the PeerOptions as the provided PeerOptionsWebRTC +func (t *PeerOptions) FromPeerOptionsWebRTC(v PeerOptionsWebRTC) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergePeerOptionsWebRTC performs a merge with any union data inside the PeerOptions, using the provided PeerOptionsWebRTC +func (t *PeerOptions) MergePeerOptionsWebRTC(v PeerOptionsWebRTC) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsPeerOptionsAgent returns the union data inside the PeerOptions as a PeerOptionsAgent +func (t PeerOptions) AsPeerOptionsAgent() (PeerOptionsAgent, error) { + var body PeerOptionsAgent + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromPeerOptionsAgent overwrites any union data inside the PeerOptions as the provided PeerOptionsAgent +func (t *PeerOptions) FromPeerOptionsAgent(v PeerOptionsAgent) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergePeerOptionsAgent performs a merge with any union data inside the PeerOptions, using the provided PeerOptionsAgent +func (t *PeerOptions) MergePeerOptionsAgent(v PeerOptionsAgent) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t PeerOptions) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *PeerOptions) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + +// RequestEditorFn is the function signature for the RequestEditor callback function +type RequestEditorFn func(ctx context.Context, req *http.Request) error + +// Doer performs HTTP requests. +// +// The standard http.Client implements this interface. +type HttpRequestDoer interface { + Do(req *http.Request) (*http.Response, error) +} + +// Client which conforms to the OpenAPI3 specification for this service. +type Client struct { + // The endpoint of the server conforming to this interface, with scheme, + // https://api.deepmap.com for example. This can contain a path relative + // to the server, such as https://api.deepmap.com/dev-test, and all the + // paths in the swagger spec will be appended to the server. + Server string + + // Doer for performing requests, typically a *http.Client with any + // customized settings, such as certificate chains. + Client HttpRequestDoer + + // A list of callbacks for modifying requests which are generated before sending over + // the network. + RequestEditors []RequestEditorFn +} + +// ClientOption allows setting custom parameters during construction +type ClientOption func(*Client) error + +// Creates a new Client, with reasonable defaults +func NewClient(server string, opts ...ClientOption) (*Client, error) { + // create a client with sane default values + client := Client{ + Server: server, + } + // mutate client and add all optional params + for _, o := range opts { + if err := o(&client); err != nil { + return nil, err + } + } + // ensure the server URL always has a trailing slash + if !strings.HasSuffix(client.Server, "/") { + client.Server += "/" + } + // create httpClient, if not already present + if client.Client == nil { + client.Client = &http.Client{} + } + return &client, nil +} + +// WithHTTPClient allows overriding the default Doer, which is +// automatically created using http.Client. This is useful for tests. +func WithHTTPClient(doer HttpRequestDoer) ClientOption { + return func(c *Client) error { + c.Client = doer + return nil + } +} + +// WithRequestEditorFn allows setting up a callback function, which will be +// called right before sending the request. This can be used to mutate the request. +func WithRequestEditorFn(fn RequestEditorFn) ClientOption { + return func(c *Client) error { + c.RequestEditors = append(c.RequestEditors, fn) + return nil + } +} + +// The interface specification for the client above. +type ClientInterface interface { + // GetAllStreams request + GetAllStreams(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) + + // CreateStreamWithBody request with any body + CreateStreamWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + CreateStream(ctx context.Context, body CreateStreamJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // DeleteStream request + DeleteStream(ctx context.Context, streamId string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetStream request + GetStream(ctx context.Context, streamId string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // CreateStreamer request + CreateStreamer(ctx context.Context, streamId string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // DeleteStreamer request + DeleteStreamer(ctx context.Context, streamId string, streamerId string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // CreateViewer request + CreateViewer(ctx context.Context, streamId string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // DeleteViewer request + DeleteViewer(ctx context.Context, streamId string, viewerId string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetAllRooms request + GetAllRooms(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) + + // CreateRoomWithBody request with any body + CreateRoomWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + CreateRoom(ctx context.Context, body CreateRoomJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // DeleteRoom request + DeleteRoom(ctx context.Context, roomId string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetRoom request + GetRoom(ctx context.Context, roomId string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // AddPeerWithBody request with any body + AddPeerWithBody(ctx context.Context, roomId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + AddPeer(ctx context.Context, roomId string, body AddPeerJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // DeletePeer request + DeletePeer(ctx context.Context, roomId string, id string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // RefreshToken request + RefreshToken(ctx context.Context, roomId string, id string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // SubscribePeer request + SubscribePeer(ctx context.Context, roomId string, id string, params *SubscribePeerParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // SubscribeTracksWithBody request with any body + SubscribeTracksWithBody(ctx context.Context, roomId string, id string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + SubscribeTracks(ctx context.Context, roomId string, id string, body SubscribeTracksJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GenerateStreamerToken request + GenerateStreamerToken(ctx context.Context, roomId string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // CreateTrackForwardingWithBody request with any body + CreateTrackForwardingWithBody(ctx context.Context, roomId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + CreateTrackForwarding(ctx context.Context, roomId string, body CreateTrackForwardingJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GenerateViewerToken request + GenerateViewerToken(ctx context.Context, roomId string, reqEditors ...RequestEditorFn) (*http.Response, error) +} + +func (c *Client) GetAllStreams(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetAllStreamsRequest(c.Server) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateStreamWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateStreamRequestWithBody(c.Server, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateStream(ctx context.Context, body CreateStreamJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateStreamRequest(c.Server, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) DeleteStream(ctx context.Context, streamId string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDeleteStreamRequest(c.Server, streamId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GetStream(ctx context.Context, streamId string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetStreamRequest(c.Server, streamId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateStreamer(ctx context.Context, streamId string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateStreamerRequest(c.Server, streamId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) DeleteStreamer(ctx context.Context, streamId string, streamerId string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDeleteStreamerRequest(c.Server, streamId, streamerId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateViewer(ctx context.Context, streamId string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateViewerRequest(c.Server, streamId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) DeleteViewer(ctx context.Context, streamId string, viewerId string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDeleteViewerRequest(c.Server, streamId, viewerId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GetAllRooms(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetAllRoomsRequest(c.Server) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateRoomWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateRoomRequestWithBody(c.Server, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateRoom(ctx context.Context, body CreateRoomJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateRoomRequest(c.Server, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) DeleteRoom(ctx context.Context, roomId string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDeleteRoomRequest(c.Server, roomId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GetRoom(ctx context.Context, roomId string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetRoomRequest(c.Server, roomId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) AddPeerWithBody(ctx context.Context, roomId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewAddPeerRequestWithBody(c.Server, roomId, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) AddPeer(ctx context.Context, roomId string, body AddPeerJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewAddPeerRequest(c.Server, roomId, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) DeletePeer(ctx context.Context, roomId string, id string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDeletePeerRequest(c.Server, roomId, id) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) RefreshToken(ctx context.Context, roomId string, id string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewRefreshTokenRequest(c.Server, roomId, id) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) SubscribePeer(ctx context.Context, roomId string, id string, params *SubscribePeerParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewSubscribePeerRequest(c.Server, roomId, id, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) SubscribeTracksWithBody(ctx context.Context, roomId string, id string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewSubscribeTracksRequestWithBody(c.Server, roomId, id, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) SubscribeTracks(ctx context.Context, roomId string, id string, body SubscribeTracksJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewSubscribeTracksRequest(c.Server, roomId, id, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GenerateStreamerToken(ctx context.Context, roomId string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGenerateStreamerTokenRequest(c.Server, roomId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateTrackForwardingWithBody(ctx context.Context, roomId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateTrackForwardingRequestWithBody(c.Server, roomId, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateTrackForwarding(ctx context.Context, roomId string, body CreateTrackForwardingJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateTrackForwardingRequest(c.Server, roomId, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GenerateViewerToken(ctx context.Context, roomId string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGenerateViewerTokenRequest(c.Server, roomId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +// NewGetAllStreamsRequest generates requests for GetAllStreams +func NewGetAllStreamsRequest(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/livestream") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewCreateStreamRequest calls the generic CreateStream builder with application/json body +func NewCreateStreamRequest(server string, body CreateStreamJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewCreateStreamRequestWithBody(server, "application/json", bodyReader) +} + +// NewCreateStreamRequestWithBody generates requests for CreateStream with any type of body +func NewCreateStreamRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/livestream") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewDeleteStreamRequest generates requests for DeleteStream +func NewDeleteStreamRequest(server string, streamId string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "stream_id", streamId, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/livestream/%s", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("DELETE", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewGetStreamRequest generates requests for GetStream +func NewGetStreamRequest(server string, streamId string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "stream_id", streamId, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/livestream/%s", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewCreateStreamerRequest generates requests for CreateStreamer +func NewCreateStreamerRequest(server string, streamId string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "stream_id", streamId, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/livestream/%s/streamer", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewDeleteStreamerRequest generates requests for DeleteStreamer +func NewDeleteStreamerRequest(server string, streamId string, streamerId string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "stream_id", streamId, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithOptions("simple", false, "streamer_id", streamerId, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/livestream/%s/streamer/%s", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("DELETE", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewCreateViewerRequest generates requests for CreateViewer +func NewCreateViewerRequest(server string, streamId string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "stream_id", streamId, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/livestream/%s/viewer", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewDeleteViewerRequest generates requests for DeleteViewer +func NewDeleteViewerRequest(server string, streamId string, viewerId string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "stream_id", streamId, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithOptions("simple", false, "viewer_id", viewerId, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/livestream/%s/viewer/%s", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("DELETE", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewGetAllRoomsRequest generates requests for GetAllRooms +func NewGetAllRoomsRequest(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/room") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewCreateRoomRequest calls the generic CreateRoom builder with application/json body +func NewCreateRoomRequest(server string, body CreateRoomJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewCreateRoomRequestWithBody(server, "application/json", bodyReader) +} + +// NewCreateRoomRequestWithBody generates requests for CreateRoom with any type of body +func NewCreateRoomRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/room") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewDeleteRoomRequest generates requests for DeleteRoom +func NewDeleteRoomRequest(server string, roomId string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "room_id", roomId, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/room/%s", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("DELETE", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewGetRoomRequest generates requests for GetRoom +func NewGetRoomRequest(server string, roomId string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "room_id", roomId, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/room/%s", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewAddPeerRequest calls the generic AddPeer builder with application/json body +func NewAddPeerRequest(server string, roomId string, body AddPeerJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewAddPeerRequestWithBody(server, roomId, "application/json", bodyReader) +} + +// NewAddPeerRequestWithBody generates requests for AddPeer with any type of body +func NewAddPeerRequestWithBody(server string, roomId string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "room_id", roomId, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/room/%s/peer", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewDeletePeerRequest generates requests for DeletePeer +func NewDeletePeerRequest(server string, roomId string, id string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "room_id", roomId, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithOptions("simple", false, "id", id, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/room/%s/peer/%s", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("DELETE", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewRefreshTokenRequest generates requests for RefreshToken +func NewRefreshTokenRequest(server string, roomId string, id string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "room_id", roomId, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithOptions("simple", false, "id", id, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/room/%s/peer/%s/refresh_token", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewSubscribePeerRequest generates requests for SubscribePeer +func NewSubscribePeerRequest(server string, roomId string, id string, params *SubscribePeerParams) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "room_id", roomId, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithOptions("simple", false, "id", id, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/room/%s/peer/%s/subscribe_peer", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + if params != nil { + queryValues := queryURL.Query() + + if params.PeerId != nil { + + if queryFrag, err := runtime.StyleParamWithOptions("form", true, "peer_id", *params.PeerId, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationQuery, Type: "string", Format: ""}); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + queryURL.RawQuery = queryValues.Encode() + } + + req, err := http.NewRequest("POST", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewSubscribeTracksRequest calls the generic SubscribeTracks builder with application/json body +func NewSubscribeTracksRequest(server string, roomId string, id string, body SubscribeTracksJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewSubscribeTracksRequestWithBody(server, roomId, id, "application/json", bodyReader) +} + +// NewSubscribeTracksRequestWithBody generates requests for SubscribeTracks with any type of body +func NewSubscribeTracksRequestWithBody(server string, roomId string, id string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "room_id", roomId, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithOptions("simple", false, "id", id, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/room/%s/peer/%s/subscribe_tracks", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewGenerateStreamerTokenRequest generates requests for GenerateStreamerToken +func NewGenerateStreamerTokenRequest(server string, roomId string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "room_id", roomId, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/room/%s/streamer", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewCreateTrackForwardingRequest calls the generic CreateTrackForwarding builder with application/json body +func NewCreateTrackForwardingRequest(server string, roomId string, body CreateTrackForwardingJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewCreateTrackForwardingRequestWithBody(server, roomId, "application/json", bodyReader) +} + +// NewCreateTrackForwardingRequestWithBody generates requests for CreateTrackForwarding with any type of body +func NewCreateTrackForwardingRequestWithBody(server string, roomId string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "room_id", roomId, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/room/%s/track_forwardings", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewGenerateViewerTokenRequest generates requests for GenerateViewerToken +func NewGenerateViewerTokenRequest(server string, roomId string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithOptions("simple", false, "room_id", roomId, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationPath, Type: "string", Format: ""}) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/room/%s/viewer", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +func (c *Client) applyEditors(ctx context.Context, req *http.Request, additionalEditors []RequestEditorFn) error { + for _, r := range c.RequestEditors { + if err := r(ctx, req); err != nil { + return err + } + } + for _, r := range additionalEditors { + if err := r(ctx, req); err != nil { + return err + } + } + return nil +} + +// ClientWithResponses builds on ClientInterface to offer response payloads +type ClientWithResponses struct { + ClientInterface +} + +// NewClientWithResponses creates a new ClientWithResponses, which wraps +// Client with return type handling +func NewClientWithResponses(server string, opts ...ClientOption) (*ClientWithResponses, error) { + client, err := NewClient(server, opts...) + if err != nil { + return nil, err + } + return &ClientWithResponses{client}, nil +} + +// WithBaseURL overrides the baseURL. +func WithBaseURL(baseURL string) ClientOption { + return func(c *Client) error { + newBaseURL, err := url.Parse(baseURL) + if err != nil { + return err + } + c.Server = newBaseURL.String() + return nil + } +} + +// ClientWithResponsesInterface is the interface specification for the client with responses above. +type ClientWithResponsesInterface interface { + // GetAllStreamsWithResponse request + GetAllStreamsWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetAllStreamsResponse, error) + + // CreateStreamWithBodyWithResponse request with any body + CreateStreamWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateStreamResponse, error) + + CreateStreamWithResponse(ctx context.Context, body CreateStreamJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateStreamResponse, error) + + // DeleteStreamWithResponse request + DeleteStreamWithResponse(ctx context.Context, streamId string, reqEditors ...RequestEditorFn) (*DeleteStreamResponse, error) + + // GetStreamWithResponse request + GetStreamWithResponse(ctx context.Context, streamId string, reqEditors ...RequestEditorFn) (*GetStreamResponse, error) + + // CreateStreamerWithResponse request + CreateStreamerWithResponse(ctx context.Context, streamId string, reqEditors ...RequestEditorFn) (*CreateStreamerResponse, error) + + // DeleteStreamerWithResponse request + DeleteStreamerWithResponse(ctx context.Context, streamId string, streamerId string, reqEditors ...RequestEditorFn) (*DeleteStreamerResponse, error) + + // CreateViewerWithResponse request + CreateViewerWithResponse(ctx context.Context, streamId string, reqEditors ...RequestEditorFn) (*CreateViewerResponse, error) + + // DeleteViewerWithResponse request + DeleteViewerWithResponse(ctx context.Context, streamId string, viewerId string, reqEditors ...RequestEditorFn) (*DeleteViewerResponse, error) + + // GetAllRoomsWithResponse request + GetAllRoomsWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetAllRoomsResponse, error) + + // CreateRoomWithBodyWithResponse request with any body + CreateRoomWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateRoomResponse, error) + + CreateRoomWithResponse(ctx context.Context, body CreateRoomJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateRoomResponse, error) + + // DeleteRoomWithResponse request + DeleteRoomWithResponse(ctx context.Context, roomId string, reqEditors ...RequestEditorFn) (*DeleteRoomResponse, error) + + // GetRoomWithResponse request + GetRoomWithResponse(ctx context.Context, roomId string, reqEditors ...RequestEditorFn) (*GetRoomResponse, error) + + // AddPeerWithBodyWithResponse request with any body + AddPeerWithBodyWithResponse(ctx context.Context, roomId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*AddPeerResponse, error) + + AddPeerWithResponse(ctx context.Context, roomId string, body AddPeerJSONRequestBody, reqEditors ...RequestEditorFn) (*AddPeerResponse, error) + + // DeletePeerWithResponse request + DeletePeerWithResponse(ctx context.Context, roomId string, id string, reqEditors ...RequestEditorFn) (*DeletePeerResponse, error) + + // RefreshTokenWithResponse request + RefreshTokenWithResponse(ctx context.Context, roomId string, id string, reqEditors ...RequestEditorFn) (*RefreshTokenResponse, error) + + // SubscribePeerWithResponse request + SubscribePeerWithResponse(ctx context.Context, roomId string, id string, params *SubscribePeerParams, reqEditors ...RequestEditorFn) (*SubscribePeerResponse, error) + + // SubscribeTracksWithBodyWithResponse request with any body + SubscribeTracksWithBodyWithResponse(ctx context.Context, roomId string, id string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*SubscribeTracksResponse, error) + + SubscribeTracksWithResponse(ctx context.Context, roomId string, id string, body SubscribeTracksJSONRequestBody, reqEditors ...RequestEditorFn) (*SubscribeTracksResponse, error) + + // GenerateStreamerTokenWithResponse request + GenerateStreamerTokenWithResponse(ctx context.Context, roomId string, reqEditors ...RequestEditorFn) (*GenerateStreamerTokenResponse, error) + + // CreateTrackForwardingWithBodyWithResponse request with any body + CreateTrackForwardingWithBodyWithResponse(ctx context.Context, roomId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateTrackForwardingResponse, error) + + CreateTrackForwardingWithResponse(ctx context.Context, roomId string, body CreateTrackForwardingJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateTrackForwardingResponse, error) + + // GenerateViewerTokenWithResponse request + GenerateViewerTokenWithResponse(ctx context.Context, roomId string, reqEditors ...RequestEditorFn) (*GenerateViewerTokenResponse, error) +} + +type GetAllStreamsResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *StreamsListingResponse + JSON401 *Error + JSON503 *Error +} + +// Status returns HTTPResponse.Status +func (r GetAllStreamsResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetAllStreamsResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type CreateStreamResponse struct { + Body []byte + HTTPResponse *http.Response + JSON201 *Stream + JSON400 *Error + JSON401 *Error + JSON503 *Error +} + +// Status returns HTTPResponse.Status +func (r CreateStreamResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r CreateStreamResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type DeleteStreamResponse struct { + Body []byte + HTTPResponse *http.Response + JSON401 *Error + JSON503 *Error +} + +// Status returns HTTPResponse.Status +func (r DeleteStreamResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r DeleteStreamResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetStreamResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Stream + JSON401 *Error + JSON404 *Error + JSON503 *Error +} + +// Status returns HTTPResponse.Status +func (r GetStreamResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetStreamResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type CreateStreamerResponse struct { + Body []byte + HTTPResponse *http.Response + JSON201 *Streamer + JSON401 *Error + JSON404 *Error + JSON503 *Error +} + +// Status returns HTTPResponse.Status +func (r CreateStreamerResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r CreateStreamerResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type DeleteStreamerResponse struct { + Body []byte + HTTPResponse *http.Response + JSON401 *Error + JSON503 *Error +} + +// Status returns HTTPResponse.Status +func (r DeleteStreamerResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r DeleteStreamerResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type CreateViewerResponse struct { + Body []byte + HTTPResponse *http.Response + JSON201 *Viewer + JSON401 *Error + JSON404 *Error + JSON503 *Error +} + +// Status returns HTTPResponse.Status +func (r CreateViewerResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r CreateViewerResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type DeleteViewerResponse struct { + Body []byte + HTTPResponse *http.Response + JSON401 *Error + JSON503 *Error +} + +// Status returns HTTPResponse.Status +func (r DeleteViewerResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r DeleteViewerResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetAllRoomsResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *RoomsListingResponse + JSON401 *Error +} + +// Status returns HTTPResponse.Status +func (r GetAllRoomsResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetAllRoomsResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type CreateRoomResponse struct { + Body []byte + HTTPResponse *http.Response + JSON201 *RoomCreateDetailsResponse + JSON400 *Error + JSON401 *Error + JSON503 *Error +} + +// Status returns HTTPResponse.Status +func (r CreateRoomResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r CreateRoomResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type DeleteRoomResponse struct { + Body []byte + HTTPResponse *http.Response + JSON400 *Error + JSON401 *Error + JSON404 *Error + JSON503 *Error +} + +// Status returns HTTPResponse.Status +func (r DeleteRoomResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r DeleteRoomResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetRoomResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *RoomDetailsResponse + JSON400 *Error + JSON401 *Error + JSON404 *Error + JSON503 *Error +} + +// Status returns HTTPResponse.Status +func (r GetRoomResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetRoomResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type AddPeerResponse struct { + Body []byte + HTTPResponse *http.Response + JSON201 *PeerDetailsResponse + JSON400 *Error + JSON401 *Error + JSON404 *Error + JSON409 *Error + JSON503 *Error +} + +// Status returns HTTPResponse.Status +func (r AddPeerResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r AddPeerResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type DeletePeerResponse struct { + Body []byte + HTTPResponse *http.Response + JSON400 *Error + JSON401 *Error + JSON404 *Error + JSON503 *Error +} + +// Status returns HTTPResponse.Status +func (r DeletePeerResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r DeletePeerResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type RefreshTokenResponse struct { + Body []byte + HTTPResponse *http.Response + JSON201 *PeerRefreshTokenResponse + JSON400 *Error + JSON401 *Error + JSON404 *Error + JSON503 *Error +} + +// Status returns HTTPResponse.Status +func (r RefreshTokenResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r RefreshTokenResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type SubscribePeerResponse struct { + Body []byte + HTTPResponse *http.Response + JSON400 *Error + JSON401 *Error + JSON404 *Error + JSON503 *Error +} + +// Status returns HTTPResponse.Status +func (r SubscribePeerResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r SubscribePeerResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type SubscribeTracksResponse struct { + Body []byte + HTTPResponse *http.Response + JSON400 *Error + JSON401 *Error + JSON404 *Error + JSON503 *Error +} + +// Status returns HTTPResponse.Status +func (r SubscribeTracksResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r SubscribeTracksResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GenerateStreamerTokenResponse struct { + Body []byte + HTTPResponse *http.Response + JSON201 *StreamerToken + JSON400 *Error + JSON401 *Error + JSON404 *Error + JSON503 *Error +} + +// Status returns HTTPResponse.Status +func (r GenerateStreamerTokenResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GenerateStreamerTokenResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type CreateTrackForwardingResponse struct { + Body []byte + HTTPResponse *http.Response + JSON400 *Error + JSON401 *Error + JSON404 *Error +} + +// Status returns HTTPResponse.Status +func (r CreateTrackForwardingResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r CreateTrackForwardingResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GenerateViewerTokenResponse struct { + Body []byte + HTTPResponse *http.Response + JSON201 *ViewerToken + JSON400 *Error + JSON401 *Error + JSON404 *Error + JSON503 *Error +} + +// Status returns HTTPResponse.Status +func (r GenerateViewerTokenResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GenerateViewerTokenResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// GetAllStreamsWithResponse request returning *GetAllStreamsResponse +func (c *ClientWithResponses) GetAllStreamsWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetAllStreamsResponse, error) { + rsp, err := c.GetAllStreams(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetAllStreamsResponse(rsp) +} + +// CreateStreamWithBodyWithResponse request with arbitrary body returning *CreateStreamResponse +func (c *ClientWithResponses) CreateStreamWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateStreamResponse, error) { + rsp, err := c.CreateStreamWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateStreamResponse(rsp) +} + +func (c *ClientWithResponses) CreateStreamWithResponse(ctx context.Context, body CreateStreamJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateStreamResponse, error) { + rsp, err := c.CreateStream(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateStreamResponse(rsp) +} + +// DeleteStreamWithResponse request returning *DeleteStreamResponse +func (c *ClientWithResponses) DeleteStreamWithResponse(ctx context.Context, streamId string, reqEditors ...RequestEditorFn) (*DeleteStreamResponse, error) { + rsp, err := c.DeleteStream(ctx, streamId, reqEditors...) + if err != nil { + return nil, err + } + return ParseDeleteStreamResponse(rsp) +} + +// GetStreamWithResponse request returning *GetStreamResponse +func (c *ClientWithResponses) GetStreamWithResponse(ctx context.Context, streamId string, reqEditors ...RequestEditorFn) (*GetStreamResponse, error) { + rsp, err := c.GetStream(ctx, streamId, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetStreamResponse(rsp) +} + +// CreateStreamerWithResponse request returning *CreateStreamerResponse +func (c *ClientWithResponses) CreateStreamerWithResponse(ctx context.Context, streamId string, reqEditors ...RequestEditorFn) (*CreateStreamerResponse, error) { + rsp, err := c.CreateStreamer(ctx, streamId, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateStreamerResponse(rsp) +} + +// DeleteStreamerWithResponse request returning *DeleteStreamerResponse +func (c *ClientWithResponses) DeleteStreamerWithResponse(ctx context.Context, streamId string, streamerId string, reqEditors ...RequestEditorFn) (*DeleteStreamerResponse, error) { + rsp, err := c.DeleteStreamer(ctx, streamId, streamerId, reqEditors...) + if err != nil { + return nil, err + } + return ParseDeleteStreamerResponse(rsp) +} + +// CreateViewerWithResponse request returning *CreateViewerResponse +func (c *ClientWithResponses) CreateViewerWithResponse(ctx context.Context, streamId string, reqEditors ...RequestEditorFn) (*CreateViewerResponse, error) { + rsp, err := c.CreateViewer(ctx, streamId, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateViewerResponse(rsp) +} + +// DeleteViewerWithResponse request returning *DeleteViewerResponse +func (c *ClientWithResponses) DeleteViewerWithResponse(ctx context.Context, streamId string, viewerId string, reqEditors ...RequestEditorFn) (*DeleteViewerResponse, error) { + rsp, err := c.DeleteViewer(ctx, streamId, viewerId, reqEditors...) + if err != nil { + return nil, err + } + return ParseDeleteViewerResponse(rsp) +} + +// GetAllRoomsWithResponse request returning *GetAllRoomsResponse +func (c *ClientWithResponses) GetAllRoomsWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetAllRoomsResponse, error) { + rsp, err := c.GetAllRooms(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetAllRoomsResponse(rsp) +} + +// CreateRoomWithBodyWithResponse request with arbitrary body returning *CreateRoomResponse +func (c *ClientWithResponses) CreateRoomWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateRoomResponse, error) { + rsp, err := c.CreateRoomWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateRoomResponse(rsp) +} + +func (c *ClientWithResponses) CreateRoomWithResponse(ctx context.Context, body CreateRoomJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateRoomResponse, error) { + rsp, err := c.CreateRoom(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateRoomResponse(rsp) +} + +// DeleteRoomWithResponse request returning *DeleteRoomResponse +func (c *ClientWithResponses) DeleteRoomWithResponse(ctx context.Context, roomId string, reqEditors ...RequestEditorFn) (*DeleteRoomResponse, error) { + rsp, err := c.DeleteRoom(ctx, roomId, reqEditors...) + if err != nil { + return nil, err + } + return ParseDeleteRoomResponse(rsp) +} + +// GetRoomWithResponse request returning *GetRoomResponse +func (c *ClientWithResponses) GetRoomWithResponse(ctx context.Context, roomId string, reqEditors ...RequestEditorFn) (*GetRoomResponse, error) { + rsp, err := c.GetRoom(ctx, roomId, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetRoomResponse(rsp) +} + +// AddPeerWithBodyWithResponse request with arbitrary body returning *AddPeerResponse +func (c *ClientWithResponses) AddPeerWithBodyWithResponse(ctx context.Context, roomId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*AddPeerResponse, error) { + rsp, err := c.AddPeerWithBody(ctx, roomId, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseAddPeerResponse(rsp) +} + +func (c *ClientWithResponses) AddPeerWithResponse(ctx context.Context, roomId string, body AddPeerJSONRequestBody, reqEditors ...RequestEditorFn) (*AddPeerResponse, error) { + rsp, err := c.AddPeer(ctx, roomId, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseAddPeerResponse(rsp) +} + +// DeletePeerWithResponse request returning *DeletePeerResponse +func (c *ClientWithResponses) DeletePeerWithResponse(ctx context.Context, roomId string, id string, reqEditors ...RequestEditorFn) (*DeletePeerResponse, error) { + rsp, err := c.DeletePeer(ctx, roomId, id, reqEditors...) + if err != nil { + return nil, err + } + return ParseDeletePeerResponse(rsp) +} + +// RefreshTokenWithResponse request returning *RefreshTokenResponse +func (c *ClientWithResponses) RefreshTokenWithResponse(ctx context.Context, roomId string, id string, reqEditors ...RequestEditorFn) (*RefreshTokenResponse, error) { + rsp, err := c.RefreshToken(ctx, roomId, id, reqEditors...) + if err != nil { + return nil, err + } + return ParseRefreshTokenResponse(rsp) +} + +// SubscribePeerWithResponse request returning *SubscribePeerResponse +func (c *ClientWithResponses) SubscribePeerWithResponse(ctx context.Context, roomId string, id string, params *SubscribePeerParams, reqEditors ...RequestEditorFn) (*SubscribePeerResponse, error) { + rsp, err := c.SubscribePeer(ctx, roomId, id, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseSubscribePeerResponse(rsp) +} + +// SubscribeTracksWithBodyWithResponse request with arbitrary body returning *SubscribeTracksResponse +func (c *ClientWithResponses) SubscribeTracksWithBodyWithResponse(ctx context.Context, roomId string, id string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*SubscribeTracksResponse, error) { + rsp, err := c.SubscribeTracksWithBody(ctx, roomId, id, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseSubscribeTracksResponse(rsp) +} + +func (c *ClientWithResponses) SubscribeTracksWithResponse(ctx context.Context, roomId string, id string, body SubscribeTracksJSONRequestBody, reqEditors ...RequestEditorFn) (*SubscribeTracksResponse, error) { + rsp, err := c.SubscribeTracks(ctx, roomId, id, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseSubscribeTracksResponse(rsp) +} + +// GenerateStreamerTokenWithResponse request returning *GenerateStreamerTokenResponse +func (c *ClientWithResponses) GenerateStreamerTokenWithResponse(ctx context.Context, roomId string, reqEditors ...RequestEditorFn) (*GenerateStreamerTokenResponse, error) { + rsp, err := c.GenerateStreamerToken(ctx, roomId, reqEditors...) + if err != nil { + return nil, err + } + return ParseGenerateStreamerTokenResponse(rsp) +} + +// CreateTrackForwardingWithBodyWithResponse request with arbitrary body returning *CreateTrackForwardingResponse +func (c *ClientWithResponses) CreateTrackForwardingWithBodyWithResponse(ctx context.Context, roomId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateTrackForwardingResponse, error) { + rsp, err := c.CreateTrackForwardingWithBody(ctx, roomId, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateTrackForwardingResponse(rsp) +} + +func (c *ClientWithResponses) CreateTrackForwardingWithResponse(ctx context.Context, roomId string, body CreateTrackForwardingJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateTrackForwardingResponse, error) { + rsp, err := c.CreateTrackForwarding(ctx, roomId, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateTrackForwardingResponse(rsp) +} + +// GenerateViewerTokenWithResponse request returning *GenerateViewerTokenResponse +func (c *ClientWithResponses) GenerateViewerTokenWithResponse(ctx context.Context, roomId string, reqEditors ...RequestEditorFn) (*GenerateViewerTokenResponse, error) { + rsp, err := c.GenerateViewerToken(ctx, roomId, reqEditors...) + if err != nil { + return nil, err + } + return ParseGenerateViewerTokenResponse(rsp) +} + +// ParseGetAllStreamsResponse parses an HTTP response from a GetAllStreamsWithResponse call +func ParseGetAllStreamsResponse(rsp *http.Response) (*GetAllStreamsResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetAllStreamsResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest StreamsListingResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 503: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON503 = &dest + + } + + return response, nil +} + +// ParseCreateStreamResponse parses an HTTP response from a CreateStreamWithResponse call +func ParseCreateStreamResponse(rsp *http.Response) (*CreateStreamResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateStreamResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest Stream + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 503: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON503 = &dest + + } + + return response, nil +} + +// ParseDeleteStreamResponse parses an HTTP response from a DeleteStreamWithResponse call +func ParseDeleteStreamResponse(rsp *http.Response) (*DeleteStreamResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &DeleteStreamResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 503: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON503 = &dest + + } + + return response, nil +} + +// ParseGetStreamResponse parses an HTTP response from a GetStreamWithResponse call +func ParseGetStreamResponse(rsp *http.Response) (*GetStreamResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetStreamResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Stream + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 503: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON503 = &dest + + } + + return response, nil +} + +// ParseCreateStreamerResponse parses an HTTP response from a CreateStreamerWithResponse call +func ParseCreateStreamerResponse(rsp *http.Response) (*CreateStreamerResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateStreamerResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest Streamer + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 503: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON503 = &dest + + } + + return response, nil +} + +// ParseDeleteStreamerResponse parses an HTTP response from a DeleteStreamerWithResponse call +func ParseDeleteStreamerResponse(rsp *http.Response) (*DeleteStreamerResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &DeleteStreamerResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 503: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON503 = &dest + + } + + return response, nil +} + +// ParseCreateViewerResponse parses an HTTP response from a CreateViewerWithResponse call +func ParseCreateViewerResponse(rsp *http.Response) (*CreateViewerResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateViewerResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest Viewer + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 503: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON503 = &dest + + } + + return response, nil +} + +// ParseDeleteViewerResponse parses an HTTP response from a DeleteViewerWithResponse call +func ParseDeleteViewerResponse(rsp *http.Response) (*DeleteViewerResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &DeleteViewerResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 503: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON503 = &dest + + } + + return response, nil +} + +// ParseGetAllRoomsResponse parses an HTTP response from a GetAllRoomsWithResponse call +func ParseGetAllRoomsResponse(rsp *http.Response) (*GetAllRoomsResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetAllRoomsResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest RoomsListingResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + } + + return response, nil +} + +// ParseCreateRoomResponse parses an HTTP response from a CreateRoomWithResponse call +func ParseCreateRoomResponse(rsp *http.Response) (*CreateRoomResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateRoomResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest RoomCreateDetailsResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 503: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON503 = &dest + + } + + return response, nil +} + +// ParseDeleteRoomResponse parses an HTTP response from a DeleteRoomWithResponse call +func ParseDeleteRoomResponse(rsp *http.Response) (*DeleteRoomResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &DeleteRoomResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 503: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON503 = &dest + + } + + return response, nil +} + +// ParseGetRoomResponse parses an HTTP response from a GetRoomWithResponse call +func ParseGetRoomResponse(rsp *http.Response) (*GetRoomResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetRoomResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest RoomDetailsResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 503: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON503 = &dest + + } + + return response, nil +} + +// ParseAddPeerResponse parses an HTTP response from a AddPeerWithResponse call +func ParseAddPeerResponse(rsp *http.Response) (*AddPeerResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &AddPeerResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest PeerDetailsResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 409: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON409 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 503: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON503 = &dest + + } + + return response, nil +} + +// ParseDeletePeerResponse parses an HTTP response from a DeletePeerWithResponse call +func ParseDeletePeerResponse(rsp *http.Response) (*DeletePeerResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &DeletePeerResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 503: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON503 = &dest + + } + + return response, nil +} + +// ParseRefreshTokenResponse parses an HTTP response from a RefreshTokenWithResponse call +func ParseRefreshTokenResponse(rsp *http.Response) (*RefreshTokenResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &RefreshTokenResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest PeerRefreshTokenResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 503: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON503 = &dest + + } + + return response, nil +} + +// ParseSubscribePeerResponse parses an HTTP response from a SubscribePeerWithResponse call +func ParseSubscribePeerResponse(rsp *http.Response) (*SubscribePeerResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &SubscribePeerResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 503: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON503 = &dest + + } + + return response, nil +} + +// ParseSubscribeTracksResponse parses an HTTP response from a SubscribeTracksWithResponse call +func ParseSubscribeTracksResponse(rsp *http.Response) (*SubscribeTracksResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &SubscribeTracksResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 503: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON503 = &dest + + } + + return response, nil +} + +// ParseGenerateStreamerTokenResponse parses an HTTP response from a GenerateStreamerTokenWithResponse call +func ParseGenerateStreamerTokenResponse(rsp *http.Response) (*GenerateStreamerTokenResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GenerateStreamerTokenResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest StreamerToken + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 503: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON503 = &dest + + } + + return response, nil +} + +// ParseCreateTrackForwardingResponse parses an HTTP response from a CreateTrackForwardingWithResponse call +func ParseCreateTrackForwardingResponse(rsp *http.Response) (*CreateTrackForwardingResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateTrackForwardingResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + } + + return response, nil +} + +// ParseGenerateViewerTokenResponse parses an HTTP response from a GenerateViewerTokenWithResponse call +func ParseGenerateViewerTokenResponse(rsp *http.Response) (*GenerateViewerTokenResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GenerateViewerTokenResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest ViewerToken + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 503: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON503 = &dest + + } + + return response, nil +} diff --git a/conference-to-stream/backend/fishjam/notifier.go b/conference-to-stream/backend/fishjam/notifier.go new file mode 100644 index 0000000..9ca78b5 --- /dev/null +++ b/conference-to-stream/backend/fishjam/notifier.go @@ -0,0 +1,190 @@ +package fishjam + +import ( + "fmt" + "log" + "net/url" + "strings" + + pb "conference-to-stream/proto/fishjam" + + "github.com/gorilla/websocket" + "google.golang.org/protobuf/proto" +) + +type TrackForwardingEvent struct { + RoomID string + PeerID string + CompositionURL string + InputID string +} + +type PeerEvent struct { + RoomID string + PeerID string +} + +type NotifierCallbacks struct { + OnTrackForwarding func(TrackForwardingEvent) + OnTrackForwardingRemoved func(TrackForwardingEvent) + OnPeerConnected func(PeerEvent) + OnPeerDisconnected func(PeerEvent) +} + +type Notifier struct { + conn *websocket.Conn + callbacks NotifierCallbacks + done chan struct{} +} + +func NewNotifier(fishjamBaseURL, managementToken string, callbacks NotifierCallbacks) (*Notifier, error) { + wsURL := httpToWebsocket(fishjamBaseURL) + "/socket/server/websocket" + + conn, _, err := websocket.DefaultDialer.Dial(wsURL, nil) + if err != nil { + return nil, fmt.Errorf("dial fishjam ws: %w", err) + } + + n := &Notifier{ + conn: conn, + callbacks: callbacks, + done: make(chan struct{}), + } + + if err := n.authenticate(managementToken); err != nil { + conn.Close() + return nil, fmt.Errorf("authenticate: %w", err) + } + + if err := n.subscribe(); err != nil { + conn.Close() + return nil, fmt.Errorf("subscribe: %w", err) + } + + go n.listen() + + return n, nil +} + +func (n *Notifier) Close() { + n.conn.Close() + <-n.done +} + +func (n *Notifier) authenticate(token string) error { + msg := &pb.ServerMessage{ + Content: &pb.ServerMessage_AuthRequest_{ + AuthRequest: &pb.ServerMessage_AuthRequest{ + Token: token, + }, + }, + } + return n.sendProto(msg) +} + +func (n *Notifier) subscribe() error { + msg := &pb.ServerMessage{ + Content: &pb.ServerMessage_SubscribeRequest_{ + SubscribeRequest: &pb.ServerMessage_SubscribeRequest{ + EventType: pb.ServerMessage_EVENT_TYPE_SERVER_NOTIFICATION, + }, + }, + } + return n.sendProto(msg) +} + +func (n *Notifier) sendProto(msg *pb.ServerMessage) error { + data, err := proto.Marshal(msg) + if err != nil { + return fmt.Errorf("marshal proto: %w", err) + } + return n.conn.WriteMessage(websocket.BinaryMessage, data) +} + +func (n *Notifier) listen() { + defer close(n.done) + + for { + _, data, err := n.conn.ReadMessage() + if err != nil { + if websocket.IsCloseError(err, websocket.CloseNormalClosure) { + return + } + log.Printf("ws read error: %v", err) + return + } + + var msg pb.ServerMessage + if err := proto.Unmarshal(data, &msg); err != nil { + log.Printf("unmarshal ws message: %v", err) + continue + } + + n.dispatch(&msg) + } +} + +func (n *Notifier) dispatch(msg *pb.ServerMessage) { + switch content := msg.Content.(type) { + case *pb.ServerMessage_Authenticated_: + log.Println("fishjam: authenticated") + case *pb.ServerMessage_SubscribeResponse_: + log.Println("fishjam: subscribed to notifications") + case *pb.ServerMessage_TrackForwarding_: + tf := content.TrackForwarding + log.Printf("fishjam: track forwarding - room=%s peer=%s input=%s", tf.RoomId, tf.PeerId, tf.InputId) + if n.callbacks.OnTrackForwarding != nil { + n.callbacks.OnTrackForwarding(TrackForwardingEvent{ + RoomID: tf.RoomId, + PeerID: tf.PeerId, + CompositionURL: tf.CompositionUrl, + InputID: tf.InputId, + }) + } + case *pb.ServerMessage_TrackForwardingRemoved_: + tf := content.TrackForwardingRemoved + log.Printf("fishjam: track forwarding removed - room=%s peer=%s input=%s", tf.RoomId, tf.PeerId, tf.InputId) + if n.callbacks.OnTrackForwardingRemoved != nil { + n.callbacks.OnTrackForwardingRemoved(TrackForwardingEvent{ + RoomID: tf.RoomId, + PeerID: tf.PeerId, + CompositionURL: tf.CompositionUrl, + InputID: tf.InputId, + }) + } + case *pb.ServerMessage_PeerConnected_: + log.Printf("fishjam: peer connected - room=%s peer=%s", + content.PeerConnected.RoomId, content.PeerConnected.PeerId) + if n.callbacks.OnPeerConnected != nil { + n.callbacks.OnPeerConnected(PeerEvent{ + RoomID: content.PeerConnected.RoomId, + PeerID: content.PeerConnected.PeerId, + }) + } + case *pb.ServerMessage_PeerDisconnected_: + log.Printf("fishjam: peer disconnected - room=%s peer=%s", + content.PeerDisconnected.RoomId, content.PeerDisconnected.PeerId) + if n.callbacks.OnPeerDisconnected != nil { + n.callbacks.OnPeerDisconnected(PeerEvent{ + RoomID: content.PeerDisconnected.RoomId, + PeerID: content.PeerDisconnected.PeerId, + }) + } + default: + // Ignore other notification types + } +} + +func httpToWebsocket(httpURL string) string { + u, err := url.Parse(httpURL) + if err != nil { + return strings.Replace(strings.Replace(httpURL, "https://", "wss://", 1), "http://", "ws://", 1) + } + switch u.Scheme { + case "https": + u.Scheme = "wss" + case "http": + u.Scheme = "ws" + } + return u.String() +} diff --git a/conference-to-stream/backend/fishjam/oapi-codegen.yaml b/conference-to-stream/backend/fishjam/oapi-codegen.yaml new file mode 100644 index 0000000..8c04977 --- /dev/null +++ b/conference-to-stream/backend/fishjam/oapi-codegen.yaml @@ -0,0 +1,5 @@ +package: fishjamapi +output: fishjam/generated/fishjam.gen.go +generate: + models: true + client: true diff --git a/conference-to-stream/backend/go.mod b/conference-to-stream/backend/go.mod new file mode 100644 index 0000000..5b8ab64 --- /dev/null +++ b/conference-to-stream/backend/go.mod @@ -0,0 +1,41 @@ +module conference-to-stream + +go 1.24.5 + +require ( + github.com/gorilla/websocket v1.5.3 + github.com/joho/godotenv v1.5.1 + github.com/rs/cors v1.11.1 + google.golang.org/protobuf v1.36.11 +) + +require ( + github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect + github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect + github.com/getkin/kin-openapi v0.133.0 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/google/uuid v1.5.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/oapi-codegen/oapi-codegen/v2 v2.0.0 // indirect + github.com/oapi-codegen/runtime v1.2.0 // indirect + github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect + github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect + github.com/perimeterx/marshmallow v1.1.5 // indirect + github.com/speakeasy-api/jsonpath v0.6.0 // indirect + github.com/speakeasy-api/openapi-overlay v0.10.2 // indirect + github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect + golang.org/x/mod v0.33.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/text v0.34.0 // indirect + golang.org/x/tools v0.42.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +tool github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen + +replace github.com/oapi-codegen/oapi-codegen/v2 => /Users/roznawsk/projects/oapi-codegen diff --git a/conference-to-stream/backend/go.sum b/conference-to-stream/backend/go.sum new file mode 100644 index 0000000..1cf337a --- /dev/null +++ b/conference-to-stream/backend/go.sum @@ -0,0 +1,192 @@ +github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= +github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= +github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= +github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= +github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= +github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= +github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+LpmzwHMP4= +github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= +github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= +github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= +github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= +github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= +github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= +github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= +github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= +github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= +github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= +github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= +github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= +github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/conference-to-stream/backend/handler/handler.go b/conference-to-stream/backend/handler/handler.go new file mode 100644 index 0000000..bf0dc96 --- /dev/null +++ b/conference-to-stream/backend/handler/handler.go @@ -0,0 +1,330 @@ +package handler + +import ( + "encoding/json" + "fmt" + "log" + "net/http" + "strings" + "sync" + + "conference-to-stream/composition" + "conference-to-stream/fishjam" +) + +const whepOutputID = "whep_output" + +type RoomState struct { + RoomID string + RoomName string + CompositionID string + CompositionURL string // base URL of the composition server (api_url) + InputIDs map[string]string // input_id → peer_id + PeerIDs map[string]struct{} + PeerNames map[string]string // peer_id → display name + WhepURL string + CompositionDeleted bool + mu sync.Mutex +} + +type Handler struct { + fishjamClient *fishjam.Client + compositionClient *composition.Client + compositionAPIURL string + managementToken string + + mu sync.Mutex + rooms map[string]*RoomState // room_name → state + roomsByID map[string]*RoomState // fishjam room_id → state +} + +func New(fishjamClient *fishjam.Client, compositionClient *composition.Client, compositionAPIURL string) *Handler { + return &Handler{ + fishjamClient: fishjamClient, + compositionClient: compositionClient, + compositionAPIURL: compositionAPIURL, + managementToken: fishjamClient.ManagementToken(), + rooms: make(map[string]*RoomState), + roomsByID: make(map[string]*RoomState), + } +} + +type createRoomRequest struct { + RoomName string `json:"roomName"` +} + +type createRoomResponse struct { + RoomID string `json:"roomId"` + WhepURL string `json:"whepUrl"` +} + +type createPeerRequest struct { + PeerName string `json:"peerName"` +} + +type createPeerResponse struct { + PeerToken string `json:"peerToken"` + PeerWebsocketURL string `json:"peerWebsocketUrl"` +} + +func (h *Handler) CreateRoom(w http.ResponseWriter, r *http.Request) { + var req createRoomRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "invalid request body", http.StatusBadRequest) + return + } + if req.RoomName == "" { + http.Error(w, "roomName is required", http.StatusBadRequest) + return + } + + // Return existing room if already created + h.mu.Lock() + if state, ok := h.rooms[req.RoomName]; ok { + h.mu.Unlock() + writeJSON(w, createRoomResponse{RoomID: state.RoomID, WhepURL: state.WhepURL}) + return + } + h.mu.Unlock() + + apiURL := h.compositionAPIURL + + // Create composition + compositionID, err := h.compositionClient.CreateComposition(apiURL) + if err != nil { + log.Printf("create composition: %v", err) + http.Error(w, "failed to create composition", http.StatusInternalServerError) + return + } + log.Printf("created composition: %s", compositionID) + + // Start composition + if err := h.compositionClient.Start(apiURL, compositionID); err != nil { + log.Printf("start composition: %v", err) + http.Error(w, "failed to start composition", http.StatusInternalServerError) + return + } + + // Register WHEP output + if err := h.compositionClient.RegisterWhepOutput(apiURL, compositionID, whepOutputID); err != nil { + log.Printf("register whep output: %v", err) + http.Error(w, "failed to register WHEP output", http.StatusInternalServerError) + return + } + + // Create Fishjam room + room, err := h.fishjamClient.CreateRoom() + if err != nil { + log.Printf("create room: %v", err) + http.Error(w, "failed to create room", http.StatusInternalServerError) + return + } + roomID := room.Id + log.Printf("created room: %s", roomID) + + // Add track forwarding — pass the composition base URL so Fishjam can forward tracks to it + compositionBaseURL := h.compositionClient.CompositionBaseURL(apiURL, compositionID) + if err := h.fishjamClient.CreateTrackForwarding(roomID, compositionBaseURL); err != nil { + log.Printf("create track forwarding: %v", err) + http.Error(w, "failed to create track forwarding", http.StatusInternalServerError) + return + } + + whepURL := h.compositionClient.WhepURL(apiURL, compositionID, whepOutputID) + + state := &RoomState{ + RoomID: roomID, + RoomName: req.RoomName, + CompositionID: compositionID, + CompositionURL: apiURL, + InputIDs: make(map[string]string), + PeerIDs: make(map[string]struct{}), + PeerNames: make(map[string]string), + WhepURL: whepURL, + } + + h.mu.Lock() + h.rooms[req.RoomName] = state + h.roomsByID[roomID] = state + h.mu.Unlock() + + // Start WS notifier for this room + fishjamBaseURL := h.fishjamClient.BaseURL() + _, err = fishjam.NewNotifier(fishjamBaseURL, h.managementToken, fishjam.NotifierCallbacks{ + OnTrackForwarding: func(event fishjam.TrackForwardingEvent) { + if event.RoomID != roomID { + return + } + state.mu.Lock() + if state.CompositionDeleted { + state.mu.Unlock() + return + } + state.InputIDs[event.InputID] = event.PeerID + inputs := collectInputEntries(state.InputIDs, state.PeerNames) + state.mu.Unlock() + + log.Printf("track forwarding: room=%s peer=%s input=%s (total=%d)", event.RoomID, event.PeerID, event.InputID, len(inputs)) + if err := h.compositionClient.UpdateOutput(apiURL, compositionID, whepOutputID, inputs); err != nil { + log.Printf("update output: %v", err) + } + }, + OnTrackForwardingRemoved: func(event fishjam.TrackForwardingEvent) { + if event.RoomID != roomID { + return + } + state.mu.Lock() + if state.CompositionDeleted { + state.mu.Unlock() + return + } + delete(state.InputIDs, event.InputID) + inputs := collectInputEntries(state.InputIDs, state.PeerNames) + state.mu.Unlock() + + log.Printf("track forwarding removed: room=%s peer=%s input=%s (total=%d)", event.RoomID, event.PeerID, event.InputID, len(inputs)) + if err := h.compositionClient.UpdateOutput(apiURL, compositionID, whepOutputID, inputs); err != nil { + log.Printf("update output: %v", err) + } + }, + OnPeerConnected: func(event fishjam.PeerEvent) { + if event.RoomID != roomID { + return + } + state.mu.Lock() + state.PeerIDs[event.PeerID] = struct{}{} + peersCount := len(state.PeerIDs) + state.mu.Unlock() + log.Printf("peer connected: room=%s peer=%s (active=%d)", event.RoomID, event.PeerID, peersCount) + }, + OnPeerDisconnected: func(event fishjam.PeerEvent) { + if event.RoomID != roomID { + return + } + state.mu.Lock() + delete(state.PeerIDs, event.PeerID) + delete(state.PeerNames, event.PeerID) + + shouldDelete := !state.CompositionDeleted && len(state.PeerIDs) == 0 + compositionID := state.CompositionID + compositionURL := state.CompositionURL + roomName := state.RoomName + roomID := state.RoomID + state.mu.Unlock() + + if !shouldDelete { + return + } + + if err := h.compositionClient.DeleteComposition(compositionURL, compositionID); err != nil { + log.Printf("delete composition: room=%s composition=%s err=%v", roomID, compositionID, err) + return + } + + state.mu.Lock() + state.CompositionDeleted = true + state.mu.Unlock() + + h.mu.Lock() + delete(h.roomsByID, roomID) + if roomName != "" { + delete(h.rooms, roomName) + } + h.mu.Unlock() + + log.Printf("deleted composition after last peer left: room=%s composition=%s", roomID, compositionID) + }, + }) + if err != nil { + log.Printf("start notifier: %v", err) + http.Error(w, "failed to start notifier", http.StatusInternalServerError) + return + } + + writeJSON(w, createRoomResponse{RoomID: roomID, WhepURL: whepURL}) +} + +func (h *Handler) CreatePeer(w http.ResponseWriter, r *http.Request) { + roomID := roomIDFromPath(r.URL.Path) + if roomID == "" { + http.Error(w, "room ID required", http.StatusBadRequest) + return + } + + var req createPeerRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "invalid request body", http.StatusBadRequest) + return + } + + metadata := map[string]string{} + if req.PeerName != "" { + metadata["name"] = req.PeerName + } + + peerID, peerToken, peerWebsocketURL, err := h.fishjamClient.CreatePeer(roomID, metadata) + if err != nil { + log.Printf("create peer: %v", err) + http.Error(w, "failed to create peer", http.StatusInternalServerError) + return + } + + // Store peer name for composition overlays + h.mu.Lock() + if state, ok := h.roomsByID[roomID]; ok { + state.mu.Lock() + state.PeerNames[peerID] = req.PeerName + state.mu.Unlock() + } + h.mu.Unlock() + + writeJSON(w, createPeerResponse{ + PeerToken: peerToken, + PeerWebsocketURL: peerWebsocketURL, + }) +} + +func writeJSON(w http.ResponseWriter, v any) { + w.Header().Set("Content-Type", "application/json") + if err := json.NewEncoder(w).Encode(v); err != nil { + log.Printf("encode response: %v", err) + } +} + +// roomIDFromPath extracts room ID from /api/rooms/{roomId}/peers +func roomIDFromPath(path string) string { + parts := strings.Split(strings.Trim(path, "/"), "/") + // Expected: ["api", "rooms", "", "peers"] + if len(parts) >= 3 { + return parts[2] + } + return "" +} + +func collectInputEntries(inputIDs, peerNames map[string]string) []composition.InputEntry { + entries := make([]composition.InputEntry, 0, len(inputIDs)) + for inputID, peerID := range inputIDs { + name := peerNames[peerID] + entries = append(entries, composition.InputEntry{InputID: inputID, PeerName: name}) + } + return entries +} + +// Route registers routes on the given mux +func (h *Handler) Route(mux *http.ServeMux) { + mux.HandleFunc("/api/rooms", func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + http.Error(w, fmt.Sprintf("method %s not allowed", r.Method), http.StatusMethodNotAllowed) + return + } + h.CreateRoom(w, r) + }) + + mux.HandleFunc("/api/rooms/", func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + http.Error(w, fmt.Sprintf("method %s not allowed", r.Method), http.StatusMethodNotAllowed) + return + } + h.CreatePeer(w, r) + }) +} diff --git a/conference-to-stream/backend/main.go b/conference-to-stream/backend/main.go new file mode 100644 index 0000000..0f55c7e --- /dev/null +++ b/conference-to-stream/backend/main.go @@ -0,0 +1,55 @@ +package main + +import ( + "log" + "net/http" + "os" + + "conference-to-stream/composition" + "conference-to-stream/fishjam" + "conference-to-stream/handler" + + "github.com/joho/godotenv" + "github.com/rs/cors" +) + +func main() { + // Load .env from parent directory (conference-to-stream/.env) when running locally + _ = godotenv.Load("../.env") + + fishjamID := os.Getenv("FISHJAM_ID") + if fishjamID == "" { + log.Fatal("FISHJAM_ID is required") + } + managementToken := os.Getenv("FISHJAM_MANAGEMENT_TOKEN") + if managementToken == "" { + log.Fatal("FISHJAM_MANAGEMENT_TOKEN is required") + } + compositionAPIURL := os.Getenv("COMPOSITION_API_URL") + if compositionAPIURL == "" { + compositionAPIURL = "https://rtc.fishjam.io" + } + port := os.Getenv("PORT") + if port == "" { + port = "8080" + } + + fishjamClient := fishjam.NewClient(fishjamID, managementToken) + compositionClient := composition.NewClient() + h := handler.New(fishjamClient, compositionClient, compositionAPIURL) + + mux := http.NewServeMux() + h.Route(mux) + + c := cors.New(cors.Options{ + AllowedOrigins: []string{"*"}, + AllowedMethods: []string{"GET", "POST", "OPTIONS"}, + AllowedHeaders: []string{"Content-Type", "Authorization"}, + }) + + addr := ":" + port + log.Printf("starting server on %s", addr) + if err := http.ListenAndServe(addr, c.Handler(mux)); err != nil { + log.Fatal(err) + } +} diff --git a/conference-to-stream/backend/mise.toml b/conference-to-stream/backend/mise.toml new file mode 100644 index 0000000..5707a5c --- /dev/null +++ b/conference-to-stream/backend/mise.toml @@ -0,0 +1,11 @@ +[tasks.generate-composition-client] +description = "Generate the composition API client from composition-openapi.json" +run = "go tool oapi-codegen -config composition/oapi-codegen.yaml composition-openapi.json" + +[tasks.generate-fishjam-client] +description = "Generate the Fishjam API client from ~/fjc/fishjam/openapi.yaml" +run = "go tool oapi-codegen -config fishjam/oapi-codegen.yaml ~/fjc/fishjam/openapi.yaml" + +[tasks.generate] +description = "Regenerate all API clients" +depends = ["generate-composition-client", "generate-fishjam-client"] diff --git a/conference-to-stream/backend/openapitools.json b/conference-to-stream/backend/openapitools.json new file mode 100644 index 0000000..a82623d --- /dev/null +++ b/conference-to-stream/backend/openapitools.json @@ -0,0 +1,7 @@ +{ + "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "spaces": 2, + "generator-cli": { + "version": "7.14.0" + } +} diff --git a/conference-to-stream/backend/proto/fishjam/notifications/shared.pb.go b/conference-to-stream/backend/proto/fishjam/notifications/shared.pb.go new file mode 100644 index 0000000..e654f9f --- /dev/null +++ b/conference-to-stream/backend/proto/fishjam/notifications/shared.pb.go @@ -0,0 +1,253 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v6.33.1 +// source: fishjam/notifications/shared.proto + +package notifications + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Defines types of tracks being published by peers and component +type TrackType int32 + +const ( + TrackType_TRACK_TYPE_UNSPECIFIED TrackType = 0 + TrackType_TRACK_TYPE_VIDEO TrackType = 1 + TrackType_TRACK_TYPE_AUDIO TrackType = 2 +) + +// Enum value maps for TrackType. +var ( + TrackType_name = map[int32]string{ + 0: "TRACK_TYPE_UNSPECIFIED", + 1: "TRACK_TYPE_VIDEO", + 2: "TRACK_TYPE_AUDIO", + } + TrackType_value = map[string]int32{ + "TRACK_TYPE_UNSPECIFIED": 0, + "TRACK_TYPE_VIDEO": 1, + "TRACK_TYPE_AUDIO": 2, + } +) + +func (x TrackType) Enum() *TrackType { + p := new(TrackType) + *p = x + return p +} + +func (x TrackType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (TrackType) Descriptor() protoreflect.EnumDescriptor { + return file_fishjam_notifications_shared_proto_enumTypes[0].Descriptor() +} + +func (TrackType) Type() protoreflect.EnumType { + return &file_fishjam_notifications_shared_proto_enumTypes[0] +} + +func (x TrackType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use TrackType.Descriptor instead. +func (TrackType) EnumDescriptor() ([]byte, []int) { + return file_fishjam_notifications_shared_proto_rawDescGZIP(), []int{0} +} + +type TrackEncoding int32 + +const ( + TrackEncoding_TRACK_ENCODING_UNSPECIFIED TrackEncoding = 0 + TrackEncoding_TRACK_ENCODING_PCM16 TrackEncoding = 1 + TrackEncoding_TRACK_ENCODING_OPUS TrackEncoding = 2 +) + +// Enum value maps for TrackEncoding. +var ( + TrackEncoding_name = map[int32]string{ + 0: "TRACK_ENCODING_UNSPECIFIED", + 1: "TRACK_ENCODING_PCM16", + 2: "TRACK_ENCODING_OPUS", + } + TrackEncoding_value = map[string]int32{ + "TRACK_ENCODING_UNSPECIFIED": 0, + "TRACK_ENCODING_PCM16": 1, + "TRACK_ENCODING_OPUS": 2, + } +) + +func (x TrackEncoding) Enum() *TrackEncoding { + p := new(TrackEncoding) + *p = x + return p +} + +func (x TrackEncoding) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (TrackEncoding) Descriptor() protoreflect.EnumDescriptor { + return file_fishjam_notifications_shared_proto_enumTypes[1].Descriptor() +} + +func (TrackEncoding) Type() protoreflect.EnumType { + return &file_fishjam_notifications_shared_proto_enumTypes[1] +} + +func (x TrackEncoding) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use TrackEncoding.Descriptor instead. +func (TrackEncoding) EnumDescriptor() ([]byte, []int) { + return file_fishjam_notifications_shared_proto_rawDescGZIP(), []int{1} +} + +// Describes a media track +type Track struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Type TrackType `protobuf:"varint,2,opt,name=type,proto3,enum=fishjam.notifications.TrackType" json:"type,omitempty"` + Metadata string `protobuf:"bytes,3,opt,name=metadata,proto3" json:"metadata,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Track) Reset() { + *x = Track{} + mi := &file_fishjam_notifications_shared_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Track) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Track) ProtoMessage() {} + +func (x *Track) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_notifications_shared_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Track.ProtoReflect.Descriptor instead. +func (*Track) Descriptor() ([]byte, []int) { + return file_fishjam_notifications_shared_proto_rawDescGZIP(), []int{0} +} + +func (x *Track) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Track) GetType() TrackType { + if x != nil { + return x.Type + } + return TrackType_TRACK_TYPE_UNSPECIFIED +} + +func (x *Track) GetMetadata() string { + if x != nil { + return x.Metadata + } + return "" +} + +var File_fishjam_notifications_shared_proto protoreflect.FileDescriptor + +const file_fishjam_notifications_shared_proto_rawDesc = "" + + "\n" + + "\"fishjam/notifications/shared.proto\x12\x15fishjam.notifications\"i\n" + + "\x05Track\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x124\n" + + "\x04type\x18\x02 \x01(\x0e2 .fishjam.notifications.TrackTypeR\x04type\x12\x1a\n" + + "\bmetadata\x18\x03 \x01(\tR\bmetadata*S\n" + + "\tTrackType\x12\x1a\n" + + "\x16TRACK_TYPE_UNSPECIFIED\x10\x00\x12\x14\n" + + "\x10TRACK_TYPE_VIDEO\x10\x01\x12\x14\n" + + "\x10TRACK_TYPE_AUDIO\x10\x02*b\n" + + "\rTrackEncoding\x12\x1e\n" + + "\x1aTRACK_ENCODING_UNSPECIFIED\x10\x00\x12\x18\n" + + "\x14TRACK_ENCODING_PCM16\x10\x01\x12\x17\n" + + "\x13TRACK_ENCODING_OPUS\x10\x02b\x06proto3" + +var ( + file_fishjam_notifications_shared_proto_rawDescOnce sync.Once + file_fishjam_notifications_shared_proto_rawDescData []byte +) + +func file_fishjam_notifications_shared_proto_rawDescGZIP() []byte { + file_fishjam_notifications_shared_proto_rawDescOnce.Do(func() { + file_fishjam_notifications_shared_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_fishjam_notifications_shared_proto_rawDesc), len(file_fishjam_notifications_shared_proto_rawDesc))) + }) + return file_fishjam_notifications_shared_proto_rawDescData +} + +var file_fishjam_notifications_shared_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_fishjam_notifications_shared_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_fishjam_notifications_shared_proto_goTypes = []any{ + (TrackType)(0), // 0: fishjam.notifications.TrackType + (TrackEncoding)(0), // 1: fishjam.notifications.TrackEncoding + (*Track)(nil), // 2: fishjam.notifications.Track +} +var file_fishjam_notifications_shared_proto_depIdxs = []int32{ + 0, // 0: fishjam.notifications.Track.type:type_name -> fishjam.notifications.TrackType + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_fishjam_notifications_shared_proto_init() } +func file_fishjam_notifications_shared_proto_init() { + if File_fishjam_notifications_shared_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_fishjam_notifications_shared_proto_rawDesc), len(file_fishjam_notifications_shared_proto_rawDesc)), + NumEnums: 2, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_fishjam_notifications_shared_proto_goTypes, + DependencyIndexes: file_fishjam_notifications_shared_proto_depIdxs, + EnumInfos: file_fishjam_notifications_shared_proto_enumTypes, + MessageInfos: file_fishjam_notifications_shared_proto_msgTypes, + }.Build() + File_fishjam_notifications_shared_proto = out.File + file_fishjam_notifications_shared_proto_goTypes = nil + file_fishjam_notifications_shared_proto_depIdxs = nil +} diff --git a/conference-to-stream/backend/proto/fishjam/server_notifications.pb.go b/conference-to-stream/backend/proto/fishjam/server_notifications.pb.go new file mode 100644 index 0000000..1cbb40c --- /dev/null +++ b/conference-to-stream/backend/proto/fishjam/server_notifications.pb.go @@ -0,0 +1,2843 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v6.33.1 +// source: fishjam/server_notifications.proto + +package fishjam + +import ( + notifications "conference-to-stream/proto/fishjam/notifications" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ServerMessage_PeerType int32 + +const ( + ServerMessage_PEER_TYPE_UNSPECIFIED ServerMessage_PeerType = 0 + ServerMessage_PEER_TYPE_WEBRTC ServerMessage_PeerType = 1 + ServerMessage_PEER_TYPE_AGENT ServerMessage_PeerType = 2 +) + +// Enum value maps for ServerMessage_PeerType. +var ( + ServerMessage_PeerType_name = map[int32]string{ + 0: "PEER_TYPE_UNSPECIFIED", + 1: "PEER_TYPE_WEBRTC", + 2: "PEER_TYPE_AGENT", + } + ServerMessage_PeerType_value = map[string]int32{ + "PEER_TYPE_UNSPECIFIED": 0, + "PEER_TYPE_WEBRTC": 1, + "PEER_TYPE_AGENT": 2, + } +) + +func (x ServerMessage_PeerType) Enum() *ServerMessage_PeerType { + p := new(ServerMessage_PeerType) + *p = x + return p +} + +func (x ServerMessage_PeerType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ServerMessage_PeerType) Descriptor() protoreflect.EnumDescriptor { + return file_fishjam_server_notifications_proto_enumTypes[0].Descriptor() +} + +func (ServerMessage_PeerType) Type() protoreflect.EnumType { + return &file_fishjam_server_notifications_proto_enumTypes[0] +} + +func (x ServerMessage_PeerType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ServerMessage_PeerType.Descriptor instead. +func (ServerMessage_PeerType) EnumDescriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 0} +} + +// Defines message groups for which peer can subscribe +type ServerMessage_EventType int32 + +const ( + ServerMessage_EVENT_TYPE_UNSPECIFIED ServerMessage_EventType = 0 + ServerMessage_EVENT_TYPE_SERVER_NOTIFICATION ServerMessage_EventType = 1 +) + +// Enum value maps for ServerMessage_EventType. +var ( + ServerMessage_EventType_name = map[int32]string{ + 0: "EVENT_TYPE_UNSPECIFIED", + 1: "EVENT_TYPE_SERVER_NOTIFICATION", + } + ServerMessage_EventType_value = map[string]int32{ + "EVENT_TYPE_UNSPECIFIED": 0, + "EVENT_TYPE_SERVER_NOTIFICATION": 1, + } +) + +func (x ServerMessage_EventType) Enum() *ServerMessage_EventType { + p := new(ServerMessage_EventType) + *p = x + return p +} + +func (x ServerMessage_EventType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ServerMessage_EventType) Descriptor() protoreflect.EnumDescriptor { + return file_fishjam_server_notifications_proto_enumTypes[1].Descriptor() +} + +func (ServerMessage_EventType) Type() protoreflect.EnumType { + return &file_fishjam_server_notifications_proto_enumTypes[1] +} + +func (x ServerMessage_EventType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ServerMessage_EventType.Descriptor instead. +func (ServerMessage_EventType) EnumDescriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 1} +} + +// Defines any type of message passed between FJ and server peer +type ServerMessage struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Content: + // + // *ServerMessage_Authenticated_ + // *ServerMessage_AuthRequest_ + // *ServerMessage_SubscribeRequest_ + // *ServerMessage_SubscribeResponse_ + // *ServerMessage_RoomCreated_ + // *ServerMessage_RoomDeleted_ + // *ServerMessage_RoomCrashed_ + // *ServerMessage_PeerConnected_ + // *ServerMessage_PeerDisconnected_ + // *ServerMessage_PeerCrashed_ + // *ServerMessage_PeerMetadataUpdated_ + // *ServerMessage_TrackAdded_ + // *ServerMessage_TrackRemoved_ + // *ServerMessage_TrackMetadataUpdated_ + // *ServerMessage_PeerAdded_ + // *ServerMessage_PeerDeleted_ + // *ServerMessage_ChannelAdded_ + // *ServerMessage_ChannelRemoved_ + // *ServerMessage_TrackForwarding_ + // *ServerMessage_TrackForwardingRemoved_ + // *ServerMessage_ViewerConnected_ + // *ServerMessage_ViewerDisconnected_ + // *ServerMessage_StreamerConnected_ + // *ServerMessage_StreamerDisconnected_ + // *ServerMessage_StreamConnected_ + // *ServerMessage_StreamDisconnected_ + // *ServerMessage_HlsPlayable_ + // *ServerMessage_HlsUploaded_ + // *ServerMessage_HlsUploadCrashed_ + // *ServerMessage_ComponentCrashed_ + Content isServerMessage_Content `protobuf_oneof:"content"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage) Reset() { + *x = ServerMessage{} + mi := &file_fishjam_server_notifications_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage) ProtoMessage() {} + +func (x *ServerMessage) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage.ProtoReflect.Descriptor instead. +func (*ServerMessage) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0} +} + +func (x *ServerMessage) GetContent() isServerMessage_Content { + if x != nil { + return x.Content + } + return nil +} + +func (x *ServerMessage) GetAuthenticated() *ServerMessage_Authenticated { + if x != nil { + if x, ok := x.Content.(*ServerMessage_Authenticated_); ok { + return x.Authenticated + } + } + return nil +} + +func (x *ServerMessage) GetAuthRequest() *ServerMessage_AuthRequest { + if x != nil { + if x, ok := x.Content.(*ServerMessage_AuthRequest_); ok { + return x.AuthRequest + } + } + return nil +} + +func (x *ServerMessage) GetSubscribeRequest() *ServerMessage_SubscribeRequest { + if x != nil { + if x, ok := x.Content.(*ServerMessage_SubscribeRequest_); ok { + return x.SubscribeRequest + } + } + return nil +} + +func (x *ServerMessage) GetSubscribeResponse() *ServerMessage_SubscribeResponse { + if x != nil { + if x, ok := x.Content.(*ServerMessage_SubscribeResponse_); ok { + return x.SubscribeResponse + } + } + return nil +} + +func (x *ServerMessage) GetRoomCreated() *ServerMessage_RoomCreated { + if x != nil { + if x, ok := x.Content.(*ServerMessage_RoomCreated_); ok { + return x.RoomCreated + } + } + return nil +} + +func (x *ServerMessage) GetRoomDeleted() *ServerMessage_RoomDeleted { + if x != nil { + if x, ok := x.Content.(*ServerMessage_RoomDeleted_); ok { + return x.RoomDeleted + } + } + return nil +} + +func (x *ServerMessage) GetRoomCrashed() *ServerMessage_RoomCrashed { + if x != nil { + if x, ok := x.Content.(*ServerMessage_RoomCrashed_); ok { + return x.RoomCrashed + } + } + return nil +} + +func (x *ServerMessage) GetPeerConnected() *ServerMessage_PeerConnected { + if x != nil { + if x, ok := x.Content.(*ServerMessage_PeerConnected_); ok { + return x.PeerConnected + } + } + return nil +} + +func (x *ServerMessage) GetPeerDisconnected() *ServerMessage_PeerDisconnected { + if x != nil { + if x, ok := x.Content.(*ServerMessage_PeerDisconnected_); ok { + return x.PeerDisconnected + } + } + return nil +} + +func (x *ServerMessage) GetPeerCrashed() *ServerMessage_PeerCrashed { + if x != nil { + if x, ok := x.Content.(*ServerMessage_PeerCrashed_); ok { + return x.PeerCrashed + } + } + return nil +} + +func (x *ServerMessage) GetPeerMetadataUpdated() *ServerMessage_PeerMetadataUpdated { + if x != nil { + if x, ok := x.Content.(*ServerMessage_PeerMetadataUpdated_); ok { + return x.PeerMetadataUpdated + } + } + return nil +} + +func (x *ServerMessage) GetTrackAdded() *ServerMessage_TrackAdded { + if x != nil { + if x, ok := x.Content.(*ServerMessage_TrackAdded_); ok { + return x.TrackAdded + } + } + return nil +} + +func (x *ServerMessage) GetTrackRemoved() *ServerMessage_TrackRemoved { + if x != nil { + if x, ok := x.Content.(*ServerMessage_TrackRemoved_); ok { + return x.TrackRemoved + } + } + return nil +} + +func (x *ServerMessage) GetTrackMetadataUpdated() *ServerMessage_TrackMetadataUpdated { + if x != nil { + if x, ok := x.Content.(*ServerMessage_TrackMetadataUpdated_); ok { + return x.TrackMetadataUpdated + } + } + return nil +} + +func (x *ServerMessage) GetPeerAdded() *ServerMessage_PeerAdded { + if x != nil { + if x, ok := x.Content.(*ServerMessage_PeerAdded_); ok { + return x.PeerAdded + } + } + return nil +} + +func (x *ServerMessage) GetPeerDeleted() *ServerMessage_PeerDeleted { + if x != nil { + if x, ok := x.Content.(*ServerMessage_PeerDeleted_); ok { + return x.PeerDeleted + } + } + return nil +} + +func (x *ServerMessage) GetChannelAdded() *ServerMessage_ChannelAdded { + if x != nil { + if x, ok := x.Content.(*ServerMessage_ChannelAdded_); ok { + return x.ChannelAdded + } + } + return nil +} + +func (x *ServerMessage) GetChannelRemoved() *ServerMessage_ChannelRemoved { + if x != nil { + if x, ok := x.Content.(*ServerMessage_ChannelRemoved_); ok { + return x.ChannelRemoved + } + } + return nil +} + +func (x *ServerMessage) GetTrackForwarding() *ServerMessage_TrackForwarding { + if x != nil { + if x, ok := x.Content.(*ServerMessage_TrackForwarding_); ok { + return x.TrackForwarding + } + } + return nil +} + +func (x *ServerMessage) GetTrackForwardingRemoved() *ServerMessage_TrackForwardingRemoved { + if x != nil { + if x, ok := x.Content.(*ServerMessage_TrackForwardingRemoved_); ok { + return x.TrackForwardingRemoved + } + } + return nil +} + +func (x *ServerMessage) GetViewerConnected() *ServerMessage_ViewerConnected { + if x != nil { + if x, ok := x.Content.(*ServerMessage_ViewerConnected_); ok { + return x.ViewerConnected + } + } + return nil +} + +func (x *ServerMessage) GetViewerDisconnected() *ServerMessage_ViewerDisconnected { + if x != nil { + if x, ok := x.Content.(*ServerMessage_ViewerDisconnected_); ok { + return x.ViewerDisconnected + } + } + return nil +} + +func (x *ServerMessage) GetStreamerConnected() *ServerMessage_StreamerConnected { + if x != nil { + if x, ok := x.Content.(*ServerMessage_StreamerConnected_); ok { + return x.StreamerConnected + } + } + return nil +} + +func (x *ServerMessage) GetStreamerDisconnected() *ServerMessage_StreamerDisconnected { + if x != nil { + if x, ok := x.Content.(*ServerMessage_StreamerDisconnected_); ok { + return x.StreamerDisconnected + } + } + return nil +} + +// Deprecated: Marked as deprecated in fishjam/server_notifications.proto. +func (x *ServerMessage) GetStreamConnected() *ServerMessage_StreamConnected { + if x != nil { + if x, ok := x.Content.(*ServerMessage_StreamConnected_); ok { + return x.StreamConnected + } + } + return nil +} + +// Deprecated: Marked as deprecated in fishjam/server_notifications.proto. +func (x *ServerMessage) GetStreamDisconnected() *ServerMessage_StreamDisconnected { + if x != nil { + if x, ok := x.Content.(*ServerMessage_StreamDisconnected_); ok { + return x.StreamDisconnected + } + } + return nil +} + +// Deprecated: Marked as deprecated in fishjam/server_notifications.proto. +func (x *ServerMessage) GetHlsPlayable() *ServerMessage_HlsPlayable { + if x != nil { + if x, ok := x.Content.(*ServerMessage_HlsPlayable_); ok { + return x.HlsPlayable + } + } + return nil +} + +// Deprecated: Marked as deprecated in fishjam/server_notifications.proto. +func (x *ServerMessage) GetHlsUploaded() *ServerMessage_HlsUploaded { + if x != nil { + if x, ok := x.Content.(*ServerMessage_HlsUploaded_); ok { + return x.HlsUploaded + } + } + return nil +} + +// Deprecated: Marked as deprecated in fishjam/server_notifications.proto. +func (x *ServerMessage) GetHlsUploadCrashed() *ServerMessage_HlsUploadCrashed { + if x != nil { + if x, ok := x.Content.(*ServerMessage_HlsUploadCrashed_); ok { + return x.HlsUploadCrashed + } + } + return nil +} + +// Deprecated: Marked as deprecated in fishjam/server_notifications.proto. +func (x *ServerMessage) GetComponentCrashed() *ServerMessage_ComponentCrashed { + if x != nil { + if x, ok := x.Content.(*ServerMessage_ComponentCrashed_); ok { + return x.ComponentCrashed + } + } + return nil +} + +type isServerMessage_Content interface { + isServerMessage_Content() +} + +type ServerMessage_Authenticated_ struct { + Authenticated *ServerMessage_Authenticated `protobuf:"bytes,6,opt,name=authenticated,proto3,oneof"` +} + +type ServerMessage_AuthRequest_ struct { + AuthRequest *ServerMessage_AuthRequest `protobuf:"bytes,7,opt,name=auth_request,json=authRequest,proto3,oneof"` +} + +type ServerMessage_SubscribeRequest_ struct { + SubscribeRequest *ServerMessage_SubscribeRequest `protobuf:"bytes,8,opt,name=subscribe_request,json=subscribeRequest,proto3,oneof"` +} + +type ServerMessage_SubscribeResponse_ struct { + SubscribeResponse *ServerMessage_SubscribeResponse `protobuf:"bytes,9,opt,name=subscribe_response,json=subscribeResponse,proto3,oneof"` +} + +type ServerMessage_RoomCreated_ struct { + RoomCreated *ServerMessage_RoomCreated `protobuf:"bytes,10,opt,name=room_created,json=roomCreated,proto3,oneof"` +} + +type ServerMessage_RoomDeleted_ struct { + RoomDeleted *ServerMessage_RoomDeleted `protobuf:"bytes,11,opt,name=room_deleted,json=roomDeleted,proto3,oneof"` +} + +type ServerMessage_RoomCrashed_ struct { + RoomCrashed *ServerMessage_RoomCrashed `protobuf:"bytes,1,opt,name=room_crashed,json=roomCrashed,proto3,oneof"` +} + +type ServerMessage_PeerConnected_ struct { + PeerConnected *ServerMessage_PeerConnected `protobuf:"bytes,2,opt,name=peer_connected,json=peerConnected,proto3,oneof"` +} + +type ServerMessage_PeerDisconnected_ struct { + PeerDisconnected *ServerMessage_PeerDisconnected `protobuf:"bytes,3,opt,name=peer_disconnected,json=peerDisconnected,proto3,oneof"` +} + +type ServerMessage_PeerCrashed_ struct { + PeerCrashed *ServerMessage_PeerCrashed `protobuf:"bytes,4,opt,name=peer_crashed,json=peerCrashed,proto3,oneof"` +} + +type ServerMessage_PeerMetadataUpdated_ struct { + PeerMetadataUpdated *ServerMessage_PeerMetadataUpdated `protobuf:"bytes,16,opt,name=peer_metadata_updated,json=peerMetadataUpdated,proto3,oneof"` +} + +type ServerMessage_TrackAdded_ struct { + TrackAdded *ServerMessage_TrackAdded `protobuf:"bytes,17,opt,name=track_added,json=trackAdded,proto3,oneof"` +} + +type ServerMessage_TrackRemoved_ struct { + TrackRemoved *ServerMessage_TrackRemoved `protobuf:"bytes,18,opt,name=track_removed,json=trackRemoved,proto3,oneof"` +} + +type ServerMessage_TrackMetadataUpdated_ struct { + TrackMetadataUpdated *ServerMessage_TrackMetadataUpdated `protobuf:"bytes,19,opt,name=track_metadata_updated,json=trackMetadataUpdated,proto3,oneof"` +} + +type ServerMessage_PeerAdded_ struct { + PeerAdded *ServerMessage_PeerAdded `protobuf:"bytes,20,opt,name=peer_added,json=peerAdded,proto3,oneof"` +} + +type ServerMessage_PeerDeleted_ struct { + PeerDeleted *ServerMessage_PeerDeleted `protobuf:"bytes,21,opt,name=peer_deleted,json=peerDeleted,proto3,oneof"` +} + +type ServerMessage_ChannelAdded_ struct { + ChannelAdded *ServerMessage_ChannelAdded `protobuf:"bytes,28,opt,name=channel_added,json=channelAdded,proto3,oneof"` +} + +type ServerMessage_ChannelRemoved_ struct { + ChannelRemoved *ServerMessage_ChannelRemoved `protobuf:"bytes,29,opt,name=channel_removed,json=channelRemoved,proto3,oneof"` +} + +type ServerMessage_TrackForwarding_ struct { + TrackForwarding *ServerMessage_TrackForwarding `protobuf:"bytes,30,opt,name=track_forwarding,json=trackForwarding,proto3,oneof"` +} + +type ServerMessage_TrackForwardingRemoved_ struct { + TrackForwardingRemoved *ServerMessage_TrackForwardingRemoved `protobuf:"bytes,31,opt,name=track_forwarding_removed,json=trackForwardingRemoved,proto3,oneof"` +} + +type ServerMessage_ViewerConnected_ struct { + ViewerConnected *ServerMessage_ViewerConnected `protobuf:"bytes,24,opt,name=viewer_connected,json=viewerConnected,proto3,oneof"` +} + +type ServerMessage_ViewerDisconnected_ struct { + ViewerDisconnected *ServerMessage_ViewerDisconnected `protobuf:"bytes,25,opt,name=viewer_disconnected,json=viewerDisconnected,proto3,oneof"` +} + +type ServerMessage_StreamerConnected_ struct { + StreamerConnected *ServerMessage_StreamerConnected `protobuf:"bytes,26,opt,name=streamer_connected,json=streamerConnected,proto3,oneof"` +} + +type ServerMessage_StreamerDisconnected_ struct { + StreamerDisconnected *ServerMessage_StreamerDisconnected `protobuf:"bytes,27,opt,name=streamer_disconnected,json=streamerDisconnected,proto3,oneof"` +} + +type ServerMessage_StreamConnected_ struct { + // Deprecated: Marked as deprecated in fishjam/server_notifications.proto. + StreamConnected *ServerMessage_StreamConnected `protobuf:"bytes,22,opt,name=stream_connected,json=streamConnected,proto3,oneof"` +} + +type ServerMessage_StreamDisconnected_ struct { + // Deprecated: Marked as deprecated in fishjam/server_notifications.proto. + StreamDisconnected *ServerMessage_StreamDisconnected `protobuf:"bytes,23,opt,name=stream_disconnected,json=streamDisconnected,proto3,oneof"` +} + +type ServerMessage_HlsPlayable_ struct { + // Deprecated: Marked as deprecated in fishjam/server_notifications.proto. + HlsPlayable *ServerMessage_HlsPlayable `protobuf:"bytes,13,opt,name=hls_playable,json=hlsPlayable,proto3,oneof"` +} + +type ServerMessage_HlsUploaded_ struct { + // Deprecated: Marked as deprecated in fishjam/server_notifications.proto. + HlsUploaded *ServerMessage_HlsUploaded `protobuf:"bytes,14,opt,name=hls_uploaded,json=hlsUploaded,proto3,oneof"` +} + +type ServerMessage_HlsUploadCrashed_ struct { + // Deprecated: Marked as deprecated in fishjam/server_notifications.proto. + HlsUploadCrashed *ServerMessage_HlsUploadCrashed `protobuf:"bytes,15,opt,name=hls_upload_crashed,json=hlsUploadCrashed,proto3,oneof"` +} + +type ServerMessage_ComponentCrashed_ struct { + // Deprecated: Marked as deprecated in fishjam/server_notifications.proto. + ComponentCrashed *ServerMessage_ComponentCrashed `protobuf:"bytes,5,opt,name=component_crashed,json=componentCrashed,proto3,oneof"` +} + +func (*ServerMessage_Authenticated_) isServerMessage_Content() {} + +func (*ServerMessage_AuthRequest_) isServerMessage_Content() {} + +func (*ServerMessage_SubscribeRequest_) isServerMessage_Content() {} + +func (*ServerMessage_SubscribeResponse_) isServerMessage_Content() {} + +func (*ServerMessage_RoomCreated_) isServerMessage_Content() {} + +func (*ServerMessage_RoomDeleted_) isServerMessage_Content() {} + +func (*ServerMessage_RoomCrashed_) isServerMessage_Content() {} + +func (*ServerMessage_PeerConnected_) isServerMessage_Content() {} + +func (*ServerMessage_PeerDisconnected_) isServerMessage_Content() {} + +func (*ServerMessage_PeerCrashed_) isServerMessage_Content() {} + +func (*ServerMessage_PeerMetadataUpdated_) isServerMessage_Content() {} + +func (*ServerMessage_TrackAdded_) isServerMessage_Content() {} + +func (*ServerMessage_TrackRemoved_) isServerMessage_Content() {} + +func (*ServerMessage_TrackMetadataUpdated_) isServerMessage_Content() {} + +func (*ServerMessage_PeerAdded_) isServerMessage_Content() {} + +func (*ServerMessage_PeerDeleted_) isServerMessage_Content() {} + +func (*ServerMessage_ChannelAdded_) isServerMessage_Content() {} + +func (*ServerMessage_ChannelRemoved_) isServerMessage_Content() {} + +func (*ServerMessage_TrackForwarding_) isServerMessage_Content() {} + +func (*ServerMessage_TrackForwardingRemoved_) isServerMessage_Content() {} + +func (*ServerMessage_ViewerConnected_) isServerMessage_Content() {} + +func (*ServerMessage_ViewerDisconnected_) isServerMessage_Content() {} + +func (*ServerMessage_StreamerConnected_) isServerMessage_Content() {} + +func (*ServerMessage_StreamerDisconnected_) isServerMessage_Content() {} + +func (*ServerMessage_StreamConnected_) isServerMessage_Content() {} + +func (*ServerMessage_StreamDisconnected_) isServerMessage_Content() {} + +func (*ServerMessage_HlsPlayable_) isServerMessage_Content() {} + +func (*ServerMessage_HlsUploaded_) isServerMessage_Content() {} + +func (*ServerMessage_HlsUploadCrashed_) isServerMessage_Content() {} + +func (*ServerMessage_ComponentCrashed_) isServerMessage_Content() {} + +// Notification sent when a room crashes +type ServerMessage_RoomCrashed struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_RoomCrashed) Reset() { + *x = ServerMessage_RoomCrashed{} + mi := &file_fishjam_server_notifications_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_RoomCrashed) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_RoomCrashed) ProtoMessage() {} + +func (x *ServerMessage_RoomCrashed) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_RoomCrashed.ProtoReflect.Descriptor instead. +func (*ServerMessage_RoomCrashed) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *ServerMessage_RoomCrashed) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +// Notification sent when a peer is added +type ServerMessage_PeerAdded struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + PeerId string `protobuf:"bytes,2,opt,name=peer_id,json=peerId,proto3" json:"peer_id,omitempty"` + PeerType ServerMessage_PeerType `protobuf:"varint,3,opt,name=peer_type,json=peerType,proto3,enum=fishjam.ServerMessage_PeerType" json:"peer_type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_PeerAdded) Reset() { + *x = ServerMessage_PeerAdded{} + mi := &file_fishjam_server_notifications_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_PeerAdded) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_PeerAdded) ProtoMessage() {} + +func (x *ServerMessage_PeerAdded) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_PeerAdded.ProtoReflect.Descriptor instead. +func (*ServerMessage_PeerAdded) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 1} +} + +func (x *ServerMessage_PeerAdded) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +func (x *ServerMessage_PeerAdded) GetPeerId() string { + if x != nil { + return x.PeerId + } + return "" +} + +func (x *ServerMessage_PeerAdded) GetPeerType() ServerMessage_PeerType { + if x != nil { + return x.PeerType + } + return ServerMessage_PEER_TYPE_UNSPECIFIED +} + +// Notification sent when a peer is removed +type ServerMessage_PeerDeleted struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + PeerId string `protobuf:"bytes,2,opt,name=peer_id,json=peerId,proto3" json:"peer_id,omitempty"` + PeerType ServerMessage_PeerType `protobuf:"varint,3,opt,name=peer_type,json=peerType,proto3,enum=fishjam.ServerMessage_PeerType" json:"peer_type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_PeerDeleted) Reset() { + *x = ServerMessage_PeerDeleted{} + mi := &file_fishjam_server_notifications_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_PeerDeleted) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_PeerDeleted) ProtoMessage() {} + +func (x *ServerMessage_PeerDeleted) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_PeerDeleted.ProtoReflect.Descriptor instead. +func (*ServerMessage_PeerDeleted) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 2} +} + +func (x *ServerMessage_PeerDeleted) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +func (x *ServerMessage_PeerDeleted) GetPeerId() string { + if x != nil { + return x.PeerId + } + return "" +} + +func (x *ServerMessage_PeerDeleted) GetPeerType() ServerMessage_PeerType { + if x != nil { + return x.PeerType + } + return ServerMessage_PEER_TYPE_UNSPECIFIED +} + +// Notification sent when a peer connects +type ServerMessage_PeerConnected struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + PeerId string `protobuf:"bytes,2,opt,name=peer_id,json=peerId,proto3" json:"peer_id,omitempty"` + PeerType ServerMessage_PeerType `protobuf:"varint,3,opt,name=peer_type,json=peerType,proto3,enum=fishjam.ServerMessage_PeerType" json:"peer_type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_PeerConnected) Reset() { + *x = ServerMessage_PeerConnected{} + mi := &file_fishjam_server_notifications_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_PeerConnected) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_PeerConnected) ProtoMessage() {} + +func (x *ServerMessage_PeerConnected) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_PeerConnected.ProtoReflect.Descriptor instead. +func (*ServerMessage_PeerConnected) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 3} +} + +func (x *ServerMessage_PeerConnected) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +func (x *ServerMessage_PeerConnected) GetPeerId() string { + if x != nil { + return x.PeerId + } + return "" +} + +func (x *ServerMessage_PeerConnected) GetPeerType() ServerMessage_PeerType { + if x != nil { + return x.PeerType + } + return ServerMessage_PEER_TYPE_UNSPECIFIED +} + +// Notification sent when a peer disconnects from FJ +type ServerMessage_PeerDisconnected struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + PeerId string `protobuf:"bytes,2,opt,name=peer_id,json=peerId,proto3" json:"peer_id,omitempty"` + PeerType ServerMessage_PeerType `protobuf:"varint,3,opt,name=peer_type,json=peerType,proto3,enum=fishjam.ServerMessage_PeerType" json:"peer_type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_PeerDisconnected) Reset() { + *x = ServerMessage_PeerDisconnected{} + mi := &file_fishjam_server_notifications_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_PeerDisconnected) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_PeerDisconnected) ProtoMessage() {} + +func (x *ServerMessage_PeerDisconnected) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_PeerDisconnected.ProtoReflect.Descriptor instead. +func (*ServerMessage_PeerDisconnected) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 4} +} + +func (x *ServerMessage_PeerDisconnected) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +func (x *ServerMessage_PeerDisconnected) GetPeerId() string { + if x != nil { + return x.PeerId + } + return "" +} + +func (x *ServerMessage_PeerDisconnected) GetPeerType() ServerMessage_PeerType { + if x != nil { + return x.PeerType + } + return ServerMessage_PEER_TYPE_UNSPECIFIED +} + +// Notification sent when a peer crashes +type ServerMessage_PeerCrashed struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + PeerId string `protobuf:"bytes,2,opt,name=peer_id,json=peerId,proto3" json:"peer_id,omitempty"` + Reason string `protobuf:"bytes,3,opt,name=reason,proto3" json:"reason,omitempty"` + PeerType ServerMessage_PeerType `protobuf:"varint,4,opt,name=peer_type,json=peerType,proto3,enum=fishjam.ServerMessage_PeerType" json:"peer_type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_PeerCrashed) Reset() { + *x = ServerMessage_PeerCrashed{} + mi := &file_fishjam_server_notifications_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_PeerCrashed) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_PeerCrashed) ProtoMessage() {} + +func (x *ServerMessage_PeerCrashed) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_PeerCrashed.ProtoReflect.Descriptor instead. +func (*ServerMessage_PeerCrashed) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 5} +} + +func (x *ServerMessage_PeerCrashed) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +func (x *ServerMessage_PeerCrashed) GetPeerId() string { + if x != nil { + return x.PeerId + } + return "" +} + +func (x *ServerMessage_PeerCrashed) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +func (x *ServerMessage_PeerCrashed) GetPeerType() ServerMessage_PeerType { + if x != nil { + return x.PeerType + } + return ServerMessage_PEER_TYPE_UNSPECIFIED +} + +// Notification sent when a component crashes +type ServerMessage_ComponentCrashed struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + ComponentId string `protobuf:"bytes,2,opt,name=component_id,json=componentId,proto3" json:"component_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_ComponentCrashed) Reset() { + *x = ServerMessage_ComponentCrashed{} + mi := &file_fishjam_server_notifications_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_ComponentCrashed) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_ComponentCrashed) ProtoMessage() {} + +func (x *ServerMessage_ComponentCrashed) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_ComponentCrashed.ProtoReflect.Descriptor instead. +func (*ServerMessage_ComponentCrashed) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 6} +} + +func (x *ServerMessage_ComponentCrashed) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +func (x *ServerMessage_ComponentCrashed) GetComponentId() string { + if x != nil { + return x.ComponentId + } + return "" +} + +// Response sent by FJ, confirming successfull authentication +type ServerMessage_Authenticated struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_Authenticated) Reset() { + *x = ServerMessage_Authenticated{} + mi := &file_fishjam_server_notifications_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_Authenticated) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_Authenticated) ProtoMessage() {} + +func (x *ServerMessage_Authenticated) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_Authenticated.ProtoReflect.Descriptor instead. +func (*ServerMessage_Authenticated) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 7} +} + +// Request sent by peer, to authenticate to FJ server +type ServerMessage_AuthRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_AuthRequest) Reset() { + *x = ServerMessage_AuthRequest{} + mi := &file_fishjam_server_notifications_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_AuthRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_AuthRequest) ProtoMessage() {} + +func (x *ServerMessage_AuthRequest) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_AuthRequest.ProtoReflect.Descriptor instead. +func (*ServerMessage_AuthRequest) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 8} +} + +func (x *ServerMessage_AuthRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +// Request sent by peer to subscribe for certain message type +type ServerMessage_SubscribeRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + EventType ServerMessage_EventType `protobuf:"varint,1,opt,name=event_type,json=eventType,proto3,enum=fishjam.ServerMessage_EventType" json:"event_type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_SubscribeRequest) Reset() { + *x = ServerMessage_SubscribeRequest{} + mi := &file_fishjam_server_notifications_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_SubscribeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_SubscribeRequest) ProtoMessage() {} + +func (x *ServerMessage_SubscribeRequest) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_SubscribeRequest.ProtoReflect.Descriptor instead. +func (*ServerMessage_SubscribeRequest) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 9} +} + +func (x *ServerMessage_SubscribeRequest) GetEventType() ServerMessage_EventType { + if x != nil { + return x.EventType + } + return ServerMessage_EVENT_TYPE_UNSPECIFIED +} + +// Response sent by FJ, confirming subscription for message type +type ServerMessage_SubscribeResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + EventType ServerMessage_EventType `protobuf:"varint,1,opt,name=event_type,json=eventType,proto3,enum=fishjam.ServerMessage_EventType" json:"event_type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_SubscribeResponse) Reset() { + *x = ServerMessage_SubscribeResponse{} + mi := &file_fishjam_server_notifications_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_SubscribeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_SubscribeResponse) ProtoMessage() {} + +func (x *ServerMessage_SubscribeResponse) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_SubscribeResponse.ProtoReflect.Descriptor instead. +func (*ServerMessage_SubscribeResponse) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 10} +} + +func (x *ServerMessage_SubscribeResponse) GetEventType() ServerMessage_EventType { + if x != nil { + return x.EventType + } + return ServerMessage_EVENT_TYPE_UNSPECIFIED +} + +// Notification sent when a room is created +type ServerMessage_RoomCreated struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_RoomCreated) Reset() { + *x = ServerMessage_RoomCreated{} + mi := &file_fishjam_server_notifications_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_RoomCreated) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_RoomCreated) ProtoMessage() {} + +func (x *ServerMessage_RoomCreated) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_RoomCreated.ProtoReflect.Descriptor instead. +func (*ServerMessage_RoomCreated) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 11} +} + +func (x *ServerMessage_RoomCreated) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +// Notification sent when a room is deleted +type ServerMessage_RoomDeleted struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_RoomDeleted) Reset() { + *x = ServerMessage_RoomDeleted{} + mi := &file_fishjam_server_notifications_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_RoomDeleted) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_RoomDeleted) ProtoMessage() {} + +func (x *ServerMessage_RoomDeleted) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_RoomDeleted.ProtoReflect.Descriptor instead. +func (*ServerMessage_RoomDeleted) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 12} +} + +func (x *ServerMessage_RoomDeleted) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +// Notification sent when the HLS stream becomes available in a room +type ServerMessage_HlsPlayable struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + ComponentId string `protobuf:"bytes,2,opt,name=component_id,json=componentId,proto3" json:"component_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_HlsPlayable) Reset() { + *x = ServerMessage_HlsPlayable{} + mi := &file_fishjam_server_notifications_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_HlsPlayable) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_HlsPlayable) ProtoMessage() {} + +func (x *ServerMessage_HlsPlayable) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_HlsPlayable.ProtoReflect.Descriptor instead. +func (*ServerMessage_HlsPlayable) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 13} +} + +func (x *ServerMessage_HlsPlayable) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +func (x *ServerMessage_HlsPlayable) GetComponentId() string { + if x != nil { + return x.ComponentId + } + return "" +} + +// Notification sent when the HLS recording is successfully uploaded to AWS S3 +type ServerMessage_HlsUploaded struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_HlsUploaded) Reset() { + *x = ServerMessage_HlsUploaded{} + mi := &file_fishjam_server_notifications_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_HlsUploaded) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_HlsUploaded) ProtoMessage() {} + +func (x *ServerMessage_HlsUploaded) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[15] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_HlsUploaded.ProtoReflect.Descriptor instead. +func (*ServerMessage_HlsUploaded) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 14} +} + +func (x *ServerMessage_HlsUploaded) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +// Notification sent when the upload of HLS recording to AWS S3 fails +type ServerMessage_HlsUploadCrashed struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_HlsUploadCrashed) Reset() { + *x = ServerMessage_HlsUploadCrashed{} + mi := &file_fishjam_server_notifications_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_HlsUploadCrashed) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_HlsUploadCrashed) ProtoMessage() {} + +func (x *ServerMessage_HlsUploadCrashed) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[16] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_HlsUploadCrashed.ProtoReflect.Descriptor instead. +func (*ServerMessage_HlsUploadCrashed) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 15} +} + +func (x *ServerMessage_HlsUploadCrashed) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +// Notification sent when peer updates its metadata +type ServerMessage_PeerMetadataUpdated struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + PeerId string `protobuf:"bytes,2,opt,name=peer_id,json=peerId,proto3" json:"peer_id,omitempty"` + Metadata string `protobuf:"bytes,3,opt,name=metadata,proto3" json:"metadata,omitempty"` + PeerType ServerMessage_PeerType `protobuf:"varint,4,opt,name=peer_type,json=peerType,proto3,enum=fishjam.ServerMessage_PeerType" json:"peer_type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_PeerMetadataUpdated) Reset() { + *x = ServerMessage_PeerMetadataUpdated{} + mi := &file_fishjam_server_notifications_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_PeerMetadataUpdated) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_PeerMetadataUpdated) ProtoMessage() {} + +func (x *ServerMessage_PeerMetadataUpdated) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[17] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_PeerMetadataUpdated.ProtoReflect.Descriptor instead. +func (*ServerMessage_PeerMetadataUpdated) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 16} +} + +func (x *ServerMessage_PeerMetadataUpdated) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +func (x *ServerMessage_PeerMetadataUpdated) GetPeerId() string { + if x != nil { + return x.PeerId + } + return "" +} + +func (x *ServerMessage_PeerMetadataUpdated) GetMetadata() string { + if x != nil { + return x.Metadata + } + return "" +} + +func (x *ServerMessage_PeerMetadataUpdated) GetPeerType() ServerMessage_PeerType { + if x != nil { + return x.PeerType + } + return ServerMessage_PEER_TYPE_UNSPECIFIED +} + +// Notification sent when peer or component adds new track +type ServerMessage_TrackAdded struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + // Types that are valid to be assigned to EndpointInfo: + // + // *ServerMessage_TrackAdded_PeerId + // *ServerMessage_TrackAdded_ComponentId + EndpointInfo isServerMessage_TrackAdded_EndpointInfo `protobuf_oneof:"endpoint_info"` + Track *notifications.Track `protobuf:"bytes,4,opt,name=track,proto3" json:"track,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_TrackAdded) Reset() { + *x = ServerMessage_TrackAdded{} + mi := &file_fishjam_server_notifications_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_TrackAdded) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_TrackAdded) ProtoMessage() {} + +func (x *ServerMessage_TrackAdded) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[18] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_TrackAdded.ProtoReflect.Descriptor instead. +func (*ServerMessage_TrackAdded) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 17} +} + +func (x *ServerMessage_TrackAdded) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +func (x *ServerMessage_TrackAdded) GetEndpointInfo() isServerMessage_TrackAdded_EndpointInfo { + if x != nil { + return x.EndpointInfo + } + return nil +} + +func (x *ServerMessage_TrackAdded) GetPeerId() string { + if x != nil { + if x, ok := x.EndpointInfo.(*ServerMessage_TrackAdded_PeerId); ok { + return x.PeerId + } + } + return "" +} + +func (x *ServerMessage_TrackAdded) GetComponentId() string { + if x != nil { + if x, ok := x.EndpointInfo.(*ServerMessage_TrackAdded_ComponentId); ok { + return x.ComponentId + } + } + return "" +} + +func (x *ServerMessage_TrackAdded) GetTrack() *notifications.Track { + if x != nil { + return x.Track + } + return nil +} + +type isServerMessage_TrackAdded_EndpointInfo interface { + isServerMessage_TrackAdded_EndpointInfo() +} + +type ServerMessage_TrackAdded_PeerId struct { + PeerId string `protobuf:"bytes,2,opt,name=peer_id,json=peerId,proto3,oneof"` +} + +type ServerMessage_TrackAdded_ComponentId struct { + ComponentId string `protobuf:"bytes,3,opt,name=component_id,json=componentId,proto3,oneof"` +} + +func (*ServerMessage_TrackAdded_PeerId) isServerMessage_TrackAdded_EndpointInfo() {} + +func (*ServerMessage_TrackAdded_ComponentId) isServerMessage_TrackAdded_EndpointInfo() {} + +// Notification sent when a track is removed +type ServerMessage_TrackRemoved struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + // Types that are valid to be assigned to EndpointInfo: + // + // *ServerMessage_TrackRemoved_PeerId + // *ServerMessage_TrackRemoved_ComponentId + EndpointInfo isServerMessage_TrackRemoved_EndpointInfo `protobuf_oneof:"endpoint_info"` + Track *notifications.Track `protobuf:"bytes,4,opt,name=track,proto3" json:"track,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_TrackRemoved) Reset() { + *x = ServerMessage_TrackRemoved{} + mi := &file_fishjam_server_notifications_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_TrackRemoved) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_TrackRemoved) ProtoMessage() {} + +func (x *ServerMessage_TrackRemoved) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[19] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_TrackRemoved.ProtoReflect.Descriptor instead. +func (*ServerMessage_TrackRemoved) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 18} +} + +func (x *ServerMessage_TrackRemoved) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +func (x *ServerMessage_TrackRemoved) GetEndpointInfo() isServerMessage_TrackRemoved_EndpointInfo { + if x != nil { + return x.EndpointInfo + } + return nil +} + +func (x *ServerMessage_TrackRemoved) GetPeerId() string { + if x != nil { + if x, ok := x.EndpointInfo.(*ServerMessage_TrackRemoved_PeerId); ok { + return x.PeerId + } + } + return "" +} + +func (x *ServerMessage_TrackRemoved) GetComponentId() string { + if x != nil { + if x, ok := x.EndpointInfo.(*ServerMessage_TrackRemoved_ComponentId); ok { + return x.ComponentId + } + } + return "" +} + +func (x *ServerMessage_TrackRemoved) GetTrack() *notifications.Track { + if x != nil { + return x.Track + } + return nil +} + +type isServerMessage_TrackRemoved_EndpointInfo interface { + isServerMessage_TrackRemoved_EndpointInfo() +} + +type ServerMessage_TrackRemoved_PeerId struct { + PeerId string `protobuf:"bytes,2,opt,name=peer_id,json=peerId,proto3,oneof"` +} + +type ServerMessage_TrackRemoved_ComponentId struct { + ComponentId string `protobuf:"bytes,3,opt,name=component_id,json=componentId,proto3,oneof"` +} + +func (*ServerMessage_TrackRemoved_PeerId) isServerMessage_TrackRemoved_EndpointInfo() {} + +func (*ServerMessage_TrackRemoved_ComponentId) isServerMessage_TrackRemoved_EndpointInfo() {} + +// Notification sent when metadata of a multimedia track is updated +type ServerMessage_TrackMetadataUpdated struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + // Types that are valid to be assigned to EndpointInfo: + // + // *ServerMessage_TrackMetadataUpdated_PeerId + // *ServerMessage_TrackMetadataUpdated_ComponentId + EndpointInfo isServerMessage_TrackMetadataUpdated_EndpointInfo `protobuf_oneof:"endpoint_info"` + Track *notifications.Track `protobuf:"bytes,4,opt,name=track,proto3" json:"track,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_TrackMetadataUpdated) Reset() { + *x = ServerMessage_TrackMetadataUpdated{} + mi := &file_fishjam_server_notifications_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_TrackMetadataUpdated) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_TrackMetadataUpdated) ProtoMessage() {} + +func (x *ServerMessage_TrackMetadataUpdated) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[20] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_TrackMetadataUpdated.ProtoReflect.Descriptor instead. +func (*ServerMessage_TrackMetadataUpdated) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 19} +} + +func (x *ServerMessage_TrackMetadataUpdated) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +func (x *ServerMessage_TrackMetadataUpdated) GetEndpointInfo() isServerMessage_TrackMetadataUpdated_EndpointInfo { + if x != nil { + return x.EndpointInfo + } + return nil +} + +func (x *ServerMessage_TrackMetadataUpdated) GetPeerId() string { + if x != nil { + if x, ok := x.EndpointInfo.(*ServerMessage_TrackMetadataUpdated_PeerId); ok { + return x.PeerId + } + } + return "" +} + +func (x *ServerMessage_TrackMetadataUpdated) GetComponentId() string { + if x != nil { + if x, ok := x.EndpointInfo.(*ServerMessage_TrackMetadataUpdated_ComponentId); ok { + return x.ComponentId + } + } + return "" +} + +func (x *ServerMessage_TrackMetadataUpdated) GetTrack() *notifications.Track { + if x != nil { + return x.Track + } + return nil +} + +type isServerMessage_TrackMetadataUpdated_EndpointInfo interface { + isServerMessage_TrackMetadataUpdated_EndpointInfo() +} + +type ServerMessage_TrackMetadataUpdated_PeerId struct { + PeerId string `protobuf:"bytes,2,opt,name=peer_id,json=peerId,proto3,oneof"` +} + +type ServerMessage_TrackMetadataUpdated_ComponentId struct { + ComponentId string `protobuf:"bytes,3,opt,name=component_id,json=componentId,proto3,oneof"` +} + +func (*ServerMessage_TrackMetadataUpdated_PeerId) isServerMessage_TrackMetadataUpdated_EndpointInfo() { +} + +func (*ServerMessage_TrackMetadataUpdated_ComponentId) isServerMessage_TrackMetadataUpdated_EndpointInfo() { +} + +// Notification sent when a peer creates a channel +type ServerMessage_ChannelAdded struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + // Types that are valid to be assigned to EndpointInfo: + // + // *ServerMessage_ChannelAdded_PeerId + // *ServerMessage_ChannelAdded_ComponentId + EndpointInfo isServerMessage_ChannelAdded_EndpointInfo `protobuf_oneof:"endpoint_info"` + ChannelId string `protobuf:"bytes,4,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_ChannelAdded) Reset() { + *x = ServerMessage_ChannelAdded{} + mi := &file_fishjam_server_notifications_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_ChannelAdded) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_ChannelAdded) ProtoMessage() {} + +func (x *ServerMessage_ChannelAdded) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[21] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_ChannelAdded.ProtoReflect.Descriptor instead. +func (*ServerMessage_ChannelAdded) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 20} +} + +func (x *ServerMessage_ChannelAdded) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +func (x *ServerMessage_ChannelAdded) GetEndpointInfo() isServerMessage_ChannelAdded_EndpointInfo { + if x != nil { + return x.EndpointInfo + } + return nil +} + +func (x *ServerMessage_ChannelAdded) GetPeerId() string { + if x != nil { + if x, ok := x.EndpointInfo.(*ServerMessage_ChannelAdded_PeerId); ok { + return x.PeerId + } + } + return "" +} + +func (x *ServerMessage_ChannelAdded) GetComponentId() string { + if x != nil { + if x, ok := x.EndpointInfo.(*ServerMessage_ChannelAdded_ComponentId); ok { + return x.ComponentId + } + } + return "" +} + +func (x *ServerMessage_ChannelAdded) GetChannelId() string { + if x != nil { + return x.ChannelId + } + return "" +} + +type isServerMessage_ChannelAdded_EndpointInfo interface { + isServerMessage_ChannelAdded_EndpointInfo() +} + +type ServerMessage_ChannelAdded_PeerId struct { + PeerId string `protobuf:"bytes,2,opt,name=peer_id,json=peerId,proto3,oneof"` +} + +type ServerMessage_ChannelAdded_ComponentId struct { + ComponentId string `protobuf:"bytes,3,opt,name=component_id,json=componentId,proto3,oneof"` +} + +func (*ServerMessage_ChannelAdded_PeerId) isServerMessage_ChannelAdded_EndpointInfo() {} + +func (*ServerMessage_ChannelAdded_ComponentId) isServerMessage_ChannelAdded_EndpointInfo() {} + +// Notification sent when a peer deletes a channel +type ServerMessage_ChannelRemoved struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + // Types that are valid to be assigned to EndpointInfo: + // + // *ServerMessage_ChannelRemoved_PeerId + // *ServerMessage_ChannelRemoved_ComponentId + EndpointInfo isServerMessage_ChannelRemoved_EndpointInfo `protobuf_oneof:"endpoint_info"` + ChannelId string `protobuf:"bytes,4,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_ChannelRemoved) Reset() { + *x = ServerMessage_ChannelRemoved{} + mi := &file_fishjam_server_notifications_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_ChannelRemoved) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_ChannelRemoved) ProtoMessage() {} + +func (x *ServerMessage_ChannelRemoved) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[22] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_ChannelRemoved.ProtoReflect.Descriptor instead. +func (*ServerMessage_ChannelRemoved) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 21} +} + +func (x *ServerMessage_ChannelRemoved) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +func (x *ServerMessage_ChannelRemoved) GetEndpointInfo() isServerMessage_ChannelRemoved_EndpointInfo { + if x != nil { + return x.EndpointInfo + } + return nil +} + +func (x *ServerMessage_ChannelRemoved) GetPeerId() string { + if x != nil { + if x, ok := x.EndpointInfo.(*ServerMessage_ChannelRemoved_PeerId); ok { + return x.PeerId + } + } + return "" +} + +func (x *ServerMessage_ChannelRemoved) GetComponentId() string { + if x != nil { + if x, ok := x.EndpointInfo.(*ServerMessage_ChannelRemoved_ComponentId); ok { + return x.ComponentId + } + } + return "" +} + +func (x *ServerMessage_ChannelRemoved) GetChannelId() string { + if x != nil { + return x.ChannelId + } + return "" +} + +type isServerMessage_ChannelRemoved_EndpointInfo interface { + isServerMessage_ChannelRemoved_EndpointInfo() +} + +type ServerMessage_ChannelRemoved_PeerId struct { + PeerId string `protobuf:"bytes,2,opt,name=peer_id,json=peerId,proto3,oneof"` +} + +type ServerMessage_ChannelRemoved_ComponentId struct { + ComponentId string `protobuf:"bytes,3,opt,name=component_id,json=componentId,proto3,oneof"` +} + +func (*ServerMessage_ChannelRemoved_PeerId) isServerMessage_ChannelRemoved_EndpointInfo() {} + +func (*ServerMessage_ChannelRemoved_ComponentId) isServerMessage_ChannelRemoved_EndpointInfo() {} + +// Sent when there is an upsert to track forwardings from Fishjam to Foundry +type ServerMessage_TrackForwarding struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + PeerId string `protobuf:"bytes,2,opt,name=peer_id,json=peerId,proto3" json:"peer_id,omitempty"` + CompositionUrl string `protobuf:"bytes,3,opt,name=composition_url,json=compositionUrl,proto3" json:"composition_url,omitempty"` + InputId string `protobuf:"bytes,4,opt,name=input_id,json=inputId,proto3" json:"input_id,omitempty"` + AudioTrack *notifications.Track `protobuf:"bytes,5,opt,name=audio_track,json=audioTrack,proto3,oneof" json:"audio_track,omitempty"` // Track has id, type, and metadata + VideoTrack *notifications.Track `protobuf:"bytes,6,opt,name=video_track,json=videoTrack,proto3,oneof" json:"video_track,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_TrackForwarding) Reset() { + *x = ServerMessage_TrackForwarding{} + mi := &file_fishjam_server_notifications_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_TrackForwarding) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_TrackForwarding) ProtoMessage() {} + +func (x *ServerMessage_TrackForwarding) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[23] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_TrackForwarding.ProtoReflect.Descriptor instead. +func (*ServerMessage_TrackForwarding) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 22} +} + +func (x *ServerMessage_TrackForwarding) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +func (x *ServerMessage_TrackForwarding) GetPeerId() string { + if x != nil { + return x.PeerId + } + return "" +} + +func (x *ServerMessage_TrackForwarding) GetCompositionUrl() string { + if x != nil { + return x.CompositionUrl + } + return "" +} + +func (x *ServerMessage_TrackForwarding) GetInputId() string { + if x != nil { + return x.InputId + } + return "" +} + +func (x *ServerMessage_TrackForwarding) GetAudioTrack() *notifications.Track { + if x != nil { + return x.AudioTrack + } + return nil +} + +func (x *ServerMessage_TrackForwarding) GetVideoTrack() *notifications.Track { + if x != nil { + return x.VideoTrack + } + return nil +} + +// Sent when track forwarding is removed +type ServerMessage_TrackForwardingRemoved struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomId string `protobuf:"bytes,1,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + PeerId string `protobuf:"bytes,2,opt,name=peer_id,json=peerId,proto3" json:"peer_id,omitempty"` + CompositionUrl string `protobuf:"bytes,3,opt,name=composition_url,json=compositionUrl,proto3" json:"composition_url,omitempty"` + InputId string `protobuf:"bytes,4,opt,name=input_id,json=inputId,proto3" json:"input_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_TrackForwardingRemoved) Reset() { + *x = ServerMessage_TrackForwardingRemoved{} + mi := &file_fishjam_server_notifications_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_TrackForwardingRemoved) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_TrackForwardingRemoved) ProtoMessage() {} + +func (x *ServerMessage_TrackForwardingRemoved) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[24] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_TrackForwardingRemoved.ProtoReflect.Descriptor instead. +func (*ServerMessage_TrackForwardingRemoved) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 23} +} + +func (x *ServerMessage_TrackForwardingRemoved) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +func (x *ServerMessage_TrackForwardingRemoved) GetPeerId() string { + if x != nil { + return x.PeerId + } + return "" +} + +func (x *ServerMessage_TrackForwardingRemoved) GetCompositionUrl() string { + if x != nil { + return x.CompositionUrl + } + return "" +} + +func (x *ServerMessage_TrackForwardingRemoved) GetInputId() string { + if x != nil { + return x.InputId + } + return "" +} + +// Notification sent when streamer successfully connects +type ServerMessage_StreamConnected struct { + state protoimpl.MessageState `protogen:"open.v1"` + StreamId string `protobuf:"bytes,1,opt,name=stream_id,json=streamId,proto3" json:"stream_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_StreamConnected) Reset() { + *x = ServerMessage_StreamConnected{} + mi := &file_fishjam_server_notifications_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_StreamConnected) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_StreamConnected) ProtoMessage() {} + +func (x *ServerMessage_StreamConnected) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[25] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_StreamConnected.ProtoReflect.Descriptor instead. +func (*ServerMessage_StreamConnected) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 24} +} + +func (x *ServerMessage_StreamConnected) GetStreamId() string { + if x != nil { + return x.StreamId + } + return "" +} + +// Notification sent when streamer disconnects +type ServerMessage_StreamDisconnected struct { + state protoimpl.MessageState `protogen:"open.v1"` + StreamId string `protobuf:"bytes,1,opt,name=stream_id,json=streamId,proto3" json:"stream_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_StreamDisconnected) Reset() { + *x = ServerMessage_StreamDisconnected{} + mi := &file_fishjam_server_notifications_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_StreamDisconnected) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_StreamDisconnected) ProtoMessage() {} + +func (x *ServerMessage_StreamDisconnected) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[26] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_StreamDisconnected.ProtoReflect.Descriptor instead. +func (*ServerMessage_StreamDisconnected) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 25} +} + +func (x *ServerMessage_StreamDisconnected) GetStreamId() string { + if x != nil { + return x.StreamId + } + return "" +} + +// Notification sent when viewer successfully connects +type ServerMessage_ViewerConnected struct { + state protoimpl.MessageState `protogen:"open.v1"` + StreamId string `protobuf:"bytes,1,opt,name=stream_id,json=streamId,proto3" json:"stream_id,omitempty"` + ViewerId string `protobuf:"bytes,2,opt,name=viewer_id,json=viewerId,proto3" json:"viewer_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_ViewerConnected) Reset() { + *x = ServerMessage_ViewerConnected{} + mi := &file_fishjam_server_notifications_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_ViewerConnected) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_ViewerConnected) ProtoMessage() {} + +func (x *ServerMessage_ViewerConnected) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[27] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_ViewerConnected.ProtoReflect.Descriptor instead. +func (*ServerMessage_ViewerConnected) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 26} +} + +func (x *ServerMessage_ViewerConnected) GetStreamId() string { + if x != nil { + return x.StreamId + } + return "" +} + +func (x *ServerMessage_ViewerConnected) GetViewerId() string { + if x != nil { + return x.ViewerId + } + return "" +} + +// Notification sent when viewer disconnects +type ServerMessage_ViewerDisconnected struct { + state protoimpl.MessageState `protogen:"open.v1"` + StreamId string `protobuf:"bytes,1,opt,name=stream_id,json=streamId,proto3" json:"stream_id,omitempty"` + ViewerId string `protobuf:"bytes,2,opt,name=viewer_id,json=viewerId,proto3" json:"viewer_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_ViewerDisconnected) Reset() { + *x = ServerMessage_ViewerDisconnected{} + mi := &file_fishjam_server_notifications_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_ViewerDisconnected) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_ViewerDisconnected) ProtoMessage() {} + +func (x *ServerMessage_ViewerDisconnected) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[28] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_ViewerDisconnected.ProtoReflect.Descriptor instead. +func (*ServerMessage_ViewerDisconnected) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 27} +} + +func (x *ServerMessage_ViewerDisconnected) GetStreamId() string { + if x != nil { + return x.StreamId + } + return "" +} + +func (x *ServerMessage_ViewerDisconnected) GetViewerId() string { + if x != nil { + return x.ViewerId + } + return "" +} + +type ServerMessage_StreamerConnected struct { + state protoimpl.MessageState `protogen:"open.v1"` + StreamId string `protobuf:"bytes,1,opt,name=stream_id,json=streamId,proto3" json:"stream_id,omitempty"` + StreamerId string `protobuf:"bytes,2,opt,name=streamer_id,json=streamerId,proto3" json:"streamer_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_StreamerConnected) Reset() { + *x = ServerMessage_StreamerConnected{} + mi := &file_fishjam_server_notifications_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_StreamerConnected) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_StreamerConnected) ProtoMessage() {} + +func (x *ServerMessage_StreamerConnected) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[29] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_StreamerConnected.ProtoReflect.Descriptor instead. +func (*ServerMessage_StreamerConnected) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 28} +} + +func (x *ServerMessage_StreamerConnected) GetStreamId() string { + if x != nil { + return x.StreamId + } + return "" +} + +func (x *ServerMessage_StreamerConnected) GetStreamerId() string { + if x != nil { + return x.StreamerId + } + return "" +} + +type ServerMessage_StreamerDisconnected struct { + state protoimpl.MessageState `protogen:"open.v1"` + StreamId string `protobuf:"bytes,1,opt,name=stream_id,json=streamId,proto3" json:"stream_id,omitempty"` + StreamerId string `protobuf:"bytes,2,opt,name=streamer_id,json=streamerId,proto3" json:"streamer_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_StreamerDisconnected) Reset() { + *x = ServerMessage_StreamerDisconnected{} + mi := &file_fishjam_server_notifications_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_StreamerDisconnected) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_StreamerDisconnected) ProtoMessage() {} + +func (x *ServerMessage_StreamerDisconnected) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_server_notifications_proto_msgTypes[30] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerMessage_StreamerDisconnected.ProtoReflect.Descriptor instead. +func (*ServerMessage_StreamerDisconnected) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 29} +} + +func (x *ServerMessage_StreamerDisconnected) GetStreamId() string { + if x != nil { + return x.StreamId + } + return "" +} + +func (x *ServerMessage_StreamerDisconnected) GetStreamerId() string { + if x != nil { + return x.StreamerId + } + return "" +} + +var File_fishjam_server_notifications_proto protoreflect.FileDescriptor + +const file_fishjam_server_notifications_proto_rawDesc = "" + + "\n" + + "\"fishjam/server_notifications.proto\x12\afishjam\x1a\"fishjam/notifications/shared.proto\"\xd9-\n" + + "\rServerMessage\x12L\n" + + "\rauthenticated\x18\x06 \x01(\v2$.fishjam.ServerMessage.AuthenticatedH\x00R\rauthenticated\x12G\n" + + "\fauth_request\x18\a \x01(\v2\".fishjam.ServerMessage.AuthRequestH\x00R\vauthRequest\x12V\n" + + "\x11subscribe_request\x18\b \x01(\v2'.fishjam.ServerMessage.SubscribeRequestH\x00R\x10subscribeRequest\x12Y\n" + + "\x12subscribe_response\x18\t \x01(\v2(.fishjam.ServerMessage.SubscribeResponseH\x00R\x11subscribeResponse\x12G\n" + + "\froom_created\x18\n" + + " \x01(\v2\".fishjam.ServerMessage.RoomCreatedH\x00R\vroomCreated\x12G\n" + + "\froom_deleted\x18\v \x01(\v2\".fishjam.ServerMessage.RoomDeletedH\x00R\vroomDeleted\x12G\n" + + "\froom_crashed\x18\x01 \x01(\v2\".fishjam.ServerMessage.RoomCrashedH\x00R\vroomCrashed\x12M\n" + + "\x0epeer_connected\x18\x02 \x01(\v2$.fishjam.ServerMessage.PeerConnectedH\x00R\rpeerConnected\x12V\n" + + "\x11peer_disconnected\x18\x03 \x01(\v2'.fishjam.ServerMessage.PeerDisconnectedH\x00R\x10peerDisconnected\x12G\n" + + "\fpeer_crashed\x18\x04 \x01(\v2\".fishjam.ServerMessage.PeerCrashedH\x00R\vpeerCrashed\x12`\n" + + "\x15peer_metadata_updated\x18\x10 \x01(\v2*.fishjam.ServerMessage.PeerMetadataUpdatedH\x00R\x13peerMetadataUpdated\x12D\n" + + "\vtrack_added\x18\x11 \x01(\v2!.fishjam.ServerMessage.TrackAddedH\x00R\n" + + "trackAdded\x12J\n" + + "\rtrack_removed\x18\x12 \x01(\v2#.fishjam.ServerMessage.TrackRemovedH\x00R\ftrackRemoved\x12c\n" + + "\x16track_metadata_updated\x18\x13 \x01(\v2+.fishjam.ServerMessage.TrackMetadataUpdatedH\x00R\x14trackMetadataUpdated\x12A\n" + + "\n" + + "peer_added\x18\x14 \x01(\v2 .fishjam.ServerMessage.PeerAddedH\x00R\tpeerAdded\x12G\n" + + "\fpeer_deleted\x18\x15 \x01(\v2\".fishjam.ServerMessage.PeerDeletedH\x00R\vpeerDeleted\x12J\n" + + "\rchannel_added\x18\x1c \x01(\v2#.fishjam.ServerMessage.ChannelAddedH\x00R\fchannelAdded\x12P\n" + + "\x0fchannel_removed\x18\x1d \x01(\v2%.fishjam.ServerMessage.ChannelRemovedH\x00R\x0echannelRemoved\x12S\n" + + "\x10track_forwarding\x18\x1e \x01(\v2&.fishjam.ServerMessage.TrackForwardingH\x00R\x0ftrackForwarding\x12i\n" + + "\x18track_forwarding_removed\x18\x1f \x01(\v2-.fishjam.ServerMessage.TrackForwardingRemovedH\x00R\x16trackForwardingRemoved\x12S\n" + + "\x10viewer_connected\x18\x18 \x01(\v2&.fishjam.ServerMessage.ViewerConnectedH\x00R\x0fviewerConnected\x12\\\n" + + "\x13viewer_disconnected\x18\x19 \x01(\v2).fishjam.ServerMessage.ViewerDisconnectedH\x00R\x12viewerDisconnected\x12Y\n" + + "\x12streamer_connected\x18\x1a \x01(\v2(.fishjam.ServerMessage.StreamerConnectedH\x00R\x11streamerConnected\x12b\n" + + "\x15streamer_disconnected\x18\x1b \x01(\v2+.fishjam.ServerMessage.StreamerDisconnectedH\x00R\x14streamerDisconnected\x12W\n" + + "\x10stream_connected\x18\x16 \x01(\v2&.fishjam.ServerMessage.StreamConnectedB\x02\x18\x01H\x00R\x0fstreamConnected\x12`\n" + + "\x13stream_disconnected\x18\x17 \x01(\v2).fishjam.ServerMessage.StreamDisconnectedB\x02\x18\x01H\x00R\x12streamDisconnected\x12K\n" + + "\fhls_playable\x18\r \x01(\v2\".fishjam.ServerMessage.HlsPlayableB\x02\x18\x01H\x00R\vhlsPlayable\x12K\n" + + "\fhls_uploaded\x18\x0e \x01(\v2\".fishjam.ServerMessage.HlsUploadedB\x02\x18\x01H\x00R\vhlsUploaded\x12[\n" + + "\x12hls_upload_crashed\x18\x0f \x01(\v2'.fishjam.ServerMessage.HlsUploadCrashedB\x02\x18\x01H\x00R\x10hlsUploadCrashed\x12Z\n" + + "\x11component_crashed\x18\x05 \x01(\v2'.fishjam.ServerMessage.ComponentCrashedB\x02\x18\x01H\x00R\x10componentCrashed\x1a&\n" + + "\vRoomCrashed\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x1a{\n" + + "\tPeerAdded\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x12\x17\n" + + "\apeer_id\x18\x02 \x01(\tR\x06peerId\x12<\n" + + "\tpeer_type\x18\x03 \x01(\x0e2\x1f.fishjam.ServerMessage.PeerTypeR\bpeerType\x1a}\n" + + "\vPeerDeleted\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x12\x17\n" + + "\apeer_id\x18\x02 \x01(\tR\x06peerId\x12<\n" + + "\tpeer_type\x18\x03 \x01(\x0e2\x1f.fishjam.ServerMessage.PeerTypeR\bpeerType\x1a\x7f\n" + + "\rPeerConnected\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x12\x17\n" + + "\apeer_id\x18\x02 \x01(\tR\x06peerId\x12<\n" + + "\tpeer_type\x18\x03 \x01(\x0e2\x1f.fishjam.ServerMessage.PeerTypeR\bpeerType\x1a\x82\x01\n" + + "\x10PeerDisconnected\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x12\x17\n" + + "\apeer_id\x18\x02 \x01(\tR\x06peerId\x12<\n" + + "\tpeer_type\x18\x03 \x01(\x0e2\x1f.fishjam.ServerMessage.PeerTypeR\bpeerType\x1a\x95\x01\n" + + "\vPeerCrashed\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x12\x17\n" + + "\apeer_id\x18\x02 \x01(\tR\x06peerId\x12\x16\n" + + "\x06reason\x18\x03 \x01(\tR\x06reason\x12<\n" + + "\tpeer_type\x18\x04 \x01(\x0e2\x1f.fishjam.ServerMessage.PeerTypeR\bpeerType\x1aN\n" + + "\x10ComponentCrashed\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x12!\n" + + "\fcomponent_id\x18\x02 \x01(\tR\vcomponentId\x1a\x0f\n" + + "\rAuthenticated\x1a#\n" + + "\vAuthRequest\x12\x14\n" + + "\x05token\x18\x01 \x01(\tR\x05token\x1aS\n" + + "\x10SubscribeRequest\x12?\n" + + "\n" + + "event_type\x18\x01 \x01(\x0e2 .fishjam.ServerMessage.EventTypeR\teventType\x1aT\n" + + "\x11SubscribeResponse\x12?\n" + + "\n" + + "event_type\x18\x01 \x01(\x0e2 .fishjam.ServerMessage.EventTypeR\teventType\x1a&\n" + + "\vRoomCreated\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x1a&\n" + + "\vRoomDeleted\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x1aI\n" + + "\vHlsPlayable\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x12!\n" + + "\fcomponent_id\x18\x02 \x01(\tR\vcomponentId\x1a&\n" + + "\vHlsUploaded\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x1a+\n" + + "\x10HlsUploadCrashed\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x1a\xa1\x01\n" + + "\x13PeerMetadataUpdated\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x12\x17\n" + + "\apeer_id\x18\x02 \x01(\tR\x06peerId\x12\x1a\n" + + "\bmetadata\x18\x03 \x01(\tR\bmetadata\x12<\n" + + "\tpeer_type\x18\x04 \x01(\x0e2\x1f.fishjam.ServerMessage.PeerTypeR\bpeerType\x1a\xaa\x01\n" + + "\n" + + "TrackAdded\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x12\x19\n" + + "\apeer_id\x18\x02 \x01(\tH\x00R\x06peerId\x12#\n" + + "\fcomponent_id\x18\x03 \x01(\tH\x00R\vcomponentId\x122\n" + + "\x05track\x18\x04 \x01(\v2\x1c.fishjam.notifications.TrackR\x05trackB\x0f\n" + + "\rendpoint_info\x1a\xac\x01\n" + + "\fTrackRemoved\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x12\x19\n" + + "\apeer_id\x18\x02 \x01(\tH\x00R\x06peerId\x12#\n" + + "\fcomponent_id\x18\x03 \x01(\tH\x00R\vcomponentId\x122\n" + + "\x05track\x18\x04 \x01(\v2\x1c.fishjam.notifications.TrackR\x05trackB\x0f\n" + + "\rendpoint_info\x1a\xb4\x01\n" + + "\x14TrackMetadataUpdated\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x12\x19\n" + + "\apeer_id\x18\x02 \x01(\tH\x00R\x06peerId\x12#\n" + + "\fcomponent_id\x18\x03 \x01(\tH\x00R\vcomponentId\x122\n" + + "\x05track\x18\x04 \x01(\v2\x1c.fishjam.notifications.TrackR\x05trackB\x0f\n" + + "\rendpoint_info\x1a\x97\x01\n" + + "\fChannelAdded\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x12\x19\n" + + "\apeer_id\x18\x02 \x01(\tH\x00R\x06peerId\x12#\n" + + "\fcomponent_id\x18\x03 \x01(\tH\x00R\vcomponentId\x12\x1d\n" + + "\n" + + "channel_id\x18\x04 \x01(\tR\tchannelIdB\x0f\n" + + "\rendpoint_info\x1a\x99\x01\n" + + "\x0eChannelRemoved\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x12\x19\n" + + "\apeer_id\x18\x02 \x01(\tH\x00R\x06peerId\x12#\n" + + "\fcomponent_id\x18\x03 \x01(\tH\x00R\vcomponentId\x12\x1d\n" + + "\n" + + "channel_id\x18\x04 \x01(\tR\tchannelIdB\x0f\n" + + "\rendpoint_info\x1a\xaf\x02\n" + + "\x0fTrackForwarding\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x12\x17\n" + + "\apeer_id\x18\x02 \x01(\tR\x06peerId\x12'\n" + + "\x0fcomposition_url\x18\x03 \x01(\tR\x0ecompositionUrl\x12\x19\n" + + "\binput_id\x18\x04 \x01(\tR\ainputId\x12B\n" + + "\vaudio_track\x18\x05 \x01(\v2\x1c.fishjam.notifications.TrackH\x00R\n" + + "audioTrack\x88\x01\x01\x12B\n" + + "\vvideo_track\x18\x06 \x01(\v2\x1c.fishjam.notifications.TrackH\x01R\n" + + "videoTrack\x88\x01\x01B\x0e\n" + + "\f_audio_trackB\x0e\n" + + "\f_video_track\x1a\x8e\x01\n" + + "\x16TrackForwardingRemoved\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x12\x17\n" + + "\apeer_id\x18\x02 \x01(\tR\x06peerId\x12'\n" + + "\x0fcomposition_url\x18\x03 \x01(\tR\x0ecompositionUrl\x12\x19\n" + + "\binput_id\x18\x04 \x01(\tR\ainputId\x1a.\n" + + "\x0fStreamConnected\x12\x1b\n" + + "\tstream_id\x18\x01 \x01(\tR\bstreamId\x1a1\n" + + "\x12StreamDisconnected\x12\x1b\n" + + "\tstream_id\x18\x01 \x01(\tR\bstreamId\x1aK\n" + + "\x0fViewerConnected\x12\x1b\n" + + "\tstream_id\x18\x01 \x01(\tR\bstreamId\x12\x1b\n" + + "\tviewer_id\x18\x02 \x01(\tR\bviewerId\x1aN\n" + + "\x12ViewerDisconnected\x12\x1b\n" + + "\tstream_id\x18\x01 \x01(\tR\bstreamId\x12\x1b\n" + + "\tviewer_id\x18\x02 \x01(\tR\bviewerId\x1aQ\n" + + "\x11StreamerConnected\x12\x1b\n" + + "\tstream_id\x18\x01 \x01(\tR\bstreamId\x12\x1f\n" + + "\vstreamer_id\x18\x02 \x01(\tR\n" + + "streamerId\x1aT\n" + + "\x14StreamerDisconnected\x12\x1b\n" + + "\tstream_id\x18\x01 \x01(\tR\bstreamId\x12\x1f\n" + + "\vstreamer_id\x18\x02 \x01(\tR\n" + + "streamerId\"P\n" + + "\bPeerType\x12\x19\n" + + "\x15PEER_TYPE_UNSPECIFIED\x10\x00\x12\x14\n" + + "\x10PEER_TYPE_WEBRTC\x10\x01\x12\x13\n" + + "\x0fPEER_TYPE_AGENT\x10\x02\"Q\n" + + "\tEventType\x12\x1a\n" + + "\x16EVENT_TYPE_UNSPECIFIED\x10\x00\x12\"\n" + + "\x1eEVENT_TYPE_SERVER_NOTIFICATION\x10\x01\"\x04\b\x02\x10\x02B\t\n" + + "\acontentJ\x04\b\f\x10\rb\x06proto3" + +var ( + file_fishjam_server_notifications_proto_rawDescOnce sync.Once + file_fishjam_server_notifications_proto_rawDescData []byte +) + +func file_fishjam_server_notifications_proto_rawDescGZIP() []byte { + file_fishjam_server_notifications_proto_rawDescOnce.Do(func() { + file_fishjam_server_notifications_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_fishjam_server_notifications_proto_rawDesc), len(file_fishjam_server_notifications_proto_rawDesc))) + }) + return file_fishjam_server_notifications_proto_rawDescData +} + +var file_fishjam_server_notifications_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_fishjam_server_notifications_proto_msgTypes = make([]protoimpl.MessageInfo, 31) +var file_fishjam_server_notifications_proto_goTypes = []any{ + (ServerMessage_PeerType)(0), // 0: fishjam.ServerMessage.PeerType + (ServerMessage_EventType)(0), // 1: fishjam.ServerMessage.EventType + (*ServerMessage)(nil), // 2: fishjam.ServerMessage + (*ServerMessage_RoomCrashed)(nil), // 3: fishjam.ServerMessage.RoomCrashed + (*ServerMessage_PeerAdded)(nil), // 4: fishjam.ServerMessage.PeerAdded + (*ServerMessage_PeerDeleted)(nil), // 5: fishjam.ServerMessage.PeerDeleted + (*ServerMessage_PeerConnected)(nil), // 6: fishjam.ServerMessage.PeerConnected + (*ServerMessage_PeerDisconnected)(nil), // 7: fishjam.ServerMessage.PeerDisconnected + (*ServerMessage_PeerCrashed)(nil), // 8: fishjam.ServerMessage.PeerCrashed + (*ServerMessage_ComponentCrashed)(nil), // 9: fishjam.ServerMessage.ComponentCrashed + (*ServerMessage_Authenticated)(nil), // 10: fishjam.ServerMessage.Authenticated + (*ServerMessage_AuthRequest)(nil), // 11: fishjam.ServerMessage.AuthRequest + (*ServerMessage_SubscribeRequest)(nil), // 12: fishjam.ServerMessage.SubscribeRequest + (*ServerMessage_SubscribeResponse)(nil), // 13: fishjam.ServerMessage.SubscribeResponse + (*ServerMessage_RoomCreated)(nil), // 14: fishjam.ServerMessage.RoomCreated + (*ServerMessage_RoomDeleted)(nil), // 15: fishjam.ServerMessage.RoomDeleted + (*ServerMessage_HlsPlayable)(nil), // 16: fishjam.ServerMessage.HlsPlayable + (*ServerMessage_HlsUploaded)(nil), // 17: fishjam.ServerMessage.HlsUploaded + (*ServerMessage_HlsUploadCrashed)(nil), // 18: fishjam.ServerMessage.HlsUploadCrashed + (*ServerMessage_PeerMetadataUpdated)(nil), // 19: fishjam.ServerMessage.PeerMetadataUpdated + (*ServerMessage_TrackAdded)(nil), // 20: fishjam.ServerMessage.TrackAdded + (*ServerMessage_TrackRemoved)(nil), // 21: fishjam.ServerMessage.TrackRemoved + (*ServerMessage_TrackMetadataUpdated)(nil), // 22: fishjam.ServerMessage.TrackMetadataUpdated + (*ServerMessage_ChannelAdded)(nil), // 23: fishjam.ServerMessage.ChannelAdded + (*ServerMessage_ChannelRemoved)(nil), // 24: fishjam.ServerMessage.ChannelRemoved + (*ServerMessage_TrackForwarding)(nil), // 25: fishjam.ServerMessage.TrackForwarding + (*ServerMessage_TrackForwardingRemoved)(nil), // 26: fishjam.ServerMessage.TrackForwardingRemoved + (*ServerMessage_StreamConnected)(nil), // 27: fishjam.ServerMessage.StreamConnected + (*ServerMessage_StreamDisconnected)(nil), // 28: fishjam.ServerMessage.StreamDisconnected + (*ServerMessage_ViewerConnected)(nil), // 29: fishjam.ServerMessage.ViewerConnected + (*ServerMessage_ViewerDisconnected)(nil), // 30: fishjam.ServerMessage.ViewerDisconnected + (*ServerMessage_StreamerConnected)(nil), // 31: fishjam.ServerMessage.StreamerConnected + (*ServerMessage_StreamerDisconnected)(nil), // 32: fishjam.ServerMessage.StreamerDisconnected + (*notifications.Track)(nil), // 33: fishjam.notifications.Track +} +var file_fishjam_server_notifications_proto_depIdxs = []int32{ + 10, // 0: fishjam.ServerMessage.authenticated:type_name -> fishjam.ServerMessage.Authenticated + 11, // 1: fishjam.ServerMessage.auth_request:type_name -> fishjam.ServerMessage.AuthRequest + 12, // 2: fishjam.ServerMessage.subscribe_request:type_name -> fishjam.ServerMessage.SubscribeRequest + 13, // 3: fishjam.ServerMessage.subscribe_response:type_name -> fishjam.ServerMessage.SubscribeResponse + 14, // 4: fishjam.ServerMessage.room_created:type_name -> fishjam.ServerMessage.RoomCreated + 15, // 5: fishjam.ServerMessage.room_deleted:type_name -> fishjam.ServerMessage.RoomDeleted + 3, // 6: fishjam.ServerMessage.room_crashed:type_name -> fishjam.ServerMessage.RoomCrashed + 6, // 7: fishjam.ServerMessage.peer_connected:type_name -> fishjam.ServerMessage.PeerConnected + 7, // 8: fishjam.ServerMessage.peer_disconnected:type_name -> fishjam.ServerMessage.PeerDisconnected + 8, // 9: fishjam.ServerMessage.peer_crashed:type_name -> fishjam.ServerMessage.PeerCrashed + 19, // 10: fishjam.ServerMessage.peer_metadata_updated:type_name -> fishjam.ServerMessage.PeerMetadataUpdated + 20, // 11: fishjam.ServerMessage.track_added:type_name -> fishjam.ServerMessage.TrackAdded + 21, // 12: fishjam.ServerMessage.track_removed:type_name -> fishjam.ServerMessage.TrackRemoved + 22, // 13: fishjam.ServerMessage.track_metadata_updated:type_name -> fishjam.ServerMessage.TrackMetadataUpdated + 4, // 14: fishjam.ServerMessage.peer_added:type_name -> fishjam.ServerMessage.PeerAdded + 5, // 15: fishjam.ServerMessage.peer_deleted:type_name -> fishjam.ServerMessage.PeerDeleted + 23, // 16: fishjam.ServerMessage.channel_added:type_name -> fishjam.ServerMessage.ChannelAdded + 24, // 17: fishjam.ServerMessage.channel_removed:type_name -> fishjam.ServerMessage.ChannelRemoved + 25, // 18: fishjam.ServerMessage.track_forwarding:type_name -> fishjam.ServerMessage.TrackForwarding + 26, // 19: fishjam.ServerMessage.track_forwarding_removed:type_name -> fishjam.ServerMessage.TrackForwardingRemoved + 29, // 20: fishjam.ServerMessage.viewer_connected:type_name -> fishjam.ServerMessage.ViewerConnected + 30, // 21: fishjam.ServerMessage.viewer_disconnected:type_name -> fishjam.ServerMessage.ViewerDisconnected + 31, // 22: fishjam.ServerMessage.streamer_connected:type_name -> fishjam.ServerMessage.StreamerConnected + 32, // 23: fishjam.ServerMessage.streamer_disconnected:type_name -> fishjam.ServerMessage.StreamerDisconnected + 27, // 24: fishjam.ServerMessage.stream_connected:type_name -> fishjam.ServerMessage.StreamConnected + 28, // 25: fishjam.ServerMessage.stream_disconnected:type_name -> fishjam.ServerMessage.StreamDisconnected + 16, // 26: fishjam.ServerMessage.hls_playable:type_name -> fishjam.ServerMessage.HlsPlayable + 17, // 27: fishjam.ServerMessage.hls_uploaded:type_name -> fishjam.ServerMessage.HlsUploaded + 18, // 28: fishjam.ServerMessage.hls_upload_crashed:type_name -> fishjam.ServerMessage.HlsUploadCrashed + 9, // 29: fishjam.ServerMessage.component_crashed:type_name -> fishjam.ServerMessage.ComponentCrashed + 0, // 30: fishjam.ServerMessage.PeerAdded.peer_type:type_name -> fishjam.ServerMessage.PeerType + 0, // 31: fishjam.ServerMessage.PeerDeleted.peer_type:type_name -> fishjam.ServerMessage.PeerType + 0, // 32: fishjam.ServerMessage.PeerConnected.peer_type:type_name -> fishjam.ServerMessage.PeerType + 0, // 33: fishjam.ServerMessage.PeerDisconnected.peer_type:type_name -> fishjam.ServerMessage.PeerType + 0, // 34: fishjam.ServerMessage.PeerCrashed.peer_type:type_name -> fishjam.ServerMessage.PeerType + 1, // 35: fishjam.ServerMessage.SubscribeRequest.event_type:type_name -> fishjam.ServerMessage.EventType + 1, // 36: fishjam.ServerMessage.SubscribeResponse.event_type:type_name -> fishjam.ServerMessage.EventType + 0, // 37: fishjam.ServerMessage.PeerMetadataUpdated.peer_type:type_name -> fishjam.ServerMessage.PeerType + 33, // 38: fishjam.ServerMessage.TrackAdded.track:type_name -> fishjam.notifications.Track + 33, // 39: fishjam.ServerMessage.TrackRemoved.track:type_name -> fishjam.notifications.Track + 33, // 40: fishjam.ServerMessage.TrackMetadataUpdated.track:type_name -> fishjam.notifications.Track + 33, // 41: fishjam.ServerMessage.TrackForwarding.audio_track:type_name -> fishjam.notifications.Track + 33, // 42: fishjam.ServerMessage.TrackForwarding.video_track:type_name -> fishjam.notifications.Track + 43, // [43:43] is the sub-list for method output_type + 43, // [43:43] is the sub-list for method input_type + 43, // [43:43] is the sub-list for extension type_name + 43, // [43:43] is the sub-list for extension extendee + 0, // [0:43] is the sub-list for field type_name +} + +func init() { file_fishjam_server_notifications_proto_init() } +func file_fishjam_server_notifications_proto_init() { + if File_fishjam_server_notifications_proto != nil { + return + } + file_fishjam_server_notifications_proto_msgTypes[0].OneofWrappers = []any{ + (*ServerMessage_Authenticated_)(nil), + (*ServerMessage_AuthRequest_)(nil), + (*ServerMessage_SubscribeRequest_)(nil), + (*ServerMessage_SubscribeResponse_)(nil), + (*ServerMessage_RoomCreated_)(nil), + (*ServerMessage_RoomDeleted_)(nil), + (*ServerMessage_RoomCrashed_)(nil), + (*ServerMessage_PeerConnected_)(nil), + (*ServerMessage_PeerDisconnected_)(nil), + (*ServerMessage_PeerCrashed_)(nil), + (*ServerMessage_PeerMetadataUpdated_)(nil), + (*ServerMessage_TrackAdded_)(nil), + (*ServerMessage_TrackRemoved_)(nil), + (*ServerMessage_TrackMetadataUpdated_)(nil), + (*ServerMessage_PeerAdded_)(nil), + (*ServerMessage_PeerDeleted_)(nil), + (*ServerMessage_ChannelAdded_)(nil), + (*ServerMessage_ChannelRemoved_)(nil), + (*ServerMessage_TrackForwarding_)(nil), + (*ServerMessage_TrackForwardingRemoved_)(nil), + (*ServerMessage_ViewerConnected_)(nil), + (*ServerMessage_ViewerDisconnected_)(nil), + (*ServerMessage_StreamerConnected_)(nil), + (*ServerMessage_StreamerDisconnected_)(nil), + (*ServerMessage_StreamConnected_)(nil), + (*ServerMessage_StreamDisconnected_)(nil), + (*ServerMessage_HlsPlayable_)(nil), + (*ServerMessage_HlsUploaded_)(nil), + (*ServerMessage_HlsUploadCrashed_)(nil), + (*ServerMessage_ComponentCrashed_)(nil), + } + file_fishjam_server_notifications_proto_msgTypes[18].OneofWrappers = []any{ + (*ServerMessage_TrackAdded_PeerId)(nil), + (*ServerMessage_TrackAdded_ComponentId)(nil), + } + file_fishjam_server_notifications_proto_msgTypes[19].OneofWrappers = []any{ + (*ServerMessage_TrackRemoved_PeerId)(nil), + (*ServerMessage_TrackRemoved_ComponentId)(nil), + } + file_fishjam_server_notifications_proto_msgTypes[20].OneofWrappers = []any{ + (*ServerMessage_TrackMetadataUpdated_PeerId)(nil), + (*ServerMessage_TrackMetadataUpdated_ComponentId)(nil), + } + file_fishjam_server_notifications_proto_msgTypes[21].OneofWrappers = []any{ + (*ServerMessage_ChannelAdded_PeerId)(nil), + (*ServerMessage_ChannelAdded_ComponentId)(nil), + } + file_fishjam_server_notifications_proto_msgTypes[22].OneofWrappers = []any{ + (*ServerMessage_ChannelRemoved_PeerId)(nil), + (*ServerMessage_ChannelRemoved_ComponentId)(nil), + } + file_fishjam_server_notifications_proto_msgTypes[23].OneofWrappers = []any{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_fishjam_server_notifications_proto_rawDesc), len(file_fishjam_server_notifications_proto_rawDesc)), + NumEnums: 2, + NumMessages: 31, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_fishjam_server_notifications_proto_goTypes, + DependencyIndexes: file_fishjam_server_notifications_proto_depIdxs, + EnumInfos: file_fishjam_server_notifications_proto_enumTypes, + MessageInfos: file_fishjam_server_notifications_proto_msgTypes, + }.Build() + File_fishjam_server_notifications_proto = out.File + file_fishjam_server_notifications_proto_goTypes = nil + file_fishjam_server_notifications_proto_depIdxs = nil +} diff --git a/conference-to-stream/docker-compose.yml b/conference-to-stream/docker-compose.yml new file mode 100644 index 0000000..b562b86 --- /dev/null +++ b/conference-to-stream/docker-compose.yml @@ -0,0 +1,23 @@ +services: + backend: + build: + context: ./backend + ports: + - "8080:8080" + environment: + FISHJAM_ID: ${FISHJAM_ID} + FISHJAM_MANAGEMENT_TOKEN: ${FISHJAM_MANAGEMENT_TOKEN} + PORT: 8080 + restart: unless-stopped + + web: + build: + context: ./web + args: + VITE_FISHJAM_ID: ${VITE_FISHJAM_ID} + VITE_BACKEND_URL: ${VITE_BACKEND_URL:-http://localhost:8080} + ports: + - "5173:80" + depends_on: + - backend + restart: unless-stopped diff --git a/conference-to-stream/web/.gitignore b/conference-to-stream/web/.gitignore new file mode 100644 index 0000000..b947077 --- /dev/null +++ b/conference-to-stream/web/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +dist/ diff --git a/conference-to-stream/web/Dockerfile b/conference-to-stream/web/Dockerfile new file mode 100644 index 0000000..9afc563 --- /dev/null +++ b/conference-to-stream/web/Dockerfile @@ -0,0 +1,15 @@ +FROM node:22-alpine AS builder +WORKDIR /app +COPY package.json ./ +RUN npm install +COPY . . +ARG VITE_FISHJAM_ID +ARG VITE_BACKEND_URL=http://localhost:8080 +ENV VITE_FISHJAM_ID=$VITE_FISHJAM_ID +ENV VITE_BACKEND_URL=$VITE_BACKEND_URL +RUN npm run build + +FROM nginx:alpine +COPY --from=builder /app/dist /usr/share/nginx/html +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] diff --git a/conference-to-stream/web/index.html b/conference-to-stream/web/index.html new file mode 100644 index 0000000..d6ac568 --- /dev/null +++ b/conference-to-stream/web/index.html @@ -0,0 +1,12 @@ + + + + + + Conference to Stream + + +
+ + + diff --git a/conference-to-stream/web/package-lock.json b/conference-to-stream/web/package-lock.json new file mode 100644 index 0000000..19e4e69 --- /dev/null +++ b/conference-to-stream/web/package-lock.json @@ -0,0 +1,2522 @@ +{ + "name": "conference-to-stream-web", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "conference-to-stream-web", + "version": "0.0.0", + "dependencies": { + "@fishjam-cloud/react-client": "^0.25.1", + "react": "^19.1.1", + "react-dom": "^19.1.1" + }, + "devDependencies": { + "@tailwindcss/vite": "^4.1.13", + "@types/react": "^19.1.13", + "@types/react-dom": "^19.1.9", + "@vitejs/plugin-react": "^5.0.3", + "tailwindcss": "^4.1.13", + "typescript": "^5.9.2", + "vite": "^7.1.7" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", + "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@binbat/whip-whep": { + "version": "1.1.1-sdp-trickle-throw", + "resolved": "https://registry.npmjs.org/@binbat/whip-whep/-/whip-whep-1.1.1-sdp-trickle-throw.tgz", + "integrity": "sha512-JFoNBEms4ECrbDd7LG2k5XP2DpGTUMGzaiCK7tjWyHYrrn58eb5BAJAX1GNQhrwkmBCRoIlhGTXULxKo6tsFug==", + "license": "MIT" + }, + "node_modules/@bufbuild/protobuf": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.11.0.tgz", + "integrity": "sha512-sBXGT13cpmPR5BMgHE6UEEfEaShh5Ror6rfN3yEK5si7QVrtZg8LEPQb0VVhiLRUslD2yLnXtnRzG035J/mZXQ==", + "license": "(Apache-2.0 AND BSD-3-Clause)" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", + "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@fishjam-cloud/react-client": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@fishjam-cloud/react-client/-/react-client-0.25.1.tgz", + "integrity": "sha512-Gg/bhpFyd7lZ0TvHPvdYue9Y70wOIvoiq3MPs0SB9maXnBxOJQl2LDO/BEXPtDB0Pz3KAVdHit/VJrVNacFaZQ==", + "license": "Apache-2.0", + "dependencies": { + "@fishjam-cloud/ts-client": "0.25.1", + "events": "3.3.0", + "lodash.isequal": "4.5.0" + }, + "peerDependencies": { + "react": "^19.1.0" + } + }, + "node_modules/@fishjam-cloud/ts-client": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@fishjam-cloud/ts-client/-/ts-client-0.25.1.tgz", + "integrity": "sha512-waYluwtjSu0lnl4+8qi4tR5J04pEK04Xx/7xMKDEp5ycXh3iZoUZO9vJvEhMDGjGLiw9JZ9WsffGgP9vkT/Y2A==", + "license": "Apache-2.0", + "dependencies": { + "@binbat/whip-whep": "^1.1.1-sdp-trickle-throw", + "@bufbuild/protobuf": "^2.2.3", + "events": "^3.3.0", + "typed-emitter": "^2.1.0", + "uuid": "^11.1.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", + "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@tailwindcss/node": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.1.tgz", + "integrity": "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.19.0", + "jiti": "^2.6.1", + "lightningcss": "1.31.1", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.2.1" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.1.tgz", + "integrity": "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.2.1", + "@tailwindcss/oxide-darwin-arm64": "4.2.1", + "@tailwindcss/oxide-darwin-x64": "4.2.1", + "@tailwindcss/oxide-freebsd-x64": "4.2.1", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", + "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", + "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", + "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", + "@tailwindcss/oxide-linux-x64-musl": "4.2.1", + "@tailwindcss/oxide-wasm32-wasi": "4.2.1", + "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", + "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.1.tgz", + "integrity": "sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.1.tgz", + "integrity": "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.1.tgz", + "integrity": "sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.1.tgz", + "integrity": "sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.1.tgz", + "integrity": "sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.1.tgz", + "integrity": "sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.1.tgz", + "integrity": "sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.1.tgz", + "integrity": "sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.1.tgz", + "integrity": "sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.1.tgz", + "integrity": "sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.8.1", + "@emnapi/runtime": "^1.8.1", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.1.1", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.1.tgz", + "integrity": "sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.1.tgz", + "integrity": "sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.1.tgz", + "integrity": "sha512-TBf2sJjYeb28jD2U/OhwdW0bbOsxkWPwQ7SrqGf9sVcoYwZj7rkXljroBO9wKBut9XnmQLXanuDUeqQK0lGg/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.2.1", + "@tailwindcss/oxide": "4.2.1", + "tailwindcss": "4.2.1" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", + "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.4.tgz", + "integrity": "sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.29.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-rc.3", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.18.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", + "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001776", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001776.tgz", + "integrity": "sha512-sg01JDPzZ9jGshqKSckOQthXnYwOEP50jeVFhaSFbZcOy05TiuuaffDOfcwtCisJ9kNQuLBFibYywv2Bgm9osw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.307", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.307.tgz", + "integrity": "sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg==", + "dev": true, + "license": "ISC" + }, + "node_modules/enhanced-resolve": { + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.0.tgz", + "integrity": "sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/esbuild": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lightningcss": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.31.1.tgz", + "integrity": "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.31.1", + "lightningcss-darwin-arm64": "1.31.1", + "lightningcss-darwin-x64": "1.31.1", + "lightningcss-freebsd-x64": "1.31.1", + "lightningcss-linux-arm-gnueabihf": "1.31.1", + "lightningcss-linux-arm64-gnu": "1.31.1", + "lightningcss-linux-arm64-musl": "1.31.1", + "lightningcss-linux-x64-gnu": "1.31.1", + "lightningcss-linux-x64-musl": "1.31.1", + "lightningcss-win32-arm64-msvc": "1.31.1", + "lightningcss-win32-x64-msvc": "1.31.1" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz", + "integrity": "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz", + "integrity": "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz", + "integrity": "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz", + "integrity": "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz", + "integrity": "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz", + "integrity": "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz", + "integrity": "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz", + "integrity": "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz", + "integrity": "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz", + "integrity": "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz", + "integrity": "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", + "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.4" + } + }, + "node_modules/react-refresh": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", + "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tailwindcss": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.1.tgz", + "integrity": "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD", + "optional": true + }, + "node_modules/typed-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/typed-emitter/-/typed-emitter-2.1.0.tgz", + "integrity": "sha512-g/KzbYKbH5C2vPkaXGu8DJlHrGKHLsM25Zg9WuC9pMGfuvT+X25tZQWo5fK1BjBm8+UrVE9LDCvaY0CQk+fXDA==", + "license": "MIT", + "optionalDependencies": { + "rxjs": "*" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "node_modules/vite": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", + "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + } + } +} diff --git a/conference-to-stream/web/package.json b/conference-to-stream/web/package.json new file mode 100644 index 0000000..cc0ff7a --- /dev/null +++ b/conference-to-stream/web/package.json @@ -0,0 +1,25 @@ +{ + "name": "conference-to-stream-web", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@fishjam-cloud/react-client": "^0.25.1", + "react": "^19.1.1", + "react-dom": "^19.1.1" + }, + "devDependencies": { + "@tailwindcss/vite": "^4.1.13", + "@types/react": "^19.1.13", + "@types/react-dom": "^19.1.9", + "@vitejs/plugin-react": "^5.0.3", + "tailwindcss": "^4.1.13", + "typescript": "^5.9.2", + "vite": "^7.1.7" + } +} diff --git a/conference-to-stream/web/src/App.tsx b/conference-to-stream/web/src/App.tsx new file mode 100644 index 0000000..96d2202 --- /dev/null +++ b/conference-to-stream/web/src/App.tsx @@ -0,0 +1,56 @@ +import { useEffect, useState } from "react"; +import { Conference } from "./components/Conference"; +import { JoinForm } from "./components/JoinForm"; + +type AppState = + | { status: "idle"; initialRoomName?: string } + | { status: "joined"; whepUrl: string; roomName: string; peerName: string }; + +function getRoomNameFromURL(): string { + const path = window.location.pathname.replace(/^\/+|\/+$/g, ""); + return path || ""; +} + +export function App() { + const [state, setState] = useState(() => { + const initialRoomName = getRoomNameFromURL(); + return { status: "idle", initialRoomName }; + }); + + useEffect(() => { + function handlePopState() { + const roomName = getRoomNameFromURL(); + if (!roomName && state.status === "joined") { + setState({ status: "idle" }); + } else if (roomName && state.status === "idle") { + setState({ status: "idle", initialRoomName: roomName }); + } + } + window.addEventListener("popstate", handlePopState); + return () => window.removeEventListener("popstate", handlePopState); + }, [state.status]); + + if (state.status === "joined") { + return ( + { + history.pushState({}, "", "/"); + setState({ status: "idle" }); + }} + /> + ); + } + + return ( + { + history.pushState({}, "", `/${roomName}`); + setState({ status: "joined", whepUrl, roomName, peerName }); + }} + /> + ); +} diff --git a/conference-to-stream/web/src/api.ts b/conference-to-stream/web/src/api.ts new file mode 100644 index 0000000..a9d4585 --- /dev/null +++ b/conference-to-stream/web/src/api.ts @@ -0,0 +1,31 @@ +const backendUrl = (import.meta.env.VITE_BACKEND_URL as string) || "http://localhost:8080"; + +export type JoinRoomResult = { + roomId: string; + whepUrl: string; +}; + +export type JoinPeerResult = { + peerToken: string; + peerWebsocketUrl: string; +}; + +export async function createRoom(roomName: string): Promise { + const res = await fetch(`${backendUrl}/api/rooms`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ roomName }), + }); + if (!res.ok) throw new Error(`create room failed: ${await res.text()}`); + return res.json(); +} + +export async function createPeer(roomId: string, peerName: string): Promise { + const res = await fetch(`${backendUrl}/api/rooms/${roomId}/peers`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ peerName }), + }); + if (!res.ok) throw new Error(`create peer failed: ${await res.text()}`); + return res.json(); +} diff --git a/conference-to-stream/web/src/components/Conference.tsx b/conference-to-stream/web/src/components/Conference.tsx new file mode 100644 index 0000000..16fc010 --- /dev/null +++ b/conference-to-stream/web/src/components/Conference.tsx @@ -0,0 +1,112 @@ +import { + useCamera, + useConnection, + useMicrophone, + usePeers, +} from "@fishjam-cloud/react-client"; +import { PeerTile } from "./PeerTile"; +import { WhepPlayer } from "./WhepPlayer"; + +type Props = { + whepUrl: string; + roomName: string; + peerName: string; + onLeave: () => void; +}; + +export function Conference({ whepUrl, roomName, peerName, onLeave }: Props) { + const { leaveRoom } = useConnection(); + const { isCameraOn, toggleCamera, cameraStream } = useCamera(); + const { isMicrophoneMuted, toggleMicrophoneMute } = useMicrophone(); + const { localPeer, remotePeers } = usePeers<{ name: string }>(); + const whepPlayToken = import.meta.env.VITE_VDO_NINJA_WHEPPLAY_TOKEN as string | undefined; + + const vdoNinjaParams = new URLSearchParams({ + whepplay: whepUrl, + stereo: "2", + whepwait: "0", + }); + if (whepPlayToken) { + vdoNinjaParams.set("whepplaytoken", whepPlayToken); + } + const vdoNinjaUrl = `https://vdo.ninja/?${vdoNinjaParams.toString()}`; + + async function handleLeave() { + try { + await leaveRoom(); + } catch (e) { + console.error("Failed to leave room:", e); + } + onLeave(); + } + + return ( +
+ {/* Header */} +
+

{roomName}

+
+ + + +
+
+ + {/* Main content */} +
+ {/* Peer grid */} +
+

Conference

+
+ + {remotePeers.map((peer) => ( + + ))} +
+
+ + {/* WHEP preview */} +
+

Live Stream Preview

+ + + Open in vdo.ninja player + +

Composed stream via Foundry

+
+
+
+ ); +} diff --git a/conference-to-stream/web/src/components/JoinForm.tsx b/conference-to-stream/web/src/components/JoinForm.tsx new file mode 100644 index 0000000..91a4f2e --- /dev/null +++ b/conference-to-stream/web/src/components/JoinForm.tsx @@ -0,0 +1,86 @@ +import { useConnection, useInitializeDevices } from "@fishjam-cloud/react-client"; +import { useEffect, useState } from "react"; +import { createPeer, createRoom } from "../api"; + +type Props = { + initialRoomName?: string; + onJoined: (result: { whepUrl: string; roomName: string; peerName: string }) => void; +}; + +export function JoinForm({ initialRoomName, onJoined }: Props) { + const { joinRoom } = useConnection(); + const { initializeDevices } = useInitializeDevices(); + const [roomName, setRoomName] = useState(initialRoomName ?? ""); + const [peerName, setPeerName] = useState(""); + const [error, setError] = useState(""); + const [loading, setLoading] = useState(false); + + useEffect(() => { + initializeDevices({ enableVideo: true, enableAudio: true }); + }, [initializeDevices]); + + async function handleSubmit(e: React.FormEvent) { + e.preventDefault(); + if (!roomName.trim() || !peerName.trim()) { + setError("Please fill in both fields."); + return; + } + setError(""); + setLoading(true); + try { + const { roomId, whepUrl } = await createRoom(roomName.trim()); + const { peerToken } = await createPeer(roomId, peerName.trim()); + await joinRoom({ peerToken, peerMetadata: { name: peerName.trim() } }); + onJoined({ whepUrl, roomName: roomName.trim(), peerName: peerName.trim() }); + } catch (err) { + setError(err instanceof Error ? err.message : "Something went wrong."); + } finally { + setLoading(false); + } + } + + return ( +
+
+

Conference to Stream

+ + + + + + {error &&

{error}

} + + +
+
+ ); +} diff --git a/conference-to-stream/web/src/components/PeerTile.tsx b/conference-to-stream/web/src/components/PeerTile.tsx new file mode 100644 index 0000000..ea008c9 --- /dev/null +++ b/conference-to-stream/web/src/components/PeerTile.tsx @@ -0,0 +1,48 @@ +import { useEffect, useRef } from "react"; + +type Props = { + stream?: MediaStream; + audioStream?: MediaStream; + name: string; +}; + +export function PeerTile({ stream, audioStream, name }: Props) { + const videoRef = useRef(null); + const audioRef = useRef(null); + + useEffect(() => { + if (videoRef.current && stream) { + videoRef.current.srcObject = stream; + } + }, [stream]); + + useEffect(() => { + if (audioRef.current && audioStream) { + audioRef.current.srcObject = audioStream; + } + }, [audioStream]); + + return ( +
+ {stream ? ( +
+ ); +} diff --git a/conference-to-stream/web/src/components/WhepPlayer.tsx b/conference-to-stream/web/src/components/WhepPlayer.tsx new file mode 100644 index 0000000..5a52c74 --- /dev/null +++ b/conference-to-stream/web/src/components/WhepPlayer.tsx @@ -0,0 +1,53 @@ +import { useEffect, useRef, useState } from "react"; +import { initializeWhep } from "../whep"; + +type Props = { + url: string; +}; + +export function WhepPlayer({ url }: Props) { + const videoRef = useRef(null); + const [error, setError] = useState(""); + + useEffect(() => { + let cancelled = false; + let peerConnection: RTCPeerConnection | null = null; + + initializeWhep(url) + .then(({ stream, peer }) => { + peerConnection = peer; + if (!cancelled && videoRef.current) { + videoRef.current.srcObject = stream; + } else { + peer.close(); + } + }) + .catch((err) => { + if (!cancelled) { + setError(err instanceof Error ? err.message : "WHEP connection failed"); + } + }); + + return () => { + cancelled = true; + peerConnection?.close(); + }; + }, [url]); + + if (error) { + return ( +
+ {error} +
+ ); + } + + return ( +