diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..7173268 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "conference-to-stream/backend/oapi-codegen"] + path = conference-to-stream/backend/oapi-codegen + url = https://github.com/roznawsk/oapi-codegen +[submodule "conference-to-stream/backend/protos"] + path = conference-to-stream/backend/protos + url = https://github.com/fishjam-cloud/protos.git diff --git a/conference-to-stream/.env.example b/conference-to-stream/.env.example new file mode 100644 index 0000000..3189cc0 --- /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://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..7472cef --- /dev/null +++ b/conference-to-stream/README.md @@ -0,0 +1,89 @@ +# Conference to Stream + +A demo showcasing Fishjam's track forwarding capability combined with [Composition API](https://fishjam.io/docs/composition-api/introduction) for real-time video composition. Participants join a video conference, their tracks are automatically forwarded to Composition API, composed into a single stream using a Tiles layout, and made available as a WHEP stream that can be previewed alongside the conference. + +## How It Works + +1. The backend creates a Composition API composition and a Fishjam conference room with track forwarding enabled. +2. When a participant joins and publishes their camera/microphone, Fishjam forwards the tracks to Composition API. +3. The backend listens for `TrackForwarding` notifications via WebSocket and updates the Composition API composition layout (Tiles grid + audio mix). +4. The frontend displays the conference (via Fishjam React SDK) side-by-side with a live WHEP preview of the composed stream. + +## Running Locally + +Before running, copy `.env.example` to `.env` and set the following values: + +```bash +# 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://rtc.fishjam.io) +COMPOSITION_API_URL=https://rtc.fishjam.io + +# Backend port (default: 8080) +PORT=8080 + +# Frontend: backend URL +VITE_BACKEND_URL=http://localhost:8080 +``` + +You can get `FISHJAM_ID` and `FISHJAM_MANAGEMENT_TOKEN` for free by logging in at . + +### Docker Compose (Recommended) + +The easiest way to run the app is with [Docker Compose](https://docs.docker.com/compose/install/). + +```bash +docker compose --env-file .env up --build +``` + +The web UI will be available at and the backend at . + +### Running Manually + +#### Requirements +- [Go](https://go.dev/dl/) `>= 1.24` +- [Node.js](https://nodejs.org/en/download) `>= 22` + +#### Backend + +```bash +cd backend +go run main.go +``` + +The server starts on by default. + +#### Frontend + +```bash +cd web +npm install +npm run dev +``` + +Open the UI at . + +## Repo Structure + +- `backend/` — Go server that orchestrates Fishjam rooms and Composition API compositions. + - `composition/` — HTTP client for Composition API (create, start, update output). + - `fishjam/` — REST client for rooms, peers, and track forwarding (generated via `oapi-codegen`) + WebSocket notification listener. + - `handler/` — HTTP handlers and in-memory room state management. + - `proto/` — Generated protobuf Go code for Fishjam server notifications. +- `web/` — React + Vite frontend. + - `src/components/JoinForm.tsx` — Room name and user name form. + - `src/components/Conference.tsx` — Peer grid with camera/mic controls + WHEP preview sidebar. + - `src/components/WhepPlayer.tsx` — Live stream player using `@fishjam-cloud/react-client`. + - `src/api.ts` — API client for communicating with the Go backend. + +### Tech Stack + +- [Fishjam](https://fishjam.io) for real-time videoconferencing and track forwarding. +- [Composition API](https://fishjam.io/docs/composition-api/introduction) for real-time video composition. +- Go backend with `oapi-codegen` generated REST client and WebSocket for notifications. +- React + Vite frontend with `@fishjam-cloud/react-client`. +- Tailwind CSS v4 for styling. 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://://://= 300 { + return fmt.Errorf("start composition: unexpected status %d: %s", statusCode, string(respBody)) + } + + return nil +} + +// DeleteComposition deletes a composition by ID. +func (c *Client) DeleteComposition(apiURL, compositionID string) error { + path := fmt.Sprintf("/api/composition/%s", compositionID) + respBody, statusCode, err := c.doRequest(context.Background(), apiURL, "DELETE", path, nil) + if err != nil { + return err + } + + if statusCode < 200 || statusCode >= 300 { + return fmt.Errorf("delete composition: unexpected status %d: %s", statusCode, string(respBody)) + } + + return nil +} + +// RegisterWhepOutput registers a WHEP server output on the composition. +func (c *Client) RegisterWhepOutput(apiURL, compositionID, outputID string) error { + var initialVideoRoot Component + if err := initialVideoRoot.FromView(View{}); err != nil { + return fmt.Errorf("build initial video root: %w", err) + } + + var audioEncoder WhepAudioEncoderOptions + if err := audioEncoder.FromWhepAudioEncoderOptions0(WhepAudioEncoderOptionsOpus{ + Type: WhepAudioEncoderOptions0TypeOpus, + }); err != nil { + return fmt.Errorf("build audio encoder: %w", err) + } + + stereo := Stereo + + var body RegisterOutput + if err := body.FromWhepOutput(WhepOutput{ + Video: &OutputWhepVideoOptions{ + Resolution: Resolution{Width: 1920, Height: 1080}, + Initial: VideoScene{Root: initialVideoRoot}, + }, + Audio: &OutputWhepAudioOptions{ + Encoder: &audioEncoder, + Channels: &stereo, + Initial: AudioScene{Inputs: []AudioSceneInput{}}, + }, + }); err != nil { + return fmt.Errorf("build register output body: %w", err) + } + + path := fmt.Sprintf("/api/composition/%s/output/%s/register", compositionID, outputID) + respBody, statusCode, err := c.doRequest(context.Background(), apiURL, "POST", path, body) + if err != nil { + return err + } + + if statusCode < 200 || statusCode >= 300 { + return fmt.Errorf("register whep output: unexpected status %d: %s", statusCode, string(respBody)) + } + + return nil +} + +// UpdateOutput updates a composition output with the given set of inputs. +func (c *Client) UpdateOutput(apiURL, compositionID, outputID string, inputs []InputEntry) error { + var videoRoot Component + audioInputs := make([]AudioSceneInput, 0, len(inputs)) + + if len(inputs) == 0 { + if err := videoRoot.FromView(View{}); err != nil { + return fmt.Errorf("build video root: %w", err) + } + } else { + tileChildren := make([]Component, 0, len(inputs)) + for _, entry := range inputs { + tile, err := buildParticipantTile(entry) + if err != nil { + return err + } + tileChildren = append(tileChildren, tile) + audioInputs = append(audioInputs, AudioSceneInput{InputId: entry.InputID}) + } + bgColor := RGBAColor("#000000FF") + ratio := AspectRatio("16:9") + if err := videoRoot.FromTiles(Tiles{ + Children: &tileChildren, + BackgroundColor: &bgColor, + TileAspectRatio: &ratio, + }); err != nil { + return fmt.Errorf("build tiles component: %w", err) + } + } + + req := UpdateOutputRequest{ + Video: &VideoScene{Root: videoRoot}, + Audio: &AudioScene{Inputs: audioInputs}, + } + + path := fmt.Sprintf("/api/composition/%s/output/%s/update", compositionID, outputID) + respBody, statusCode, err := c.doRequest(context.Background(), apiURL, "POST", path, req) + if err != nil { + return err + } + + if statusCode < 200 || statusCode >= 300 { + return fmt.Errorf("update output: unexpected status %d: %s", statusCode, string(respBody)) + } + + 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) (Component, error) { + // InputStream + var inputStream Component + if err := inputStream.FromInputStream(InputStream{ + InputId: entry.InputID, + }); err != nil { + return Component{}, fmt.Errorf("build input stream: %w", err) + } + + viewChildren := []Component{inputStream} + + // Name label overlay (only if name is non-empty) + if entry.PeerName != "" { + var textComp Component + fontSize := float32(24) + textColor := RGBAColor("#FFFFFFFF") + weight := TextWeightBold + align := HorizontalAlignCenter + labelWidth := float32(1280) + if err := textComp.FromText(Text{ + Text: entry.PeerName, + FontSize: fontSize, + Color: &textColor, + Weight: &weight, + Align: &align, + Width: &labelWidth, + }); err != nil { + return Component{}, fmt.Errorf("build text component: %w", err) + } + + labelChildren := []Component{textComp} + labelBg := RGBAColor("#00000088") + bottom := float32(0) + left := float32(0) + labelHeight := float32(40) + var labelView Component + if err := labelView.FromView(View{ + Children: &labelChildren, + Bottom: &bottom, + Left: &left, + Width: &labelWidth, + Height: &labelHeight, + BackgroundColor: &labelBg, + }); err != nil { + return Component{}, fmt.Errorf("build label view: %w", err) + } + + viewChildren = append(viewChildren, labelView) + } + + // Outer View wrapping input + label + overflow := OverflowHidden + viewWidth := float32(1280) + viewHeight := float32(720) + var outerView Component + if err := outerView.FromView(View{ + Children: &viewChildren, + Width: &viewWidth, + Height: &viewHeight, + Overflow: &overflow, + }); err != nil { + return Component{}, fmt.Errorf("build outer view: %w", err) + } + + // Rescaler + mode := RescaleModeFit + var rescaler Component + if err := rescaler.FromRescaler(Rescaler{ + Child: outerView, + Mode: &mode, + }); err != nil { + return Component{}, fmt.Errorf("build rescaler: %w", err) + } + + return rescaler, nil +} + +// RegisterWhipOutput registers a WHIP output on the composition that pushes to an external WHIP endpoint. +func (c *Client) RegisterWhipOutput(apiURL, compositionID, outputID, whipEndpointURL, bearerToken string) error { + var initialVideoRoot Component + if err := initialVideoRoot.FromView(View{}); err != nil { + return fmt.Errorf("build initial video root: %w", err) + } + + var body RegisterOutput + if err := body.FromWhipOutput(WhipOutput{ + EndpointUrl: whipEndpointURL, + BearerToken: &bearerToken, + Video: &OutputWhipVideoOptions{ + Resolution: Resolution{Width: 1920, Height: 1080}, + Initial: VideoScene{Root: initialVideoRoot}, + }, + Audio: &OutputWhipAudioOptions{ + Initial: AudioScene{Inputs: []AudioSceneInput{}}, + }, + }); err != nil { + return fmt.Errorf("build register whip output body: %w", err) + } + + path := fmt.Sprintf("/api/composition/%s/output/%s/register", compositionID, outputID) + respBody, statusCode, err := c.doRequest(context.Background(), apiURL, "POST", path, body) + if err != nil { + return err + } + + if statusCode < 200 || statusCode >= 300 { + return fmt.Errorf("register whip output: unexpected status %d: %s", statusCode, string(respBody)) + } + return nil +} + +// 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/models.go b/conference-to-stream/backend/composition/models.go new file mode 100644 index 0000000..c23287d --- /dev/null +++ b/conference-to-stream/backend/composition/models.go @@ -0,0 +1,393 @@ +package composition + +import ( + "encoding/json" + "fmt" +) + +// Common Types +type CompositionId = string +type ComponentId = string +type InputId = string +type OutputId = string +type RGBAColor string +type AspectRatio string + +type Resolution struct { + Width int `json:"width"` + Height int `json:"height"` +} + +// Enums +type AudioChannels string + +const ( + Mono AudioChannels = "mono" + Stereo AudioChannels = "stereo" +) + +type AudioMixingStrategy string + +const ( + SumClip AudioMixingStrategy = "sum_clip" + SumScale AudioMixingStrategy = "sum_scale" +) + +type RescaleMode string + +const ( + RescaleModeFit RescaleMode = "fit" + RescaleModeFill RescaleMode = "fill" +) + +type HorizontalAlign string + +const ( + HorizontalAlignLeft HorizontalAlign = "left" + HorizontalAlignRight HorizontalAlign = "right" + HorizontalAlignJustified HorizontalAlign = "justified" + HorizontalAlignCenter HorizontalAlign = "center" +) + +type VerticalAlign string + +const ( + VerticalAlignTop VerticalAlign = "top" + VerticalAlignCenter VerticalAlign = "center" + VerticalAlignBottom VerticalAlign = "bottom" + VerticalAlignJustified VerticalAlign = "justified" +) + +type Overflow string + +const ( + OverflowVisible Overflow = "visible" + OverflowHidden Overflow = "hidden" + OverflowFit Overflow = "fit" +) + +type TextWeight string + +const ( + TextWeightThin TextWeight = "thin" + TextWeightExtraLight TextWeight = "extra_light" + TextWeightLight TextWeight = "light" + TextWeightNormal TextWeight = "normal" + TextWeightMedium TextWeight = "medium" + TextWeightSemiBold TextWeight = "semi_bold" + TextWeightBold TextWeight = "bold" + TextWeightExtraBold TextWeight = "extra_bold" + TextWeightBlack TextWeight = "black" +) + +type TextStyle string + +const ( + TextStyleNormal TextStyle = "normal" + TextStyleItalic TextStyle = "italic" + TextStyleOblique TextStyle = "oblique" +) + +type TextWrapMode string + +const ( + TextWrapModeNone TextWrapMode = "none" + TextWrapModeGlyph TextWrapMode = "glyph" + TextWrapModeWord TextWrapMode = "word" +) + +// API Requests & Responses +type CreateCompositionRequest struct { + Autostart *bool `json:"autostart,omitempty"` +} + +type CompositionCreatedResponse struct { + CompositionId CompositionId `json:"composition_id"` + ApiUrl string `json:"api_url"` +} + +// Scenes +type AudioScene struct { + Inputs []AudioSceneInput `json:"inputs"` +} + +type AudioSceneInput struct { + InputId InputId `json:"input_id"` + Volume *float32 `json:"volume,omitempty"` +} + +type VideoScene struct { + Root Component `json:"root"` +} + +// Components +type Component struct { + Type string `json:"type"` + InputStream *InputStream `json:"-"` + View *View `json:"-"` + Text *Text `json:"-"` + Tiles *Tiles `json:"-"` + Rescaler *Rescaler `json:"-"` +} + +func (c Component) MarshalJSON() ([]byte, error) { + var data interface{} + switch c.Type { + case "input_stream": + data = c.InputStream + case "view": + data = c.View + case "text": + data = c.Text + case "tiles": + data = c.Tiles + case "rescaler": + data = c.Rescaler + default: + return nil, fmt.Errorf("unknown component type: %s", c.Type) + } + + b, err := json.Marshal(data) + if err != nil { + return nil, err + } + + var m map[string]interface{} + if err := json.Unmarshal(b, &m); err != nil { + return nil, err + } + m["type"] = c.Type + return json.Marshal(m) +} + +func (c *Component) UnmarshalJSON(data []byte) error { + var m map[string]interface{} + if err := json.Unmarshal(data, &m); err != nil { + return err + } + t, ok := m["type"].(string) + if !ok { + return fmt.Errorf("missing component type") + } + c.Type = t + switch t { + case "input_stream": + c.InputStream = &InputStream{} + return json.Unmarshal(data, c.InputStream) + case "view": + c.View = &View{} + return json.Unmarshal(data, c.View) + case "text": + c.Text = &Text{} + return json.Unmarshal(data, c.Text) + case "tiles": + c.Tiles = &Tiles{} + return json.Unmarshal(data, c.Tiles) + case "rescaler": + c.Rescaler = &Rescaler{} + return json.Unmarshal(data, c.Rescaler) + } + return nil +} + +func (c *Component) FromInputStream(v InputStream) error { + c.Type = "input_stream" + c.InputStream = &v + return nil +} + +func (c *Component) FromView(v View) error { + c.Type = "view" + c.View = &v + return nil +} + +func (c *Component) FromText(v Text) error { + c.Type = "text" + c.Text = &v + return nil +} + +func (c *Component) FromTiles(v Tiles) error { + c.Type = "tiles" + c.Tiles = &v + return nil +} + +func (c *Component) FromRescaler(v Rescaler) error { + c.Type = "rescaler" + c.Rescaler = &v + return nil +} + +type InputStream struct { + Id *ComponentId `json:"id,omitempty"` + InputId InputId `json:"input_id"` +} + +type View struct { + Id *ComponentId `json:"id,omitempty"` + Children *[]Component `json:"children,omitempty"` + Width *float32 `json:"width,omitempty"` + Height *float32 `json:"height,omitempty"` + Top *float32 `json:"top,omitempty"` + Left *float32 `json:"left,omitempty"` + Bottom *float32 `json:"bottom,omitempty"` + Right *float32 `json:"right,omitempty"` + Rotation *float32 `json:"rotation,omitempty"` + BackgroundColor *RGBAColor `json:"background_color,omitempty"` + Overflow *Overflow `json:"overflow,omitempty"` + BorderRadius *float32 `json:"border_radius,omitempty"` + BorderWidth *float32 `json:"border_width,omitempty"` + BorderColor *RGBAColor `json:"border_color,omitempty"` + Padding *float32 `json:"padding,omitempty"` +} + +type Text struct { + Id *ComponentId `json:"id,omitempty"` + Text string `json:"text"` + FontSize float32 `json:"font_size"` + LineHeight *float32 `json:"line_height,omitempty"` + Color *RGBAColor `json:"color,omitempty"` + BackgroundColor *RGBAColor `json:"background_color,omitempty"` + FontFamily *string `json:"font_family,omitempty"` + Style *TextStyle `json:"style,omitempty"` + Weight *TextWeight `json:"weight,omitempty"` + Align *HorizontalAlign `json:"align,omitempty"` + Width *float32 `json:"width,omitempty"` + Height *float32 `json:"height,omitempty"` +} + +type Tiles struct { + Id *ComponentId `json:"id,omitempty"` + Children *[]Component `json:"children,omitempty"` + Width *float32 `json:"width,omitempty"` + Height *float32 `json:"height,omitempty"` + BackgroundColor *RGBAColor `json:"background_color,omitempty"` + TileAspectRatio *AspectRatio `json:"tile_aspect_ratio,omitempty"` + Margin *float32 `json:"margin,omitempty"` + Padding *float32 `json:"padding,omitempty"` + HorizontalAlign *HorizontalAlign `json:"horizontal_align,omitempty"` + VerticalAlign *VerticalAlign `json:"vertical_align,omitempty"` +} + +type Rescaler struct { + Id *ComponentId `json:"id,omitempty"` + Child Component `json:"child"` + Mode *RescaleMode `json:"mode,omitempty"` + HorizontalAlign *HorizontalAlign `json:"horizontal_align,omitempty"` + VerticalAlign *VerticalAlign `json:"vertical_align,omitempty"` + Width *float32 `json:"width,omitempty"` + Height *float32 `json:"height,omitempty"` +} + +// Output Registration +type RegisterOutput struct { + Type string `json:"type"` + WhepOutput *WhepOutput `json:"-"` + WhipOutput *WhipOutput `json:"-"` +} + +func (r RegisterOutput) MarshalJSON() ([]byte, error) { + var data interface{} + switch r.Type { + case "whep_server": + data = r.WhepOutput + case "whip_client": + data = r.WhipOutput + default: + return nil, fmt.Errorf("unknown register output type: %s", r.Type) + } + + b, err := json.Marshal(data) + if err != nil { + return nil, err + } + + var m map[string]interface{} + if err := json.Unmarshal(b, &m); err != nil { + return nil, err + } + m["type"] = r.Type + return json.Marshal(m) +} + +func (r *RegisterOutput) FromWhepOutput(v WhepOutput) error { + r.Type = "whep_server" + r.WhepOutput = &v + return nil +} + +func (r *RegisterOutput) FromWhipOutput(v WhipOutput) error { + r.Type = "whip_client" + r.WhipOutput = &v + return nil +} + +type OutputEndCondition struct { + AnyOf []InputId `json:"any_of,omitempty"` + AllOf []InputId `json:"all_of,omitempty"` + AnyInput *bool `json:"any_input,omitempty"` + AllInputs *bool `json:"all_inputs,omitempty"` +} + +type WhepOutput struct { + Video *OutputWhepVideoOptions `json:"video,omitempty"` + Audio *OutputWhepAudioOptions `json:"audio,omitempty"` +} + +type OutputWhepVideoOptions struct { + Resolution Resolution `json:"resolution"` + Initial VideoScene `json:"initial"` + SendEosWhen *OutputEndCondition `json:"send_eos_when,omitempty"` +} + +type OutputWhepAudioOptions struct { + MixingStrategy *AudioMixingStrategy `json:"mixing_strategy,omitempty"` + Channels *AudioChannels `json:"channels,omitempty"` + Initial AudioScene `json:"initial"` + Encoder *WhepAudioEncoderOptions `json:"encoder,omitempty"` + SendEosWhen *OutputEndCondition `json:"send_eos_when,omitempty"` +} + +type WhipOutput struct { + EndpointUrl string `json:"endpoint_url"` + BearerToken *string `json:"bearer_token,omitempty"` + Video *OutputWhipVideoOptions `json:"video,omitempty"` + Audio *OutputWhipAudioOptions `json:"audio,omitempty"` +} + +type OutputWhipVideoOptions struct { + Resolution Resolution `json:"resolution"` + Initial VideoScene `json:"initial"` + SendEosWhen *OutputEndCondition `json:"send_eos_when,omitempty"` +} + +type OutputWhipAudioOptions struct { + MixingStrategy *AudioMixingStrategy `json:"mixing_strategy,omitempty"` + Channels *AudioChannels `json:"channels,omitempty"` + Initial AudioScene `json:"initial"` + SendEosWhen *OutputEndCondition `json:"send_eos_when,omitempty"` +} + +type WhepAudioEncoderOptions struct { + Type string `json:"type"` +} + +func (o *WhepAudioEncoderOptions) FromWhepAudioEncoderOptions0(v WhepAudioEncoderOptionsOpus) error { + o.Type = "opus" + return nil +} + +type WhepAudioEncoderOptionsOpus struct { + Type string `json:"type"` +} + +const ( + WhepAudioEncoderOptions0TypeOpus = "opus" +) + +type UpdateOutputRequest struct { + Video *VideoScene `json:"video,omitempty"` + Audio *AudioScene `json:"audio,omitempty"` +} diff --git a/conference-to-stream/backend/composition/openapi.json b/conference-to-stream/backend/composition/openapi.json new file mode 100644 index 0000000..5b4496c --- /dev/null +++ b/conference-to-stream/backend/composition/openapi.json @@ -0,0 +1,4296 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Composition API", + "description": "Real-time video compositing", + "license": { + "name": "Apache 2.0", + "url": "https://www.apache.org/licenses/LICENSE-2.0" + }, + "version": "0.1.0" + }, + "servers": [ + { + "url": "https://rtc.fishjam.io" + } + ], + "paths": { + "/api/composition": { + "post": { + "tags": [ + "composition" + ], + "operationId": "create_composition", + "requestBody": { + "description": "Composition creation options.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateCompositionRequest" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Composition created.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CompositionCreatedResponse" + } + } + } + }, + "401": { + "description": "Unauthorized.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/api/composition/{composition_id}": { + "delete": { + "tags": [ + "composition" + ], + "operationId": "delete_composition", + "parameters": [ + { + "name": "composition_id", + "in": "path", + "description": "Composition ID.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Composition deleted." + }, + "401": { + "description": "Unauthorized.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "404": { + "description": "Composition not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/api/composition/{composition_id}/start": { + "post": { + "tags": [ + "control_request" + ], + "operationId": "start", + "parameters": [ + { + "name": "composition_id", + "in": "path", + "description": "Composition ID.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Composition started.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Response" + } + } + } + }, + "401": { + "description": "Unauthorized.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "404": { + "description": "Composition not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/api/composition/{composition_id}/reset": { + "post": { + "tags": [ + "control_request" + ], + "operationId": "reset", + "parameters": [ + { + "name": "composition_id", + "in": "path", + "description": "Composition ID.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Composition reset.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Response" + } + } + } + }, + "401": { + "description": "Unauthorized.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "404": { + "description": "Composition not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/api/composition/{composition_id}/input/{input_id}/register": { + "post": { + "tags": [ + "register_request" + ], + "operationId": "register_input", + "parameters": [ + { + "name": "composition_id", + "in": "path", + "description": "Composition ID.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "input_id", + "in": "path", + "description": "Input ID.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RegisterInput" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Input registered successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Response" + } + } + } + }, + "400": { + "description": "Bad request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "401": { + "description": "Unauthorized.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "404": { + "description": "Composition not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/api/composition/{composition_id}/output/{output_id}/register": { + "post": { + "tags": [ + "register_request" + ], + "operationId": "register_output", + "parameters": [ + { + "name": "composition_id", + "in": "path", + "description": "Composition ID.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "output_id", + "in": "path", + "description": "Output ID.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RegisterOutput" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Output registered successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Response" + } + } + } + }, + "400": { + "description": "Bad request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "401": { + "description": "Unauthorized.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "404": { + "description": "Composition not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/api/composition/{composition_id}/image/{image_id}/register": { + "post": { + "tags": [ + "register_request" + ], + "operationId": "register_image", + "parameters": [ + { + "name": "composition_id", + "in": "path", + "description": "Composition ID.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "image_id", + "in": "path", + "description": "Image ID.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ImageSpec" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Image registered successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Response" + } + } + } + }, + "400": { + "description": "Bad request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "401": { + "description": "Unauthorized.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "404": { + "description": "Composition not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/api/composition/{composition_id}/font/register": { + "post": { + "tags": [ + "register_request" + ], + "operationId": "register_font", + "parameters": [ + { + "name": "composition_id", + "in": "path", + "description": "Composition ID.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "required": [ + "font" + ], + "properties": { + "font": { + "type": "string", + "format": "binary" + } + } + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Font registered successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Response" + } + } + } + }, + "400": { + "description": "Bad request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "401": { + "description": "Unauthorized.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "404": { + "description": "Composition not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/api/composition/{composition_id}/input/{input_id}/unregister": { + "post": { + "tags": [ + "unregister_request" + ], + "operationId": "unregister_input", + "parameters": [ + { + "name": "composition_id", + "in": "path", + "description": "Composition ID.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "input_id", + "in": "path", + "description": "Input ID.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnregisterInput" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Input unregistered successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Response" + } + } + } + }, + "400": { + "description": "Bad request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "401": { + "description": "Unauthorized.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "404": { + "description": "Input not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/api/composition/{composition_id}/output/{output_id}/unregister": { + "post": { + "tags": [ + "unregister_request" + ], + "operationId": "unregister_output", + "parameters": [ + { + "name": "composition_id", + "in": "path", + "description": "Composition ID.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "output_id", + "in": "path", + "description": "Output ID.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnregisterOutput" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Output unregistered successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Response" + } + } + } + }, + "400": { + "description": "Bad request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "401": { + "description": "Unauthorized.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "404": { + "description": "Output not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/api/composition/{composition_id}/image/{image_id}/unregister": { + "post": { + "tags": [ + "unregister_request" + ], + "operationId": "unregister_image", + "parameters": [ + { + "name": "composition_id", + "in": "path", + "description": "Composition ID.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "image_id", + "in": "path", + "description": "Image ID.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnregisterRenderer" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Image unregistered successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Response" + } + } + } + }, + "400": { + "description": "Bad request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "401": { + "description": "Unauthorized.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "404": { + "description": "Image not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/api/composition/{composition_id}/output/{output_id}/update": { + "post": { + "tags": [ + "update_request" + ], + "operationId": "update_output", + "parameters": [ + { + "name": "composition_id", + "in": "path", + "description": "Composition ID.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "output_id", + "in": "path", + "description": "Output ID.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateOutputRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Output updated successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Response" + } + } + } + }, + "400": { + "description": "Bad request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "401": { + "description": "Unauthorized.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "404": { + "description": "Composition not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/api/composition/{composition_id}/output/{output_id}/request_keyframe": { + "post": { + "tags": [ + "update_request" + ], + "operationId": "request_keyframe", + "parameters": [ + { + "name": "composition_id", + "in": "path", + "description": "Composition ID.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "output_id", + "in": "path", + "description": "Output ID.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Keyframe request successful.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Response" + } + } + } + }, + "400": { + "description": "Bad request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "401": { + "description": "Unauthorized.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "404": { + "description": "Composition not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/api/composition/{composition_id}/whip/{input_id}": { + "post": { + "tags": [ + "whip_whep" + ], + "operationId": "whip_offer", + "parameters": [ + { + "name": "composition_id", + "in": "path", + "description": "Composition ID.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "input_id", + "in": "path", + "description": "Input ID.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "SDP offer.", + "content": { + "application/sdp": { + "schema": { + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Session created.", + "headers": { + "location": { + "schema": { + "type": "string" + }, + "description": "Session URL." + } + }, + "content": { + "application/sdp": { + "schema": { + "type": "string" + } + } + } + }, + "400": { + "description": "Bad request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "401": { + "description": "Unauthorized.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "404": { + "description": "Composition or input not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + } + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/api/composition/{composition_id}/whep/{output_id}": { + "post": { + "tags": [ + "whip_whep" + ], + "operationId": "whep_offer", + "parameters": [ + { + "name": "composition_id", + "in": "path", + "description": "Composition ID.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "output_id", + "in": "path", + "description": "Output ID.", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "SDP offer.", + "content": { + "application/sdp": { + "schema": { + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Session created.", + "headers": { + "location": { + "schema": { + "type": "string" + }, + "description": "Session URL." + } + }, + "content": { + "application/sdp": { + "schema": { + "type": "string" + } + } + } + }, + "400": { + "description": "Bad request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "401": { + "description": "Unauthorized.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "404": { + "description": "Composition or output not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "500": { + "description": "Internal server error.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + } + }, + "security": [ + {}, + { + "BearerAuth": [] + } + ] + } + } + }, + "components": { + "schemas": { + "ApiError": { + "type": "object", + "required": [ + "message", + "http_status_code" + ], + "properties": { + "message": { + "type": "string" + }, + "http_status_code": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + } + }, + "AspectRatio": { + "type": "string" + }, + "AudioChannels": { + "type": "string", + "enum": [ + "mono", + "stereo" + ] + }, + "AudioMixingStrategy": { + "type": "string", + "enum": [ + "sum_clip", + "sum_scale" + ] + }, + "AudioScene": { + "type": "object", + "required": [ + "inputs" + ], + "properties": { + "inputs": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AudioSceneInput" + } + } + }, + "additionalProperties": false + }, + "AudioSceneInput": { + "type": "object", + "required": [ + "input_id" + ], + "properties": { + "input_id": { + "$ref": "#/components/schemas/InputId" + }, + "volume": { + "type": [ + "number", + "null" + ], + "format": "float", + "description": "(**default=`1.0`**) float in `[0, 2]` range representing input volume" + } + }, + "additionalProperties": false + }, + "BoxShadow": { + "type": "object", + "properties": { + "offset_x": { + "type": [ + "number", + "null" + ], + "format": "float" + }, + "offset_y": { + "type": [ + "number", + "null" + ], + "format": "float" + }, + "color": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/RGBAColor" + } + ] + }, + "blur_radius": { + "type": [ + "number", + "null" + ], + "format": "float" + } + }, + "additionalProperties": false + }, + "Component": { + "oneOf": [ + { + "allOf": [ + { + "$ref": "#/components/schemas/InputStream" + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "input_stream" + ] + } + } + } + ] + }, + { + "allOf": [ + { + "$ref": "#/components/schemas/View" + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "view" + ] + } + } + } + ] + }, + { + "allOf": [ + { + "$ref": "#/components/schemas/Text" + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "text" + ] + } + } + } + ] + }, + { + "allOf": [ + { + "$ref": "#/components/schemas/Tiles" + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "tiles" + ] + } + } + } + ] + }, + { + "allOf": [ + { + "$ref": "#/components/schemas/Rescaler" + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "rescaler" + ] + } + } + } + ] + } + ] + }, + "ComponentId": { + "type": "string" + }, + "CompositionCreatedResponse": { + "type": "object", + "required": [ + "composition_id", + "api_url" + ], + "properties": { + "composition_id": { + "$ref": "#/components/schemas/CompositionId" + }, + "api_url": { + "type": "string" + } + } + }, + "CompositionId": { + "type": "string" + }, + "CreateCompositionRequest": { + "type": "object", + "properties": { + "autostart": { + "type": "boolean", + "description": "If true, outputs will immediately start producing audio and video.\nIf false, call `POST /api/composition/{composition_id}/start` to start the composition.", + "default": true + } + } + }, + "EasingFunction": { + "oneOf": [ + { + "type": "object", + "required": [ + "function_name" + ], + "properties": { + "function_name": { + "type": "string", + "enum": [ + "linear" + ] + } + } + }, + { + "type": "object", + "required": [ + "function_name" + ], + "properties": { + "function_name": { + "type": "string", + "enum": [ + "bounce" + ] + } + } + }, + { + "type": "object", + "required": [ + "points", + "function_name" + ], + "properties": { + "points": { + "type": "array", + "items": { + "type": "number", + "format": "double" + } + }, + "function_name": { + "type": "string", + "enum": [ + "cubic_bezier" + ] + } + } + } + ], + "description": "Easing functions are used to interpolate between two values over time.\n\nCustom easing functions can be implemented with cubic Bézier.\nThe 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]`.\nYou can find example control point configurations [here](https://easings.net/)." + }, + "FontUpload": { + "type": "object", + "required": [ + "font" + ], + "properties": { + "font": { + "type": "string", + "format": "binary" + } + } + }, + "Framerate": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "integer", + "format": "int32", + "minimum": 0 + } + ] + }, + "H264EncoderPreset": { + "type": "string", + "enum": [ + "ultrafast", + "superfast", + "veryfast", + "faster", + "fast", + "medium", + "slow", + "slower", + "veryslow", + "placebo" + ] + }, + "HlsInput": { + "type": "object", + "description": "Parameters for an input stream from HLS source.", + "required": [ + "url" + ], + "properties": { + "url": { + "type": "string", + "description": "URL to HLS playlist" + }, + "required": { + "type": [ + "boolean", + "null" + ], + "description": "(**default=`false`**) If input is required and the stream is not delivered\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 the offset is\nnot defined then the stream will be synchronized based on the delivery time of the initial\nframes." + } + }, + "additionalProperties": false + }, + "HlsOutput": { + "type": "object", + "required": [ + "path" + ], + "properties": { + "path": { + "type": "string", + "description": "Path to output HLS playlist." + }, + "max_playlist_size": { + "type": [ + "integer", + "null" + ], + "description": "Number of segments kept in the playlist. When the limit is reached the oldest segment is removed.\nIf not specified, no segments will removed.", + "minimum": 0 + }, + "video": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/OutputHlsVideoOptions", + "description": "Video track configuration." + } + ] + }, + "audio": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/OutputHlsAudioOptions", + "description": "Audio track configuration." + } + ] + } + }, + "additionalProperties": false + }, + "HorizontalAlign": { + "type": "string", + "enum": [ + "left", + "right", + "justified", + "center" + ] + }, + "ImageSpec": { + "oneOf": [ + { + "type": "object", + "required": [ + "asset_type" + ], + "properties": { + "url": { + "type": [ + "string", + "null" + ] + }, + "asset_type": { + "type": "string", + "enum": [ + "png" + ] + } + } + }, + { + "type": "object", + "required": [ + "asset_type" + ], + "properties": { + "url": { + "type": [ + "string", + "null" + ] + }, + "asset_type": { + "type": "string", + "enum": [ + "jpeg" + ] + } + } + }, + { + "type": "object", + "required": [ + "asset_type" + ], + "properties": { + "url": { + "type": [ + "string", + "null" + ] + }, + "resolution": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/Resolution" + } + ] + }, + "asset_type": { + "type": "string", + "enum": [ + "svg" + ] + } + } + }, + { + "type": "object", + "required": [ + "asset_type" + ], + "properties": { + "url": { + "type": [ + "string", + "null" + ] + }, + "asset_type": { + "type": "string", + "enum": [ + "gif" + ] + } + } + }, + { + "type": "object", + "required": [ + "asset_type" + ], + "properties": { + "url": { + "type": [ + "string", + "null" + ] + }, + "asset_type": { + "type": "string", + "enum": [ + "auto" + ] + } + } + } + ] + }, + "InputId": { + "type": "string" + }, + "InputStream": { + "type": "object", + "required": [ + "input_id" + ], + "properties": { + "id": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/ComponentId", + "description": "Id of a component." + } + ] + }, + "input_id": { + "$ref": "#/components/schemas/InputId", + "description": "Id of an input. It identifies a stream registered using a [`RegisterInputStream`](../routes.md#register-input) request." + } + }, + "additionalProperties": false + }, + "Interpolation": { + "type": "string", + "enum": [ + "linear", + "spring" + ] + }, + "Mp4Input": { + "type": "object", + "description": "Input stream from MP4 file.\nExactly one of `url` and `path` has to be defined.", + "properties": { + "url": { + "type": [ + "string", + "null" + ], + "description": "URL of the MP4 file." + }, + "loop": { + "type": [ + "boolean", + "null" + ], + "description": "(**default=`false`**) If input should be played in the loop. 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 + }, + "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": [ + "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." + } + ] + }, + "initial": { + "$ref": "#/components/schemas/AudioScene", + "description": "Initial audio mixer configuration for output." + } + }, + "additionalProperties": false + }, + "OutputHlsVideoOptions": { + "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": "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." + } + ] + }, + "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": [ + "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." + } + ] + }, + "initial": { + "$ref": "#/components/schemas/AudioScene", + "description": "Initial audio mixer configuration for output." + } + }, + "additionalProperties": false + }, + "OutputMp4VideoOptions": { + "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": "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." + } + ] + }, + "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": [ + "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." + } + ] + }, + "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", + "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." + } + ] + }, + "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": [ + "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." + } + ] + }, + "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", + "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." + } + ] + }, + "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": [ + "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": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/WhepAudioEncoderOptions", + "description": "(**default=`{\"type\": \"opus\"}`**) 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", + "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." + } + ] + }, + "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." + } + ] + }, + "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": [ + { + "allOf": [ + { + "$ref": "#/components/schemas/RtpInput" + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "rtp_stream" + ] + } + } + } + ] + }, + { + "allOf": [ + { + "$ref": "#/components/schemas/RtmpInput" + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "rtmp_server" + ] + } + } + } + ] + }, + { + "allOf": [ + { + "$ref": "#/components/schemas/Mp4Input" + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "mp4" + ] + } + } + } + ] + }, + { + "allOf": [ + { + "$ref": "#/components/schemas/WhipInput" + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "whip_server" + ] + } + } + } + ] + }, + { + "allOf": [ + { + "$ref": "#/components/schemas/WhepInput" + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "whep_client" + ] + } + } + } + ] + }, + { + "allOf": [ + { + "$ref": "#/components/schemas/HlsInput" + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "hls" + ] + } + } + } + ] + } + ] + }, + "RegisterOutput": { + "oneOf": [ + { + "allOf": [ + { + "$ref": "#/components/schemas/RtpOutput" + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "rtp_stream" + ] + } + } + } + ] + }, + { + "allOf": [ + { + "$ref": "#/components/schemas/RtmpOutput" + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "rtmp_client" + ] + } + } + } + ] + }, + { + "allOf": [ + { + "$ref": "#/components/schemas/Mp4Output" + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "mp4" + ] + } + } + } + ] + }, + { + "allOf": [ + { + "$ref": "#/components/schemas/WhipOutput" + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "whip_client" + ] + } + } + } + ] + }, + { + "allOf": [ + { + "$ref": "#/components/schemas/WhepOutput" + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "whep_server" + ] + } + } + } + ] + }, + { + "allOf": [ + { + "$ref": "#/components/schemas/HlsOutput" + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "hls" + ] + } + } + } + ] + } + ] + }, + "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" + } + ] + }, + "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("delete stream: unexpected status %d: %s", resp.StatusCode(), string(resp.Body)) + } + log.Printf("fishjam: deleted stream: id=%s", streamID) + return nil +} + +// LiveWhipURL returns the WHIP endpoint URL for composition → Fishjam livestream. +func (c *Client) LiveWhipURL() string { + base := strings.TrimRight(c.baseURL, "/") + // Replace /connect/{id} suffix with /live + if idx := strings.Index(base, "/connect/"); idx != -1 { + base = base[:idx] + } + return base + "/live/api/whip" +} + +// LiveWhepURL returns the public WHEP playback URL for a livestream. +func (c *Client) LiveWhepURL(streamID string) string { + base := strings.TrimRight(c.baseURL, "/") + if idx := strings.Index(base, "/connect/"); idx != -1 { + base = base[:idx] + } + return base + "/live/api/whep/" + streamID +} + +func (c *Client) CreateTrackForwarding(roomID, compositionURL string) error { + cl, err := c.newAPI() + if err != nil { + return err + } + selector := "all" + resp, err := cl.CreateTrackForwardingWithResponse(context.Background(), roomID, api.TrackForwarding{ + CompositionURL: compositionURL, + Selector: &selector, + }) + if err != nil { + return fmt.Errorf("create track forwarding: %w", err) + } + if resp.StatusCode() < 200 || resp.StatusCode() >= 300 { + return fmt.Errorf("create track forwarding: unexpected status %d: %s", resp.StatusCode(), string(resp.Body)) + } + log.Printf("fishjam: created track forwarding: room=%s composition=%s", roomID, compositionURL) + 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..84bb432 --- /dev/null +++ b/conference-to-stream/backend/fishjam/generated/fishjam.gen.go @@ -0,0 +1,3543 @@ +// 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 + } +} + +// 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"` +} + +// StreamDetailsResponse Response containing stream details +type StreamDetailsResponse struct { + // Data Describes stream status + Data Stream `json:"data"` +} + +// 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 + +// StreamerDetailsResponse Response containing streamer details +type StreamerDetailsResponse struct { + // Data Describes streamer status + Data Streamer `json:"data"` +} + +// StreamerToken Token for authorizing broadcaster streamer connection +type StreamerToken = string + +// 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"` + + // Token Token for authorizing broadcaster viewer connection + Token ViewerToken `json:"token"` +} + +// ViewerDetailsResponse Response containing viewer details +type ViewerDetailsResponse struct { + // Data Describes viewer status + Data Viewer `json:"data"` +} + +// ViewerToken Token for authorizing broadcaster viewer connection +type ViewerToken = string + +// 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 *StreamDetailsResponse + 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 *StreamDetailsResponse + 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 *StreamerDetailsResponse + 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 *ViewerDetailsResponse + 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 StreamDetailsResponse + 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 StreamDetailsResponse + 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 StreamerDetailsResponse + 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 ViewerDetailsResponse + 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..7464a00 --- /dev/null +++ b/conference-to-stream/backend/fishjam/notifier.go @@ -0,0 +1,210 @@ +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 VadEvent struct { + RoomID string + PeerID string + TrackID string + Status pb.ServerMessage_VadNotification_Status +} + +type NotifierCallbacks struct { + OnTrackForwarding func(TrackForwardingEvent) + OnTrackForwardingRemoved func(TrackForwardingEvent) + OnPeerConnected func(PeerEvent) + OnPeerDisconnected func(PeerEvent) + OnVadNotification func(VadEvent) +} + +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 notifier: authenticated") + case *pb.ServerMessage_SubscribeResponse_: + log.Println("fishjam notifier: subscribed to notifications") + case *pb.ServerMessage_TrackForwarding_: + tf := content.TrackForwarding + log.Printf("fishjam notifier: track forwarding - 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 notifier: track forwarding removed - 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 notifier: 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 notifier: 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, + }) + } + case *pb.ServerMessage_VadNotification_: + vad := content.VadNotification + log.Printf("fishjam notifier: VAD notification - room=%s peer=%s track=%s status=%s", + vad.RoomId, vad.PeerId, vad.TrackId, vad.Status) + if n.callbacks.OnVadNotification != nil { + n.callbacks.OnVadNotification(VadEvent{ + RoomID: vad.RoomId, + PeerID: vad.PeerId, + TrackID: vad.TrackId, + Status: vad.Status, + }) + } + 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/fishjam/openapi.yaml b/conference-to-stream/backend/fishjam/openapi.yaml new file mode 100644 index 0000000..4376115 --- /dev/null +++ b/conference-to-stream/backend/fishjam/openapi.yaml @@ -0,0 +1,1384 @@ +--- +components: + responses: {} + schemas: + PeerRefreshTokenResponse: + description: Response containing new peer token + properties: + data: + properties: + token: + $ref: '#/components/schemas/AuthToken' + required: + - token + type: object + required: + - data + title: PeerRefreshTokenResponse + type: object + PeerOptionsAgent: + additionalProperties: false + description: Options specific to the Agent peer + properties: + output: + $ref: '#/components/schemas/AgentOutput' + subscribeMode: + $ref: '#/components/schemas/SubscribeMode' + title: PeerOptionsAgent + type: object + RoomDetailsResponse: + description: Response containing room details + properties: + data: + $ref: '#/components/schemas/Room' + required: + - data + title: RoomDetailsResponse + type: object + RoomCreateDetailsResponse: + description: Response containing room details + properties: + data: + properties: + room: + $ref: '#/components/schemas/Room' + required: + - room + - fishjam_address + type: object + required: + - data + title: RoomCreateDetailsResponse + type: object + Room: + description: Description of the room state + properties: + config: + $ref: '#/components/schemas/RoomConfig' + id: + description: Room ID + example: room-1 + type: string + peers: + description: List of all peers + items: + $ref: '#/components/schemas/Peer' + type: array + required: + - id + - config + - peers + title: Room + type: object + TrackID: + description: Assigned track id + example: 8dbd2e6b-a1e7-4670-95a2-0262aa6c6321 + title: TrackID + type: string + PeerType: + description: Peer type + enum: + - webrtc + - agent + example: webrtc + title: PeerType + type: string + SubscribeMode: + default: auto + description: Configuration of peer's subscribing policy + enum: + - auto + - manual + nullable: false + title: SubscribeMode + type: string + StreamConfig: + additionalProperties: false + description: Stream configuration + properties: + audioOnly: + default: false + description: Restrics stream to audio only + nullable: true + type: boolean + public: + default: false + description: True if livestream viewers can omit specifying a token. + nullable: false + type: boolean + webhookUrl: + description: Webhook URL for receiving server notifications + nullable: true + pattern: ^https?://[^/]+/.*$ + type: string + title: StreamConfig + type: object + Error: + description: Error message + properties: + errors: + description: Error details + example: Token has expired + type: string + required: + - errors + title: Error + type: object + PeerID: + description: Assigned peer id + example: 4a1c1164-5fb7-425d-89d7-24cdb8fff1cf + title: PeerID + type: string + PeerDetailsResponse: + description: Response containing peer details and their token + properties: + data: + properties: + peer: + $ref: '#/components/schemas/Peer' + peer_websocket_url: + $ref: '#/components/schemas/WebsocketURL' + token: + $ref: '#/components/schemas/AuthToken' + required: + - peer + - token + type: object + required: + - data + title: PeerDetailsResponse + type: object + StreamerDetailsResponse: + description: Response containing streamer details + properties: + data: + $ref: '#/components/schemas/Streamer' + required: + - data + title: StreamerDetailsResponse + type: object + AuthToken: + description: Token for authorizing websocket connection + example: 5cdac726-57a3-4ecb-b1d5-72a3d62ec242 + title: AuthToken + type: string + AudioSampleRate: + default: 16000 + description: The sample rate of the output audio + enum: + - 16000 + - 24000 + example: 16000 + title: AudioSampleRate + type: integer + PeerStatus: + description: Informs about the peer status + enum: + - connected + - disconnected + example: disconnected + title: PeerStatus + type: string + StreamsListingResponse: + description: Response containing list of all streams + properties: + data: + items: + $ref: '#/components/schemas/Stream' + type: array + required: + - data + title: StreamsListingResponse + type: object + PeerOptions: + additionalProperties: false + description: Peer-specific options + oneOf: + - $ref: '#/components/schemas/PeerOptionsWebRTC' + - $ref: '#/components/schemas/PeerOptionsAgent' + title: PeerOptions + type: object + Streamer: + description: Describes streamer status + properties: + id: + description: Assigned streamer id + type: string + status: + enum: + - connected + - disconnected + type: string + token: + $ref: '#/components/schemas/StreamerToken' + required: + - id + - status + - token + title: Streamer + type: object + VideoCodec: + default: h264 + description: Enforces video codec for each peer in the room + enum: + - h264 + - vp8 + title: VideoCodec + type: string + ViewerDetailsResponse: + description: Response containing viewer details + properties: + data: + $ref: '#/components/schemas/Viewer' + required: + - data + title: ViewerDetailsResponse + type: object + RoomType: + default: conference + description: The use-case of the room. If not provided, this defaults to conference. + enum: + - full_feature + - audio_only + - broadcaster + - livestream + - conference + - audio_only_livestream + nullable: false + title: RoomType + type: string + PeerConfig: + additionalProperties: false + description: Peer configuration + properties: + options: + $ref: '#/components/schemas/PeerOptions' + type: + $ref: '#/components/schemas/PeerType' + required: + - options + - type + title: PeerConfig + type: object + TrackMetadata: + example: + source: camera + nullable: true + title: TrackMetadata + type: object + TrackForwarding: + additionalProperties: false + description: Track forwardings for a room + properties: + compositionURL: + description: URL for the composition + nullable: false + pattern: ^https?://[^/]+/.*$ + type: string + selector: + default: all + description: Selects tracks that should be forwarded, currently only "all" is supported + nullable: false + pattern: ^all$ + type: string + required: + - compositionURL + title: TrackForwarding + type: object + Subscriptions: + description: Describes peer's subscriptions in manual mode + properties: + peers: + description: List of peer IDs this peer subscribes to + items: + $ref: '#/components/schemas/PeerID' + type: array + tracks: + description: List of track IDs this peer subscribes to + items: + $ref: '#/components/schemas/TrackID' + type: array + required: + - peers + - tracks + title: Subscriptions + type: object + WebsocketURL: + description: Websocket URL to which peer has to connect + example: www.fishjam.org/socket/peer + title: WebsocketURL + type: string + ViewerToken: + description: Token for authorizing broadcaster viewer connection + example: 5cdac72657a34ecbb1d572a3d62ec242 + title: ViewerToken + type: string + Viewer: + description: Describes viewer status + properties: + id: + description: Assigned viewer id + type: string + token: + $ref: '#/components/schemas/ViewerToken' + required: + - id + - token + title: Viewer + type: object + WebRTCMetadata: + additionalProperties: true + description: Custom peer metadata + title: WebRTCMetadata + type: object + RoomConfig: + additionalProperties: false + description: Room configuration + properties: + maxPeers: + description: Maximum amount of peers allowed into the room + example: 10 + minimum: 0 + nullable: true + type: integer + public: + default: false + description: True if livestream viewers can omit specifying a token. + nullable: false + type: boolean + roomType: + $ref: '#/components/schemas/RoomType' + videoCodec: + $ref: '#/components/schemas/VideoCodec' + webhookUrl: + description: URL where Fishjam notifications will be sent + example: https://backend.address.com/fishjam-notifications-endpoint + nullable: true + pattern: ^https?://[^/]+/.*$ + type: string + title: RoomConfig + type: object + PeerMetadata: + description: Custom metadata set by the peer + example: + name: FishjamUser + nullable: true + title: PeerMetadata + type: object + Peer: + description: Describes peer status + properties: + id: + $ref: '#/components/schemas/PeerID' + metadata: + $ref: '#/components/schemas/PeerMetadata' + status: + $ref: '#/components/schemas/PeerStatus' + subscribeMode: + $ref: '#/components/schemas/SubscribeMode' + subscriptions: + $ref: '#/components/schemas/Subscriptions' + tracks: + description: List of all peer's tracks + items: + $ref: '#/components/schemas/Track' + type: array + type: + $ref: '#/components/schemas/PeerType' + required: + - id + - type + - status + - tracks + - metadata + - subscribeMode + - subscriptions + title: Peer + type: object + TrackType: + enum: + - audio + - video + title: TrackType + type: string + StreamDetailsResponse: + description: Response containing stream details + properties: + data: + $ref: '#/components/schemas/Stream' + required: + - data + title: StreamDetailsResponse + type: object + PeerOptionsWebRTC: + additionalProperties: false + description: Options specific to the WebRTC peer + properties: + metadata: + $ref: '#/components/schemas/WebRTCMetadata' + subscribeMode: + $ref: '#/components/schemas/SubscribeMode' + title: PeerOptionsWebRTC + type: object + RoomsListingResponse: + description: Response containing list of all rooms + properties: + data: + items: + $ref: '#/components/schemas/Room' + type: array + required: + - data + title: RoomsListingResponse + type: object + Stream: + description: Describes stream status + properties: + audioOnly: + description: True if stream is restricted to audio only + type: boolean + id: + description: Assigned stream id + type: string + public: + type: boolean + streamers: + description: List of all streamers + items: + $ref: '#/components/schemas/Streamer' + type: array + viewers: + description: List of all viewers + items: + $ref: '#/components/schemas/Viewer' + type: array + required: + - id + - public + - viewers + - streamers + title: Stream + type: object + StreamerToken: + description: Token for authorizing broadcaster streamer connection + example: 5cdac72657a34ecbb1d572a3d62ec242 + title: StreamerToken + type: string + Track: + description: Describes media track of a Peer + properties: + id: + $ref: '#/components/schemas/TrackID' + metadata: + $ref: '#/components/schemas/TrackMetadata' + type: + $ref: '#/components/schemas/TrackType' + title: Track + type: object + AgentOutput: + additionalProperties: false + description: Output audio options + properties: + audioFormat: + $ref: '#/components/schemas/AudioFormat' + audioSampleRate: + $ref: '#/components/schemas/AudioSampleRate' + title: AgentOutput + type: object + AudioFormat: + default: pcm16 + description: The format of the output audio + enum: + - pcm16 + example: pcm16 + title: AudioFormat + type: string + securitySchemes: + authorization: + scheme: bearer + type: http +info: + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0 + title: Fishjam Media Server + version: 0.26.1 +openapi: 3.0.0 +paths: + /livestream: + get: + callbacks: {} + operationId: get_all_streams + parameters: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/StreamsListingResponse' + description: Success + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unauthorized + '503': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Service temporarily unavailable + security: + - authorization: [] + summary: Show information about all streams + tags: + - stream + post: + callbacks: {} + operationId: create_stream + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/StreamConfig' + description: Stream configuration + required: false + responses: + '201': + content: + application/json: + schema: + $ref: '#/components/schemas/StreamDetailsResponse' + description: Stream created successfully + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Invalid request structure + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unauthorized + '503': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Service temporarily unavailable + security: + - authorization: [] + summary: Creates stream + tags: + - stream + /livestream/{stream_id}: + delete: + callbacks: {} + operationId: delete_stream + parameters: + - description: Stream ID + in: path + name: stream_id + required: true + schema: + type: string + responses: + '204': + description: Successfully deleted stream + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unauthorized + '503': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Service temporarily unavailable + security: + - authorization: [] + summary: Deletes stream + tags: + - stream + get: + callbacks: {} + operationId: get_stream + parameters: + - description: Stream ID + in: path + name: stream_id + required: true + schema: + type: string + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/StreamDetailsResponse' + description: Success + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unauthorized + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Stream doesn't exist + '503': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Service temporarily unavailable + security: + - authorization: [] + summary: Shows information about the stream + tags: + - stream + /livestream/{stream_id}/streamer: + post: + callbacks: {} + operationId: create_streamer + parameters: + - description: Stream id + in: path + name: stream_id + required: true + schema: + type: string + responses: + '201': + content: + application/json: + schema: + $ref: '#/components/schemas/StreamerDetailsResponse' + description: Streamer successfully created + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unauthorized + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Stream doesn't exist + '503': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Service temporarily unavailable + security: + - authorization: [] + summary: Creates streamer + tags: + - streamer + /livestream/{stream_id}/streamer/{streamer_id}: + delete: + callbacks: {} + operationId: delete_streamer + parameters: + - description: Stream id + in: path + name: stream_id + required: true + schema: + type: string + - description: Streamer id + in: path + name: streamer_id + required: true + schema: + type: string + responses: + '204': + description: Streamer successfully deleted + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unauthorized + '503': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Service temporarily unavailable + security: + - authorization: [] + summary: Deletes streamer + tags: + - streamer + /livestream/{stream_id}/viewer: + post: + callbacks: {} + operationId: create_viewer + parameters: + - description: Stream id + in: path + name: stream_id + required: true + schema: + type: string + responses: + '201': + content: + application/json: + schema: + $ref: '#/components/schemas/ViewerDetailsResponse' + description: Viewer successfully created + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unauthorized + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Stream doesn't exist + '503': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Service temporarily unavailable + security: + - authorization: [] + summary: Creates viewer + tags: + - viewer + /livestream/{stream_id}/viewer/{viewer_id}: + delete: + callbacks: {} + operationId: delete_viewer + parameters: + - description: Stream id + in: path + name: stream_id + required: true + schema: + type: string + - description: Viewer id + in: path + name: viewer_id + required: true + schema: + type: string + responses: + '204': + description: Viewer successfully deleted + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unauthorized + '503': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Service temporarily unavailable + security: + - authorization: [] + summary: Deletes viewer + tags: + - viewer + /room: + get: + callbacks: {} + operationId: get_all_rooms + parameters: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/RoomsListingResponse' + description: Success + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unauthorized + security: + - authorization: [] + summary: Show information about all rooms + tags: + - room + post: + callbacks: {} + operationId: create_room + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RoomConfig' + description: Room configuration + required: false + responses: + '201': + content: + application/json: + schema: + $ref: '#/components/schemas/RoomCreateDetailsResponse' + description: Room successfully created + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Invalid request structure + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unauthorized + '503': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Service temporarily unavailable + security: + - authorization: [] + summary: Creates a room + tags: + - room + /room/{room_id}: + delete: + callbacks: {} + operationId: delete_room + parameters: + - description: Room id + in: path + name: room_id + required: true + schema: + type: string + responses: + '204': + description: Successfully deleted room + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Invalid request + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unauthorized + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Room doesn't exist + '503': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Service temporarily unavailable + security: + - authorization: [] + summary: Delete the room + tags: + - room + get: + callbacks: {} + operationId: get_room + parameters: + - description: Room ID + in: path + name: room_id + required: true + schema: + type: string + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/RoomDetailsResponse' + description: Success + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Invalid request + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unauthorized + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Room doesn't exist + '503': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Service temporarily unavailable + security: + - authorization: [] + summary: Shows information about the room + tags: + - room + /room/{room_id}/peer: + post: + callbacks: {} + operationId: add_peer + parameters: + - description: Room id + in: path + name: room_id + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PeerConfig' + description: Peer specification + required: false + responses: + '201': + content: + application/json: + schema: + $ref: '#/components/schemas/PeerDetailsResponse' + description: Peer successfully created + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Invalid request body structure + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unauthorized + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Room doesn't exist + '409': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Request conflict + '503': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Service temporarily unavailable + security: + - authorization: [] + summary: Create peer + tags: + - room + /room/{room_id}/peer/{id}: + delete: + callbacks: {} + operationId: delete_peer + parameters: + - description: Room id + in: path + name: room_id + required: true + schema: + type: string + - description: Peer id + in: path + name: id + required: true + schema: + type: string + responses: + '204': + description: Peer successfully deleted + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Invalid request body structure + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unauthorized + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Room ID or Peer ID references a resource that doesn't exist + '503': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Service temporarily unavailable + security: + - authorization: [] + summary: Delete peer + tags: + - room + /room/{room_id}/peer/{id}/refresh_token: + post: + callbacks: {} + operationId: refresh_token + parameters: + - description: Room id + in: path + name: room_id + required: true + schema: + type: string + - description: Peer id + in: path + name: id + required: true + schema: + type: string + responses: + '201': + content: + application/json: + schema: + $ref: '#/components/schemas/PeerRefreshTokenResponse' + description: Token successfully created + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Invalid request body structure + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unauthorized + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Room ID or Peer ID references a resource that doesn't exist + '503': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Service temporarily unavailable + security: + - authorization: [] + summary: Refresh peer token + tags: + - room + /room/{room_id}/peer/{id}/subscribe_peer: + post: + callbacks: {} + operationId: subscribe_peer + parameters: + - description: Room id + in: path + name: room_id + required: true + schema: + type: string + - description: Peer id + in: path + name: id + required: true + schema: + type: string + - description: ID of the peer that produces the track + in: query + name: peer_id + required: false + schema: + type: string + responses: + '200': + description: Peer successfully subscribed to another peer's tracks + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Invalid request body structure + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unauthorized + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Room ID or Peer ID references a resource that doesn't exist + '503': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Service temporarily unavailable + security: + - authorization: [] + summary: Subscribe peer to another peer's tracks + tags: + - room + /room/{room_id}/peer/{id}/subscribe_tracks: + post: + callbacks: {} + operationId: subscribe_tracks + parameters: + - description: Room id + in: path + name: room_id + required: true + schema: + type: string + - description: Peer id + in: path + name: id + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + properties: + track_ids: + description: List of track IDs to subscribe to + items: + $ref: '#/components/schemas/TrackID' + type: array + required: + - track_ids + type: object + description: Track IDs + required: false + responses: + '200': + description: Peer successfully subscribed to tracks + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Invalid request body structure + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unauthorized + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Room ID or Peer ID references a resource that doesn't exist + '503': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Service temporarily unavailable + security: + - authorization: [] + summary: Subscribe peer to specific tracks + tags: + - room + /room/{room_id}/streamer: + post: + callbacks: {} + operationId: generate_streamer_token + parameters: + - description: ID of the stream. + in: path + name: room_id + required: true + schema: + type: string + responses: + '201': + content: + application/json: + schema: + $ref: '#/components/schemas/StreamerToken' + description: Token successfully created + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Invalid request body structure + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unauthorized + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Room doesn't exist + '503': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Service temporarily unavailable + security: + - authorization: [] + summary: Generate a token that can be used by a streamer to start streaming + tags: + - streamer + /room/{room_id}/track_forwardings: + post: + callbacks: {} + operationId: create_track_forwarding + parameters: + - description: Room id + in: path + name: room_id + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/TrackForwarding' + description: Track forwardings + required: false + responses: + '201': + description: Track forwardings added successfully + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Invalid request + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unauthorized + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Room doesn't exist + security: + - authorization: [] + summary: Creates a track forwarding in a room + tags: + - track_forwarding + /room/{room_id}/viewer: + post: + callbacks: {} + operationId: generate_viewer_token + parameters: + - description: ID of the stream. + in: path + name: room_id + required: true + schema: + type: string + responses: + '201': + content: + application/json: + schema: + $ref: '#/components/schemas/ViewerToken' + description: Token successfully created + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Invalid request body structure + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unauthorized + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Room doesn't exist + '503': + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Service temporarily unavailable + security: + - authorization: [] + summary: Generates token that a viewer can use to watch a livestream + tags: + - viewer +security: [] +servers: + - url: https://fishjam.io/api/v1/connect/{fishjamId} + variables: + fishjamId: + default: '' + description: Id of user's Fishjam instance +tags: [] diff --git a/conference-to-stream/backend/go.mod b/conference-to-stream/backend/go.mod new file mode 100644 index 0000000..8c5ebfe --- /dev/null +++ b/conference-to-stream/backend/go.mod @@ -0,0 +1,44 @@ +module conference-to-stream + +go 1.26 + +require ( + github.com/gorilla/websocket v1.5.3 + github.com/joho/godotenv v1.5.1 +github.com/oapi-codegen/runtime v1.2.0 + 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/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 + google.golang.org/protobuf/cmd/protoc-gen-go +) + +replace github.com/oapi-codegen/oapi-codegen/v2 => ./oapi-codegen diff --git a/conference-to-stream/backend/go.sum b/conference-to-stream/backend/go.sum new file mode 100644 index 0000000..41099f3 --- /dev/null +++ b/conference-to-stream/backend/go.sum @@ -0,0 +1,191 @@ +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.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +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..891a593 --- /dev/null +++ b/conference-to-stream/backend/handler/handler.go @@ -0,0 +1,479 @@ +package handler + +import ( + "encoding/json" + "fmt" + "log" + "net/http" + "strings" + "time" + "sync" + "conference-to-stream/composition" + "conference-to-stream/fishjam" +) + +const whipOutputID = "whip_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 + LivestreamID 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"` + LivestreamID string `json:"livestreamID"` +} + +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, LivestreamID: state.LivestreamID}) + 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) + + time.Sleep(1500 * time.Millisecond) + + // 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 + } + + // Create Fishjam livestream + stream, err := h.fishjamClient.CreateStream() + if err != nil { + log.Printf("create livestream: %v", err) + http.Error(w, "failed to create livestream", http.StatusInternalServerError) + return + } + log.Printf("created livestream: %s", stream.Id) + + // Create streamer → get bearer token + streamerToken, err := h.fishjamClient.CreateStreamer(stream.Id) + if err != nil { + log.Printf("create streamer: %v", err) + http.Error(w, "failed to create streamer", http.StatusInternalServerError) + return + } + + // Register WHIP output on composition pointing to Fishjam's WHIP endpoint + whipURL := h.fishjamClient.LiveWhipURL() + if err := h.compositionClient.RegisterWhipOutput(apiURL, compositionID, whipOutputID, whipURL, streamerToken); err != nil { + log.Printf("register whip output: %v", err) + http.Error(w, "failed to register WHIP output", http.StatusInternalServerError) + return + } + + // Create Fishjam conference 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.fishjamClient.LiveWhepURL(stream.Id) + + 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, + LivestreamID: stream.Id, + } + + h.mu.Lock() + h.rooms[req.RoomName] = state + h.roomsByID[roomID] = state + h.mu.Unlock() + + if err := h.startNotifier(state, apiURL, compositionID, roomID); 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, LivestreamID: stream.Id}) +} + +func (h *Handler) startNotifier(state *RoomState, apiURL, compositionID, roomID string) error { + 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, whipOutputID, 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, whipOutputID, 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 + livestreamID := state.LivestreamID + 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() + + if livestreamID != "" { + if err := h.fishjamClient.DeleteStream(livestreamID); err != nil { + log.Printf("delete livestream: room=%s stream=%s err=%v", roomID, livestreamID, err) + } else { + log.Printf("deleted livestream after last peer left: room=%s stream=%s", roomID, livestreamID) + } + } + + 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) + }, + }) + return err +} + +type attachRoomRequest struct { + RoomID string `json:"roomId"` +} + +func (h *Handler) AttachRoom(w http.ResponseWriter, r *http.Request) { + var req attachRoomRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "invalid request body", http.StatusBadRequest) + return + } + if req.RoomID == "" { + http.Error(w, "roomId is required", http.StatusBadRequest) + return + } + + // Return existing state if already attached + h.mu.Lock() + if state, ok := h.roomsByID[req.RoomID]; ok { + h.mu.Unlock() + writeJSON(w, createRoomResponse{RoomID: state.RoomID, WhepURL: state.WhepURL, LivestreamID: state.LivestreamID}) + return + } + h.mu.Unlock() + + apiURL := h.compositionAPIURL + roomID := req.RoomID + + // 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 + } + + // Create Fishjam livestream + stream, err := h.fishjamClient.CreateStream() + if err != nil { + log.Printf("create livestream: %v", err) + http.Error(w, "failed to create livestream", http.StatusInternalServerError) + return + } + log.Printf("created livestream: %s", stream.Id) + + // Create streamer → get bearer token + streamerToken, err := h.fishjamClient.CreateStreamer(stream.Id) + if err != nil { + log.Printf("create streamer: %v", err) + http.Error(w, "failed to create streamer", http.StatusInternalServerError) + return + } + + // log.Printf("streamer token: %v", streamerToken); + + // Register WHIP output on composition pointing to Fishjam's WHIP endpoint + whipURL := h.fishjamClient.LiveWhipURL() + if err := h.compositionClient.RegisterWhipOutput(apiURL, compositionID, whipOutputID, whipURL, streamerToken); err != nil { + log.Printf("register whip output: %v", err) + http.Error(w, "failed to register WHIP output", http.StatusInternalServerError) + return + } + + // Add track forwarding + 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.fishjamClient.LiveWhepURL(stream.Id) + + state := &RoomState{ + RoomID: roomID, + RoomName: roomID, + CompositionID: compositionID, + CompositionURL: apiURL, + InputIDs: make(map[string]string), + PeerIDs: make(map[string]struct{}), + PeerNames: make(map[string]string), + WhepURL: whepURL, + LivestreamID: stream.Id, + } + + h.mu.Lock() + h.roomsByID[roomID] = state + h.rooms[roomID] = state + h.mu.Unlock() + + if err := h.startNotifier(state, apiURL, compositionID, roomID); 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, LivestreamID: stream.Id}) +} + +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/attach", 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.AttachRoom(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..63b2885 --- /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(managementToken) + 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..12ef283 --- /dev/null +++ b/conference-to-stream/backend/mise.toml @@ -0,0 +1,11 @@ +[tasks.generate-protos] +description = "Generate Go protobufs from the source" +run = "find protos -name '*.proto' | xargs protoc --proto_path=protos --go_out=. --go_opt=module=conference-to-stream" + +[tasks.generate-fishjam-client] +description = "Generate the Fishjam API client from openapi" +run = "go tool oapi-codegen -config fishjam/oapi-codegen.yaml ./fishjam/openapi.yaml" + +[tasks.generate] +description = "Regenerate all API clients" +depends = ["generate-protos", "generate-fishjam-client"] diff --git a/conference-to-stream/backend/oapi-codegen b/conference-to-stream/backend/oapi-codegen new file mode 160000 index 0000000..a13ef41 --- /dev/null +++ b/conference-to-stream/backend/oapi-codegen @@ -0,0 +1 @@ +Subproject commit a13ef41dfc5276e20728bc65b88399d16bee63ad 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/agent_notifications.pb.go b/conference-to-stream/backend/proto/fishjam/agent_notifications.pb.go new file mode 100644 index 0000000..acf4c17 --- /dev/null +++ b/conference-to-stream/backend/proto/fishjam/agent_notifications.pb.go @@ -0,0 +1,915 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v6.33.1 +// source: fishjam/agent_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) +) + +// Defines any type of message passed from agent peer to Fishjam +type AgentRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Content: + // + // *AgentRequest_AuthRequest_ + // *AgentRequest_AddTrack_ + // *AgentRequest_RemoveTrack_ + // *AgentRequest_TrackData_ + // *AgentRequest_InterruptTrack_ + // *AgentRequest_CaptureImage_ + Content isAgentRequest_Content `protobuf_oneof:"content"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentRequest) Reset() { + *x = AgentRequest{} + mi := &file_fishjam_agent_notifications_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentRequest) ProtoMessage() {} + +func (x *AgentRequest) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_agent_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 AgentRequest.ProtoReflect.Descriptor instead. +func (*AgentRequest) Descriptor() ([]byte, []int) { + return file_fishjam_agent_notifications_proto_rawDescGZIP(), []int{0} +} + +func (x *AgentRequest) GetContent() isAgentRequest_Content { + if x != nil { + return x.Content + } + return nil +} + +func (x *AgentRequest) GetAuthRequest() *AgentRequest_AuthRequest { + if x != nil { + if x, ok := x.Content.(*AgentRequest_AuthRequest_); ok { + return x.AuthRequest + } + } + return nil +} + +func (x *AgentRequest) GetAddTrack() *AgentRequest_AddTrack { + if x != nil { + if x, ok := x.Content.(*AgentRequest_AddTrack_); ok { + return x.AddTrack + } + } + return nil +} + +func (x *AgentRequest) GetRemoveTrack() *AgentRequest_RemoveTrack { + if x != nil { + if x, ok := x.Content.(*AgentRequest_RemoveTrack_); ok { + return x.RemoveTrack + } + } + return nil +} + +func (x *AgentRequest) GetTrackData() *AgentRequest_TrackData { + if x != nil { + if x, ok := x.Content.(*AgentRequest_TrackData_); ok { + return x.TrackData + } + } + return nil +} + +func (x *AgentRequest) GetInterruptTrack() *AgentRequest_InterruptTrack { + if x != nil { + if x, ok := x.Content.(*AgentRequest_InterruptTrack_); ok { + return x.InterruptTrack + } + } + return nil +} + +func (x *AgentRequest) GetCaptureImage() *AgentRequest_CaptureImage { + if x != nil { + if x, ok := x.Content.(*AgentRequest_CaptureImage_); ok { + return x.CaptureImage + } + } + return nil +} + +type isAgentRequest_Content interface { + isAgentRequest_Content() +} + +type AgentRequest_AuthRequest_ struct { + AuthRequest *AgentRequest_AuthRequest `protobuf:"bytes,1,opt,name=auth_request,json=authRequest,proto3,oneof"` +} + +type AgentRequest_AddTrack_ struct { + AddTrack *AgentRequest_AddTrack `protobuf:"bytes,2,opt,name=add_track,json=addTrack,proto3,oneof"` +} + +type AgentRequest_RemoveTrack_ struct { + RemoveTrack *AgentRequest_RemoveTrack `protobuf:"bytes,3,opt,name=remove_track,json=removeTrack,proto3,oneof"` +} + +type AgentRequest_TrackData_ struct { + TrackData *AgentRequest_TrackData `protobuf:"bytes,4,opt,name=track_data,json=trackData,proto3,oneof"` +} + +type AgentRequest_InterruptTrack_ struct { + InterruptTrack *AgentRequest_InterruptTrack `protobuf:"bytes,5,opt,name=interrupt_track,json=interruptTrack,proto3,oneof"` +} + +type AgentRequest_CaptureImage_ struct { + CaptureImage *AgentRequest_CaptureImage `protobuf:"bytes,6,opt,name=capture_image,json=captureImage,proto3,oneof"` +} + +func (*AgentRequest_AuthRequest_) isAgentRequest_Content() {} + +func (*AgentRequest_AddTrack_) isAgentRequest_Content() {} + +func (*AgentRequest_RemoveTrack_) isAgentRequest_Content() {} + +func (*AgentRequest_TrackData_) isAgentRequest_Content() {} + +func (*AgentRequest_InterruptTrack_) isAgentRequest_Content() {} + +func (*AgentRequest_CaptureImage_) isAgentRequest_Content() {} + +// Defines any type of message passed from Fishjam to agent peer +type AgentResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Content: + // + // *AgentResponse_Authenticated_ + // *AgentResponse_TrackData_ + // *AgentResponse_TrackImage_ + Content isAgentResponse_Content `protobuf_oneof:"content"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentResponse) Reset() { + *x = AgentResponse{} + mi := &file_fishjam_agent_notifications_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentResponse) ProtoMessage() {} + +func (x *AgentResponse) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_agent_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 AgentResponse.ProtoReflect.Descriptor instead. +func (*AgentResponse) Descriptor() ([]byte, []int) { + return file_fishjam_agent_notifications_proto_rawDescGZIP(), []int{1} +} + +func (x *AgentResponse) GetContent() isAgentResponse_Content { + if x != nil { + return x.Content + } + return nil +} + +func (x *AgentResponse) GetAuthenticated() *AgentResponse_Authenticated { + if x != nil { + if x, ok := x.Content.(*AgentResponse_Authenticated_); ok { + return x.Authenticated + } + } + return nil +} + +func (x *AgentResponse) GetTrackData() *AgentResponse_TrackData { + if x != nil { + if x, ok := x.Content.(*AgentResponse_TrackData_); ok { + return x.TrackData + } + } + return nil +} + +func (x *AgentResponse) GetTrackImage() *AgentResponse_TrackImage { + if x != nil { + if x, ok := x.Content.(*AgentResponse_TrackImage_); ok { + return x.TrackImage + } + } + return nil +} + +type isAgentResponse_Content interface { + isAgentResponse_Content() +} + +type AgentResponse_Authenticated_ struct { + Authenticated *AgentResponse_Authenticated `protobuf:"bytes,1,opt,name=authenticated,proto3,oneof"` +} + +type AgentResponse_TrackData_ struct { + TrackData *AgentResponse_TrackData `protobuf:"bytes,2,opt,name=track_data,json=trackData,proto3,oneof"` +} + +type AgentResponse_TrackImage_ struct { + TrackImage *AgentResponse_TrackImage `protobuf:"bytes,3,opt,name=track_image,json=trackImage,proto3,oneof"` +} + +func (*AgentResponse_Authenticated_) isAgentResponse_Content() {} + +func (*AgentResponse_TrackData_) isAgentResponse_Content() {} + +func (*AgentResponse_TrackImage_) isAgentResponse_Content() {} + +// Request sent by agent, to authenticate to Fishjam server +type AgentRequest_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 *AgentRequest_AuthRequest) Reset() { + *x = AgentRequest_AuthRequest{} + mi := &file_fishjam_agent_notifications_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentRequest_AuthRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentRequest_AuthRequest) ProtoMessage() {} + +func (x *AgentRequest_AuthRequest) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_agent_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 AgentRequest_AuthRequest.ProtoReflect.Descriptor instead. +func (*AgentRequest_AuthRequest) Descriptor() ([]byte, []int) { + return file_fishjam_agent_notifications_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *AgentRequest_AuthRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +// Request to add a track of the specified type +type AgentRequest_AddTrack struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Specification of the track to be added + Track *notifications.Track `protobuf:"bytes,1,opt,name=track,proto3" json:"track,omitempty"` + // Parameters of the input data stream + CodecParams *AgentRequest_AddTrack_CodecParameters `protobuf:"bytes,2,opt,name=codec_params,json=codecParams,proto3" json:"codec_params,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentRequest_AddTrack) Reset() { + *x = AgentRequest_AddTrack{} + mi := &file_fishjam_agent_notifications_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentRequest_AddTrack) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentRequest_AddTrack) ProtoMessage() {} + +func (x *AgentRequest_AddTrack) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_agent_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 AgentRequest_AddTrack.ProtoReflect.Descriptor instead. +func (*AgentRequest_AddTrack) Descriptor() ([]byte, []int) { + return file_fishjam_agent_notifications_proto_rawDescGZIP(), []int{0, 1} +} + +func (x *AgentRequest_AddTrack) GetTrack() *notifications.Track { + if x != nil { + return x.Track + } + return nil +} + +func (x *AgentRequest_AddTrack) GetCodecParams() *AgentRequest_AddTrack_CodecParameters { + if x != nil { + return x.CodecParams + } + return nil +} + +// Removes the given track +type AgentRequest_RemoveTrack struct { + state protoimpl.MessageState `protogen:"open.v1"` + TrackId string `protobuf:"bytes,1,opt,name=track_id,json=trackId,proto3" json:"track_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentRequest_RemoveTrack) Reset() { + *x = AgentRequest_RemoveTrack{} + mi := &file_fishjam_agent_notifications_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentRequest_RemoveTrack) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentRequest_RemoveTrack) ProtoMessage() {} + +func (x *AgentRequest_RemoveTrack) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_agent_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 AgentRequest_RemoveTrack.ProtoReflect.Descriptor instead. +func (*AgentRequest_RemoveTrack) Descriptor() ([]byte, []int) { + return file_fishjam_agent_notifications_proto_rawDescGZIP(), []int{0, 2} +} + +func (x *AgentRequest_RemoveTrack) GetTrackId() string { + if x != nil { + return x.TrackId + } + return "" +} + +// Notification containing a chunk of an agent's track's data stream +type AgentRequest_TrackData struct { + state protoimpl.MessageState `protogen:"open.v1"` + TrackId string `protobuf:"bytes,1,opt,name=track_id,json=trackId,proto3" json:"track_id,omitempty"` + Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentRequest_TrackData) Reset() { + *x = AgentRequest_TrackData{} + mi := &file_fishjam_agent_notifications_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentRequest_TrackData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentRequest_TrackData) ProtoMessage() {} + +func (x *AgentRequest_TrackData) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_agent_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 AgentRequest_TrackData.ProtoReflect.Descriptor instead. +func (*AgentRequest_TrackData) Descriptor() ([]byte, []int) { + return file_fishjam_agent_notifications_proto_rawDescGZIP(), []int{0, 3} +} + +func (x *AgentRequest_TrackData) GetTrackId() string { + if x != nil { + return x.TrackId + } + return "" +} + +func (x *AgentRequest_TrackData) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +// Interrupts an agent's outgoing track, preventing already queued audio from being played +type AgentRequest_InterruptTrack struct { + state protoimpl.MessageState `protogen:"open.v1"` + TrackId string `protobuf:"bytes,1,opt,name=track_id,json=trackId,proto3" json:"track_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentRequest_InterruptTrack) Reset() { + *x = AgentRequest_InterruptTrack{} + mi := &file_fishjam_agent_notifications_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentRequest_InterruptTrack) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentRequest_InterruptTrack) ProtoMessage() {} + +func (x *AgentRequest_InterruptTrack) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_agent_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 AgentRequest_InterruptTrack.ProtoReflect.Descriptor instead. +func (*AgentRequest_InterruptTrack) Descriptor() ([]byte, []int) { + return file_fishjam_agent_notifications_proto_rawDescGZIP(), []int{0, 4} +} + +func (x *AgentRequest_InterruptTrack) GetTrackId() string { + if x != nil { + return x.TrackId + } + return "" +} + +type AgentRequest_CaptureImage struct { + state protoimpl.MessageState `protogen:"open.v1"` + TrackId string `protobuf:"bytes,1,opt,name=track_id,json=trackId,proto3" json:"track_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentRequest_CaptureImage) Reset() { + *x = AgentRequest_CaptureImage{} + mi := &file_fishjam_agent_notifications_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentRequest_CaptureImage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentRequest_CaptureImage) ProtoMessage() {} + +func (x *AgentRequest_CaptureImage) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_agent_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 AgentRequest_CaptureImage.ProtoReflect.Descriptor instead. +func (*AgentRequest_CaptureImage) Descriptor() ([]byte, []int) { + return file_fishjam_agent_notifications_proto_rawDescGZIP(), []int{0, 5} +} + +func (x *AgentRequest_CaptureImage) GetTrackId() string { + if x != nil { + return x.TrackId + } + return "" +} + +type AgentRequest_AddTrack_CodecParameters struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The format of the input stream, defaults to pcm16 + Encoding notifications.TrackEncoding `protobuf:"varint,1,opt,name=encoding,proto3,enum=fishjam.notifications.TrackEncoding" json:"encoding,omitempty"` + // The sample rate of the input stream, may be omitted for opus + SampleRate uint32 `protobuf:"varint,2,opt,name=sample_rate,json=sampleRate,proto3" json:"sample_rate,omitempty"` + // The number of channels. 1 means mono, 2 means stereo + Channels uint32 `protobuf:"varint,3,opt,name=channels,proto3" json:"channels,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentRequest_AddTrack_CodecParameters) Reset() { + *x = AgentRequest_AddTrack_CodecParameters{} + mi := &file_fishjam_agent_notifications_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentRequest_AddTrack_CodecParameters) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentRequest_AddTrack_CodecParameters) ProtoMessage() {} + +func (x *AgentRequest_AddTrack_CodecParameters) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_agent_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 AgentRequest_AddTrack_CodecParameters.ProtoReflect.Descriptor instead. +func (*AgentRequest_AddTrack_CodecParameters) Descriptor() ([]byte, []int) { + return file_fishjam_agent_notifications_proto_rawDescGZIP(), []int{0, 1, 0} +} + +func (x *AgentRequest_AddTrack_CodecParameters) GetEncoding() notifications.TrackEncoding { + if x != nil { + return x.Encoding + } + return notifications.TrackEncoding(0) +} + +func (x *AgentRequest_AddTrack_CodecParameters) GetSampleRate() uint32 { + if x != nil { + return x.SampleRate + } + return 0 +} + +func (x *AgentRequest_AddTrack_CodecParameters) GetChannels() uint32 { + if x != nil { + return x.Channels + } + return 0 +} + +// Response confirming successful authentication +type AgentResponse_Authenticated struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentResponse_Authenticated) Reset() { + *x = AgentResponse_Authenticated{} + mi := &file_fishjam_agent_notifications_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentResponse_Authenticated) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentResponse_Authenticated) ProtoMessage() {} + +func (x *AgentResponse_Authenticated) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_agent_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 AgentResponse_Authenticated.ProtoReflect.Descriptor instead. +func (*AgentResponse_Authenticated) Descriptor() ([]byte, []int) { + return file_fishjam_agent_notifications_proto_rawDescGZIP(), []int{1, 0} +} + +// Notification containing a chunk of a track's data stream +type AgentResponse_TrackData struct { + state protoimpl.MessageState `protogen:"open.v1"` + PeerId string `protobuf:"bytes,1,opt,name=peer_id,json=peerId,proto3" json:"peer_id,omitempty"` + Track *notifications.Track `protobuf:"bytes,2,opt,name=track,proto3" json:"track,omitempty"` + Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentResponse_TrackData) Reset() { + *x = AgentResponse_TrackData{} + mi := &file_fishjam_agent_notifications_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentResponse_TrackData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentResponse_TrackData) ProtoMessage() {} + +func (x *AgentResponse_TrackData) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_agent_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 AgentResponse_TrackData.ProtoReflect.Descriptor instead. +func (*AgentResponse_TrackData) Descriptor() ([]byte, []int) { + return file_fishjam_agent_notifications_proto_rawDescGZIP(), []int{1, 1} +} + +func (x *AgentResponse_TrackData) GetPeerId() string { + if x != nil { + return x.PeerId + } + return "" +} + +func (x *AgentResponse_TrackData) GetTrack() *notifications.Track { + if x != nil { + return x.Track + } + return nil +} + +func (x *AgentResponse_TrackData) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +type AgentResponse_TrackImage struct { + state protoimpl.MessageState `protogen:"open.v1"` + TrackId string `protobuf:"bytes,1,opt,name=track_id,json=trackId,proto3" json:"track_id,omitempty"` + ContentType string `protobuf:"bytes,2,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"` + Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentResponse_TrackImage) Reset() { + *x = AgentResponse_TrackImage{} + mi := &file_fishjam_agent_notifications_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentResponse_TrackImage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentResponse_TrackImage) ProtoMessage() {} + +func (x *AgentResponse_TrackImage) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_agent_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 AgentResponse_TrackImage.ProtoReflect.Descriptor instead. +func (*AgentResponse_TrackImage) Descriptor() ([]byte, []int) { + return file_fishjam_agent_notifications_proto_rawDescGZIP(), []int{1, 2} +} + +func (x *AgentResponse_TrackImage) GetTrackId() string { + if x != nil { + return x.TrackId + } + return "" +} + +func (x *AgentResponse_TrackImage) GetContentType() string { + if x != nil { + return x.ContentType + } + return "" +} + +func (x *AgentResponse_TrackImage) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +var File_fishjam_agent_notifications_proto protoreflect.FileDescriptor + +const file_fishjam_agent_notifications_proto_rawDesc = "" + + "\n" + + "!fishjam/agent_notifications.proto\x12\afishjam\x1a\"fishjam/notifications/shared.proto\"\xd0\a\n" + + "\fAgentRequest\x12F\n" + + "\fauth_request\x18\x01 \x01(\v2!.fishjam.AgentRequest.AuthRequestH\x00R\vauthRequest\x12=\n" + + "\tadd_track\x18\x02 \x01(\v2\x1e.fishjam.AgentRequest.AddTrackH\x00R\baddTrack\x12F\n" + + "\fremove_track\x18\x03 \x01(\v2!.fishjam.AgentRequest.RemoveTrackH\x00R\vremoveTrack\x12@\n" + + "\n" + + "track_data\x18\x04 \x01(\v2\x1f.fishjam.AgentRequest.TrackDataH\x00R\ttrackData\x12O\n" + + "\x0finterrupt_track\x18\x05 \x01(\v2$.fishjam.AgentRequest.InterruptTrackH\x00R\x0einterruptTrack\x12I\n" + + "\rcapture_image\x18\x06 \x01(\v2\".fishjam.AgentRequest.CaptureImageH\x00R\fcaptureImage\x1a#\n" + + "\vAuthRequest\x12\x14\n" + + "\x05token\x18\x01 \x01(\tR\x05token\x1a\xa4\x02\n" + + "\bAddTrack\x122\n" + + "\x05track\x18\x01 \x01(\v2\x1c.fishjam.notifications.TrackR\x05track\x12Q\n" + + "\fcodec_params\x18\x02 \x01(\v2..fishjam.AgentRequest.AddTrack.CodecParametersR\vcodecParams\x1a\x90\x01\n" + + "\x0fCodecParameters\x12@\n" + + "\bencoding\x18\x01 \x01(\x0e2$.fishjam.notifications.TrackEncodingR\bencoding\x12\x1f\n" + + "\vsample_rate\x18\x02 \x01(\rR\n" + + "sampleRate\x12\x1a\n" + + "\bchannels\x18\x03 \x01(\rR\bchannels\x1a(\n" + + "\vRemoveTrack\x12\x19\n" + + "\btrack_id\x18\x01 \x01(\tR\atrackId\x1a:\n" + + "\tTrackData\x12\x19\n" + + "\btrack_id\x18\x01 \x01(\tR\atrackId\x12\x12\n" + + "\x04data\x18\x02 \x01(\fR\x04data\x1a+\n" + + "\x0eInterruptTrack\x12\x19\n" + + "\btrack_id\x18\x01 \x01(\tR\atrackId\x1a)\n" + + "\fCaptureImage\x12\x19\n" + + "\btrack_id\x18\x01 \x01(\tR\atrackIdB\t\n" + + "\acontent\"\xd0\x03\n" + + "\rAgentResponse\x12L\n" + + "\rauthenticated\x18\x01 \x01(\v2$.fishjam.AgentResponse.AuthenticatedH\x00R\rauthenticated\x12A\n" + + "\n" + + "track_data\x18\x02 \x01(\v2 .fishjam.AgentResponse.TrackDataH\x00R\ttrackData\x12D\n" + + "\vtrack_image\x18\x03 \x01(\v2!.fishjam.AgentResponse.TrackImageH\x00R\n" + + "trackImage\x1a\x0f\n" + + "\rAuthenticated\x1al\n" + + "\tTrackData\x12\x17\n" + + "\apeer_id\x18\x01 \x01(\tR\x06peerId\x122\n" + + "\x05track\x18\x02 \x01(\v2\x1c.fishjam.notifications.TrackR\x05track\x12\x12\n" + + "\x04data\x18\x03 \x01(\fR\x04data\x1a^\n" + + "\n" + + "TrackImage\x12\x19\n" + + "\btrack_id\x18\x01 \x01(\tR\atrackId\x12!\n" + + "\fcontent_type\x18\x02 \x01(\tR\vcontentType\x12\x12\n" + + "\x04data\x18\x03 \x01(\fR\x04dataB\t\n" + + "\acontentB$Z\"conference-to-stream/proto/fishjamb\x06proto3" + +var ( + file_fishjam_agent_notifications_proto_rawDescOnce sync.Once + file_fishjam_agent_notifications_proto_rawDescData []byte +) + +func file_fishjam_agent_notifications_proto_rawDescGZIP() []byte { + file_fishjam_agent_notifications_proto_rawDescOnce.Do(func() { + file_fishjam_agent_notifications_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_fishjam_agent_notifications_proto_rawDesc), len(file_fishjam_agent_notifications_proto_rawDesc))) + }) + return file_fishjam_agent_notifications_proto_rawDescData +} + +var file_fishjam_agent_notifications_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_fishjam_agent_notifications_proto_goTypes = []any{ + (*AgentRequest)(nil), // 0: fishjam.AgentRequest + (*AgentResponse)(nil), // 1: fishjam.AgentResponse + (*AgentRequest_AuthRequest)(nil), // 2: fishjam.AgentRequest.AuthRequest + (*AgentRequest_AddTrack)(nil), // 3: fishjam.AgentRequest.AddTrack + (*AgentRequest_RemoveTrack)(nil), // 4: fishjam.AgentRequest.RemoveTrack + (*AgentRequest_TrackData)(nil), // 5: fishjam.AgentRequest.TrackData + (*AgentRequest_InterruptTrack)(nil), // 6: fishjam.AgentRequest.InterruptTrack + (*AgentRequest_CaptureImage)(nil), // 7: fishjam.AgentRequest.CaptureImage + (*AgentRequest_AddTrack_CodecParameters)(nil), // 8: fishjam.AgentRequest.AddTrack.CodecParameters + (*AgentResponse_Authenticated)(nil), // 9: fishjam.AgentResponse.Authenticated + (*AgentResponse_TrackData)(nil), // 10: fishjam.AgentResponse.TrackData + (*AgentResponse_TrackImage)(nil), // 11: fishjam.AgentResponse.TrackImage + (*notifications.Track)(nil), // 12: fishjam.notifications.Track + (notifications.TrackEncoding)(0), // 13: fishjam.notifications.TrackEncoding +} +var file_fishjam_agent_notifications_proto_depIdxs = []int32{ + 2, // 0: fishjam.AgentRequest.auth_request:type_name -> fishjam.AgentRequest.AuthRequest + 3, // 1: fishjam.AgentRequest.add_track:type_name -> fishjam.AgentRequest.AddTrack + 4, // 2: fishjam.AgentRequest.remove_track:type_name -> fishjam.AgentRequest.RemoveTrack + 5, // 3: fishjam.AgentRequest.track_data:type_name -> fishjam.AgentRequest.TrackData + 6, // 4: fishjam.AgentRequest.interrupt_track:type_name -> fishjam.AgentRequest.InterruptTrack + 7, // 5: fishjam.AgentRequest.capture_image:type_name -> fishjam.AgentRequest.CaptureImage + 9, // 6: fishjam.AgentResponse.authenticated:type_name -> fishjam.AgentResponse.Authenticated + 10, // 7: fishjam.AgentResponse.track_data:type_name -> fishjam.AgentResponse.TrackData + 11, // 8: fishjam.AgentResponse.track_image:type_name -> fishjam.AgentResponse.TrackImage + 12, // 9: fishjam.AgentRequest.AddTrack.track:type_name -> fishjam.notifications.Track + 8, // 10: fishjam.AgentRequest.AddTrack.codec_params:type_name -> fishjam.AgentRequest.AddTrack.CodecParameters + 13, // 11: fishjam.AgentRequest.AddTrack.CodecParameters.encoding:type_name -> fishjam.notifications.TrackEncoding + 12, // 12: fishjam.AgentResponse.TrackData.track:type_name -> fishjam.notifications.Track + 13, // [13:13] is the sub-list for method output_type + 13, // [13:13] is the sub-list for method input_type + 13, // [13:13] is the sub-list for extension type_name + 13, // [13:13] is the sub-list for extension extendee + 0, // [0:13] is the sub-list for field type_name +} + +func init() { file_fishjam_agent_notifications_proto_init() } +func file_fishjam_agent_notifications_proto_init() { + if File_fishjam_agent_notifications_proto != nil { + return + } + file_fishjam_agent_notifications_proto_msgTypes[0].OneofWrappers = []any{ + (*AgentRequest_AuthRequest_)(nil), + (*AgentRequest_AddTrack_)(nil), + (*AgentRequest_RemoveTrack_)(nil), + (*AgentRequest_TrackData_)(nil), + (*AgentRequest_InterruptTrack_)(nil), + (*AgentRequest_CaptureImage_)(nil), + } + file_fishjam_agent_notifications_proto_msgTypes[1].OneofWrappers = []any{ + (*AgentResponse_Authenticated_)(nil), + (*AgentResponse_TrackData_)(nil), + (*AgentResponse_TrackImage_)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_fishjam_agent_notifications_proto_rawDesc), len(file_fishjam_agent_notifications_proto_rawDesc)), + NumEnums: 0, + NumMessages: 12, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_fishjam_agent_notifications_proto_goTypes, + DependencyIndexes: file_fishjam_agent_notifications_proto_depIdxs, + MessageInfos: file_fishjam_agent_notifications_proto_msgTypes, + }.Build() + File_fishjam_agent_notifications_proto = out.File + file_fishjam_agent_notifications_proto_goTypes = nil + file_fishjam_agent_notifications_proto_depIdxs = nil +} diff --git a/conference-to-stream/backend/proto/fishjam/media_events/peer/peer.pb.go b/conference-to-stream/backend/proto/fishjam/media_events/peer/peer.pb.go new file mode 100644 index 0000000..e6cb920 --- /dev/null +++ b/conference-to-stream/backend/proto/fishjam/media_events/peer/peer.pb.go @@ -0,0 +1,1026 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v6.33.1 +// source: fishjam/media_events/peer/peer.proto + +package peer + +import ( + media_events "conference-to-stream/proto/fishjam/media_events" + 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 any type of message sent from Peer to Membrane RTC Engine +type MediaEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Content: + // + // *MediaEvent_Connect_ + // *MediaEvent_Disconnect_ + // *MediaEvent_UpdateEndpointMetadata_ + // *MediaEvent_UpdateTrackMetadata_ + // *MediaEvent_RenegotiateTracks_ + // *MediaEvent_Candidate + // *MediaEvent_SdpOffer_ + // *MediaEvent_TrackBitrates_ + // *MediaEvent_EnableTrackVariant_ + // *MediaEvent_DisableTrackVariant_ + // *MediaEvent_SetTargetTrackVariant_ + // *MediaEvent_UnmuteTrack_ + Content isMediaEvent_Content `protobuf_oneof:"content"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent) Reset() { + *x = MediaEvent{} + mi := &file_fishjam_media_events_peer_peer_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent) ProtoMessage() {} + +func (x *MediaEvent) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_peer_peer_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 MediaEvent.ProtoReflect.Descriptor instead. +func (*MediaEvent) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_peer_peer_proto_rawDescGZIP(), []int{0} +} + +func (x *MediaEvent) GetContent() isMediaEvent_Content { + if x != nil { + return x.Content + } + return nil +} + +func (x *MediaEvent) GetConnect() *MediaEvent_Connect { + if x != nil { + if x, ok := x.Content.(*MediaEvent_Connect_); ok { + return x.Connect + } + } + return nil +} + +func (x *MediaEvent) GetDisconnect() *MediaEvent_Disconnect { + if x != nil { + if x, ok := x.Content.(*MediaEvent_Disconnect_); ok { + return x.Disconnect + } + } + return nil +} + +func (x *MediaEvent) GetUpdateEndpointMetadata() *MediaEvent_UpdateEndpointMetadata { + if x != nil { + if x, ok := x.Content.(*MediaEvent_UpdateEndpointMetadata_); ok { + return x.UpdateEndpointMetadata + } + } + return nil +} + +func (x *MediaEvent) GetUpdateTrackMetadata() *MediaEvent_UpdateTrackMetadata { + if x != nil { + if x, ok := x.Content.(*MediaEvent_UpdateTrackMetadata_); ok { + return x.UpdateTrackMetadata + } + } + return nil +} + +func (x *MediaEvent) GetRenegotiateTracks() *MediaEvent_RenegotiateTracks { + if x != nil { + if x, ok := x.Content.(*MediaEvent_RenegotiateTracks_); ok { + return x.RenegotiateTracks + } + } + return nil +} + +func (x *MediaEvent) GetCandidate() *media_events.Candidate { + if x != nil { + if x, ok := x.Content.(*MediaEvent_Candidate); ok { + return x.Candidate + } + } + return nil +} + +func (x *MediaEvent) GetSdpOffer() *MediaEvent_SdpOffer { + if x != nil { + if x, ok := x.Content.(*MediaEvent_SdpOffer_); ok { + return x.SdpOffer + } + } + return nil +} + +func (x *MediaEvent) GetTrackBitrates() *MediaEvent_TrackBitrates { + if x != nil { + if x, ok := x.Content.(*MediaEvent_TrackBitrates_); ok { + return x.TrackBitrates + } + } + return nil +} + +func (x *MediaEvent) GetEnableTrackVariant() *MediaEvent_EnableTrackVariant { + if x != nil { + if x, ok := x.Content.(*MediaEvent_EnableTrackVariant_); ok { + return x.EnableTrackVariant + } + } + return nil +} + +func (x *MediaEvent) GetDisableTrackVariant() *MediaEvent_DisableTrackVariant { + if x != nil { + if x, ok := x.Content.(*MediaEvent_DisableTrackVariant_); ok { + return x.DisableTrackVariant + } + } + return nil +} + +func (x *MediaEvent) GetSetTargetTrackVariant() *MediaEvent_SetTargetTrackVariant { + if x != nil { + if x, ok := x.Content.(*MediaEvent_SetTargetTrackVariant_); ok { + return x.SetTargetTrackVariant + } + } + return nil +} + +func (x *MediaEvent) GetUnmuteTrack() *MediaEvent_UnmuteTrack { + if x != nil { + if x, ok := x.Content.(*MediaEvent_UnmuteTrack_); ok { + return x.UnmuteTrack + } + } + return nil +} + +type isMediaEvent_Content interface { + isMediaEvent_Content() +} + +type MediaEvent_Connect_ struct { + Connect *MediaEvent_Connect `protobuf:"bytes,1,opt,name=connect,proto3,oneof"` +} + +type MediaEvent_Disconnect_ struct { + Disconnect *MediaEvent_Disconnect `protobuf:"bytes,2,opt,name=disconnect,proto3,oneof"` +} + +type MediaEvent_UpdateEndpointMetadata_ struct { + UpdateEndpointMetadata *MediaEvent_UpdateEndpointMetadata `protobuf:"bytes,3,opt,name=update_endpoint_metadata,json=updateEndpointMetadata,proto3,oneof"` +} + +type MediaEvent_UpdateTrackMetadata_ struct { + UpdateTrackMetadata *MediaEvent_UpdateTrackMetadata `protobuf:"bytes,4,opt,name=update_track_metadata,json=updateTrackMetadata,proto3,oneof"` +} + +type MediaEvent_RenegotiateTracks_ struct { + RenegotiateTracks *MediaEvent_RenegotiateTracks `protobuf:"bytes,5,opt,name=renegotiate_tracks,json=renegotiateTracks,proto3,oneof"` +} + +type MediaEvent_Candidate struct { + Candidate *media_events.Candidate `protobuf:"bytes,6,opt,name=candidate,proto3,oneof"` +} + +type MediaEvent_SdpOffer_ struct { + SdpOffer *MediaEvent_SdpOffer `protobuf:"bytes,7,opt,name=sdp_offer,json=sdpOffer,proto3,oneof"` +} + +type MediaEvent_TrackBitrates_ struct { + TrackBitrates *MediaEvent_TrackBitrates `protobuf:"bytes,8,opt,name=track_bitrates,json=trackBitrates,proto3,oneof"` +} + +type MediaEvent_EnableTrackVariant_ struct { + EnableTrackVariant *MediaEvent_EnableTrackVariant `protobuf:"bytes,9,opt,name=enable_track_variant,json=enableTrackVariant,proto3,oneof"` +} + +type MediaEvent_DisableTrackVariant_ struct { + DisableTrackVariant *MediaEvent_DisableTrackVariant `protobuf:"bytes,10,opt,name=disable_track_variant,json=disableTrackVariant,proto3,oneof"` +} + +type MediaEvent_SetTargetTrackVariant_ struct { + SetTargetTrackVariant *MediaEvent_SetTargetTrackVariant `protobuf:"bytes,11,opt,name=set_target_track_variant,json=setTargetTrackVariant,proto3,oneof"` +} + +type MediaEvent_UnmuteTrack_ struct { + UnmuteTrack *MediaEvent_UnmuteTrack `protobuf:"bytes,12,opt,name=unmute_track,json=unmuteTrack,proto3,oneof"` +} + +func (*MediaEvent_Connect_) isMediaEvent_Content() {} + +func (*MediaEvent_Disconnect_) isMediaEvent_Content() {} + +func (*MediaEvent_UpdateEndpointMetadata_) isMediaEvent_Content() {} + +func (*MediaEvent_UpdateTrackMetadata_) isMediaEvent_Content() {} + +func (*MediaEvent_RenegotiateTracks_) isMediaEvent_Content() {} + +func (*MediaEvent_Candidate) isMediaEvent_Content() {} + +func (*MediaEvent_SdpOffer_) isMediaEvent_Content() {} + +func (*MediaEvent_TrackBitrates_) isMediaEvent_Content() {} + +func (*MediaEvent_EnableTrackVariant_) isMediaEvent_Content() {} + +func (*MediaEvent_DisableTrackVariant_) isMediaEvent_Content() {} + +func (*MediaEvent_SetTargetTrackVariant_) isMediaEvent_Content() {} + +func (*MediaEvent_UnmuteTrack_) isMediaEvent_Content() {} + +type MediaEvent_VariantBitrate struct { + state protoimpl.MessageState `protogen:"open.v1"` + Variant media_events.Variant `protobuf:"varint,1,opt,name=variant,proto3,enum=fishjam.media_events.Variant" json:"variant,omitempty"` + Bitrate int32 `protobuf:"varint,2,opt,name=bitrate,proto3" json:"bitrate,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_VariantBitrate) Reset() { + *x = MediaEvent_VariantBitrate{} + mi := &file_fishjam_media_events_peer_peer_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_VariantBitrate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_VariantBitrate) ProtoMessage() {} + +func (x *MediaEvent_VariantBitrate) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_peer_peer_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 MediaEvent_VariantBitrate.ProtoReflect.Descriptor instead. +func (*MediaEvent_VariantBitrate) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_peer_peer_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *MediaEvent_VariantBitrate) GetVariant() media_events.Variant { + if x != nil { + return x.Variant + } + return media_events.Variant(0) +} + +func (x *MediaEvent_VariantBitrate) GetBitrate() int32 { + if x != nil { + return x.Bitrate + } + return 0 +} + +// Sent when a peer wants to join WebRTC Endpoint. +type MediaEvent_Connect struct { + state protoimpl.MessageState `protogen:"open.v1"` + MetadataJson string `protobuf:"bytes,1,opt,name=metadata_json,json=metadataJson,proto3" json:"metadata_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_Connect) Reset() { + *x = MediaEvent_Connect{} + mi := &file_fishjam_media_events_peer_peer_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_Connect) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_Connect) ProtoMessage() {} + +func (x *MediaEvent_Connect) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_peer_peer_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 MediaEvent_Connect.ProtoReflect.Descriptor instead. +func (*MediaEvent_Connect) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_peer_peer_proto_rawDescGZIP(), []int{0, 1} +} + +func (x *MediaEvent_Connect) GetMetadataJson() string { + if x != nil { + return x.MetadataJson + } + return "" +} + +// Sent when a peer disconnects from WebRTC Endpoint. +type MediaEvent_Disconnect struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_Disconnect) Reset() { + *x = MediaEvent_Disconnect{} + mi := &file_fishjam_media_events_peer_peer_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_Disconnect) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_Disconnect) ProtoMessage() {} + +func (x *MediaEvent_Disconnect) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_peer_peer_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 MediaEvent_Disconnect.ProtoReflect.Descriptor instead. +func (*MediaEvent_Disconnect) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_peer_peer_proto_rawDescGZIP(), []int{0, 2} +} + +// Sent when a peer wants to update its metadata +type MediaEvent_UpdateEndpointMetadata struct { + state protoimpl.MessageState `protogen:"open.v1"` + MetadataJson string `protobuf:"bytes,1,opt,name=metadata_json,json=metadataJson,proto3" json:"metadata_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_UpdateEndpointMetadata) Reset() { + *x = MediaEvent_UpdateEndpointMetadata{} + mi := &file_fishjam_media_events_peer_peer_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_UpdateEndpointMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_UpdateEndpointMetadata) ProtoMessage() {} + +func (x *MediaEvent_UpdateEndpointMetadata) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_peer_peer_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 MediaEvent_UpdateEndpointMetadata.ProtoReflect.Descriptor instead. +func (*MediaEvent_UpdateEndpointMetadata) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_peer_peer_proto_rawDescGZIP(), []int{0, 3} +} + +func (x *MediaEvent_UpdateEndpointMetadata) GetMetadataJson() string { + if x != nil { + return x.MetadataJson + } + return "" +} + +// Sent when a peer wants to update its track's metadata +type MediaEvent_UpdateTrackMetadata struct { + state protoimpl.MessageState `protogen:"open.v1"` + TrackId string `protobuf:"bytes,1,opt,name=track_id,json=trackId,proto3" json:"track_id,omitempty"` + MetadataJson string `protobuf:"bytes,2,opt,name=metadata_json,json=metadataJson,proto3" json:"metadata_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_UpdateTrackMetadata) Reset() { + *x = MediaEvent_UpdateTrackMetadata{} + mi := &file_fishjam_media_events_peer_peer_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_UpdateTrackMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_UpdateTrackMetadata) ProtoMessage() {} + +func (x *MediaEvent_UpdateTrackMetadata) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_peer_peer_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 MediaEvent_UpdateTrackMetadata.ProtoReflect.Descriptor instead. +func (*MediaEvent_UpdateTrackMetadata) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_peer_peer_proto_rawDescGZIP(), []int{0, 4} +} + +func (x *MediaEvent_UpdateTrackMetadata) GetTrackId() string { + if x != nil { + return x.TrackId + } + return "" +} + +func (x *MediaEvent_UpdateTrackMetadata) GetMetadataJson() string { + if x != nil { + return x.MetadataJson + } + return "" +} + +// Sent when peer wants to renegotiate connection due to adding a track or removing a track +type MediaEvent_RenegotiateTracks struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_RenegotiateTracks) Reset() { + *x = MediaEvent_RenegotiateTracks{} + mi := &file_fishjam_media_events_peer_peer_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_RenegotiateTracks) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_RenegotiateTracks) ProtoMessage() {} + +func (x *MediaEvent_RenegotiateTracks) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_peer_peer_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 MediaEvent_RenegotiateTracks.ProtoReflect.Descriptor instead. +func (*MediaEvent_RenegotiateTracks) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_peer_peer_proto_rawDescGZIP(), []int{0, 5} +} + +// Sent as a response to `offerData` media event during renegotiation +// Maps contain only information about current peer's `sendonly` tracks. +// The "mid" is an identifier used to associate an RTP packet with an MLine from the SDP offer/answer. +type MediaEvent_SdpOffer struct { + state protoimpl.MessageState `protogen:"open.v1"` + Sdp string `protobuf:"bytes,1,opt,name=sdp,proto3" json:"sdp,omitempty"` // The value of the `sessionDescription.sdp` + TrackIdToMetadataJson map[string]string `protobuf:"bytes,2,rep,name=track_id_to_metadata_json,json=trackIdToMetadataJson,proto3" json:"track_id_to_metadata_json,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + TrackIdToBitrates map[string]*MediaEvent_TrackBitrates `protobuf:"bytes,3,rep,name=track_id_to_bitrates,json=trackIdToBitrates,proto3" json:"track_id_to_bitrates,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // Maps track_id to its bitrate. The track_id in the TrackBitrates message is ignored (we use the map key), so it can be omitted. + MidToTrackId map[string]string `protobuf:"bytes,4,rep,name=mid_to_track_id,json=midToTrackId,proto3" json:"mid_to_track_id,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_SdpOffer) Reset() { + *x = MediaEvent_SdpOffer{} + mi := &file_fishjam_media_events_peer_peer_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_SdpOffer) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_SdpOffer) ProtoMessage() {} + +func (x *MediaEvent_SdpOffer) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_peer_peer_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 MediaEvent_SdpOffer.ProtoReflect.Descriptor instead. +func (*MediaEvent_SdpOffer) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_peer_peer_proto_rawDescGZIP(), []int{0, 6} +} + +func (x *MediaEvent_SdpOffer) GetSdp() string { + if x != nil { + return x.Sdp + } + return "" +} + +func (x *MediaEvent_SdpOffer) GetTrackIdToMetadataJson() map[string]string { + if x != nil { + return x.TrackIdToMetadataJson + } + return nil +} + +func (x *MediaEvent_SdpOffer) GetTrackIdToBitrates() map[string]*MediaEvent_TrackBitrates { + if x != nil { + return x.TrackIdToBitrates + } + return nil +} + +func (x *MediaEvent_SdpOffer) GetMidToTrackId() map[string]string { + if x != nil { + return x.MidToTrackId + } + return nil +} + +// Sent when Peer wants to update its track's bitrate +type MediaEvent_TrackBitrates struct { + state protoimpl.MessageState `protogen:"open.v1"` + TrackId string `protobuf:"bytes,1,opt,name=track_id,json=trackId,proto3" json:"track_id,omitempty"` + VariantBitrates []*MediaEvent_VariantBitrate `protobuf:"bytes,2,rep,name=variant_bitrates,json=variantBitrates,proto3" json:"variant_bitrates,omitempty"` // Bitrate of each variant. For non-simulcast tracks use VARIANT_UNSPECIFIED. + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_TrackBitrates) Reset() { + *x = MediaEvent_TrackBitrates{} + mi := &file_fishjam_media_events_peer_peer_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_TrackBitrates) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_TrackBitrates) ProtoMessage() {} + +func (x *MediaEvent_TrackBitrates) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_peer_peer_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 MediaEvent_TrackBitrates.ProtoReflect.Descriptor instead. +func (*MediaEvent_TrackBitrates) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_peer_peer_proto_rawDescGZIP(), []int{0, 7} +} + +func (x *MediaEvent_TrackBitrates) GetTrackId() string { + if x != nil { + return x.TrackId + } + return "" +} + +func (x *MediaEvent_TrackBitrates) GetVariantBitrates() []*MediaEvent_VariantBitrate { + if x != nil { + return x.VariantBitrates + } + return nil +} + +// Sent when client disables one of the track variants +type MediaEvent_DisableTrackVariant struct { + state protoimpl.MessageState `protogen:"open.v1"` + TrackId string `protobuf:"bytes,1,opt,name=track_id,json=trackId,proto3" json:"track_id,omitempty"` + Variant media_events.Variant `protobuf:"varint,2,opt,name=variant,proto3,enum=fishjam.media_events.Variant" json:"variant,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_DisableTrackVariant) Reset() { + *x = MediaEvent_DisableTrackVariant{} + mi := &file_fishjam_media_events_peer_peer_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_DisableTrackVariant) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_DisableTrackVariant) ProtoMessage() {} + +func (x *MediaEvent_DisableTrackVariant) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_peer_peer_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 MediaEvent_DisableTrackVariant.ProtoReflect.Descriptor instead. +func (*MediaEvent_DisableTrackVariant) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_peer_peer_proto_rawDescGZIP(), []int{0, 8} +} + +func (x *MediaEvent_DisableTrackVariant) GetTrackId() string { + if x != nil { + return x.TrackId + } + return "" +} + +func (x *MediaEvent_DisableTrackVariant) GetVariant() media_events.Variant { + if x != nil { + return x.Variant + } + return media_events.Variant(0) +} + +// Sent when client enables one of the track variants +type MediaEvent_EnableTrackVariant struct { + state protoimpl.MessageState `protogen:"open.v1"` + TrackId string `protobuf:"bytes,1,opt,name=track_id,json=trackId,proto3" json:"track_id,omitempty"` + Variant media_events.Variant `protobuf:"varint,2,opt,name=variant,proto3,enum=fishjam.media_events.Variant" json:"variant,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_EnableTrackVariant) Reset() { + *x = MediaEvent_EnableTrackVariant{} + mi := &file_fishjam_media_events_peer_peer_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_EnableTrackVariant) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_EnableTrackVariant) ProtoMessage() {} + +func (x *MediaEvent_EnableTrackVariant) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_peer_peer_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 MediaEvent_EnableTrackVariant.ProtoReflect.Descriptor instead. +func (*MediaEvent_EnableTrackVariant) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_peer_peer_proto_rawDescGZIP(), []int{0, 9} +} + +func (x *MediaEvent_EnableTrackVariant) GetTrackId() string { + if x != nil { + return x.TrackId + } + return "" +} + +func (x *MediaEvent_EnableTrackVariant) GetVariant() media_events.Variant { + if x != nil { + return x.Variant + } + return media_events.Variant(0) +} + +type MediaEvent_SetTargetTrackVariant struct { + state protoimpl.MessageState `protogen:"open.v1"` + TrackId string `protobuf:"bytes,1,opt,name=track_id,json=trackId,proto3" json:"track_id,omitempty"` + Variant media_events.Variant `protobuf:"varint,2,opt,name=variant,proto3,enum=fishjam.media_events.Variant" json:"variant,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_SetTargetTrackVariant) Reset() { + *x = MediaEvent_SetTargetTrackVariant{} + mi := &file_fishjam_media_events_peer_peer_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_SetTargetTrackVariant) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_SetTargetTrackVariant) ProtoMessage() {} + +func (x *MediaEvent_SetTargetTrackVariant) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_peer_peer_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 MediaEvent_SetTargetTrackVariant.ProtoReflect.Descriptor instead. +func (*MediaEvent_SetTargetTrackVariant) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_peer_peer_proto_rawDescGZIP(), []int{0, 10} +} + +func (x *MediaEvent_SetTargetTrackVariant) GetTrackId() string { + if x != nil { + return x.TrackId + } + return "" +} + +func (x *MediaEvent_SetTargetTrackVariant) GetVariant() media_events.Variant { + if x != nil { + return x.Variant + } + return media_events.Variant(0) +} + +type MediaEvent_UnmuteTrack struct { + state protoimpl.MessageState `protogen:"open.v1"` + TrackId string `protobuf:"bytes,1,opt,name=track_id,json=trackId,proto3" json:"track_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_UnmuteTrack) Reset() { + *x = MediaEvent_UnmuteTrack{} + mi := &file_fishjam_media_events_peer_peer_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_UnmuteTrack) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_UnmuteTrack) ProtoMessage() {} + +func (x *MediaEvent_UnmuteTrack) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_peer_peer_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 MediaEvent_UnmuteTrack.ProtoReflect.Descriptor instead. +func (*MediaEvent_UnmuteTrack) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_peer_peer_proto_rawDescGZIP(), []int{0, 11} +} + +func (x *MediaEvent_UnmuteTrack) GetTrackId() string { + if x != nil { + return x.TrackId + } + return "" +} + +var File_fishjam_media_events_peer_peer_proto protoreflect.FileDescriptor + +const file_fishjam_media_events_peer_peer_proto_rawDesc = "" + + "\n" + + "$fishjam/media_events/peer/peer.proto\x12\x19fishjam.media_events.peer\x1a!fishjam/media_events/shared.proto\"\xfc\x14\n" + + "\n" + + "MediaEvent\x12I\n" + + "\aconnect\x18\x01 \x01(\v2-.fishjam.media_events.peer.MediaEvent.ConnectH\x00R\aconnect\x12R\n" + + "\n" + + "disconnect\x18\x02 \x01(\v20.fishjam.media_events.peer.MediaEvent.DisconnectH\x00R\n" + + "disconnect\x12x\n" + + "\x18update_endpoint_metadata\x18\x03 \x01(\v2<.fishjam.media_events.peer.MediaEvent.UpdateEndpointMetadataH\x00R\x16updateEndpointMetadata\x12o\n" + + "\x15update_track_metadata\x18\x04 \x01(\v29.fishjam.media_events.peer.MediaEvent.UpdateTrackMetadataH\x00R\x13updateTrackMetadata\x12h\n" + + "\x12renegotiate_tracks\x18\x05 \x01(\v27.fishjam.media_events.peer.MediaEvent.RenegotiateTracksH\x00R\x11renegotiateTracks\x12?\n" + + "\tcandidate\x18\x06 \x01(\v2\x1f.fishjam.media_events.CandidateH\x00R\tcandidate\x12M\n" + + "\tsdp_offer\x18\a \x01(\v2..fishjam.media_events.peer.MediaEvent.SdpOfferH\x00R\bsdpOffer\x12\\\n" + + "\x0etrack_bitrates\x18\b \x01(\v23.fishjam.media_events.peer.MediaEvent.TrackBitratesH\x00R\rtrackBitrates\x12l\n" + + "\x14enable_track_variant\x18\t \x01(\v28.fishjam.media_events.peer.MediaEvent.EnableTrackVariantH\x00R\x12enableTrackVariant\x12o\n" + + "\x15disable_track_variant\x18\n" + + " \x01(\v29.fishjam.media_events.peer.MediaEvent.DisableTrackVariantH\x00R\x13disableTrackVariant\x12v\n" + + "\x18set_target_track_variant\x18\v \x01(\v2;.fishjam.media_events.peer.MediaEvent.SetTargetTrackVariantH\x00R\x15setTargetTrackVariant\x12V\n" + + "\funmute_track\x18\f \x01(\v21.fishjam.media_events.peer.MediaEvent.UnmuteTrackH\x00R\vunmuteTrack\x1ac\n" + + "\x0eVariantBitrate\x127\n" + + "\avariant\x18\x01 \x01(\x0e2\x1d.fishjam.media_events.VariantR\avariant\x12\x18\n" + + "\abitrate\x18\x02 \x01(\x05R\abitrate\x1a.\n" + + "\aConnect\x12#\n" + + "\rmetadata_json\x18\x01 \x01(\tR\fmetadataJson\x1a\f\n" + + "\n" + + "Disconnect\x1a=\n" + + "\x16UpdateEndpointMetadata\x12#\n" + + "\rmetadata_json\x18\x01 \x01(\tR\fmetadataJson\x1aU\n" + + "\x13UpdateTrackMetadata\x12\x19\n" + + "\btrack_id\x18\x01 \x01(\tR\atrackId\x12#\n" + + "\rmetadata_json\x18\x02 \x01(\tR\fmetadataJson\x1a\x13\n" + + "\x11RenegotiateTracks\x1a\x89\x05\n" + + "\bSdpOffer\x12\x10\n" + + "\x03sdp\x18\x01 \x01(\tR\x03sdp\x12\x83\x01\n" + + "\x19track_id_to_metadata_json\x18\x02 \x03(\v2I.fishjam.media_events.peer.MediaEvent.SdpOffer.TrackIdToMetadataJsonEntryR\x15trackIdToMetadataJson\x12v\n" + + "\x14track_id_to_bitrates\x18\x03 \x03(\v2E.fishjam.media_events.peer.MediaEvent.SdpOffer.TrackIdToBitratesEntryR\x11trackIdToBitrates\x12g\n" + + "\x0fmid_to_track_id\x18\x04 \x03(\v2@.fishjam.media_events.peer.MediaEvent.SdpOffer.MidToTrackIdEntryR\fmidToTrackId\x1aH\n" + + "\x1aTrackIdToMetadataJsonEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1ay\n" + + "\x16TrackIdToBitratesEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12I\n" + + "\x05value\x18\x02 \x01(\v23.fishjam.media_events.peer.MediaEvent.TrackBitratesR\x05value:\x028\x01\x1a?\n" + + "\x11MidToTrackIdEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1a\x8b\x01\n" + + "\rTrackBitrates\x12\x19\n" + + "\btrack_id\x18\x01 \x01(\tR\atrackId\x12_\n" + + "\x10variant_bitrates\x18\x02 \x03(\v24.fishjam.media_events.peer.MediaEvent.VariantBitrateR\x0fvariantBitrates\x1ai\n" + + "\x13DisableTrackVariant\x12\x19\n" + + "\btrack_id\x18\x01 \x01(\tR\atrackId\x127\n" + + "\avariant\x18\x02 \x01(\x0e2\x1d.fishjam.media_events.VariantR\avariant\x1ah\n" + + "\x12EnableTrackVariant\x12\x19\n" + + "\btrack_id\x18\x01 \x01(\tR\atrackId\x127\n" + + "\avariant\x18\x02 \x01(\x0e2\x1d.fishjam.media_events.VariantR\avariant\x1ak\n" + + "\x15SetTargetTrackVariant\x12\x19\n" + + "\btrack_id\x18\x01 \x01(\tR\atrackId\x127\n" + + "\avariant\x18\x02 \x01(\x0e2\x1d.fishjam.media_events.VariantR\avariant\x1a(\n" + + "\vUnmuteTrack\x12\x19\n" + + "\btrack_id\x18\x01 \x01(\tR\atrackIdB\t\n" + + "\acontentB6Z4conference-to-stream/proto/fishjam/media_events/peerb\x06proto3" + +var ( + file_fishjam_media_events_peer_peer_proto_rawDescOnce sync.Once + file_fishjam_media_events_peer_peer_proto_rawDescData []byte +) + +func file_fishjam_media_events_peer_peer_proto_rawDescGZIP() []byte { + file_fishjam_media_events_peer_peer_proto_rawDescOnce.Do(func() { + file_fishjam_media_events_peer_peer_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_fishjam_media_events_peer_peer_proto_rawDesc), len(file_fishjam_media_events_peer_peer_proto_rawDesc))) + }) + return file_fishjam_media_events_peer_peer_proto_rawDescData +} + +var file_fishjam_media_events_peer_peer_proto_msgTypes = make([]protoimpl.MessageInfo, 16) +var file_fishjam_media_events_peer_peer_proto_goTypes = []any{ + (*MediaEvent)(nil), // 0: fishjam.media_events.peer.MediaEvent + (*MediaEvent_VariantBitrate)(nil), // 1: fishjam.media_events.peer.MediaEvent.VariantBitrate + (*MediaEvent_Connect)(nil), // 2: fishjam.media_events.peer.MediaEvent.Connect + (*MediaEvent_Disconnect)(nil), // 3: fishjam.media_events.peer.MediaEvent.Disconnect + (*MediaEvent_UpdateEndpointMetadata)(nil), // 4: fishjam.media_events.peer.MediaEvent.UpdateEndpointMetadata + (*MediaEvent_UpdateTrackMetadata)(nil), // 5: fishjam.media_events.peer.MediaEvent.UpdateTrackMetadata + (*MediaEvent_RenegotiateTracks)(nil), // 6: fishjam.media_events.peer.MediaEvent.RenegotiateTracks + (*MediaEvent_SdpOffer)(nil), // 7: fishjam.media_events.peer.MediaEvent.SdpOffer + (*MediaEvent_TrackBitrates)(nil), // 8: fishjam.media_events.peer.MediaEvent.TrackBitrates + (*MediaEvent_DisableTrackVariant)(nil), // 9: fishjam.media_events.peer.MediaEvent.DisableTrackVariant + (*MediaEvent_EnableTrackVariant)(nil), // 10: fishjam.media_events.peer.MediaEvent.EnableTrackVariant + (*MediaEvent_SetTargetTrackVariant)(nil), // 11: fishjam.media_events.peer.MediaEvent.SetTargetTrackVariant + (*MediaEvent_UnmuteTrack)(nil), // 12: fishjam.media_events.peer.MediaEvent.UnmuteTrack + nil, // 13: fishjam.media_events.peer.MediaEvent.SdpOffer.TrackIdToMetadataJsonEntry + nil, // 14: fishjam.media_events.peer.MediaEvent.SdpOffer.TrackIdToBitratesEntry + nil, // 15: fishjam.media_events.peer.MediaEvent.SdpOffer.MidToTrackIdEntry + (*media_events.Candidate)(nil), // 16: fishjam.media_events.Candidate + (media_events.Variant)(0), // 17: fishjam.media_events.Variant +} +var file_fishjam_media_events_peer_peer_proto_depIdxs = []int32{ + 2, // 0: fishjam.media_events.peer.MediaEvent.connect:type_name -> fishjam.media_events.peer.MediaEvent.Connect + 3, // 1: fishjam.media_events.peer.MediaEvent.disconnect:type_name -> fishjam.media_events.peer.MediaEvent.Disconnect + 4, // 2: fishjam.media_events.peer.MediaEvent.update_endpoint_metadata:type_name -> fishjam.media_events.peer.MediaEvent.UpdateEndpointMetadata + 5, // 3: fishjam.media_events.peer.MediaEvent.update_track_metadata:type_name -> fishjam.media_events.peer.MediaEvent.UpdateTrackMetadata + 6, // 4: fishjam.media_events.peer.MediaEvent.renegotiate_tracks:type_name -> fishjam.media_events.peer.MediaEvent.RenegotiateTracks + 16, // 5: fishjam.media_events.peer.MediaEvent.candidate:type_name -> fishjam.media_events.Candidate + 7, // 6: fishjam.media_events.peer.MediaEvent.sdp_offer:type_name -> fishjam.media_events.peer.MediaEvent.SdpOffer + 8, // 7: fishjam.media_events.peer.MediaEvent.track_bitrates:type_name -> fishjam.media_events.peer.MediaEvent.TrackBitrates + 10, // 8: fishjam.media_events.peer.MediaEvent.enable_track_variant:type_name -> fishjam.media_events.peer.MediaEvent.EnableTrackVariant + 9, // 9: fishjam.media_events.peer.MediaEvent.disable_track_variant:type_name -> fishjam.media_events.peer.MediaEvent.DisableTrackVariant + 11, // 10: fishjam.media_events.peer.MediaEvent.set_target_track_variant:type_name -> fishjam.media_events.peer.MediaEvent.SetTargetTrackVariant + 12, // 11: fishjam.media_events.peer.MediaEvent.unmute_track:type_name -> fishjam.media_events.peer.MediaEvent.UnmuteTrack + 17, // 12: fishjam.media_events.peer.MediaEvent.VariantBitrate.variant:type_name -> fishjam.media_events.Variant + 13, // 13: fishjam.media_events.peer.MediaEvent.SdpOffer.track_id_to_metadata_json:type_name -> fishjam.media_events.peer.MediaEvent.SdpOffer.TrackIdToMetadataJsonEntry + 14, // 14: fishjam.media_events.peer.MediaEvent.SdpOffer.track_id_to_bitrates:type_name -> fishjam.media_events.peer.MediaEvent.SdpOffer.TrackIdToBitratesEntry + 15, // 15: fishjam.media_events.peer.MediaEvent.SdpOffer.mid_to_track_id:type_name -> fishjam.media_events.peer.MediaEvent.SdpOffer.MidToTrackIdEntry + 1, // 16: fishjam.media_events.peer.MediaEvent.TrackBitrates.variant_bitrates:type_name -> fishjam.media_events.peer.MediaEvent.VariantBitrate + 17, // 17: fishjam.media_events.peer.MediaEvent.DisableTrackVariant.variant:type_name -> fishjam.media_events.Variant + 17, // 18: fishjam.media_events.peer.MediaEvent.EnableTrackVariant.variant:type_name -> fishjam.media_events.Variant + 17, // 19: fishjam.media_events.peer.MediaEvent.SetTargetTrackVariant.variant:type_name -> fishjam.media_events.Variant + 8, // 20: fishjam.media_events.peer.MediaEvent.SdpOffer.TrackIdToBitratesEntry.value:type_name -> fishjam.media_events.peer.MediaEvent.TrackBitrates + 21, // [21:21] is the sub-list for method output_type + 21, // [21:21] is the sub-list for method input_type + 21, // [21:21] is the sub-list for extension type_name + 21, // [21:21] is the sub-list for extension extendee + 0, // [0:21] is the sub-list for field type_name +} + +func init() { file_fishjam_media_events_peer_peer_proto_init() } +func file_fishjam_media_events_peer_peer_proto_init() { + if File_fishjam_media_events_peer_peer_proto != nil { + return + } + file_fishjam_media_events_peer_peer_proto_msgTypes[0].OneofWrappers = []any{ + (*MediaEvent_Connect_)(nil), + (*MediaEvent_Disconnect_)(nil), + (*MediaEvent_UpdateEndpointMetadata_)(nil), + (*MediaEvent_UpdateTrackMetadata_)(nil), + (*MediaEvent_RenegotiateTracks_)(nil), + (*MediaEvent_Candidate)(nil), + (*MediaEvent_SdpOffer_)(nil), + (*MediaEvent_TrackBitrates_)(nil), + (*MediaEvent_EnableTrackVariant_)(nil), + (*MediaEvent_DisableTrackVariant_)(nil), + (*MediaEvent_SetTargetTrackVariant_)(nil), + (*MediaEvent_UnmuteTrack_)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_fishjam_media_events_peer_peer_proto_rawDesc), len(file_fishjam_media_events_peer_peer_proto_rawDesc)), + NumEnums: 0, + NumMessages: 16, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_fishjam_media_events_peer_peer_proto_goTypes, + DependencyIndexes: file_fishjam_media_events_peer_peer_proto_depIdxs, + MessageInfos: file_fishjam_media_events_peer_peer_proto_msgTypes, + }.Build() + File_fishjam_media_events_peer_peer_proto = out.File + file_fishjam_media_events_peer_peer_proto_goTypes = nil + file_fishjam_media_events_peer_peer_proto_depIdxs = nil +} diff --git a/conference-to-stream/backend/proto/fishjam/media_events/server/server.pb.go b/conference-to-stream/backend/proto/fishjam/media_events/server/server.pb.go new file mode 100644 index 0000000..b1d9490 --- /dev/null +++ b/conference-to-stream/backend/proto/fishjam/media_events/server/server.pb.go @@ -0,0 +1,1651 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v6.33.1 +// source: fishjam/media_events/server/server.proto + +package server + +import ( + media_events "conference-to-stream/proto/fishjam/media_events" + 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 MediaEvent_VadNotification_Status int32 + +const ( + MediaEvent_VadNotification_STATUS_UNSPECIFIED MediaEvent_VadNotification_Status = 0 + MediaEvent_VadNotification_STATUS_SILENCE MediaEvent_VadNotification_Status = 1 + MediaEvent_VadNotification_STATUS_SPEECH MediaEvent_VadNotification_Status = 2 +) + +// Enum value maps for MediaEvent_VadNotification_Status. +var ( + MediaEvent_VadNotification_Status_name = map[int32]string{ + 0: "STATUS_UNSPECIFIED", + 1: "STATUS_SILENCE", + 2: "STATUS_SPEECH", + } + MediaEvent_VadNotification_Status_value = map[string]int32{ + "STATUS_UNSPECIFIED": 0, + "STATUS_SILENCE": 1, + "STATUS_SPEECH": 2, + } +) + +func (x MediaEvent_VadNotification_Status) Enum() *MediaEvent_VadNotification_Status { + p := new(MediaEvent_VadNotification_Status) + *p = x + return p +} + +func (x MediaEvent_VadNotification_Status) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (MediaEvent_VadNotification_Status) Descriptor() protoreflect.EnumDescriptor { + return file_fishjam_media_events_server_server_proto_enumTypes[0].Descriptor() +} + +func (MediaEvent_VadNotification_Status) Type() protoreflect.EnumType { + return &file_fishjam_media_events_server_server_proto_enumTypes[0] +} + +func (x MediaEvent_VadNotification_Status) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use MediaEvent_VadNotification_Status.Descriptor instead. +func (MediaEvent_VadNotification_Status) EnumDescriptor() ([]byte, []int) { + return file_fishjam_media_events_server_server_proto_rawDescGZIP(), []int{0, 13, 0} +} + +// Defines any type of message sent from Membrane RTC Engine to Peer +type MediaEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Content: + // + // *MediaEvent_EndpointUpdated_ + // *MediaEvent_TrackUpdated_ + // *MediaEvent_TracksAdded_ + // *MediaEvent_TracksRemoved_ + // *MediaEvent_EndpointAdded_ + // *MediaEvent_EndpointRemoved_ + // *MediaEvent_Connected_ + // *MediaEvent_Error_ + // *MediaEvent_OfferData_ + // *MediaEvent_Candidate + // *MediaEvent_SdpAnswer_ + // *MediaEvent_VadNotification_ + // *MediaEvent_TrackVariantSwitched_ + // *MediaEvent_TrackVariantDisabled_ + // *MediaEvent_TrackVariantEnabled_ + Content isMediaEvent_Content `protobuf_oneof:"content"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent) Reset() { + *x = MediaEvent{} + mi := &file_fishjam_media_events_server_server_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent) ProtoMessage() {} + +func (x *MediaEvent) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_server_server_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 MediaEvent.ProtoReflect.Descriptor instead. +func (*MediaEvent) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_server_server_proto_rawDescGZIP(), []int{0} +} + +func (x *MediaEvent) GetContent() isMediaEvent_Content { + if x != nil { + return x.Content + } + return nil +} + +func (x *MediaEvent) GetEndpointUpdated() *MediaEvent_EndpointUpdated { + if x != nil { + if x, ok := x.Content.(*MediaEvent_EndpointUpdated_); ok { + return x.EndpointUpdated + } + } + return nil +} + +func (x *MediaEvent) GetTrackUpdated() *MediaEvent_TrackUpdated { + if x != nil { + if x, ok := x.Content.(*MediaEvent_TrackUpdated_); ok { + return x.TrackUpdated + } + } + return nil +} + +func (x *MediaEvent) GetTracksAdded() *MediaEvent_TracksAdded { + if x != nil { + if x, ok := x.Content.(*MediaEvent_TracksAdded_); ok { + return x.TracksAdded + } + } + return nil +} + +func (x *MediaEvent) GetTracksRemoved() *MediaEvent_TracksRemoved { + if x != nil { + if x, ok := x.Content.(*MediaEvent_TracksRemoved_); ok { + return x.TracksRemoved + } + } + return nil +} + +func (x *MediaEvent) GetEndpointAdded() *MediaEvent_EndpointAdded { + if x != nil { + if x, ok := x.Content.(*MediaEvent_EndpointAdded_); ok { + return x.EndpointAdded + } + } + return nil +} + +func (x *MediaEvent) GetEndpointRemoved() *MediaEvent_EndpointRemoved { + if x != nil { + if x, ok := x.Content.(*MediaEvent_EndpointRemoved_); ok { + return x.EndpointRemoved + } + } + return nil +} + +func (x *MediaEvent) GetConnected() *MediaEvent_Connected { + if x != nil { + if x, ok := x.Content.(*MediaEvent_Connected_); ok { + return x.Connected + } + } + return nil +} + +func (x *MediaEvent) GetError() *MediaEvent_Error { + if x != nil { + if x, ok := x.Content.(*MediaEvent_Error_); ok { + return x.Error + } + } + return nil +} + +func (x *MediaEvent) GetOfferData() *MediaEvent_OfferData { + if x != nil { + if x, ok := x.Content.(*MediaEvent_OfferData_); ok { + return x.OfferData + } + } + return nil +} + +func (x *MediaEvent) GetCandidate() *media_events.Candidate { + if x != nil { + if x, ok := x.Content.(*MediaEvent_Candidate); ok { + return x.Candidate + } + } + return nil +} + +func (x *MediaEvent) GetSdpAnswer() *MediaEvent_SdpAnswer { + if x != nil { + if x, ok := x.Content.(*MediaEvent_SdpAnswer_); ok { + return x.SdpAnswer + } + } + return nil +} + +func (x *MediaEvent) GetVadNotification() *MediaEvent_VadNotification { + if x != nil { + if x, ok := x.Content.(*MediaEvent_VadNotification_); ok { + return x.VadNotification + } + } + return nil +} + +func (x *MediaEvent) GetTrackVariantSwitched() *MediaEvent_TrackVariantSwitched { + if x != nil { + if x, ok := x.Content.(*MediaEvent_TrackVariantSwitched_); ok { + return x.TrackVariantSwitched + } + } + return nil +} + +func (x *MediaEvent) GetTrackVariantDisabled() *MediaEvent_TrackVariantDisabled { + if x != nil { + if x, ok := x.Content.(*MediaEvent_TrackVariantDisabled_); ok { + return x.TrackVariantDisabled + } + } + return nil +} + +func (x *MediaEvent) GetTrackVariantEnabled() *MediaEvent_TrackVariantEnabled { + if x != nil { + if x, ok := x.Content.(*MediaEvent_TrackVariantEnabled_); ok { + return x.TrackVariantEnabled + } + } + return nil +} + +type isMediaEvent_Content interface { + isMediaEvent_Content() +} + +type MediaEvent_EndpointUpdated_ struct { + EndpointUpdated *MediaEvent_EndpointUpdated `protobuf:"bytes,1,opt,name=endpoint_updated,json=endpointUpdated,proto3,oneof"` +} + +type MediaEvent_TrackUpdated_ struct { + TrackUpdated *MediaEvent_TrackUpdated `protobuf:"bytes,2,opt,name=track_updated,json=trackUpdated,proto3,oneof"` +} + +type MediaEvent_TracksAdded_ struct { + TracksAdded *MediaEvent_TracksAdded `protobuf:"bytes,3,opt,name=tracks_added,json=tracksAdded,proto3,oneof"` +} + +type MediaEvent_TracksRemoved_ struct { + TracksRemoved *MediaEvent_TracksRemoved `protobuf:"bytes,4,opt,name=tracks_removed,json=tracksRemoved,proto3,oneof"` +} + +type MediaEvent_EndpointAdded_ struct { + EndpointAdded *MediaEvent_EndpointAdded `protobuf:"bytes,5,opt,name=endpoint_added,json=endpointAdded,proto3,oneof"` +} + +type MediaEvent_EndpointRemoved_ struct { + EndpointRemoved *MediaEvent_EndpointRemoved `protobuf:"bytes,6,opt,name=endpoint_removed,json=endpointRemoved,proto3,oneof"` +} + +type MediaEvent_Connected_ struct { + Connected *MediaEvent_Connected `protobuf:"bytes,7,opt,name=connected,proto3,oneof"` +} + +type MediaEvent_Error_ struct { + Error *MediaEvent_Error `protobuf:"bytes,8,opt,name=error,proto3,oneof"` +} + +type MediaEvent_OfferData_ struct { + OfferData *MediaEvent_OfferData `protobuf:"bytes,9,opt,name=offer_data,json=offerData,proto3,oneof"` +} + +type MediaEvent_Candidate struct { + Candidate *media_events.Candidate `protobuf:"bytes,10,opt,name=candidate,proto3,oneof"` +} + +type MediaEvent_SdpAnswer_ struct { + SdpAnswer *MediaEvent_SdpAnswer `protobuf:"bytes,11,opt,name=sdp_answer,json=sdpAnswer,proto3,oneof"` +} + +type MediaEvent_VadNotification_ struct { + VadNotification *MediaEvent_VadNotification `protobuf:"bytes,12,opt,name=vad_notification,json=vadNotification,proto3,oneof"` +} + +type MediaEvent_TrackVariantSwitched_ struct { + TrackVariantSwitched *MediaEvent_TrackVariantSwitched `protobuf:"bytes,13,opt,name=track_variant_switched,json=trackVariantSwitched,proto3,oneof"` +} + +type MediaEvent_TrackVariantDisabled_ struct { + TrackVariantDisabled *MediaEvent_TrackVariantDisabled `protobuf:"bytes,14,opt,name=track_variant_disabled,json=trackVariantDisabled,proto3,oneof"` +} + +type MediaEvent_TrackVariantEnabled_ struct { + TrackVariantEnabled *MediaEvent_TrackVariantEnabled `protobuf:"bytes,15,opt,name=track_variant_enabled,json=trackVariantEnabled,proto3,oneof"` +} + +func (*MediaEvent_EndpointUpdated_) isMediaEvent_Content() {} + +func (*MediaEvent_TrackUpdated_) isMediaEvent_Content() {} + +func (*MediaEvent_TracksAdded_) isMediaEvent_Content() {} + +func (*MediaEvent_TracksRemoved_) isMediaEvent_Content() {} + +func (*MediaEvent_EndpointAdded_) isMediaEvent_Content() {} + +func (*MediaEvent_EndpointRemoved_) isMediaEvent_Content() {} + +func (*MediaEvent_Connected_) isMediaEvent_Content() {} + +func (*MediaEvent_Error_) isMediaEvent_Content() {} + +func (*MediaEvent_OfferData_) isMediaEvent_Content() {} + +func (*MediaEvent_Candidate) isMediaEvent_Content() {} + +func (*MediaEvent_SdpAnswer_) isMediaEvent_Content() {} + +func (*MediaEvent_VadNotification_) isMediaEvent_Content() {} + +func (*MediaEvent_TrackVariantSwitched_) isMediaEvent_Content() {} + +func (*MediaEvent_TrackVariantDisabled_) isMediaEvent_Content() {} + +func (*MediaEvent_TrackVariantEnabled_) isMediaEvent_Content() {} + +// SCHEMAS +type MediaEvent_Track struct { + state protoimpl.MessageState `protogen:"open.v1"` + MetadataJson string `protobuf:"bytes,1,opt,name=metadata_json,json=metadataJson,proto3" json:"metadata_json,omitempty"` + SimulcastConfig *MediaEvent_Track_SimulcastConfig `protobuf:"bytes,2,opt,name=simulcast_config,json=simulcastConfig,proto3" json:"simulcast_config,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_Track) Reset() { + *x = MediaEvent_Track{} + mi := &file_fishjam_media_events_server_server_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_Track) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_Track) ProtoMessage() {} + +func (x *MediaEvent_Track) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_server_server_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 MediaEvent_Track.ProtoReflect.Descriptor instead. +func (*MediaEvent_Track) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_server_server_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *MediaEvent_Track) GetMetadataJson() string { + if x != nil { + return x.MetadataJson + } + return "" +} + +func (x *MediaEvent_Track) GetSimulcastConfig() *MediaEvent_Track_SimulcastConfig { + if x != nil { + return x.SimulcastConfig + } + return nil +} + +type MediaEvent_Endpoint struct { + state protoimpl.MessageState `protogen:"open.v1"` + EndpointType string `protobuf:"bytes,2,opt,name=endpoint_type,json=endpointType,proto3" json:"endpoint_type,omitempty"` + MetadataJson string `protobuf:"bytes,3,opt,name=metadata_json,json=metadataJson,proto3" json:"metadata_json,omitempty"` + TrackIdToTrack map[string]*MediaEvent_Track `protobuf:"bytes,4,rep,name=track_id_to_track,json=trackIdToTrack,proto3" json:"track_id_to_track,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_Endpoint) Reset() { + *x = MediaEvent_Endpoint{} + mi := &file_fishjam_media_events_server_server_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_Endpoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_Endpoint) ProtoMessage() {} + +func (x *MediaEvent_Endpoint) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_server_server_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 MediaEvent_Endpoint.ProtoReflect.Descriptor instead. +func (*MediaEvent_Endpoint) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_server_server_proto_rawDescGZIP(), []int{0, 1} +} + +func (x *MediaEvent_Endpoint) GetEndpointType() string { + if x != nil { + return x.EndpointType + } + return "" +} + +func (x *MediaEvent_Endpoint) GetMetadataJson() string { + if x != nil { + return x.MetadataJson + } + return "" +} + +func (x *MediaEvent_Endpoint) GetTrackIdToTrack() map[string]*MediaEvent_Track { + if x != nil { + return x.TrackIdToTrack + } + return nil +} + +type MediaEvent_IceServer struct { + state protoimpl.MessageState `protogen:"open.v1"` + Credential string `protobuf:"bytes,1,opt,name=credential,proto3" json:"credential,omitempty"` + Urls []string `protobuf:"bytes,2,rep,name=urls,proto3" json:"urls,omitempty"` + Username string `protobuf:"bytes,3,opt,name=username,proto3" json:"username,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_IceServer) Reset() { + *x = MediaEvent_IceServer{} + mi := &file_fishjam_media_events_server_server_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_IceServer) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_IceServer) ProtoMessage() {} + +func (x *MediaEvent_IceServer) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_server_server_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 MediaEvent_IceServer.ProtoReflect.Descriptor instead. +func (*MediaEvent_IceServer) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_server_server_proto_rawDescGZIP(), []int{0, 2} +} + +func (x *MediaEvent_IceServer) GetCredential() string { + if x != nil { + return x.Credential + } + return "" +} + +func (x *MediaEvent_IceServer) GetUrls() []string { + if x != nil { + return x.Urls + } + return nil +} + +func (x *MediaEvent_IceServer) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +// Sent when metadata of one of the endpoints was updated +type MediaEvent_EndpointUpdated struct { + state protoimpl.MessageState `protogen:"open.v1"` + EndpointId string `protobuf:"bytes,1,opt,name=endpoint_id,json=endpointId,proto3" json:"endpoint_id,omitempty"` + MetadataJson string `protobuf:"bytes,2,opt,name=metadata_json,json=metadataJson,proto3" json:"metadata_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_EndpointUpdated) Reset() { + *x = MediaEvent_EndpointUpdated{} + mi := &file_fishjam_media_events_server_server_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_EndpointUpdated) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_EndpointUpdated) ProtoMessage() {} + +func (x *MediaEvent_EndpointUpdated) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_server_server_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 MediaEvent_EndpointUpdated.ProtoReflect.Descriptor instead. +func (*MediaEvent_EndpointUpdated) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_server_server_proto_rawDescGZIP(), []int{0, 3} +} + +func (x *MediaEvent_EndpointUpdated) GetEndpointId() string { + if x != nil { + return x.EndpointId + } + return "" +} + +func (x *MediaEvent_EndpointUpdated) GetMetadataJson() string { + if x != nil { + return x.MetadataJson + } + return "" +} + +// Sent when metadata of one of the tracks was updated +type MediaEvent_TrackUpdated struct { + state protoimpl.MessageState `protogen:"open.v1"` + EndpointId string `protobuf:"bytes,1,opt,name=endpoint_id,json=endpointId,proto3" json:"endpoint_id,omitempty"` + TrackId string `protobuf:"bytes,2,opt,name=track_id,json=trackId,proto3" json:"track_id,omitempty"` + MetadataJson string `protobuf:"bytes,3,opt,name=metadata_json,json=metadataJson,proto3" json:"metadata_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_TrackUpdated) Reset() { + *x = MediaEvent_TrackUpdated{} + mi := &file_fishjam_media_events_server_server_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_TrackUpdated) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_TrackUpdated) ProtoMessage() {} + +func (x *MediaEvent_TrackUpdated) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_server_server_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 MediaEvent_TrackUpdated.ProtoReflect.Descriptor instead. +func (*MediaEvent_TrackUpdated) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_server_server_proto_rawDescGZIP(), []int{0, 4} +} + +func (x *MediaEvent_TrackUpdated) GetEndpointId() string { + if x != nil { + return x.EndpointId + } + return "" +} + +func (x *MediaEvent_TrackUpdated) GetTrackId() string { + if x != nil { + return x.TrackId + } + return "" +} + +func (x *MediaEvent_TrackUpdated) GetMetadataJson() string { + if x != nil { + return x.MetadataJson + } + return "" +} + +// Sent to informs that one of the peers has added one or more tracks. +type MediaEvent_TracksAdded struct { + state protoimpl.MessageState `protogen:"open.v1"` + EndpointId string `protobuf:"bytes,1,opt,name=endpoint_id,json=endpointId,proto3" json:"endpoint_id,omitempty"` + TrackIdToTrack map[string]*MediaEvent_Track `protobuf:"bytes,2,rep,name=track_id_to_track,json=trackIdToTrack,proto3" json:"track_id_to_track,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_TracksAdded) Reset() { + *x = MediaEvent_TracksAdded{} + mi := &file_fishjam_media_events_server_server_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_TracksAdded) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_TracksAdded) ProtoMessage() {} + +func (x *MediaEvent_TracksAdded) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_server_server_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 MediaEvent_TracksAdded.ProtoReflect.Descriptor instead. +func (*MediaEvent_TracksAdded) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_server_server_proto_rawDescGZIP(), []int{0, 5} +} + +func (x *MediaEvent_TracksAdded) GetEndpointId() string { + if x != nil { + return x.EndpointId + } + return "" +} + +func (x *MediaEvent_TracksAdded) GetTrackIdToTrack() map[string]*MediaEvent_Track { + if x != nil { + return x.TrackIdToTrack + } + return nil +} + +// Sent to informs that one of the peers has removed one or more tracks. +type MediaEvent_TracksRemoved struct { + state protoimpl.MessageState `protogen:"open.v1"` + EndpointId string `protobuf:"bytes,1,opt,name=endpoint_id,json=endpointId,proto3" json:"endpoint_id,omitempty"` + TrackIds []string `protobuf:"bytes,2,rep,name=track_ids,json=trackIds,proto3" json:"track_ids,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_TracksRemoved) Reset() { + *x = MediaEvent_TracksRemoved{} + mi := &file_fishjam_media_events_server_server_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_TracksRemoved) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_TracksRemoved) ProtoMessage() {} + +func (x *MediaEvent_TracksRemoved) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_server_server_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 MediaEvent_TracksRemoved.ProtoReflect.Descriptor instead. +func (*MediaEvent_TracksRemoved) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_server_server_proto_rawDescGZIP(), []int{0, 6} +} + +func (x *MediaEvent_TracksRemoved) GetEndpointId() string { + if x != nil { + return x.EndpointId + } + return "" +} + +func (x *MediaEvent_TracksRemoved) GetTrackIds() []string { + if x != nil { + return x.TrackIds + } + return nil +} + +// Sent to all peers in the room after a new endpoint was added. +type MediaEvent_EndpointAdded struct { + state protoimpl.MessageState `protogen:"open.v1"` + EndpointId string `protobuf:"bytes,1,opt,name=endpoint_id,json=endpointId,proto3" json:"endpoint_id,omitempty"` + MetadataJson string `protobuf:"bytes,2,opt,name=metadata_json,json=metadataJson,proto3" json:"metadata_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_EndpointAdded) Reset() { + *x = MediaEvent_EndpointAdded{} + mi := &file_fishjam_media_events_server_server_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_EndpointAdded) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_EndpointAdded) ProtoMessage() {} + +func (x *MediaEvent_EndpointAdded) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_server_server_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 MediaEvent_EndpointAdded.ProtoReflect.Descriptor instead. +func (*MediaEvent_EndpointAdded) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_server_server_proto_rawDescGZIP(), []int{0, 7} +} + +func (x *MediaEvent_EndpointAdded) GetEndpointId() string { + if x != nil { + return x.EndpointId + } + return "" +} + +func (x *MediaEvent_EndpointAdded) GetMetadataJson() string { + if x != nil { + return x.MetadataJson + } + return "" +} + +// Sent to the peer after connecting to the WebRTC Endpoint. +type MediaEvent_Connected struct { + state protoimpl.MessageState `protogen:"open.v1"` + EndpointId string `protobuf:"bytes,1,opt,name=endpoint_id,json=endpointId,proto3" json:"endpoint_id,omitempty"` + EndpointIdToEndpoint map[string]*MediaEvent_Endpoint `protobuf:"bytes,2,rep,name=endpoint_id_to_endpoint,json=endpointIdToEndpoint,proto3" json:"endpoint_id_to_endpoint,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + IceServers []*MediaEvent_IceServer `protobuf:"bytes,3,rep,name=ice_servers,json=iceServers,proto3" json:"ice_servers,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_Connected) Reset() { + *x = MediaEvent_Connected{} + mi := &file_fishjam_media_events_server_server_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_Connected) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_Connected) ProtoMessage() {} + +func (x *MediaEvent_Connected) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_server_server_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 MediaEvent_Connected.ProtoReflect.Descriptor instead. +func (*MediaEvent_Connected) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_server_server_proto_rawDescGZIP(), []int{0, 8} +} + +func (x *MediaEvent_Connected) GetEndpointId() string { + if x != nil { + return x.EndpointId + } + return "" +} + +func (x *MediaEvent_Connected) GetEndpointIdToEndpoint() map[string]*MediaEvent_Endpoint { + if x != nil { + return x.EndpointIdToEndpoint + } + return nil +} + +func (x *MediaEvent_Connected) GetIceServers() []*MediaEvent_IceServer { + if x != nil { + return x.IceServers + } + return nil +} + +// Sent to all remaining peers in the room after some endpoint was removed. +type MediaEvent_EndpointRemoved struct { + state protoimpl.MessageState `protogen:"open.v1"` + EndpointId string `protobuf:"bytes,1,opt,name=endpoint_id,json=endpointId,proto3" json:"endpoint_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_EndpointRemoved) Reset() { + *x = MediaEvent_EndpointRemoved{} + mi := &file_fishjam_media_events_server_server_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_EndpointRemoved) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_EndpointRemoved) ProtoMessage() {} + +func (x *MediaEvent_EndpointRemoved) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_server_server_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 MediaEvent_EndpointRemoved.ProtoReflect.Descriptor instead. +func (*MediaEvent_EndpointRemoved) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_server_server_proto_rawDescGZIP(), []int{0, 9} +} + +func (x *MediaEvent_EndpointRemoved) GetEndpointId() string { + if x != nil { + return x.EndpointId + } + return "" +} + +// Sent to inform that an error occurred on the server providing a message to show +type MediaEvent_Error struct { + state protoimpl.MessageState `protogen:"open.v1"` + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_Error) Reset() { + *x = MediaEvent_Error{} + mi := &file_fishjam_media_events_server_server_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_Error) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_Error) ProtoMessage() {} + +func (x *MediaEvent_Error) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_server_server_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 MediaEvent_Error.ProtoReflect.Descriptor instead. +func (*MediaEvent_Error) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_server_server_proto_rawDescGZIP(), []int{0, 10} +} + +func (x *MediaEvent_Error) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +// Sent to inform about the number of audio and video tracks that will be sent from the engine to the peer +type MediaEvent_OfferData struct { + state protoimpl.MessageState `protogen:"open.v1"` + TracksTypes *MediaEvent_OfferData_TrackTypes `protobuf:"bytes,1,opt,name=tracks_types,json=tracksTypes,proto3" json:"tracks_types,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_OfferData) Reset() { + *x = MediaEvent_OfferData{} + mi := &file_fishjam_media_events_server_server_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_OfferData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_OfferData) ProtoMessage() {} + +func (x *MediaEvent_OfferData) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_server_server_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 MediaEvent_OfferData.ProtoReflect.Descriptor instead. +func (*MediaEvent_OfferData) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_server_server_proto_rawDescGZIP(), []int{0, 11} +} + +func (x *MediaEvent_OfferData) GetTracksTypes() *MediaEvent_OfferData_TrackTypes { + if x != nil { + return x.TracksTypes + } + return nil +} + +// Sent after receiving `SdpOffer` from Peer +type MediaEvent_SdpAnswer struct { + state protoimpl.MessageState `protogen:"open.v1"` + Sdp string `protobuf:"bytes,1,opt,name=sdp,proto3" json:"sdp,omitempty"` // The value of the `sessionDescription.sdp` + MidToTrackId map[string]string `protobuf:"bytes,2,rep,name=mid_to_track_id,json=midToTrackId,proto3" json:"mid_to_track_id,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_SdpAnswer) Reset() { + *x = MediaEvent_SdpAnswer{} + mi := &file_fishjam_media_events_server_server_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_SdpAnswer) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_SdpAnswer) ProtoMessage() {} + +func (x *MediaEvent_SdpAnswer) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_server_server_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 MediaEvent_SdpAnswer.ProtoReflect.Descriptor instead. +func (*MediaEvent_SdpAnswer) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_server_server_proto_rawDescGZIP(), []int{0, 12} +} + +func (x *MediaEvent_SdpAnswer) GetSdp() string { + if x != nil { + return x.Sdp + } + return "" +} + +func (x *MediaEvent_SdpAnswer) GetMidToTrackId() map[string]string { + if x != nil { + return x.MidToTrackId + } + return nil +} + +// Sent to inform that the track denoted by `trackId` has changed their voice activity +// For this notification to work, the server must be configured to use VAD extension +// and the sender must support it. +type MediaEvent_VadNotification struct { + state protoimpl.MessageState `protogen:"open.v1"` + TrackId string `protobuf:"bytes,1,opt,name=track_id,json=trackId,proto3" json:"track_id,omitempty"` + Status MediaEvent_VadNotification_Status `protobuf:"varint,2,opt,name=status,proto3,enum=fishjam.media_events.server.MediaEvent_VadNotification_Status" json:"status,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_VadNotification) Reset() { + *x = MediaEvent_VadNotification{} + mi := &file_fishjam_media_events_server_server_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_VadNotification) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_VadNotification) ProtoMessage() {} + +func (x *MediaEvent_VadNotification) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_server_server_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 MediaEvent_VadNotification.ProtoReflect.Descriptor instead. +func (*MediaEvent_VadNotification) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_server_server_proto_rawDescGZIP(), []int{0, 13} +} + +func (x *MediaEvent_VadNotification) GetTrackId() string { + if x != nil { + return x.TrackId + } + return "" +} + +func (x *MediaEvent_VadNotification) GetStatus() MediaEvent_VadNotification_Status { + if x != nil { + return x.Status + } + return MediaEvent_VadNotification_STATUS_UNSPECIFIED +} + +// Informs that track's variant has been changed +type MediaEvent_TrackVariantSwitched struct { + state protoimpl.MessageState `protogen:"open.v1"` + EndpointId string `protobuf:"bytes,1,opt,name=endpoint_id,json=endpointId,proto3" json:"endpoint_id,omitempty"` + TrackId string `protobuf:"bytes,2,opt,name=track_id,json=trackId,proto3" json:"track_id,omitempty"` + Variant media_events.Variant `protobuf:"varint,3,opt,name=variant,proto3,enum=fishjam.media_events.Variant" json:"variant,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_TrackVariantSwitched) Reset() { + *x = MediaEvent_TrackVariantSwitched{} + mi := &file_fishjam_media_events_server_server_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_TrackVariantSwitched) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_TrackVariantSwitched) ProtoMessage() {} + +func (x *MediaEvent_TrackVariantSwitched) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_server_server_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 MediaEvent_TrackVariantSwitched.ProtoReflect.Descriptor instead. +func (*MediaEvent_TrackVariantSwitched) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_server_server_proto_rawDescGZIP(), []int{0, 14} +} + +func (x *MediaEvent_TrackVariantSwitched) GetEndpointId() string { + if x != nil { + return x.EndpointId + } + return "" +} + +func (x *MediaEvent_TrackVariantSwitched) GetTrackId() string { + if x != nil { + return x.TrackId + } + return "" +} + +func (x *MediaEvent_TrackVariantSwitched) GetVariant() media_events.Variant { + if x != nil { + return x.Variant + } + return media_events.Variant(0) +} + +// Sent when track's variant has been disabled +type MediaEvent_TrackVariantDisabled struct { + state protoimpl.MessageState `protogen:"open.v1"` + EndpointId string `protobuf:"bytes,1,opt,name=endpoint_id,json=endpointId,proto3" json:"endpoint_id,omitempty"` + TrackId string `protobuf:"bytes,2,opt,name=track_id,json=trackId,proto3" json:"track_id,omitempty"` + Variant media_events.Variant `protobuf:"varint,3,opt,name=variant,proto3,enum=fishjam.media_events.Variant" json:"variant,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_TrackVariantDisabled) Reset() { + *x = MediaEvent_TrackVariantDisabled{} + mi := &file_fishjam_media_events_server_server_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_TrackVariantDisabled) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_TrackVariantDisabled) ProtoMessage() {} + +func (x *MediaEvent_TrackVariantDisabled) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_server_server_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 MediaEvent_TrackVariantDisabled.ProtoReflect.Descriptor instead. +func (*MediaEvent_TrackVariantDisabled) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_server_server_proto_rawDescGZIP(), []int{0, 15} +} + +func (x *MediaEvent_TrackVariantDisabled) GetEndpointId() string { + if x != nil { + return x.EndpointId + } + return "" +} + +func (x *MediaEvent_TrackVariantDisabled) GetTrackId() string { + if x != nil { + return x.TrackId + } + return "" +} + +func (x *MediaEvent_TrackVariantDisabled) GetVariant() media_events.Variant { + if x != nil { + return x.Variant + } + return media_events.Variant(0) +} + +// Sent when track's variant has been enabled +type MediaEvent_TrackVariantEnabled struct { + state protoimpl.MessageState `protogen:"open.v1"` + EndpointId string `protobuf:"bytes,1,opt,name=endpoint_id,json=endpointId,proto3" json:"endpoint_id,omitempty"` + TrackId string `protobuf:"bytes,2,opt,name=track_id,json=trackId,proto3" json:"track_id,omitempty"` + Variant media_events.Variant `protobuf:"varint,3,opt,name=variant,proto3,enum=fishjam.media_events.Variant" json:"variant,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_TrackVariantEnabled) Reset() { + *x = MediaEvent_TrackVariantEnabled{} + mi := &file_fishjam_media_events_server_server_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_TrackVariantEnabled) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_TrackVariantEnabled) ProtoMessage() {} + +func (x *MediaEvent_TrackVariantEnabled) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_server_server_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 MediaEvent_TrackVariantEnabled.ProtoReflect.Descriptor instead. +func (*MediaEvent_TrackVariantEnabled) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_server_server_proto_rawDescGZIP(), []int{0, 16} +} + +func (x *MediaEvent_TrackVariantEnabled) GetEndpointId() string { + if x != nil { + return x.EndpointId + } + return "" +} + +func (x *MediaEvent_TrackVariantEnabled) GetTrackId() string { + if x != nil { + return x.TrackId + } + return "" +} + +func (x *MediaEvent_TrackVariantEnabled) GetVariant() media_events.Variant { + if x != nil { + return x.Variant + } + return media_events.Variant(0) +} + +type MediaEvent_Track_SimulcastConfig struct { + state protoimpl.MessageState `protogen:"open.v1"` + Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` + EnabledVariants []media_events.Variant `protobuf:"varint,2,rep,packed,name=enabled_variants,json=enabledVariants,proto3,enum=fishjam.media_events.Variant" json:"enabled_variants,omitempty"` + DisabledVariants []media_events.Variant `protobuf:"varint,3,rep,packed,name=disabled_variants,json=disabledVariants,proto3,enum=fishjam.media_events.Variant" json:"disabled_variants,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_Track_SimulcastConfig) Reset() { + *x = MediaEvent_Track_SimulcastConfig{} + mi := &file_fishjam_media_events_server_server_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_Track_SimulcastConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_Track_SimulcastConfig) ProtoMessage() {} + +func (x *MediaEvent_Track_SimulcastConfig) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_server_server_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 MediaEvent_Track_SimulcastConfig.ProtoReflect.Descriptor instead. +func (*MediaEvent_Track_SimulcastConfig) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_server_server_proto_rawDescGZIP(), []int{0, 0, 0} +} + +func (x *MediaEvent_Track_SimulcastConfig) GetEnabled() bool { + if x != nil { + return x.Enabled + } + return false +} + +func (x *MediaEvent_Track_SimulcastConfig) GetEnabledVariants() []media_events.Variant { + if x != nil { + return x.EnabledVariants + } + return nil +} + +func (x *MediaEvent_Track_SimulcastConfig) GetDisabledVariants() []media_events.Variant { + if x != nil { + return x.DisabledVariants + } + return nil +} + +type MediaEvent_OfferData_TrackTypes struct { + state protoimpl.MessageState `protogen:"open.v1"` + Audio int32 `protobuf:"varint,1,opt,name=audio,proto3" json:"audio,omitempty"` + Video int32 `protobuf:"varint,2,opt,name=video,proto3" json:"video,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MediaEvent_OfferData_TrackTypes) Reset() { + *x = MediaEvent_OfferData_TrackTypes{} + mi := &file_fishjam_media_events_server_server_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MediaEvent_OfferData_TrackTypes) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MediaEvent_OfferData_TrackTypes) ProtoMessage() {} + +func (x *MediaEvent_OfferData_TrackTypes) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_server_server_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 MediaEvent_OfferData_TrackTypes.ProtoReflect.Descriptor instead. +func (*MediaEvent_OfferData_TrackTypes) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_server_server_proto_rawDescGZIP(), []int{0, 11, 0} +} + +func (x *MediaEvent_OfferData_TrackTypes) GetAudio() int32 { + if x != nil { + return x.Audio + } + return 0 +} + +func (x *MediaEvent_OfferData_TrackTypes) GetVideo() int32 { + if x != nil { + return x.Video + } + return 0 +} + +var File_fishjam_media_events_server_server_proto protoreflect.FileDescriptor + +const file_fishjam_media_events_server_server_proto_rawDesc = "" + + "\n" + + "(fishjam/media_events/server/server.proto\x12\x1bfishjam.media_events.server\x1a!fishjam/media_events/shared.proto\"\xe6!\n" + + "\n" + + "MediaEvent\x12d\n" + + "\x10endpoint_updated\x18\x01 \x01(\v27.fishjam.media_events.server.MediaEvent.EndpointUpdatedH\x00R\x0fendpointUpdated\x12[\n" + + "\rtrack_updated\x18\x02 \x01(\v24.fishjam.media_events.server.MediaEvent.TrackUpdatedH\x00R\ftrackUpdated\x12X\n" + + "\ftracks_added\x18\x03 \x01(\v23.fishjam.media_events.server.MediaEvent.TracksAddedH\x00R\vtracksAdded\x12^\n" + + "\x0etracks_removed\x18\x04 \x01(\v25.fishjam.media_events.server.MediaEvent.TracksRemovedH\x00R\rtracksRemoved\x12^\n" + + "\x0eendpoint_added\x18\x05 \x01(\v25.fishjam.media_events.server.MediaEvent.EndpointAddedH\x00R\rendpointAdded\x12d\n" + + "\x10endpoint_removed\x18\x06 \x01(\v27.fishjam.media_events.server.MediaEvent.EndpointRemovedH\x00R\x0fendpointRemoved\x12Q\n" + + "\tconnected\x18\a \x01(\v21.fishjam.media_events.server.MediaEvent.ConnectedH\x00R\tconnected\x12E\n" + + "\x05error\x18\b \x01(\v2-.fishjam.media_events.server.MediaEvent.ErrorH\x00R\x05error\x12R\n" + + "\n" + + "offer_data\x18\t \x01(\v21.fishjam.media_events.server.MediaEvent.OfferDataH\x00R\tofferData\x12?\n" + + "\tcandidate\x18\n" + + " \x01(\v2\x1f.fishjam.media_events.CandidateH\x00R\tcandidate\x12R\n" + + "\n" + + "sdp_answer\x18\v \x01(\v21.fishjam.media_events.server.MediaEvent.SdpAnswerH\x00R\tsdpAnswer\x12d\n" + + "\x10vad_notification\x18\f \x01(\v27.fishjam.media_events.server.MediaEvent.VadNotificationH\x00R\x0fvadNotification\x12t\n" + + "\x16track_variant_switched\x18\r \x01(\v2<.fishjam.media_events.server.MediaEvent.TrackVariantSwitchedH\x00R\x14trackVariantSwitched\x12t\n" + + "\x16track_variant_disabled\x18\x0e \x01(\v2<.fishjam.media_events.server.MediaEvent.TrackVariantDisabledH\x00R\x14trackVariantDisabled\x12q\n" + + "\x15track_variant_enabled\x18\x0f \x01(\v2;.fishjam.media_events.server.MediaEvent.TrackVariantEnabledH\x00R\x13trackVariantEnabled\x1a\xda\x02\n" + + "\x05Track\x12#\n" + + "\rmetadata_json\x18\x01 \x01(\tR\fmetadataJson\x12h\n" + + "\x10simulcast_config\x18\x02 \x01(\v2=.fishjam.media_events.server.MediaEvent.Track.SimulcastConfigR\x0fsimulcastConfig\x1a\xc1\x01\n" + + "\x0fSimulcastConfig\x12\x18\n" + + "\aenabled\x18\x01 \x01(\bR\aenabled\x12H\n" + + "\x10enabled_variants\x18\x02 \x03(\x0e2\x1d.fishjam.media_events.VariantR\x0fenabledVariants\x12J\n" + + "\x11disabled_variants\x18\x03 \x03(\x0e2\x1d.fishjam.media_events.VariantR\x10disabledVariants\x1a\xb7\x02\n" + + "\bEndpoint\x12#\n" + + "\rendpoint_type\x18\x02 \x01(\tR\fendpointType\x12#\n" + + "\rmetadata_json\x18\x03 \x01(\tR\fmetadataJson\x12o\n" + + "\x11track_id_to_track\x18\x04 \x03(\v2D.fishjam.media_events.server.MediaEvent.Endpoint.TrackIdToTrackEntryR\x0etrackIdToTrack\x1ap\n" + + "\x13TrackIdToTrackEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12C\n" + + "\x05value\x18\x02 \x01(\v2-.fishjam.media_events.server.MediaEvent.TrackR\x05value:\x028\x01\x1a[\n" + + "\tIceServer\x12\x1e\n" + + "\n" + + "credential\x18\x01 \x01(\tR\n" + + "credential\x12\x12\n" + + "\x04urls\x18\x02 \x03(\tR\x04urls\x12\x1a\n" + + "\busername\x18\x03 \x01(\tR\busername\x1aW\n" + + "\x0fEndpointUpdated\x12\x1f\n" + + "\vendpoint_id\x18\x01 \x01(\tR\n" + + "endpointId\x12#\n" + + "\rmetadata_json\x18\x02 \x01(\tR\fmetadataJson\x1ao\n" + + "\fTrackUpdated\x12\x1f\n" + + "\vendpoint_id\x18\x01 \x01(\tR\n" + + "endpointId\x12\x19\n" + + "\btrack_id\x18\x02 \x01(\tR\atrackId\x12#\n" + + "\rmetadata_json\x18\x03 \x01(\tR\fmetadataJson\x1a\x94\x02\n" + + "\vTracksAdded\x12\x1f\n" + + "\vendpoint_id\x18\x01 \x01(\tR\n" + + "endpointId\x12r\n" + + "\x11track_id_to_track\x18\x02 \x03(\v2G.fishjam.media_events.server.MediaEvent.TracksAdded.TrackIdToTrackEntryR\x0etrackIdToTrack\x1ap\n" + + "\x13TrackIdToTrackEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12C\n" + + "\x05value\x18\x02 \x01(\v2-.fishjam.media_events.server.MediaEvent.TrackR\x05value:\x028\x01\x1aM\n" + + "\rTracksRemoved\x12\x1f\n" + + "\vendpoint_id\x18\x01 \x01(\tR\n" + + "endpointId\x12\x1b\n" + + "\ttrack_ids\x18\x02 \x03(\tR\btrackIds\x1aU\n" + + "\rEndpointAdded\x12\x1f\n" + + "\vendpoint_id\x18\x01 \x01(\tR\n" + + "endpointId\x12#\n" + + "\rmetadata_json\x18\x02 \x01(\tR\fmetadataJson\x1a\x80\x03\n" + + "\tConnected\x12\x1f\n" + + "\vendpoint_id\x18\x01 \x01(\tR\n" + + "endpointId\x12\x82\x01\n" + + "\x17endpoint_id_to_endpoint\x18\x02 \x03(\v2K.fishjam.media_events.server.MediaEvent.Connected.EndpointIdToEndpointEntryR\x14endpointIdToEndpoint\x12R\n" + + "\vice_servers\x18\x03 \x03(\v21.fishjam.media_events.server.MediaEvent.IceServerR\n" + + "iceServers\x1ay\n" + + "\x19EndpointIdToEndpointEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12F\n" + + "\x05value\x18\x02 \x01(\v20.fishjam.media_events.server.MediaEvent.EndpointR\x05value:\x028\x01\x1a2\n" + + "\x0fEndpointRemoved\x12\x1f\n" + + "\vendpoint_id\x18\x01 \x01(\tR\n" + + "endpointId\x1a!\n" + + "\x05Error\x12\x18\n" + + "\amessage\x18\x01 \x01(\tR\amessage\x1a\xa6\x01\n" + + "\tOfferData\x12_\n" + + "\ftracks_types\x18\x01 \x01(\v2<.fishjam.media_events.server.MediaEvent.OfferData.TrackTypesR\vtracksTypes\x1a8\n" + + "\n" + + "TrackTypes\x12\x14\n" + + "\x05audio\x18\x01 \x01(\x05R\x05audio\x12\x14\n" + + "\x05video\x18\x02 \x01(\x05R\x05video\x1a\xca\x01\n" + + "\tSdpAnswer\x12\x10\n" + + "\x03sdp\x18\x01 \x01(\tR\x03sdp\x12j\n" + + "\x0fmid_to_track_id\x18\x02 \x03(\v2C.fishjam.media_events.server.MediaEvent.SdpAnswer.MidToTrackIdEntryR\fmidToTrackId\x1a?\n" + + "\x11MidToTrackIdEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1a\xcd\x01\n" + + "\x0fVadNotification\x12\x19\n" + + "\btrack_id\x18\x01 \x01(\tR\atrackId\x12V\n" + + "\x06status\x18\x02 \x01(\x0e2>.fishjam.media_events.server.MediaEvent.VadNotification.StatusR\x06status\"G\n" + + "\x06Status\x12\x16\n" + + "\x12STATUS_UNSPECIFIED\x10\x00\x12\x12\n" + + "\x0eSTATUS_SILENCE\x10\x01\x12\x11\n" + + "\rSTATUS_SPEECH\x10\x02\x1a\x8b\x01\n" + + "\x14TrackVariantSwitched\x12\x1f\n" + + "\vendpoint_id\x18\x01 \x01(\tR\n" + + "endpointId\x12\x19\n" + + "\btrack_id\x18\x02 \x01(\tR\atrackId\x127\n" + + "\avariant\x18\x03 \x01(\x0e2\x1d.fishjam.media_events.VariantR\avariant\x1a\x8b\x01\n" + + "\x14TrackVariantDisabled\x12\x1f\n" + + "\vendpoint_id\x18\x01 \x01(\tR\n" + + "endpointId\x12\x19\n" + + "\btrack_id\x18\x02 \x01(\tR\atrackId\x127\n" + + "\avariant\x18\x03 \x01(\x0e2\x1d.fishjam.media_events.VariantR\avariant\x1a\x8a\x01\n" + + "\x13TrackVariantEnabled\x12\x1f\n" + + "\vendpoint_id\x18\x01 \x01(\tR\n" + + "endpointId\x12\x19\n" + + "\btrack_id\x18\x02 \x01(\tR\atrackId\x127\n" + + "\avariant\x18\x03 \x01(\x0e2\x1d.fishjam.media_events.VariantR\avariantB\t\n" + + "\acontentB8Z6conference-to-stream/proto/fishjam/media_events/serverb\x06proto3" + +var ( + file_fishjam_media_events_server_server_proto_rawDescOnce sync.Once + file_fishjam_media_events_server_server_proto_rawDescData []byte +) + +func file_fishjam_media_events_server_server_proto_rawDescGZIP() []byte { + file_fishjam_media_events_server_server_proto_rawDescOnce.Do(func() { + file_fishjam_media_events_server_server_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_fishjam_media_events_server_server_proto_rawDesc), len(file_fishjam_media_events_server_server_proto_rawDesc))) + }) + return file_fishjam_media_events_server_server_proto_rawDescData +} + +var file_fishjam_media_events_server_server_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_fishjam_media_events_server_server_proto_msgTypes = make([]protoimpl.MessageInfo, 24) +var file_fishjam_media_events_server_server_proto_goTypes = []any{ + (MediaEvent_VadNotification_Status)(0), // 0: fishjam.media_events.server.MediaEvent.VadNotification.Status + (*MediaEvent)(nil), // 1: fishjam.media_events.server.MediaEvent + (*MediaEvent_Track)(nil), // 2: fishjam.media_events.server.MediaEvent.Track + (*MediaEvent_Endpoint)(nil), // 3: fishjam.media_events.server.MediaEvent.Endpoint + (*MediaEvent_IceServer)(nil), // 4: fishjam.media_events.server.MediaEvent.IceServer + (*MediaEvent_EndpointUpdated)(nil), // 5: fishjam.media_events.server.MediaEvent.EndpointUpdated + (*MediaEvent_TrackUpdated)(nil), // 6: fishjam.media_events.server.MediaEvent.TrackUpdated + (*MediaEvent_TracksAdded)(nil), // 7: fishjam.media_events.server.MediaEvent.TracksAdded + (*MediaEvent_TracksRemoved)(nil), // 8: fishjam.media_events.server.MediaEvent.TracksRemoved + (*MediaEvent_EndpointAdded)(nil), // 9: fishjam.media_events.server.MediaEvent.EndpointAdded + (*MediaEvent_Connected)(nil), // 10: fishjam.media_events.server.MediaEvent.Connected + (*MediaEvent_EndpointRemoved)(nil), // 11: fishjam.media_events.server.MediaEvent.EndpointRemoved + (*MediaEvent_Error)(nil), // 12: fishjam.media_events.server.MediaEvent.Error + (*MediaEvent_OfferData)(nil), // 13: fishjam.media_events.server.MediaEvent.OfferData + (*MediaEvent_SdpAnswer)(nil), // 14: fishjam.media_events.server.MediaEvent.SdpAnswer + (*MediaEvent_VadNotification)(nil), // 15: fishjam.media_events.server.MediaEvent.VadNotification + (*MediaEvent_TrackVariantSwitched)(nil), // 16: fishjam.media_events.server.MediaEvent.TrackVariantSwitched + (*MediaEvent_TrackVariantDisabled)(nil), // 17: fishjam.media_events.server.MediaEvent.TrackVariantDisabled + (*MediaEvent_TrackVariantEnabled)(nil), // 18: fishjam.media_events.server.MediaEvent.TrackVariantEnabled + (*MediaEvent_Track_SimulcastConfig)(nil), // 19: fishjam.media_events.server.MediaEvent.Track.SimulcastConfig + nil, // 20: fishjam.media_events.server.MediaEvent.Endpoint.TrackIdToTrackEntry + nil, // 21: fishjam.media_events.server.MediaEvent.TracksAdded.TrackIdToTrackEntry + nil, // 22: fishjam.media_events.server.MediaEvent.Connected.EndpointIdToEndpointEntry + (*MediaEvent_OfferData_TrackTypes)(nil), // 23: fishjam.media_events.server.MediaEvent.OfferData.TrackTypes + nil, // 24: fishjam.media_events.server.MediaEvent.SdpAnswer.MidToTrackIdEntry + (*media_events.Candidate)(nil), // 25: fishjam.media_events.Candidate + (media_events.Variant)(0), // 26: fishjam.media_events.Variant +} +var file_fishjam_media_events_server_server_proto_depIdxs = []int32{ + 5, // 0: fishjam.media_events.server.MediaEvent.endpoint_updated:type_name -> fishjam.media_events.server.MediaEvent.EndpointUpdated + 6, // 1: fishjam.media_events.server.MediaEvent.track_updated:type_name -> fishjam.media_events.server.MediaEvent.TrackUpdated + 7, // 2: fishjam.media_events.server.MediaEvent.tracks_added:type_name -> fishjam.media_events.server.MediaEvent.TracksAdded + 8, // 3: fishjam.media_events.server.MediaEvent.tracks_removed:type_name -> fishjam.media_events.server.MediaEvent.TracksRemoved + 9, // 4: fishjam.media_events.server.MediaEvent.endpoint_added:type_name -> fishjam.media_events.server.MediaEvent.EndpointAdded + 11, // 5: fishjam.media_events.server.MediaEvent.endpoint_removed:type_name -> fishjam.media_events.server.MediaEvent.EndpointRemoved + 10, // 6: fishjam.media_events.server.MediaEvent.connected:type_name -> fishjam.media_events.server.MediaEvent.Connected + 12, // 7: fishjam.media_events.server.MediaEvent.error:type_name -> fishjam.media_events.server.MediaEvent.Error + 13, // 8: fishjam.media_events.server.MediaEvent.offer_data:type_name -> fishjam.media_events.server.MediaEvent.OfferData + 25, // 9: fishjam.media_events.server.MediaEvent.candidate:type_name -> fishjam.media_events.Candidate + 14, // 10: fishjam.media_events.server.MediaEvent.sdp_answer:type_name -> fishjam.media_events.server.MediaEvent.SdpAnswer + 15, // 11: fishjam.media_events.server.MediaEvent.vad_notification:type_name -> fishjam.media_events.server.MediaEvent.VadNotification + 16, // 12: fishjam.media_events.server.MediaEvent.track_variant_switched:type_name -> fishjam.media_events.server.MediaEvent.TrackVariantSwitched + 17, // 13: fishjam.media_events.server.MediaEvent.track_variant_disabled:type_name -> fishjam.media_events.server.MediaEvent.TrackVariantDisabled + 18, // 14: fishjam.media_events.server.MediaEvent.track_variant_enabled:type_name -> fishjam.media_events.server.MediaEvent.TrackVariantEnabled + 19, // 15: fishjam.media_events.server.MediaEvent.Track.simulcast_config:type_name -> fishjam.media_events.server.MediaEvent.Track.SimulcastConfig + 20, // 16: fishjam.media_events.server.MediaEvent.Endpoint.track_id_to_track:type_name -> fishjam.media_events.server.MediaEvent.Endpoint.TrackIdToTrackEntry + 21, // 17: fishjam.media_events.server.MediaEvent.TracksAdded.track_id_to_track:type_name -> fishjam.media_events.server.MediaEvent.TracksAdded.TrackIdToTrackEntry + 22, // 18: fishjam.media_events.server.MediaEvent.Connected.endpoint_id_to_endpoint:type_name -> fishjam.media_events.server.MediaEvent.Connected.EndpointIdToEndpointEntry + 4, // 19: fishjam.media_events.server.MediaEvent.Connected.ice_servers:type_name -> fishjam.media_events.server.MediaEvent.IceServer + 23, // 20: fishjam.media_events.server.MediaEvent.OfferData.tracks_types:type_name -> fishjam.media_events.server.MediaEvent.OfferData.TrackTypes + 24, // 21: fishjam.media_events.server.MediaEvent.SdpAnswer.mid_to_track_id:type_name -> fishjam.media_events.server.MediaEvent.SdpAnswer.MidToTrackIdEntry + 0, // 22: fishjam.media_events.server.MediaEvent.VadNotification.status:type_name -> fishjam.media_events.server.MediaEvent.VadNotification.Status + 26, // 23: fishjam.media_events.server.MediaEvent.TrackVariantSwitched.variant:type_name -> fishjam.media_events.Variant + 26, // 24: fishjam.media_events.server.MediaEvent.TrackVariantDisabled.variant:type_name -> fishjam.media_events.Variant + 26, // 25: fishjam.media_events.server.MediaEvent.TrackVariantEnabled.variant:type_name -> fishjam.media_events.Variant + 26, // 26: fishjam.media_events.server.MediaEvent.Track.SimulcastConfig.enabled_variants:type_name -> fishjam.media_events.Variant + 26, // 27: fishjam.media_events.server.MediaEvent.Track.SimulcastConfig.disabled_variants:type_name -> fishjam.media_events.Variant + 2, // 28: fishjam.media_events.server.MediaEvent.Endpoint.TrackIdToTrackEntry.value:type_name -> fishjam.media_events.server.MediaEvent.Track + 2, // 29: fishjam.media_events.server.MediaEvent.TracksAdded.TrackIdToTrackEntry.value:type_name -> fishjam.media_events.server.MediaEvent.Track + 3, // 30: fishjam.media_events.server.MediaEvent.Connected.EndpointIdToEndpointEntry.value:type_name -> fishjam.media_events.server.MediaEvent.Endpoint + 31, // [31:31] is the sub-list for method output_type + 31, // [31:31] is the sub-list for method input_type + 31, // [31:31] is the sub-list for extension type_name + 31, // [31:31] is the sub-list for extension extendee + 0, // [0:31] is the sub-list for field type_name +} + +func init() { file_fishjam_media_events_server_server_proto_init() } +func file_fishjam_media_events_server_server_proto_init() { + if File_fishjam_media_events_server_server_proto != nil { + return + } + file_fishjam_media_events_server_server_proto_msgTypes[0].OneofWrappers = []any{ + (*MediaEvent_EndpointUpdated_)(nil), + (*MediaEvent_TrackUpdated_)(nil), + (*MediaEvent_TracksAdded_)(nil), + (*MediaEvent_TracksRemoved_)(nil), + (*MediaEvent_EndpointAdded_)(nil), + (*MediaEvent_EndpointRemoved_)(nil), + (*MediaEvent_Connected_)(nil), + (*MediaEvent_Error_)(nil), + (*MediaEvent_OfferData_)(nil), + (*MediaEvent_Candidate)(nil), + (*MediaEvent_SdpAnswer_)(nil), + (*MediaEvent_VadNotification_)(nil), + (*MediaEvent_TrackVariantSwitched_)(nil), + (*MediaEvent_TrackVariantDisabled_)(nil), + (*MediaEvent_TrackVariantEnabled_)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_fishjam_media_events_server_server_proto_rawDesc), len(file_fishjam_media_events_server_server_proto_rawDesc)), + NumEnums: 1, + NumMessages: 24, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_fishjam_media_events_server_server_proto_goTypes, + DependencyIndexes: file_fishjam_media_events_server_server_proto_depIdxs, + EnumInfos: file_fishjam_media_events_server_server_proto_enumTypes, + MessageInfos: file_fishjam_media_events_server_server_proto_msgTypes, + }.Build() + File_fishjam_media_events_server_server_proto = out.File + file_fishjam_media_events_server_server_proto_goTypes = nil + file_fishjam_media_events_server_server_proto_depIdxs = nil +} diff --git a/conference-to-stream/backend/proto/fishjam/media_events/shared.pb.go b/conference-to-stream/backend/proto/fishjam/media_events/shared.pb.go new file mode 100644 index 0000000..6e4868c --- /dev/null +++ b/conference-to-stream/backend/proto/fishjam/media_events/shared.pb.go @@ -0,0 +1,349 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v6.33.1 +// source: fishjam/media_events/shared.proto + +package media_events + +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) +) + +type Variant int32 + +const ( + Variant_VARIANT_UNSPECIFIED Variant = 0 + Variant_VARIANT_LOW Variant = 1 + Variant_VARIANT_MEDIUM Variant = 2 + Variant_VARIANT_HIGH Variant = 3 +) + +// Enum value maps for Variant. +var ( + Variant_name = map[int32]string{ + 0: "VARIANT_UNSPECIFIED", + 1: "VARIANT_LOW", + 2: "VARIANT_MEDIUM", + 3: "VARIANT_HIGH", + } + Variant_value = map[string]int32{ + "VARIANT_UNSPECIFIED": 0, + "VARIANT_LOW": 1, + "VARIANT_MEDIUM": 2, + "VARIANT_HIGH": 3, + } +) + +func (x Variant) Enum() *Variant { + p := new(Variant) + *p = x + return p +} + +func (x Variant) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Variant) Descriptor() protoreflect.EnumDescriptor { + return file_fishjam_media_events_shared_proto_enumTypes[0].Descriptor() +} + +func (Variant) Type() protoreflect.EnumType { + return &file_fishjam_media_events_shared_proto_enumTypes[0] +} + +func (x Variant) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Variant.Descriptor instead. +func (Variant) EnumDescriptor() ([]byte, []int) { + return file_fishjam_media_events_shared_proto_rawDescGZIP(), []int{0} +} + +// Contains information about an ICE candidate which will be sent to the peer/server +type Candidate struct { + state protoimpl.MessageState `protogen:"open.v1"` + Candidate string `protobuf:"bytes,1,opt,name=candidate,proto3" json:"candidate,omitempty"` + SdpMLineIndex int32 `protobuf:"varint,2,opt,name=sdp_m_line_index,json=sdpMLineIndex,proto3" json:"sdp_m_line_index,omitempty"` + SdpMid string `protobuf:"bytes,3,opt,name=sdp_mid,json=sdpMid,proto3" json:"sdp_mid,omitempty"` + UsernameFragment string `protobuf:"bytes,4,opt,name=username_fragment,json=usernameFragment,proto3" json:"username_fragment,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Candidate) Reset() { + *x = Candidate{} + mi := &file_fishjam_media_events_shared_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Candidate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Candidate) ProtoMessage() {} + +func (x *Candidate) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_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 Candidate.ProtoReflect.Descriptor instead. +func (*Candidate) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_shared_proto_rawDescGZIP(), []int{0} +} + +func (x *Candidate) GetCandidate() string { + if x != nil { + return x.Candidate + } + return "" +} + +func (x *Candidate) GetSdpMLineIndex() int32 { + if x != nil { + return x.SdpMLineIndex + } + return 0 +} + +func (x *Candidate) GetSdpMid() string { + if x != nil { + return x.SdpMid + } + return "" +} + +func (x *Candidate) GetUsernameFragment() string { + if x != nil { + return x.UsernameFragment + } + return "" +} + +type ChannelMessageBinaryPayload struct { + state protoimpl.MessageState `protogen:"open.v1"` + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ChannelMessageBinaryPayload) Reset() { + *x = ChannelMessageBinaryPayload{} + mi := &file_fishjam_media_events_shared_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ChannelMessageBinaryPayload) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChannelMessageBinaryPayload) ProtoMessage() {} + +func (x *ChannelMessageBinaryPayload) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_shared_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 ChannelMessageBinaryPayload.ProtoReflect.Descriptor instead. +func (*ChannelMessageBinaryPayload) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_shared_proto_rawDescGZIP(), []int{1} +} + +func (x *ChannelMessageBinaryPayload) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +type ChannelMessage struct { + state protoimpl.MessageState `protogen:"open.v1"` + Source string `protobuf:"bytes,1,opt,name=source,proto3" json:"source,omitempty"` + Destinations []string `protobuf:"bytes,2,rep,name=destinations,proto3" json:"destinations,omitempty"` + // Types that are valid to be assigned to Payload: + // + // *ChannelMessage_Binary + Payload isChannelMessage_Payload `protobuf_oneof:"payload"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ChannelMessage) Reset() { + *x = ChannelMessage{} + mi := &file_fishjam_media_events_shared_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ChannelMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChannelMessage) ProtoMessage() {} + +func (x *ChannelMessage) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_media_events_shared_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 ChannelMessage.ProtoReflect.Descriptor instead. +func (*ChannelMessage) Descriptor() ([]byte, []int) { + return file_fishjam_media_events_shared_proto_rawDescGZIP(), []int{2} +} + +func (x *ChannelMessage) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *ChannelMessage) GetDestinations() []string { + if x != nil { + return x.Destinations + } + return nil +} + +func (x *ChannelMessage) GetPayload() isChannelMessage_Payload { + if x != nil { + return x.Payload + } + return nil +} + +func (x *ChannelMessage) GetBinary() *ChannelMessageBinaryPayload { + if x != nil { + if x, ok := x.Payload.(*ChannelMessage_Binary); ok { + return x.Binary + } + } + return nil +} + +type isChannelMessage_Payload interface { + isChannelMessage_Payload() +} + +type ChannelMessage_Binary struct { + Binary *ChannelMessageBinaryPayload `protobuf:"bytes,3,opt,name=binary,proto3,oneof"` +} + +func (*ChannelMessage_Binary) isChannelMessage_Payload() {} + +var File_fishjam_media_events_shared_proto protoreflect.FileDescriptor + +const file_fishjam_media_events_shared_proto_rawDesc = "" + + "\n" + + "!fishjam/media_events/shared.proto\x12\x14fishjam.media_events\"\x98\x01\n" + + "\tCandidate\x12\x1c\n" + + "\tcandidate\x18\x01 \x01(\tR\tcandidate\x12'\n" + + "\x10sdp_m_line_index\x18\x02 \x01(\x05R\rsdpMLineIndex\x12\x17\n" + + "\asdp_mid\x18\x03 \x01(\tR\x06sdpMid\x12+\n" + + "\x11username_fragment\x18\x04 \x01(\tR\x10usernameFragment\"1\n" + + "\x1bChannelMessageBinaryPayload\x12\x12\n" + + "\x04data\x18\x01 \x01(\fR\x04data\"\xa4\x01\n" + + "\x0eChannelMessage\x12\x16\n" + + "\x06source\x18\x01 \x01(\tR\x06source\x12\"\n" + + "\fdestinations\x18\x02 \x03(\tR\fdestinations\x12K\n" + + "\x06binary\x18\x03 \x01(\v21.fishjam.media_events.ChannelMessageBinaryPayloadH\x00R\x06binaryB\t\n" + + "\apayload*Y\n" + + "\aVariant\x12\x17\n" + + "\x13VARIANT_UNSPECIFIED\x10\x00\x12\x0f\n" + + "\vVARIANT_LOW\x10\x01\x12\x12\n" + + "\x0eVARIANT_MEDIUM\x10\x02\x12\x10\n" + + "\fVARIANT_HIGH\x10\x03B1Z/conference-to-stream/proto/fishjam/media_eventsb\x06proto3" + +var ( + file_fishjam_media_events_shared_proto_rawDescOnce sync.Once + file_fishjam_media_events_shared_proto_rawDescData []byte +) + +func file_fishjam_media_events_shared_proto_rawDescGZIP() []byte { + file_fishjam_media_events_shared_proto_rawDescOnce.Do(func() { + file_fishjam_media_events_shared_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_fishjam_media_events_shared_proto_rawDesc), len(file_fishjam_media_events_shared_proto_rawDesc))) + }) + return file_fishjam_media_events_shared_proto_rawDescData +} + +var file_fishjam_media_events_shared_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_fishjam_media_events_shared_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_fishjam_media_events_shared_proto_goTypes = []any{ + (Variant)(0), // 0: fishjam.media_events.Variant + (*Candidate)(nil), // 1: fishjam.media_events.Candidate + (*ChannelMessageBinaryPayload)(nil), // 2: fishjam.media_events.ChannelMessageBinaryPayload + (*ChannelMessage)(nil), // 3: fishjam.media_events.ChannelMessage +} +var file_fishjam_media_events_shared_proto_depIdxs = []int32{ + 2, // 0: fishjam.media_events.ChannelMessage.binary:type_name -> fishjam.media_events.ChannelMessageBinaryPayload + 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_media_events_shared_proto_init() } +func file_fishjam_media_events_shared_proto_init() { + if File_fishjam_media_events_shared_proto != nil { + return + } + file_fishjam_media_events_shared_proto_msgTypes[2].OneofWrappers = []any{ + (*ChannelMessage_Binary)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_fishjam_media_events_shared_proto_rawDesc), len(file_fishjam_media_events_shared_proto_rawDesc)), + NumEnums: 1, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_fishjam_media_events_shared_proto_goTypes, + DependencyIndexes: file_fishjam_media_events_shared_proto_depIdxs, + EnumInfos: file_fishjam_media_events_shared_proto_enumTypes, + MessageInfos: file_fishjam_media_events_shared_proto_msgTypes, + }.Build() + File_fishjam_media_events_shared_proto = out.File + file_fishjam_media_events_shared_proto_goTypes = nil + file_fishjam_media_events_shared_proto_depIdxs = nil +} 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..ef912cf --- /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\x02B2Z0conference-to-stream/proto/fishjam/notificationsb\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/peer_notifications.pb.go b/conference-to-stream/backend/proto/fishjam/peer_notifications.pb.go new file mode 100644 index 0000000..4199b5c --- /dev/null +++ b/conference-to-stream/backend/proto/fishjam/peer_notifications.pb.go @@ -0,0 +1,642 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v6.33.1 +// source: fishjam/peer_notifications.proto + +package fishjam + +import ( + peer "conference-to-stream/proto/fishjam/media_events/peer" + server "conference-to-stream/proto/fishjam/media_events/server" + 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 rooms peers may connect to +type PeerMessage_RoomType int32 + +const ( + PeerMessage_ROOM_TYPE_UNSPECIFIED PeerMessage_RoomType = 0 + PeerMessage_ROOM_TYPE_CONFERENCE PeerMessage_RoomType = 1 + PeerMessage_ROOM_TYPE_AUDIO_ONLY PeerMessage_RoomType = 2 + PeerMessage_ROOM_TYPE_LIVESTREAM PeerMessage_RoomType = 3 +) + +// Enum value maps for PeerMessage_RoomType. +var ( + PeerMessage_RoomType_name = map[int32]string{ + 0: "ROOM_TYPE_UNSPECIFIED", + 1: "ROOM_TYPE_CONFERENCE", + 2: "ROOM_TYPE_AUDIO_ONLY", + 3: "ROOM_TYPE_LIVESTREAM", + } + PeerMessage_RoomType_value = map[string]int32{ + "ROOM_TYPE_UNSPECIFIED": 0, + "ROOM_TYPE_CONFERENCE": 1, + "ROOM_TYPE_AUDIO_ONLY": 2, + "ROOM_TYPE_LIVESTREAM": 3, + } +) + +func (x PeerMessage_RoomType) Enum() *PeerMessage_RoomType { + p := new(PeerMessage_RoomType) + *p = x + return p +} + +func (x PeerMessage_RoomType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (PeerMessage_RoomType) Descriptor() protoreflect.EnumDescriptor { + return file_fishjam_peer_notifications_proto_enumTypes[0].Descriptor() +} + +func (PeerMessage_RoomType) Type() protoreflect.EnumType { + return &file_fishjam_peer_notifications_proto_enumTypes[0] +} + +func (x PeerMessage_RoomType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use PeerMessage_RoomType.Descriptor instead. +func (PeerMessage_RoomType) EnumDescriptor() ([]byte, []int) { + return file_fishjam_peer_notifications_proto_rawDescGZIP(), []int{0, 0} +} + +type PeerMessage_SdkDeprecation_Status int32 + +const ( + PeerMessage_SdkDeprecation_STATUS_UNSPECIFIED PeerMessage_SdkDeprecation_Status = 0 + PeerMessage_SdkDeprecation_STATUS_UP_TO_DATE PeerMessage_SdkDeprecation_Status = 1 + PeerMessage_SdkDeprecation_STATUS_DEPRECATED PeerMessage_SdkDeprecation_Status = 2 + PeerMessage_SdkDeprecation_STATUS_UNSUPPORTED PeerMessage_SdkDeprecation_Status = 3 +) + +// Enum value maps for PeerMessage_SdkDeprecation_Status. +var ( + PeerMessage_SdkDeprecation_Status_name = map[int32]string{ + 0: "STATUS_UNSPECIFIED", + 1: "STATUS_UP_TO_DATE", + 2: "STATUS_DEPRECATED", + 3: "STATUS_UNSUPPORTED", + } + PeerMessage_SdkDeprecation_Status_value = map[string]int32{ + "STATUS_UNSPECIFIED": 0, + "STATUS_UP_TO_DATE": 1, + "STATUS_DEPRECATED": 2, + "STATUS_UNSUPPORTED": 3, + } +) + +func (x PeerMessage_SdkDeprecation_Status) Enum() *PeerMessage_SdkDeprecation_Status { + p := new(PeerMessage_SdkDeprecation_Status) + *p = x + return p +} + +func (x PeerMessage_SdkDeprecation_Status) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (PeerMessage_SdkDeprecation_Status) Descriptor() protoreflect.EnumDescriptor { + return file_fishjam_peer_notifications_proto_enumTypes[1].Descriptor() +} + +func (PeerMessage_SdkDeprecation_Status) Type() protoreflect.EnumType { + return &file_fishjam_peer_notifications_proto_enumTypes[1] +} + +func (x PeerMessage_SdkDeprecation_Status) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use PeerMessage_SdkDeprecation_Status.Descriptor instead. +func (PeerMessage_SdkDeprecation_Status) EnumDescriptor() ([]byte, []int) { + return file_fishjam_peer_notifications_proto_rawDescGZIP(), []int{0, 0, 0} +} + +// Defines any type of message sent between FJ and a peer +type PeerMessage struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Content: + // + // *PeerMessage_Authenticated_ + // *PeerMessage_AuthRequest_ + // *PeerMessage_MediaEvent_ + // *PeerMessage_RtcStatsReport + // *PeerMessage_PeerMediaEvent + // *PeerMessage_ServerMediaEvent + Content isPeerMessage_Content `protobuf_oneof:"content"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PeerMessage) Reset() { + *x = PeerMessage{} + mi := &file_fishjam_peer_notifications_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PeerMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeerMessage) ProtoMessage() {} + +func (x *PeerMessage) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_peer_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 PeerMessage.ProtoReflect.Descriptor instead. +func (*PeerMessage) Descriptor() ([]byte, []int) { + return file_fishjam_peer_notifications_proto_rawDescGZIP(), []int{0} +} + +func (x *PeerMessage) GetContent() isPeerMessage_Content { + if x != nil { + return x.Content + } + return nil +} + +func (x *PeerMessage) GetAuthenticated() *PeerMessage_Authenticated { + if x != nil { + if x, ok := x.Content.(*PeerMessage_Authenticated_); ok { + return x.Authenticated + } + } + return nil +} + +func (x *PeerMessage) GetAuthRequest() *PeerMessage_AuthRequest { + if x != nil { + if x, ok := x.Content.(*PeerMessage_AuthRequest_); ok { + return x.AuthRequest + } + } + return nil +} + +func (x *PeerMessage) GetMediaEvent() *PeerMessage_MediaEvent { + if x != nil { + if x, ok := x.Content.(*PeerMessage_MediaEvent_); ok { + return x.MediaEvent + } + } + return nil +} + +func (x *PeerMessage) GetRtcStatsReport() *PeerMessage_RTCStatsReport { + if x != nil { + if x, ok := x.Content.(*PeerMessage_RtcStatsReport); ok { + return x.RtcStatsReport + } + } + return nil +} + +func (x *PeerMessage) GetPeerMediaEvent() *peer.MediaEvent { + if x != nil { + if x, ok := x.Content.(*PeerMessage_PeerMediaEvent); ok { + return x.PeerMediaEvent + } + } + return nil +} + +func (x *PeerMessage) GetServerMediaEvent() *server.MediaEvent { + if x != nil { + if x, ok := x.Content.(*PeerMessage_ServerMediaEvent); ok { + return x.ServerMediaEvent + } + } + return nil +} + +type isPeerMessage_Content interface { + isPeerMessage_Content() +} + +type PeerMessage_Authenticated_ struct { + Authenticated *PeerMessage_Authenticated `protobuf:"bytes,1,opt,name=authenticated,proto3,oneof"` +} + +type PeerMessage_AuthRequest_ struct { + AuthRequest *PeerMessage_AuthRequest `protobuf:"bytes,2,opt,name=auth_request,json=authRequest,proto3,oneof"` +} + +type PeerMessage_MediaEvent_ struct { + MediaEvent *PeerMessage_MediaEvent `protobuf:"bytes,3,opt,name=media_event,json=mediaEvent,proto3,oneof"` +} + +type PeerMessage_RtcStatsReport struct { + RtcStatsReport *PeerMessage_RTCStatsReport `protobuf:"bytes,4,opt,name=rtc_stats_report,json=rtcStatsReport,proto3,oneof"` +} + +type PeerMessage_PeerMediaEvent struct { + PeerMediaEvent *peer.MediaEvent `protobuf:"bytes,5,opt,name=peer_media_event,json=peerMediaEvent,proto3,oneof"` +} + +type PeerMessage_ServerMediaEvent struct { + ServerMediaEvent *server.MediaEvent `protobuf:"bytes,6,opt,name=server_media_event,json=serverMediaEvent,proto3,oneof"` +} + +func (*PeerMessage_Authenticated_) isPeerMessage_Content() {} + +func (*PeerMessage_AuthRequest_) isPeerMessage_Content() {} + +func (*PeerMessage_MediaEvent_) isPeerMessage_Content() {} + +func (*PeerMessage_RtcStatsReport) isPeerMessage_Content() {} + +func (*PeerMessage_PeerMediaEvent) isPeerMessage_Content() {} + +func (*PeerMessage_ServerMediaEvent) isPeerMessage_Content() {} + +// Deprecation status for SDK version +type PeerMessage_SdkDeprecation struct { + state protoimpl.MessageState `protogen:"open.v1"` + Status PeerMessage_SdkDeprecation_Status `protobuf:"varint,1,opt,name=status,proto3,enum=fishjam.PeerMessage_SdkDeprecation_Status" json:"status,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PeerMessage_SdkDeprecation) Reset() { + *x = PeerMessage_SdkDeprecation{} + mi := &file_fishjam_peer_notifications_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PeerMessage_SdkDeprecation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeerMessage_SdkDeprecation) ProtoMessage() {} + +func (x *PeerMessage_SdkDeprecation) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_peer_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 PeerMessage_SdkDeprecation.ProtoReflect.Descriptor instead. +func (*PeerMessage_SdkDeprecation) Descriptor() ([]byte, []int) { + return file_fishjam_peer_notifications_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *PeerMessage_SdkDeprecation) GetStatus() PeerMessage_SdkDeprecation_Status { + if x != nil { + return x.Status + } + return PeerMessage_SdkDeprecation_STATUS_UNSPECIFIED +} + +func (x *PeerMessage_SdkDeprecation) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +// Response sent by FJ, confirming successful authentication +type PeerMessage_Authenticated struct { + state protoimpl.MessageState `protogen:"open.v1"` + RoomType PeerMessage_RoomType `protobuf:"varint,1,opt,name=room_type,json=roomType,proto3,enum=fishjam.PeerMessage_RoomType" json:"room_type,omitempty"` + SdkDeprecation *PeerMessage_SdkDeprecation `protobuf:"bytes,2,opt,name=sdk_deprecation,json=sdkDeprecation,proto3" json:"sdk_deprecation,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PeerMessage_Authenticated) Reset() { + *x = PeerMessage_Authenticated{} + mi := &file_fishjam_peer_notifications_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PeerMessage_Authenticated) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeerMessage_Authenticated) ProtoMessage() {} + +func (x *PeerMessage_Authenticated) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_peer_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 PeerMessage_Authenticated.ProtoReflect.Descriptor instead. +func (*PeerMessage_Authenticated) Descriptor() ([]byte, []int) { + return file_fishjam_peer_notifications_proto_rawDescGZIP(), []int{0, 1} +} + +func (x *PeerMessage_Authenticated) GetRoomType() PeerMessage_RoomType { + if x != nil { + return x.RoomType + } + return PeerMessage_ROOM_TYPE_UNSPECIFIED +} + +func (x *PeerMessage_Authenticated) GetSdkDeprecation() *PeerMessage_SdkDeprecation { + if x != nil { + return x.SdkDeprecation + } + return nil +} + +// Request sent by peer, to authenticate to FJ server +type PeerMessage_AuthRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + SdkVersion string `protobuf:"bytes,2,opt,name=sdk_version,json=sdkVersion,proto3" json:"sdk_version,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PeerMessage_AuthRequest) Reset() { + *x = PeerMessage_AuthRequest{} + mi := &file_fishjam_peer_notifications_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PeerMessage_AuthRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeerMessage_AuthRequest) ProtoMessage() {} + +func (x *PeerMessage_AuthRequest) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_peer_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 PeerMessage_AuthRequest.ProtoReflect.Descriptor instead. +func (*PeerMessage_AuthRequest) Descriptor() ([]byte, []int) { + return file_fishjam_peer_notifications_proto_rawDescGZIP(), []int{0, 2} +} + +func (x *PeerMessage_AuthRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *PeerMessage_AuthRequest) GetSdkVersion() string { + if x != nil { + return x.SdkVersion + } + return "" +} + +// PeerConnection stats sent by peer +// https://developer.mozilla.org/en-US/docs/Web/API/RTCStatsReport#the_statistic_types +type PeerMessage_RTCStatsReport struct { + state protoimpl.MessageState `protogen:"open.v1"` + Data string `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PeerMessage_RTCStatsReport) Reset() { + *x = PeerMessage_RTCStatsReport{} + mi := &file_fishjam_peer_notifications_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PeerMessage_RTCStatsReport) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeerMessage_RTCStatsReport) ProtoMessage() {} + +func (x *PeerMessage_RTCStatsReport) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_peer_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 PeerMessage_RTCStatsReport.ProtoReflect.Descriptor instead. +func (*PeerMessage_RTCStatsReport) Descriptor() ([]byte, []int) { + return file_fishjam_peer_notifications_proto_rawDescGZIP(), []int{0, 3} +} + +func (x *PeerMessage_RTCStatsReport) GetData() string { + if x != nil { + return x.Data + } + return "" +} + +// Any type of WebRTC messages passed between FJ and peer +type PeerMessage_MediaEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + Data string `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PeerMessage_MediaEvent) Reset() { + *x = PeerMessage_MediaEvent{} + mi := &file_fishjam_peer_notifications_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PeerMessage_MediaEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeerMessage_MediaEvent) ProtoMessage() {} + +func (x *PeerMessage_MediaEvent) ProtoReflect() protoreflect.Message { + mi := &file_fishjam_peer_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 PeerMessage_MediaEvent.ProtoReflect.Descriptor instead. +func (*PeerMessage_MediaEvent) Descriptor() ([]byte, []int) { + return file_fishjam_peer_notifications_proto_rawDescGZIP(), []int{0, 4} +} + +func (x *PeerMessage_MediaEvent) GetData() string { + if x != nil { + return x.Data + } + return "" +} + +var File_fishjam_peer_notifications_proto protoreflect.FileDescriptor + +const file_fishjam_peer_notifications_proto_rawDesc = "" + + "\n" + + " fishjam/peer_notifications.proto\x12\afishjam\x1a$fishjam/media_events/peer/peer.proto\x1a(fishjam/media_events/server/server.proto\"\xe4\b\n" + + "\vPeerMessage\x12J\n" + + "\rauthenticated\x18\x01 \x01(\v2\".fishjam.PeerMessage.AuthenticatedH\x00R\rauthenticated\x12E\n" + + "\fauth_request\x18\x02 \x01(\v2 .fishjam.PeerMessage.AuthRequestH\x00R\vauthRequest\x12B\n" + + "\vmedia_event\x18\x03 \x01(\v2\x1f.fishjam.PeerMessage.MediaEventH\x00R\n" + + "mediaEvent\x12O\n" + + "\x10rtc_stats_report\x18\x04 \x01(\v2#.fishjam.PeerMessage.RTCStatsReportH\x00R\x0ertcStatsReport\x12Q\n" + + "\x10peer_media_event\x18\x05 \x01(\v2%.fishjam.media_events.peer.MediaEventH\x00R\x0epeerMediaEvent\x12W\n" + + "\x12server_media_event\x18\x06 \x01(\v2'.fishjam.media_events.server.MediaEventH\x00R\x10serverMediaEvent\x1a\xd6\x01\n" + + "\x0eSdkDeprecation\x12B\n" + + "\x06status\x18\x01 \x01(\x0e2*.fishjam.PeerMessage.SdkDeprecation.StatusR\x06status\x12\x18\n" + + "\amessage\x18\x02 \x01(\tR\amessage\"f\n" + + "\x06Status\x12\x16\n" + + "\x12STATUS_UNSPECIFIED\x10\x00\x12\x15\n" + + "\x11STATUS_UP_TO_DATE\x10\x01\x12\x15\n" + + "\x11STATUS_DEPRECATED\x10\x02\x12\x16\n" + + "\x12STATUS_UNSUPPORTED\x10\x03\x1a\x99\x01\n" + + "\rAuthenticated\x12:\n" + + "\troom_type\x18\x01 \x01(\x0e2\x1d.fishjam.PeerMessage.RoomTypeR\broomType\x12L\n" + + "\x0fsdk_deprecation\x18\x02 \x01(\v2#.fishjam.PeerMessage.SdkDeprecationR\x0esdkDeprecation\x1aD\n" + + "\vAuthRequest\x12\x14\n" + + "\x05token\x18\x01 \x01(\tR\x05token\x12\x1f\n" + + "\vsdk_version\x18\x02 \x01(\tR\n" + + "sdkVersion\x1a$\n" + + "\x0eRTCStatsReport\x12\x12\n" + + "\x04data\x18\x01 \x01(\tR\x04data\x1a \n" + + "\n" + + "MediaEvent\x12\x12\n" + + "\x04data\x18\x01 \x01(\tR\x04data\"s\n" + + "\bRoomType\x12\x19\n" + + "\x15ROOM_TYPE_UNSPECIFIED\x10\x00\x12\x18\n" + + "\x14ROOM_TYPE_CONFERENCE\x10\x01\x12\x18\n" + + "\x14ROOM_TYPE_AUDIO_ONLY\x10\x02\x12\x18\n" + + "\x14ROOM_TYPE_LIVESTREAM\x10\x03B\t\n" + + "\acontentB$Z\"conference-to-stream/proto/fishjamb\x06proto3" + +var ( + file_fishjam_peer_notifications_proto_rawDescOnce sync.Once + file_fishjam_peer_notifications_proto_rawDescData []byte +) + +func file_fishjam_peer_notifications_proto_rawDescGZIP() []byte { + file_fishjam_peer_notifications_proto_rawDescOnce.Do(func() { + file_fishjam_peer_notifications_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_fishjam_peer_notifications_proto_rawDesc), len(file_fishjam_peer_notifications_proto_rawDesc))) + }) + return file_fishjam_peer_notifications_proto_rawDescData +} + +var file_fishjam_peer_notifications_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_fishjam_peer_notifications_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_fishjam_peer_notifications_proto_goTypes = []any{ + (PeerMessage_RoomType)(0), // 0: fishjam.PeerMessage.RoomType + (PeerMessage_SdkDeprecation_Status)(0), // 1: fishjam.PeerMessage.SdkDeprecation.Status + (*PeerMessage)(nil), // 2: fishjam.PeerMessage + (*PeerMessage_SdkDeprecation)(nil), // 3: fishjam.PeerMessage.SdkDeprecation + (*PeerMessage_Authenticated)(nil), // 4: fishjam.PeerMessage.Authenticated + (*PeerMessage_AuthRequest)(nil), // 5: fishjam.PeerMessage.AuthRequest + (*PeerMessage_RTCStatsReport)(nil), // 6: fishjam.PeerMessage.RTCStatsReport + (*PeerMessage_MediaEvent)(nil), // 7: fishjam.PeerMessage.MediaEvent + (*peer.MediaEvent)(nil), // 8: fishjam.media_events.peer.MediaEvent + (*server.MediaEvent)(nil), // 9: fishjam.media_events.server.MediaEvent +} +var file_fishjam_peer_notifications_proto_depIdxs = []int32{ + 4, // 0: fishjam.PeerMessage.authenticated:type_name -> fishjam.PeerMessage.Authenticated + 5, // 1: fishjam.PeerMessage.auth_request:type_name -> fishjam.PeerMessage.AuthRequest + 7, // 2: fishjam.PeerMessage.media_event:type_name -> fishjam.PeerMessage.MediaEvent + 6, // 3: fishjam.PeerMessage.rtc_stats_report:type_name -> fishjam.PeerMessage.RTCStatsReport + 8, // 4: fishjam.PeerMessage.peer_media_event:type_name -> fishjam.media_events.peer.MediaEvent + 9, // 5: fishjam.PeerMessage.server_media_event:type_name -> fishjam.media_events.server.MediaEvent + 1, // 6: fishjam.PeerMessage.SdkDeprecation.status:type_name -> fishjam.PeerMessage.SdkDeprecation.Status + 0, // 7: fishjam.PeerMessage.Authenticated.room_type:type_name -> fishjam.PeerMessage.RoomType + 3, // 8: fishjam.PeerMessage.Authenticated.sdk_deprecation:type_name -> fishjam.PeerMessage.SdkDeprecation + 9, // [9:9] is the sub-list for method output_type + 9, // [9:9] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name +} + +func init() { file_fishjam_peer_notifications_proto_init() } +func file_fishjam_peer_notifications_proto_init() { + if File_fishjam_peer_notifications_proto != nil { + return + } + file_fishjam_peer_notifications_proto_msgTypes[0].OneofWrappers = []any{ + (*PeerMessage_Authenticated_)(nil), + (*PeerMessage_AuthRequest_)(nil), + (*PeerMessage_MediaEvent_)(nil), + (*PeerMessage_RtcStatsReport)(nil), + (*PeerMessage_PeerMediaEvent)(nil), + (*PeerMessage_ServerMediaEvent)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_fishjam_peer_notifications_proto_rawDesc), len(file_fishjam_peer_notifications_proto_rawDesc)), + NumEnums: 2, + NumMessages: 6, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_fishjam_peer_notifications_proto_goTypes, + DependencyIndexes: file_fishjam_peer_notifications_proto_depIdxs, + EnumInfos: file_fishjam_peer_notifications_proto_enumTypes, + MessageInfos: file_fishjam_peer_notifications_proto_msgTypes, + }.Build() + File_fishjam_peer_notifications_proto = out.File + file_fishjam_peer_notifications_proto_goTypes = nil + file_fishjam_peer_notifications_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..954b484 --- /dev/null +++ b/conference-to-stream/backend/proto/fishjam/server_notifications.pb.go @@ -0,0 +1,2992 @@ +// 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} +} + +type ServerMessage_VadNotification_Status int32 + +const ( + ServerMessage_VadNotification_STATUS_UNSPECIFIED ServerMessage_VadNotification_Status = 0 + ServerMessage_VadNotification_STATUS_SILENCE ServerMessage_VadNotification_Status = 1 + ServerMessage_VadNotification_STATUS_SPEECH ServerMessage_VadNotification_Status = 2 +) + +// Enum value maps for ServerMessage_VadNotification_Status. +var ( + ServerMessage_VadNotification_Status_name = map[int32]string{ + 0: "STATUS_UNSPECIFIED", + 1: "STATUS_SILENCE", + 2: "STATUS_SPEECH", + } + ServerMessage_VadNotification_Status_value = map[string]int32{ + "STATUS_UNSPECIFIED": 0, + "STATUS_SILENCE": 1, + "STATUS_SPEECH": 2, + } +) + +func (x ServerMessage_VadNotification_Status) Enum() *ServerMessage_VadNotification_Status { + p := new(ServerMessage_VadNotification_Status) + *p = x + return p +} + +func (x ServerMessage_VadNotification_Status) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ServerMessage_VadNotification_Status) Descriptor() protoreflect.EnumDescriptor { + return file_fishjam_server_notifications_proto_enumTypes[2].Descriptor() +} + +func (ServerMessage_VadNotification_Status) Type() protoreflect.EnumType { + return &file_fishjam_server_notifications_proto_enumTypes[2] +} + +func (x ServerMessage_VadNotification_Status) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ServerMessage_VadNotification_Status.Descriptor instead. +func (ServerMessage_VadNotification_Status) EnumDescriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 24, 0} +} + +// 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_VadNotification_ + // *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) GetVadNotification() *ServerMessage_VadNotification { + if x != nil { + if x, ok := x.Content.(*ServerMessage_VadNotification_); ok { + return x.VadNotification + } + } + 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_VadNotification_ struct { + VadNotification *ServerMessage_VadNotification `protobuf:"bytes,32,opt,name=vad_notification,json=vadNotification,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_VadNotification_) 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 Composition +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 voice activity changes on a track +type ServerMessage_VadNotification 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"` + TrackId string `protobuf:"bytes,3,opt,name=track_id,json=trackId,proto3" json:"track_id,omitempty"` + Status ServerMessage_VadNotification_Status `protobuf:"varint,4,opt,name=status,proto3,enum=fishjam.ServerMessage_VadNotification_Status" json:"status,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServerMessage_VadNotification) Reset() { + *x = ServerMessage_VadNotification{} + mi := &file_fishjam_server_notifications_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerMessage_VadNotification) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerMessage_VadNotification) ProtoMessage() {} + +func (x *ServerMessage_VadNotification) 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_VadNotification.ProtoReflect.Descriptor instead. +func (*ServerMessage_VadNotification) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 24} +} + +func (x *ServerMessage_VadNotification) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +func (x *ServerMessage_VadNotification) GetPeerId() string { + if x != nil { + return x.PeerId + } + return "" +} + +func (x *ServerMessage_VadNotification) GetTrackId() string { + if x != nil { + return x.TrackId + } + return "" +} + +func (x *ServerMessage_VadNotification) GetStatus() ServerMessage_VadNotification_Status { + if x != nil { + return x.Status + } + return ServerMessage_VadNotification_STATUS_UNSPECIFIED +} + +// 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[26] + 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[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_StreamConnected.ProtoReflect.Descriptor instead. +func (*ServerMessage_StreamConnected) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 25} +} + +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[27] + 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[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_StreamDisconnected.ProtoReflect.Descriptor instead. +func (*ServerMessage_StreamDisconnected) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 26} +} + +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[28] + 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[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_ViewerConnected.ProtoReflect.Descriptor instead. +func (*ServerMessage_ViewerConnected) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 27} +} + +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[29] + 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[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_ViewerDisconnected.ProtoReflect.Descriptor instead. +func (*ServerMessage_ViewerDisconnected) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 28} +} + +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[30] + 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[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_StreamerConnected.ProtoReflect.Descriptor instead. +func (*ServerMessage_StreamerConnected) Descriptor() ([]byte, []int) { + return file_fishjam_server_notifications_proto_rawDescGZIP(), []int{0, 29} +} + +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[31] + 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[31] + 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, 30} +} + +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\"\x9f0\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" + + "\x10vad_notification\x18 \x01(\v2&.fishjam.ServerMessage.VadNotificationH\x00R\x0fvadNotification\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\xee\x01\n" + + "\x0fVadNotification\x12\x17\n" + + "\aroom_id\x18\x01 \x01(\tR\x06roomId\x12\x17\n" + + "\apeer_id\x18\x02 \x01(\tR\x06peerId\x12\x19\n" + + "\btrack_id\x18\x03 \x01(\tR\atrackId\x12E\n" + + "\x06status\x18\x04 \x01(\x0e2-.fishjam.ServerMessage.VadNotification.StatusR\x06status\"G\n" + + "\x06Status\x12\x16\n" + + "\x12STATUS_UNSPECIFIED\x10\x00\x12\x12\n" + + "\x0eSTATUS_SILENCE\x10\x01\x12\x11\n" + + "\rSTATUS_SPEECH\x10\x02\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$Z\"conference-to-stream/proto/fishjamb\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, 3) +var file_fishjam_server_notifications_proto_msgTypes = make([]protoimpl.MessageInfo, 32) +var file_fishjam_server_notifications_proto_goTypes = []any{ + (ServerMessage_PeerType)(0), // 0: fishjam.ServerMessage.PeerType + (ServerMessage_EventType)(0), // 1: fishjam.ServerMessage.EventType + (ServerMessage_VadNotification_Status)(0), // 2: fishjam.ServerMessage.VadNotification.Status + (*ServerMessage)(nil), // 3: fishjam.ServerMessage + (*ServerMessage_RoomCrashed)(nil), // 4: fishjam.ServerMessage.RoomCrashed + (*ServerMessage_PeerAdded)(nil), // 5: fishjam.ServerMessage.PeerAdded + (*ServerMessage_PeerDeleted)(nil), // 6: fishjam.ServerMessage.PeerDeleted + (*ServerMessage_PeerConnected)(nil), // 7: fishjam.ServerMessage.PeerConnected + (*ServerMessage_PeerDisconnected)(nil), // 8: fishjam.ServerMessage.PeerDisconnected + (*ServerMessage_PeerCrashed)(nil), // 9: fishjam.ServerMessage.PeerCrashed + (*ServerMessage_ComponentCrashed)(nil), // 10: fishjam.ServerMessage.ComponentCrashed + (*ServerMessage_Authenticated)(nil), // 11: fishjam.ServerMessage.Authenticated + (*ServerMessage_AuthRequest)(nil), // 12: fishjam.ServerMessage.AuthRequest + (*ServerMessage_SubscribeRequest)(nil), // 13: fishjam.ServerMessage.SubscribeRequest + (*ServerMessage_SubscribeResponse)(nil), // 14: fishjam.ServerMessage.SubscribeResponse + (*ServerMessage_RoomCreated)(nil), // 15: fishjam.ServerMessage.RoomCreated + (*ServerMessage_RoomDeleted)(nil), // 16: fishjam.ServerMessage.RoomDeleted + (*ServerMessage_HlsPlayable)(nil), // 17: fishjam.ServerMessage.HlsPlayable + (*ServerMessage_HlsUploaded)(nil), // 18: fishjam.ServerMessage.HlsUploaded + (*ServerMessage_HlsUploadCrashed)(nil), // 19: fishjam.ServerMessage.HlsUploadCrashed + (*ServerMessage_PeerMetadataUpdated)(nil), // 20: fishjam.ServerMessage.PeerMetadataUpdated + (*ServerMessage_TrackAdded)(nil), // 21: fishjam.ServerMessage.TrackAdded + (*ServerMessage_TrackRemoved)(nil), // 22: fishjam.ServerMessage.TrackRemoved + (*ServerMessage_TrackMetadataUpdated)(nil), // 23: fishjam.ServerMessage.TrackMetadataUpdated + (*ServerMessage_ChannelAdded)(nil), // 24: fishjam.ServerMessage.ChannelAdded + (*ServerMessage_ChannelRemoved)(nil), // 25: fishjam.ServerMessage.ChannelRemoved + (*ServerMessage_TrackForwarding)(nil), // 26: fishjam.ServerMessage.TrackForwarding + (*ServerMessage_TrackForwardingRemoved)(nil), // 27: fishjam.ServerMessage.TrackForwardingRemoved + (*ServerMessage_VadNotification)(nil), // 28: fishjam.ServerMessage.VadNotification + (*ServerMessage_StreamConnected)(nil), // 29: fishjam.ServerMessage.StreamConnected + (*ServerMessage_StreamDisconnected)(nil), // 30: fishjam.ServerMessage.StreamDisconnected + (*ServerMessage_ViewerConnected)(nil), // 31: fishjam.ServerMessage.ViewerConnected + (*ServerMessage_ViewerDisconnected)(nil), // 32: fishjam.ServerMessage.ViewerDisconnected + (*ServerMessage_StreamerConnected)(nil), // 33: fishjam.ServerMessage.StreamerConnected + (*ServerMessage_StreamerDisconnected)(nil), // 34: fishjam.ServerMessage.StreamerDisconnected + (*notifications.Track)(nil), // 35: fishjam.notifications.Track +} +var file_fishjam_server_notifications_proto_depIdxs = []int32{ + 11, // 0: fishjam.ServerMessage.authenticated:type_name -> fishjam.ServerMessage.Authenticated + 12, // 1: fishjam.ServerMessage.auth_request:type_name -> fishjam.ServerMessage.AuthRequest + 13, // 2: fishjam.ServerMessage.subscribe_request:type_name -> fishjam.ServerMessage.SubscribeRequest + 14, // 3: fishjam.ServerMessage.subscribe_response:type_name -> fishjam.ServerMessage.SubscribeResponse + 15, // 4: fishjam.ServerMessage.room_created:type_name -> fishjam.ServerMessage.RoomCreated + 16, // 5: fishjam.ServerMessage.room_deleted:type_name -> fishjam.ServerMessage.RoomDeleted + 4, // 6: fishjam.ServerMessage.room_crashed:type_name -> fishjam.ServerMessage.RoomCrashed + 7, // 7: fishjam.ServerMessage.peer_connected:type_name -> fishjam.ServerMessage.PeerConnected + 8, // 8: fishjam.ServerMessage.peer_disconnected:type_name -> fishjam.ServerMessage.PeerDisconnected + 9, // 9: fishjam.ServerMessage.peer_crashed:type_name -> fishjam.ServerMessage.PeerCrashed + 20, // 10: fishjam.ServerMessage.peer_metadata_updated:type_name -> fishjam.ServerMessage.PeerMetadataUpdated + 21, // 11: fishjam.ServerMessage.track_added:type_name -> fishjam.ServerMessage.TrackAdded + 22, // 12: fishjam.ServerMessage.track_removed:type_name -> fishjam.ServerMessage.TrackRemoved + 23, // 13: fishjam.ServerMessage.track_metadata_updated:type_name -> fishjam.ServerMessage.TrackMetadataUpdated + 5, // 14: fishjam.ServerMessage.peer_added:type_name -> fishjam.ServerMessage.PeerAdded + 6, // 15: fishjam.ServerMessage.peer_deleted:type_name -> fishjam.ServerMessage.PeerDeleted + 24, // 16: fishjam.ServerMessage.channel_added:type_name -> fishjam.ServerMessage.ChannelAdded + 25, // 17: fishjam.ServerMessage.channel_removed:type_name -> fishjam.ServerMessage.ChannelRemoved + 26, // 18: fishjam.ServerMessage.track_forwarding:type_name -> fishjam.ServerMessage.TrackForwarding + 27, // 19: fishjam.ServerMessage.track_forwarding_removed:type_name -> fishjam.ServerMessage.TrackForwardingRemoved + 28, // 20: fishjam.ServerMessage.vad_notification:type_name -> fishjam.ServerMessage.VadNotification + 31, // 21: fishjam.ServerMessage.viewer_connected:type_name -> fishjam.ServerMessage.ViewerConnected + 32, // 22: fishjam.ServerMessage.viewer_disconnected:type_name -> fishjam.ServerMessage.ViewerDisconnected + 33, // 23: fishjam.ServerMessage.streamer_connected:type_name -> fishjam.ServerMessage.StreamerConnected + 34, // 24: fishjam.ServerMessage.streamer_disconnected:type_name -> fishjam.ServerMessage.StreamerDisconnected + 29, // 25: fishjam.ServerMessage.stream_connected:type_name -> fishjam.ServerMessage.StreamConnected + 30, // 26: fishjam.ServerMessage.stream_disconnected:type_name -> fishjam.ServerMessage.StreamDisconnected + 17, // 27: fishjam.ServerMessage.hls_playable:type_name -> fishjam.ServerMessage.HlsPlayable + 18, // 28: fishjam.ServerMessage.hls_uploaded:type_name -> fishjam.ServerMessage.HlsUploaded + 19, // 29: fishjam.ServerMessage.hls_upload_crashed:type_name -> fishjam.ServerMessage.HlsUploadCrashed + 10, // 30: fishjam.ServerMessage.component_crashed:type_name -> fishjam.ServerMessage.ComponentCrashed + 0, // 31: fishjam.ServerMessage.PeerAdded.peer_type:type_name -> fishjam.ServerMessage.PeerType + 0, // 32: fishjam.ServerMessage.PeerDeleted.peer_type:type_name -> fishjam.ServerMessage.PeerType + 0, // 33: fishjam.ServerMessage.PeerConnected.peer_type:type_name -> fishjam.ServerMessage.PeerType + 0, // 34: fishjam.ServerMessage.PeerDisconnected.peer_type:type_name -> fishjam.ServerMessage.PeerType + 0, // 35: fishjam.ServerMessage.PeerCrashed.peer_type:type_name -> fishjam.ServerMessage.PeerType + 1, // 36: fishjam.ServerMessage.SubscribeRequest.event_type:type_name -> fishjam.ServerMessage.EventType + 1, // 37: fishjam.ServerMessage.SubscribeResponse.event_type:type_name -> fishjam.ServerMessage.EventType + 0, // 38: fishjam.ServerMessage.PeerMetadataUpdated.peer_type:type_name -> fishjam.ServerMessage.PeerType + 35, // 39: fishjam.ServerMessage.TrackAdded.track:type_name -> fishjam.notifications.Track + 35, // 40: fishjam.ServerMessage.TrackRemoved.track:type_name -> fishjam.notifications.Track + 35, // 41: fishjam.ServerMessage.TrackMetadataUpdated.track:type_name -> fishjam.notifications.Track + 35, // 42: fishjam.ServerMessage.TrackForwarding.audio_track:type_name -> fishjam.notifications.Track + 35, // 43: fishjam.ServerMessage.TrackForwarding.video_track:type_name -> fishjam.notifications.Track + 2, // 44: fishjam.ServerMessage.VadNotification.status:type_name -> fishjam.ServerMessage.VadNotification.Status + 45, // [45:45] is the sub-list for method output_type + 45, // [45:45] is the sub-list for method input_type + 45, // [45:45] is the sub-list for extension type_name + 45, // [45:45] is the sub-list for extension extendee + 0, // [0:45] 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_VadNotification_)(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: 3, + NumMessages: 32, + 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/backend/protos b/conference-to-stream/backend/protos new file mode 160000 index 0000000..80c65b5 --- /dev/null +++ b/conference-to-stream/backend/protos @@ -0,0 +1 @@ +Subproject commit 80c65b540df739f10000451b3faceb066fbaa0b3 diff --git a/conference-to-stream/docker-compose.yml b/conference-to-stream/docker-compose.yml new file mode 100644 index 0000000..41668e5 --- /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: + FISHJAM_ID: ${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..bf01524 --- /dev/null +++ b/conference-to-stream/web/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +dist/ +tsconfig.tsbuildinfo diff --git a/conference-to-stream/web/.yarn/install-state.gz b/conference-to-stream/web/.yarn/install-state.gz new file mode 100644 index 0000000..2ed85d3 Binary files /dev/null and b/conference-to-stream/web/.yarn/install-state.gz differ diff --git a/conference-to-stream/web/.yarnrc.yml b/conference-to-stream/web/.yarnrc.yml new file mode 100644 index 0000000..3186f3f --- /dev/null +++ b/conference-to-stream/web/.yarnrc.yml @@ -0,0 +1 @@ +nodeLinker: node-modules diff --git a/conference-to-stream/web/Dockerfile b/conference-to-stream/web/Dockerfile new file mode 100644 index 0000000..8d71af3 --- /dev/null +++ b/conference-to-stream/web/Dockerfile @@ -0,0 +1,15 @@ +FROM node:22-alpine AS builder +WORKDIR /app +COPY package.json package-lock.json ./ +RUN npm install +COPY . . +ARG FISHJAM_ID +ARG VITE_BACKEND_URL=http://localhost:8080 +ENV FISHJAM_ID=$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.json b/conference-to-stream/web/package.json new file mode 100644 index 0000000..e8601c9 --- /dev/null +++ b/conference-to-stream/web/package.json @@ -0,0 +1,30 @@ +{ + "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": "file:/Users/roznawsk/fjc/web-client-sdk/packages/react-client", + "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" + }, + "resolutions": { + "@fishjam-cloud/ts-client": "file:/Users/roznawsk/fjc/web-client-sdk/packages/ts-client", + "@fishjam-cloud/webrtc-client": "file:/Users/roznawsk/fjc/web-client-sdk/packages/webrtc-client" + }, + "packageManager": "yarn@4.13.0" +} diff --git a/conference-to-stream/web/src/App.tsx b/conference-to-stream/web/src/App.tsx new file mode 100644 index 0000000..9d91332 --- /dev/null +++ b/conference-to-stream/web/src/App.tsx @@ -0,0 +1,57 @@ +import { useEffect, useState } from "react"; +import { Conference } from "./components/Conference"; +import { JoinForm } from "./components/JoinForm"; + +type AppState = + | { status: "idle"; initialRoomName?: string } + | { status: "joined"; roomId: string; whepUrl: string; livestreamID: 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", roomId, livestreamID, 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..53dc812 --- /dev/null +++ b/conference-to-stream/web/src/api.ts @@ -0,0 +1,32 @@ +const backendUrl = (import.meta.env.VITE_BACKEND_URL as string) || "http://localhost:8080"; + +export type JoinRoomResult = { + roomId: string; + whepUrl: string; + livestreamID: 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..02eb14d --- /dev/null +++ b/conference-to-stream/web/src/components/Conference.tsx @@ -0,0 +1,130 @@ +import { + useCamera, + useConnection, + useMicrophone, + usePeers, + useVAD, +} from "@fishjam-cloud/react-client"; +import { useEffect, useMemo } from "react"; +import { PeerTile } from "./PeerTile"; +import { WhepPlayer } from "./WhepPlayer"; + +type Props = { + livestreamID: string; + whepUrl: string; + roomName: string; + peerName: string; + onLeave: () => void; +}; + +export function Conference({ whepUrl, livestreamID, roomName, peerName, onLeave }: Props) { + const { leaveRoom } = useConnection(); + const { isCameraOn, toggleCamera, cameraStream } = useCamera(); + const { isMicrophoneMuted, toggleMicrophoneMute } = useMicrophone(); + const { remotePeers, localPeer } = usePeers<{ name: string }>(); + + const peerIds = useMemo(() => { + const ids = remotePeers.map((p) => p.id); + if (localPeer) ids.push(localPeer.id); + return ids; + }, [localPeer, remotePeers]); + + const vadStatuses = useVAD({ peerIds }); + + useEffect(() => { + if (Object.keys(vadStatuses).length > 0) { + console.log("VAD statuses:", vadStatuses); + } + }, [vadStatuses]); + + 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 Composition API

+
+
+
+ ); +} 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..34b3d64 --- /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: { roomId: string; whepUrl: string; livestreamID: 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, livestreamID } = await createRoom(roomName.trim()); + const { peerToken } = await createPeer(roomId, peerName.trim()); + await joinRoom({ peerToken, peerMetadata: { name: peerName.trim() } }); + onJoined({ roomId, whepUrl, livestreamID, 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..a3dbeef --- /dev/null +++ b/conference-to-stream/web/src/components/WhepPlayer.tsx @@ -0,0 +1,41 @@ +import { useEffect, useRef } from "react"; +import { useLivestreamViewer } from "@fishjam-cloud/react-client"; + +type Props = { + livestreamID: string; +}; + +export function WhepPlayer({ livestreamID }: Props) { + const videoRef = useRef(null); + const { connect, disconnect, stream, error } = useLivestreamViewer(); + + useEffect(() => { + connect({ streamId: livestreamID }); + return () => { + disconnect(); + }; + }, [livestreamID, connect, disconnect]); + + useEffect(() => { + if (videoRef.current && stream) { + videoRef.current.srcObject = stream; + } + }, [stream]); + + if (error) { + return ( +
+ {error} +
+ ); + } + + return ( +