diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..29c5a1a --- /dev/null +++ b/Makefile @@ -0,0 +1,3 @@ +default: + go build -gcflags="-e" . + diff --git a/README.md b/README.md index 6970926..3603b47 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![GoDoc](https://godoc.org/github.com/christopher-dG/go-obs-websocket?status.svg)](https://godoc.org/github.com/christopher-dG/go-obs-websocket) `obsws` provides client functionality for [`obs-websocket`](https://github.com/Palakis/obs-websocket). -Currently, the target version is `4.4`. +Currently, the target version is `4.8`. ## Installation @@ -25,8 +25,12 @@ import ( ) func main() { + // Optionally create a logger + + logger := log.New(os.Stdout, "obsws ", log.Lstdflags) + // Connect a client. - c := obsws.Client{Host: "localhost", Port: 4444} + c := obsws.Client{Host: "localhost", Port: 4444, logger: Logger} if err := c.Connect(); err != nil { log.Fatal(err) } diff --git a/client.go b/client.go index 928fa8d..f81b6cd 100644 --- a/client.go +++ b/client.go @@ -1,6 +1,7 @@ package obsws import ( + "log" "strconv" "sync" "time" @@ -24,6 +25,7 @@ type Client struct { Port int // Port (OBS default is 4444). Password string // Password (OBS default is ""). conn *websocket.Conn // Underlying connection to OBS. + Logger *log.Logger // Logger to use for most messages receiveTimeout time.Duration // Maximum blocking time for receiving request responses connected bool // True until Disconnect is called. handlers map[string]func(e Event) // Event handlers. @@ -33,7 +35,7 @@ type Client struct { // poll listens for responses/events. // This function blocks until Disconnect is called. func (c *Client) poll() { - Logger.Println("started polling") + c.Logger.Println("started polling") for c.connected { m := make(map[string]interface{}) @@ -77,6 +79,8 @@ func GetMessageID() string { // mapToStruct serializes a map into a struct. func mapToStruct(data map[string]interface{}, dest interface{}) error { + // func mapToStruct(resp Response, dest interface{}) error { + // data := resp.(map[string]) decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ TagName: "json", Result: dest, diff --git a/client_connection.go b/client_connection.go index 1228d68..d4acceb 100644 --- a/client_connection.go +++ b/client_connection.go @@ -14,6 +14,11 @@ func (c *Client) Connect() error { c.handlers = make(map[string]func(Event)) c.respQ = make(chan map[string]interface{}, bufferSize) + // Setup default logger + if c.Logger == nil { + c.Logger = Logger + } + conn, err := connectWS(c.Host, c.Port) if err != nil { return err @@ -33,14 +38,14 @@ func (c *Client) Connect() error { } if !respGAR.AuthRequired { - Logger.Println("logged in (no authentication required)") + c.Logger.Println("logged in (no authentication required)") c.connected = true go c.poll() return nil } auth := getAuth(c.Password, respGAR.Salt, respGAR.Challenge) - Logger.Println("auth:", auth) + c.Logger.Println("auth:", auth) reqA := NewAuthenticateRequest(auth) if err = c.conn.WriteJSON(reqA); err != nil { @@ -55,7 +60,7 @@ func (c *Client) Connect() error { return errors.New(respA.Error()) } - Logger.Println("logged in (authentication successful)") + c.Logger.Println("logged in (authentication successful)") c.connected = true go c.poll() return nil diff --git a/client_events.go b/client_events.go index bc53e7c..9bd98cf 100644 --- a/client_events.go +++ b/client_events.go @@ -35,7 +35,7 @@ func (c *Client) handleEvent(m map[string]interface{}) { eventFn, ok := eventMap[t] if !ok { - Logger.Println("unknown event type:", m["update-type"]) + c.Logger.Println("unknown event type:", m["update-type"]) return } event := eventFn() @@ -46,7 +46,7 @@ func (c *Client) handleEvent(m map[string]interface{}) { } if err := mapToStruct(m, event); err != nil { - Logger.Println("event handler failed:", err) + c.Logger.Println("event handler failed:", err) return } diff --git a/client_requests.go b/client_requests.go index d43db8d..6d6da6d 100644 --- a/client_requests.go +++ b/client_requests.go @@ -23,7 +23,7 @@ func (c *Client) SendRequest(req Request) (chan map[string]interface{}, error) { if err := c.conn.WriteJSON(req); err != nil { return nil, err } - Logger.Println("sent request", req.ID()) + c.Logger.Println("sent request", req.ID()) go func() { future <- c.receive(req.ID()) }() return future, nil } @@ -33,7 +33,7 @@ func (c *Client) receive(id string) map[string]interface{} { for { resp := <-c.respQ if resp["message-id"] == id { - Logger.Println("received response", resp["message-id"]) + c.Logger.Println("received response", resp["message-id"]) return resp } c.respQ <- resp diff --git a/codegen/protocol.py b/codegen/protocol.py index 154b588..3a4c6b5 100644 --- a/codegen/protocol.py +++ b/codegen/protocol.py @@ -26,12 +26,15 @@ "string": "string", "array": "[]interface{}", "array": "[]string", + "string | object": "interface{}", "object": "map[string]interface{}", "output": "map[string]interface{}", "array": "[]map[string]interface{}", "array": "[]map[string]interface{}", "array": "[]*Scene", "array": "[]*SceneItem", + "array": "[]*ScenesCollection", + "array": "[]*SceneItemTransform", "obsstats": "*OBSStats", "sceneitemtransform": "*SceneItemTransform", } @@ -157,7 +160,7 @@ def gen_request(data: Dict) -> str: }} // Receive waits for the response. - func (r {data["name"]}Request) Receive() ({data["name"]}Response, error) {{ + func (r {data["name"]}Request) Receive() (Response, error) {{ if !r.sent {{ return {data["name"]}Response{{}}, ErrNotSent }} @@ -181,7 +184,7 @@ def gen_request(data: Dict) -> str: }} // SendReceive sends the request then immediately waits for the response. - func (r {data["name"]}Request) SendReceive(c Client) ({data["name"]}Response, error) {{ + func (r {data["name"]}Request) SendReceive(c Client) (Response, error) {{ if err := r.Send(c); err != nil {{ return {data["name"]}Response{{}}, err }} @@ -385,6 +388,7 @@ def newlinify(s: str, comment: bool = True) -> str: def optional_type(s: str) -> Tuple[str, bool]: """Determine if a type is optional and parse the actual type name.""" + s = s.lower() if s.endswith("(optional)"): return s[: s.find("(optional)")].strip(), True return s, False diff --git a/event_utils.go b/event_utils.go index 2dad571..b7bd29d 100644 --- a/event_utils.go +++ b/event_utils.go @@ -12,6 +12,8 @@ var eventMap = map[string]func() Event{ "TransitionListChanged": func() Event { return &TransitionListChangedEvent{} }, "TransitionDurationChanged": func() Event { return &TransitionDurationChangedEvent{} }, "TransitionBegin": func() Event { return &TransitionBeginEvent{} }, + "TransitionEnd": func() Event { return &TransitionEndEvent{} }, + "TransitionVideoEnd": func() Event { return &TransitionVideoEndEvent{} }, "ProfileChanged": func() Event { return &ProfileChangedEvent{} }, "ProfileListChanged": func() Event { return &ProfileListChangedEvent{} }, "StreamStarting": func() Event { return &StreamStartingEvent{} }, @@ -36,6 +38,8 @@ var eventMap = map[string]func() Event{ "SourceDestroyed": func() Event { return &SourceDestroyedEvent{} }, "SourceVolumeChanged": func() Event { return &SourceVolumeChangedEvent{} }, "SourceMuteStateChanged": func() Event { return &SourceMuteStateChangedEvent{} }, + "SourceAudioDeactivated": func() Event { return &SourceAudioDeactivatedEvent{} }, + "SourceAudioActivated": func() Event { return &SourceAudioActivatedEvent{} }, "SourceAudioSyncOffsetChanged": func() Event { return &SourceAudioSyncOffsetChangedEvent{} }, "SourceAudioMixersChanged": func() Event { return &SourceAudioMixersChangedEvent{} }, "SourceRenamed": func() Event { return &SourceRenamedEvent{} }, @@ -43,10 +47,19 @@ var eventMap = map[string]func() Event{ "SourceFilterRemoved": func() Event { return &SourceFilterRemovedEvent{} }, "SourceFilterVisibilityChanged": func() Event { return &SourceFilterVisibilityChangedEvent{} }, "SourceFiltersReordered": func() Event { return &SourceFiltersReorderedEvent{} }, + "MediaPlaying": func() Event { return &MediaPlayingEvent{} }, + "MediaPaused": func() Event { return &MediaPausedEvent{} }, + "MediaRestarted": func() Event { return &MediaRestartedEvent{} }, + "MediaStopped": func() Event { return &MediaStoppedEvent{} }, + "MediaNext": func() Event { return &MediaNextEvent{} }, + "MediaPrevious": func() Event { return &MediaPreviousEvent{} }, + "MediaStarted": func() Event { return &MediaStartedEvent{} }, + "MediaEnded": func() Event { return &MediaEndedEvent{} }, "SourceOrderChanged": func() Event { return &SourceOrderChangedEvent{} }, "SceneItemAdded": func() Event { return &SceneItemAddedEvent{} }, "SceneItemRemoved": func() Event { return &SceneItemRemovedEvent{} }, "SceneItemVisibilityChanged": func() Event { return &SceneItemVisibilityChangedEvent{} }, + "SceneItemLockChanged": func() Event { return &SceneItemLockChangedEvent{} }, "SceneItemTransformChanged": func() Event { return &SceneItemTransformChangedEvent{} }, "SceneItemSelected": func() Event { return &SceneItemSelectedEvent{} }, "SceneItemDeselected": func() Event { return &SceneItemDeselectedEvent{} }, @@ -74,6 +87,10 @@ func derefEvent(e Event) Event { return *e case *TransitionBeginEvent: return *e + case *TransitionEndEvent: + return *e + case *TransitionVideoEndEvent: + return *e case *ProfileChangedEvent: return *e case *ProfileListChangedEvent: @@ -122,6 +139,10 @@ func derefEvent(e Event) Event { return *e case *SourceMuteStateChangedEvent: return *e + case *SourceAudioDeactivatedEvent: + return *e + case *SourceAudioActivatedEvent: + return *e case *SourceAudioSyncOffsetChangedEvent: return *e case *SourceAudioMixersChangedEvent: @@ -136,6 +157,22 @@ func derefEvent(e Event) Event { return *e case *SourceFiltersReorderedEvent: return *e + case *MediaPlayingEvent: + return *e + case *MediaPausedEvent: + return *e + case *MediaRestartedEvent: + return *e + case *MediaStoppedEvent: + return *e + case *MediaNextEvent: + return *e + case *MediaPreviousEvent: + return *e + case *MediaStartedEvent: + return *e + case *MediaEndedEvent: + return *e case *SourceOrderChangedEvent: return *e case *SceneItemAddedEvent: @@ -144,6 +181,8 @@ func derefEvent(e Event) Event { return *e case *SceneItemVisibilityChangedEvent: return *e + case *SceneItemLockChangedEvent: + return *e case *SceneItemTransformChangedEvent: return *e case *SceneItemSelectedEvent: diff --git a/events_general.go b/events_general.go index cd13ae6..7405d45 100644 --- a/events_general.go +++ b/events_general.go @@ -5,6 +5,8 @@ package obsws // HeartbeatEvent : Emitted every 2 seconds after enabling it by calling SetHeartbeat. // +// Since obs-websocket version: V0.3. +// // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#heartbeat type HeartbeatEvent struct { // Toggles between every JSON message as an "I am alive" indicator. @@ -46,7 +48,7 @@ type HeartbeatEvent struct { _event `json:",squash"` } -// BroadcastCustomMessageEvent : A custom broadcast message was received. +// BroadcastCustomMessageEvent : A custom broadcast message, sent by the server, requested by one of the websocket clients. // // Since obs-websocket version: 4.7.0. // diff --git a/events_media.go b/events_media.go new file mode 100644 index 0000000..3c3d952 --- /dev/null +++ b/events_media.go @@ -0,0 +1,158 @@ +package obsws + +// This file is automatically generated. +// https://github.com/christopher-dG/go-obs-websocket/blob/master/codegen/protocol.py + +// MediaPlayingEvent : +// +// Note: This event is only emitted when something actively controls the media/VLC source +// In other words, the source will never emit this on its own naturally. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#mediaplaying +type MediaPlayingEvent struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + // The ID type of the source (Eg. + // `vlc_source` or `ffmpeg_source`). + // Required: Yes. + SourceKind string `json:"sourceKind"` + _event `json:",squash"` +} + +// MediaPausedEvent : +// +// Note: This event is only emitted when something actively controls the media/VLC source +// In other words, the source will never emit this on its own naturally. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#mediapaused +type MediaPausedEvent struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + // The ID type of the source (Eg. + // `vlc_source` or `ffmpeg_source`). + // Required: Yes. + SourceKind string `json:"sourceKind"` + _event `json:",squash"` +} + +// MediaRestartedEvent : +// +// Note: This event is only emitted when something actively controls the media/VLC source +// In other words, the source will never emit this on its own naturally. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#mediarestarted +type MediaRestartedEvent struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + // The ID type of the source (Eg. + // `vlc_source` or `ffmpeg_source`). + // Required: Yes. + SourceKind string `json:"sourceKind"` + _event `json:",squash"` +} + +// MediaStoppedEvent : +// +// Note: This event is only emitted when something actively controls the media/VLC source +// In other words, the source will never emit this on its own naturally. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#mediastopped +type MediaStoppedEvent struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + // The ID type of the source (Eg. + // `vlc_source` or `ffmpeg_source`). + // Required: Yes. + SourceKind string `json:"sourceKind"` + _event `json:",squash"` +} + +// MediaNextEvent : +// +// Note: This event is only emitted when something actively controls the media/VLC source +// In other words, the source will never emit this on its own naturally. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#medianext +type MediaNextEvent struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + // The ID type of the source (Eg. + // `vlc_source` or `ffmpeg_source`). + // Required: Yes. + SourceKind string `json:"sourceKind"` + _event `json:",squash"` +} + +// MediaPreviousEvent : +// +// Note: This event is only emitted when something actively controls the media/VLC source +// In other words, the source will never emit this on its own naturally. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#mediaprevious +type MediaPreviousEvent struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + // The ID type of the source (Eg. + // `vlc_source` or `ffmpeg_source`). + // Required: Yes. + SourceKind string `json:"sourceKind"` + _event `json:",squash"` +} + +// MediaStartedEvent : +// +// Note: These events are emitted by the OBS sources themselves +// For example when the media file starts playing +// The behavior depends on the type of media source being used. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#mediastarted +type MediaStartedEvent struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + // The ID type of the source (Eg. + // `vlc_source` or `ffmpeg_source`). + // Required: Yes. + SourceKind string `json:"sourceKind"` + _event `json:",squash"` +} + +// MediaEndedEvent : +// +// Note: These events are emitted by the OBS sources themselves +// For example when the media file ends +// The behavior depends on the type of media source being used. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#mediaended +type MediaEndedEvent struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + // The ID type of the source (Eg. + // `vlc_source` or `ffmpeg_source`). + // Required: Yes. + SourceKind string `json:"sourceKind"` + _event `json:",squash"` +} diff --git a/events_profiles.go b/events_profiles.go index 78b288d..54f796b 100644 --- a/events_profiles.go +++ b/events_profiles.go @@ -9,7 +9,10 @@ package obsws // // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#profilechanged type ProfileChangedEvent struct { - _event `json:",squash"` + // Name of the new current profile. + // Required: Yes. + Profile string `json:"profile"` + _event `json:",squash"` } // ProfileListChangedEvent : Triggered when a profile is created, added, renamed, or removed. @@ -18,5 +21,11 @@ type ProfileChangedEvent struct { // // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#profilelistchanged type ProfileListChangedEvent struct { - _event `json:",squash"` + // Profiles list. + // Required: Yes. + Profiles []map[string]interface{} `json:"profiles"` + // Profile name. + // Required: Yes. + ProfilesName string `json:"profiles.*.name"` + _event `json:",squash"` } diff --git a/events_recording.go b/events_recording.go index d53d097..5ece737 100644 --- a/events_recording.go +++ b/events_recording.go @@ -3,7 +3,10 @@ package obsws // This file is automatically generated. // https://github.com/christopher-dG/go-obs-websocket/blob/master/codegen/protocol.py -// RecordingStartingEvent : A request to start recording has been issued. +// RecordingStartingEvent : +// +// Note: `recordingFilename` is not provided in this event because this information +// is not available at the time this event is emitted. // // Since obs-websocket version: 0.3. // @@ -18,7 +21,10 @@ type RecordingStartingEvent struct { // // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#recordingstarted type RecordingStartedEvent struct { - _event `json:",squash"` + // Absolute path to the file of the current recording. + // Required: Yes. + RecordingFilename string `json:"recordingFilename"` + _event `json:",squash"` } // RecordingStoppingEvent : A request to stop recording has been issued. @@ -27,7 +33,10 @@ type RecordingStartedEvent struct { // // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#recordingstopping type RecordingStoppingEvent struct { - _event `json:",squash"` + // Absolute path to the file of the current recording. + // Required: Yes. + RecordingFilename string `json:"recordingFilename"` + _event `json:",squash"` } // RecordingStoppedEvent : Recording stopped successfully. @@ -36,7 +45,10 @@ type RecordingStoppingEvent struct { // // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#recordingstopped type RecordingStoppedEvent struct { - _event `json:",squash"` + // Absolute path to the file of the current recording. + // Required: Yes. + RecordingFilename string `json:"recordingFilename"` + _event `json:",squash"` } // RecordingPausedEvent : Current recording paused. diff --git a/events_scene_items.go b/events_scene_items.go new file mode 100644 index 0000000..f72685e --- /dev/null +++ b/events_scene_items.go @@ -0,0 +1,160 @@ +package obsws + +// This file is automatically generated. +// https://github.com/christopher-dG/go-obs-websocket/blob/master/codegen/protocol.py + +// SourceOrderChangedEvent : Scene items within a scene have been reordered. +// +// Since obs-websocket version: 4.0.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#sourceorderchanged +type SourceOrderChangedEvent struct { + // Name of the scene where items have been reordered. + // Required: Yes. + SceneName string `json:"scene-name"` + // Ordered list of scene items. + // Required: Yes. + SceneItems []map[string]interface{} `json:"scene-items"` + // Item source name. + // Required: Yes. + SceneItemsSourceName string `json:"scene-items.*.source-name"` + // Scene item unique ID. + // Required: Yes. + SceneItemsItemID int `json:"scene-items.*.item-id"` + _event `json:",squash"` +} + +// SceneItemAddedEvent : A scene item has been added to a scene. +// +// Since obs-websocket version: 4.0.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#sceneitemadded +type SceneItemAddedEvent struct { + // Name of the scene. + // Required: Yes. + SceneName string `json:"scene-name"` + // Name of the item added to the scene. + // Required: Yes. + ItemName string `json:"item-name"` + // Scene item ID. + // Required: Yes. + ItemID int `json:"item-id"` + _event `json:",squash"` +} + +// SceneItemRemovedEvent : A scene item has been removed from a scene. +// +// Since obs-websocket version: 4.0.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#sceneitemremoved +type SceneItemRemovedEvent struct { + // Name of the scene. + // Required: Yes. + SceneName string `json:"scene-name"` + // Name of the item removed from the scene. + // Required: Yes. + ItemName string `json:"item-name"` + // Scene item ID. + // Required: Yes. + ItemID int `json:"item-id"` + _event `json:",squash"` +} + +// SceneItemVisibilityChangedEvent : A scene item's visibility has been toggled. +// +// Since obs-websocket version: 4.0.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#sceneitemvisibilitychanged +type SceneItemVisibilityChangedEvent struct { + // Name of the scene. + // Required: Yes. + SceneName string `json:"scene-name"` + // Name of the item in the scene. + // Required: Yes. + ItemName string `json:"item-name"` + // Scene item ID. + // Required: Yes. + ItemID int `json:"item-id"` + // New visibility state of the item. + // Required: Yes. + ItemVisible bool `json:"item-visible"` + _event `json:",squash"` +} + +// SceneItemLockChangedEvent : A scene item's locked status has been toggled. +// +// Since obs-websocket version: 4.8.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#sceneitemlockchanged +type SceneItemLockChangedEvent struct { + // Name of the scene. + // Required: Yes. + SceneName string `json:"scene-name"` + // Name of the item in the scene. + // Required: Yes. + ItemName string `json:"item-name"` + // Scene item ID. + // Required: Yes. + ItemID int `json:"item-id"` + // New locked state of the item. + // Required: Yes. + ItemLocked bool `json:"item-locked"` + _event `json:",squash"` +} + +// SceneItemTransformChangedEvent : A scene item's transform has been changed. +// +// Since obs-websocket version: 4.6.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#sceneitemtransformchanged +type SceneItemTransformChangedEvent struct { + // Name of the scene. + // Required: Yes. + SceneName string `json:"scene-name"` + // Name of the item in the scene. + // Required: Yes. + ItemName string `json:"item-name"` + // Scene item ID. + // Required: Yes. + ItemID int `json:"item-id"` + // Scene item transform properties. + // Required: Yes. + Transform *SceneItemTransform `json:"transform"` + _event `json:",squash"` +} + +// SceneItemSelectedEvent : A scene item is selected. +// +// Since obs-websocket version: 4.6.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#sceneitemselected +type SceneItemSelectedEvent struct { + // Name of the scene. + // Required: Yes. + SceneName string `json:"scene-name"` + // Name of the item in the scene. + // Required: Yes. + ItemName string `json:"item-name"` + // Name of the item in the scene. + // Required: Yes. + ItemID int `json:"item-id"` + _event `json:",squash"` +} + +// SceneItemDeselectedEvent : A scene item is deselected. +// +// Since obs-websocket version: 4.6.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#sceneitemdeselected +type SceneItemDeselectedEvent struct { + // Name of the scene. + // Required: Yes. + SceneName string `json:"scene-name"` + // Name of the item in the scene. + // Required: Yes. + ItemName string `json:"item-name"` + // Name of the item in the scene. + // Required: Yes. + ItemID int `json:"item-id"` + _event `json:",squash"` +} diff --git a/events_scenes.go b/events_scenes.go index 50fb5a2..46b360b 100644 --- a/events_scenes.go +++ b/events_scenes.go @@ -19,13 +19,17 @@ type SwitchScenesEvent struct { _event `json:",squash"` } -// ScenesChangedEvent : The scene list has been modified. -// Scenes have been added, removed, or renamed. +// ScenesChangedEvent : +// +// Note: This event is not fired when the scenes are reordered. // // Since obs-websocket version: 0.3. // // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#sceneschanged type ScenesChangedEvent struct { + // Scenes list. + // Required: Yes. + Scenes []*Scene `json:"scenes"` _event `json:",squash"` } @@ -35,7 +39,10 @@ type ScenesChangedEvent struct { // // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#scenecollectionchanged type SceneCollectionChangedEvent struct { - _event `json:",squash"` + // Name of the new current scene collection. + // Required: Yes. + SceneCollection string `json:"sceneCollection"` + _event `json:",squash"` } // SceneCollectionListChangedEvent : Triggered when a scene collection is created, added, renamed, or removed. @@ -44,5 +51,11 @@ type SceneCollectionChangedEvent struct { // // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#scenecollectionlistchanged type SceneCollectionListChangedEvent struct { - _event `json:",squash"` + // Scene collections list. + // Required: Yes. + SceneCollections []map[string]interface{} `json:"sceneCollections"` + // Scene collection name. + // Required: Yes. + SceneCollectionsName string `json:"sceneCollections.*.name"` + _event `json:",squash"` } diff --git a/events_sources.go b/events_sources.go index 70102be..dc20eed 100644 --- a/events_sources.go +++ b/events_sources.go @@ -76,6 +76,30 @@ type SourceMuteStateChangedEvent struct { _event `json:",squash"` } +// SourceAudioDeactivatedEvent : A source has removed audio. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#sourceaudiodeactivated +type SourceAudioDeactivatedEvent struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + _event `json:",squash"` +} + +// SourceAudioActivatedEvent : A source has added audio. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#sourceaudioactivated +type SourceAudioActivatedEvent struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + _event `json:",squash"` +} + // SourceAudioSyncOffsetChangedEvent : The audio sync offset of a source has changed. // // Since obs-websocket version: 4.6.0. @@ -127,7 +151,10 @@ type SourceRenamedEvent struct { // New source name. // Required: Yes. NewName string `json:"newName"` - _event `json:",squash"` + // Type of source (input, scene, filter, transition). + // Required: Yes. + SourceType string `json:"sourceType"` + _event `json:",squash"` } // SourceFilterAddedEvent : A filter was added to a source. @@ -205,140 +232,8 @@ type SourceFiltersReorderedEvent struct { // Filter type. // Required: Yes. FiltersType string `json:"filters.*.type"` - _event `json:",squash"` -} - -// SourceOrderChangedEvent : Scene items have been reordered. -// -// Since obs-websocket version: 4.0.0. -// -// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#sourceorderchanged -type SourceOrderChangedEvent struct { - // Name of the scene where items have been reordered. - // Required: Yes. - SceneName string `json:"scene-name"` - // Ordered list of scene items. - // Required: Yes. - SceneItems []map[string]interface{} `json:"scene-items"` - // Item source name. - // Required: Yes. - SceneItemsSourceName string `json:"scene-items.*.source-name"` - // Scene item unique ID. - // Required: Yes. - SceneItemsItemID int `json:"scene-items.*.item-id"` - _event `json:",squash"` -} - -// SceneItemAddedEvent : An item has been added to the current scene. -// -// Since obs-websocket version: 4.0.0. -// -// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#sceneitemadded -type SceneItemAddedEvent struct { - // Name of the scene. - // Required: Yes. - SceneName string `json:"scene-name"` - // Name of the item added to the scene. - // Required: Yes. - ItemName string `json:"item-name"` - // Scene item ID. - // Required: Yes. - ItemID int `json:"item-id"` - _event `json:",squash"` -} - -// SceneItemRemovedEvent : An item has been removed from the current scene. -// -// Since obs-websocket version: 4.0.0. -// -// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#sceneitemremoved -type SceneItemRemovedEvent struct { - // Name of the scene. + // Filter visibility status. // Required: Yes. - SceneName string `json:"scene-name"` - // Name of the item removed from the scene. - // Required: Yes. - ItemName string `json:"item-name"` - // Scene item ID. - // Required: Yes. - ItemID int `json:"item-id"` - _event `json:",squash"` -} - -// SceneItemVisibilityChangedEvent : An item's visibility has been toggled. -// -// Since obs-websocket version: 4.0.0. -// -// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#sceneitemvisibilitychanged -type SceneItemVisibilityChangedEvent struct { - // Name of the scene. - // Required: Yes. - SceneName string `json:"scene-name"` - // Name of the item in the scene. - // Required: Yes. - ItemName string `json:"item-name"` - // Scene item ID. - // Required: Yes. - ItemID int `json:"item-id"` - // New visibility state of the item. - // Required: Yes. - ItemVisible bool `json:"item-visible"` - _event `json:",squash"` -} - -// SceneItemTransformChangedEvent : An item's transform has been changed. -// -// Since obs-websocket version: 4.6.0. -// -// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#sceneitemtransformchanged -type SceneItemTransformChangedEvent struct { - // Name of the scene. - // Required: Yes. - SceneName string `json:"scene-name"` - // Name of the item in the scene. - // Required: Yes. - ItemName string `json:"item-name"` - // Scene item ID. - // Required: Yes. - ItemID int `json:"item-id"` - // Scene item transform properties. - // Required: Yes. - Transform *SceneItemTransform `json:"transform"` - _event `json:",squash"` -} - -// SceneItemSelectedEvent : A scene item is selected. -// -// Since obs-websocket version: 4.6.0. -// -// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#sceneitemselected -type SceneItemSelectedEvent struct { - // Name of the scene. - // Required: Yes. - SceneName string `json:"scene-name"` - // Name of the item in the scene. - // Required: Yes. - ItemName string `json:"item-name"` - // Name of the item in the scene. - // Required: Yes. - ItemID int `json:"item-id"` - _event `json:",squash"` -} - -// SceneItemDeselectedEvent : A scene item is deselected. -// -// Since obs-websocket version: 4.6.0. -// -// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#sceneitemdeselected -type SceneItemDeselectedEvent struct { - // Name of the scene. - // Required: Yes. - SceneName string `json:"scene-name"` - // Name of the item in the scene. - // Required: Yes. - ItemName string `json:"item-name"` - // Name of the item in the scene. - // Required: Yes. - ItemID int `json:"item-id"` - _event `json:",squash"` + FiltersEnabled bool `json:"filters.*.enabled"` + _event `json:",squash"` } diff --git a/events_streaming.go b/events_streaming.go index 99d2d50..08f9ac6 100644 --- a/events_streaming.go +++ b/events_streaming.go @@ -45,7 +45,7 @@ type StreamStoppedEvent struct { _event `json:",squash"` } -// StreamStatusEvent : Emit every 2 seconds. +// StreamStatusEvent : Emitted every 2 seconds when stream is active. // // Since obs-websocket version: 0.3. // diff --git a/events_transitions.go b/events_transitions.go index a529fc0..e7fcdd4 100644 --- a/events_transitions.go +++ b/events_transitions.go @@ -22,7 +22,13 @@ type SwitchTransitionEvent struct { // // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#transitionlistchanged type TransitionListChangedEvent struct { - _event `json:",squash"` + // Transitions list. + // Required: Yes. + Transitions []map[string]interface{} `json:"transitions"` + // Transition name. + // Required: Yes. + TransitionsName string `json:"transitions.*.name"` + _event `json:",squash"` } // TransitionDurationChangedEvent : The active transition duration has been changed. @@ -46,6 +52,56 @@ type TransitionBeginEvent struct { // Transition name. // Required: Yes. Name string `json:"name"` + // Transition type. + // Required: Yes. + Type_ string `json:"type"` + // Transition duration (in milliseconds). + // Will be -1 for any transition with a fixed duration, such as a Stinger, due to limitations of the OBS API. + // Required: Yes. + Duration int `json:"duration"` + // Source scene of the transition. + // Required: Yes. + FromScene string `json:"from-scene"` + // Destination scene of the transition. + // Required: Yes. + ToScene string `json:"to-scene"` + _event `json:",squash"` +} + +// TransitionEndEvent : A transition (other than "cut") has ended. +// Note: The `from-scene` field is not available in TransitionEnd. +// +// Since obs-websocket version: 4.8.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#transitionend +type TransitionEndEvent struct { + // Transition name. + // Required: Yes. + Name string `json:"name"` + // Transition type. + // Required: Yes. + Type_ string `json:"type"` + // Transition duration (in milliseconds). + // Required: Yes. + Duration int `json:"duration"` + // Destination scene of the transition. + // Required: Yes. + ToScene string `json:"to-scene"` + _event `json:",squash"` +} + +// TransitionVideoEndEvent : A stinger transition has finished playing its video. +// +// Since obs-websocket version: 4.8.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#transitionvideoend +type TransitionVideoEndEvent struct { + // Transition name. + // Required: Yes. + Name string `json:"name"` + // Transition type. + // Required: Yes. + Type_ string `json:"type"` // Transition duration (in milliseconds). // Required: Yes. Duration int `json:"duration"` diff --git a/go.mod b/go.mod index a8d8ec2..5afe1f4 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/christopher-dG/go-obs-websocket +module github.com/davidbegin/go-obs-websocket require ( github.com/gorilla/websocket v1.4.0 diff --git a/requests.go b/requests.go index cd2b879..522028c 100644 --- a/requests.go +++ b/requests.go @@ -21,11 +21,11 @@ type Request interface { ID() string Type() string Send(Client) error + Receive() (Response, error) } -// Response is a response from obs-websocket. type Response interface { - ID() string + // ID() string Status() string Error() string } diff --git a/requests_general.go b/requests_general.go index 111eac6..1753116 100644 --- a/requests_general.go +++ b/requests_general.go @@ -55,7 +55,7 @@ func (r *GetVersionRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetVersionRequest) Receive() (GetVersionResponse, error) { +func (r GetVersionRequest) Receive() (Response, error) { if !r.sent { return GetVersionResponse{}, ErrNotSent } @@ -79,7 +79,7 @@ func (r GetVersionRequest) Receive() (GetVersionResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r GetVersionRequest) SendReceive(c Client) (GetVersionResponse, error) { +func (r GetVersionRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetVersionResponse{}, err } @@ -105,7 +105,10 @@ type GetVersionResponse struct { // List of available request types, formatted as a comma-separated list string (e.g. : "Method1,Method2,Method3"). // Required: Yes. AvailableRequests string `json:"available-requests"` - _response `json:",squash"` + // List of supported formats for features that use image export (like the TakeSourceScreenshot request type) formatted as a comma-separated list string. + // Required: Yes. + SupportedImageExportFormats string `json:"supported-image-export-formats"` + _response `json:",squash"` } // GetAuthRequiredRequest : Tells the client if authentication is required @@ -157,7 +160,7 @@ func (r *GetAuthRequiredRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetAuthRequiredRequest) Receive() (GetAuthRequiredResponse, error) { +func (r GetAuthRequiredRequest) Receive() (Response, error) { if !r.sent { return GetAuthRequiredResponse{}, ErrNotSent } @@ -181,7 +184,7 @@ func (r GetAuthRequiredRequest) Receive() (GetAuthRequiredResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r GetAuthRequiredRequest) SendReceive(c Client) (GetAuthRequiredResponse, error) { +func (r GetAuthRequiredRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetAuthRequiredResponse{}, err } @@ -255,7 +258,7 @@ func (r *AuthenticateRequest) Send(c Client) error { } // Receive waits for the response. -func (r AuthenticateRequest) Receive() (AuthenticateResponse, error) { +func (r AuthenticateRequest) Receive() (Response, error) { if !r.sent { return AuthenticateResponse{}, ErrNotSent } @@ -279,7 +282,7 @@ func (r AuthenticateRequest) Receive() (AuthenticateResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r AuthenticateRequest) SendReceive(c Client) (AuthenticateResponse, error) { +func (r AuthenticateRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return AuthenticateResponse{}, err } @@ -346,7 +349,7 @@ func (r *SetHeartbeatRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetHeartbeatRequest) Receive() (SetHeartbeatResponse, error) { +func (r SetHeartbeatRequest) Receive() (Response, error) { if !r.sent { return SetHeartbeatResponse{}, ErrNotSent } @@ -370,7 +373,7 @@ func (r SetHeartbeatRequest) Receive() (SetHeartbeatResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r SetHeartbeatRequest) SendReceive(c Client) (SetHeartbeatResponse, error) { +func (r SetHeartbeatRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetHeartbeatResponse{}, err } @@ -437,7 +440,7 @@ func (r *SetFilenameFormattingRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetFilenameFormattingRequest) Receive() (SetFilenameFormattingResponse, error) { +func (r SetFilenameFormattingRequest) Receive() (Response, error) { if !r.sent { return SetFilenameFormattingResponse{}, ErrNotSent } @@ -461,7 +464,7 @@ func (r SetFilenameFormattingRequest) Receive() (SetFilenameFormattingResponse, } // SendReceive sends the request then immediately waits for the response. -func (r SetFilenameFormattingRequest) SendReceive(c Client) (SetFilenameFormattingResponse, error) { +func (r SetFilenameFormattingRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetFilenameFormattingResponse{}, err } @@ -524,7 +527,7 @@ func (r *GetFilenameFormattingRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetFilenameFormattingRequest) Receive() (GetFilenameFormattingResponse, error) { +func (r GetFilenameFormattingRequest) Receive() (Response, error) { if !r.sent { return GetFilenameFormattingResponse{}, ErrNotSent } @@ -548,7 +551,7 @@ func (r GetFilenameFormattingRequest) Receive() (GetFilenameFormattingResponse, } // SendReceive sends the request then immediately waits for the response. -func (r GetFilenameFormattingRequest) SendReceive(c Client) (GetFilenameFormattingResponse, error) { +func (r GetFilenameFormattingRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetFilenameFormattingResponse{}, err } @@ -614,7 +617,7 @@ func (r *GetStatsRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetStatsRequest) Receive() (GetStatsResponse, error) { +func (r GetStatsRequest) Receive() (Response, error) { if !r.sent { return GetStatsResponse{}, ErrNotSent } @@ -638,7 +641,7 @@ func (r GetStatsRequest) Receive() (GetStatsResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r GetStatsRequest) SendReceive(c Client) (GetStatsResponse, error) { +func (r GetStatsRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetStatsResponse{}, err } @@ -651,7 +654,7 @@ func (r GetStatsRequest) SendReceive(c Client) (GetStatsResponse, error) { // // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getstats type GetStatsResponse struct { - // OBS stats. + // [OBS stats](#obsstats). // Required: Yes. Stats *OBSStats `json:"stats"` _response `json:",squash"` @@ -715,7 +718,7 @@ func (r *BroadcastCustomMessageRequest) Send(c Client) error { } // Receive waits for the response. -func (r BroadcastCustomMessageRequest) Receive() (BroadcastCustomMessageResponse, error) { +func (r BroadcastCustomMessageRequest) Receive() (Response, error) { if !r.sent { return BroadcastCustomMessageResponse{}, ErrNotSent } @@ -739,7 +742,7 @@ func (r BroadcastCustomMessageRequest) Receive() (BroadcastCustomMessageResponse } // SendReceive sends the request then immediately waits for the response. -func (r BroadcastCustomMessageRequest) SendReceive(c Client) (BroadcastCustomMessageResponse, error) { +func (r BroadcastCustomMessageRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return BroadcastCustomMessageResponse{}, err } @@ -802,7 +805,7 @@ func (r *GetVideoInfoRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetVideoInfoRequest) Receive() (GetVideoInfoResponse, error) { +func (r GetVideoInfoRequest) Receive() (Response, error) { if !r.sent { return GetVideoInfoResponse{}, ErrNotSent } @@ -826,7 +829,7 @@ func (r GetVideoInfoRequest) Receive() (GetVideoInfoResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r GetVideoInfoRequest) SendReceive(c Client) (GetVideoInfoResponse, error) { +func (r GetVideoInfoRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetVideoInfoResponse{}, err } @@ -868,3 +871,453 @@ type GetVideoInfoResponse struct { ColorRange string `json:"colorRange"` _response `json:",squash"` } + +// OpenProjectorRequest : Open a projector window or create a projector on a monitor +// Requires OBS v24.0.4 or newer. +// +// Since obs-websocket version: 4.8.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#openprojector +type OpenProjectorRequest struct { + // Type of projector: `Preview` (default), `Source`, `Scene`, `StudioProgram`, or `Multiview` (case insensitive). + // Required: No. + Type_ string `json:"type"` + // Monitor to open the projector on. + // If -1 or omitted, opens a window. + // Required: No. + Monitor int `json:"monitor"` + // Size and position of the projector window (only if monitor is -1). + // Encoded in Base64 using [Qt's geometry encoding](https://doc.qt.io/qt-5/qwidget.html#saveGeometry). + // Corresponds to OBS's saved projectors. + // Required: No. + Geometry string `json:"geometry"` + // Name of the source or scene to be displayed (ignored for other projector types). + // Required: No. + Name string `json:"name"` + _request `json:",squash"` + response chan OpenProjectorResponse +} + +// NewOpenProjectorRequest returns a new OpenProjectorRequest. +func NewOpenProjectorRequest( + _type string, + monitor int, + geometry string, + name string, +) OpenProjectorRequest { + return OpenProjectorRequest{ + _type, + monitor, + geometry, + name, + _request{ + ID_: GetMessageID(), + Type_: "OpenProjector", + err: make(chan error, 1), + }, + make(chan OpenProjectorResponse, 1), + } +} + +// Send sends the request. +func (r *OpenProjectorRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp OpenProjectorResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r OpenProjectorRequest) Receive() (Response, error) { + if !r.sent { + return OpenProjectorResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return OpenProjectorResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return OpenProjectorResponse{}, err + case <-time.After(receiveTimeout): + return OpenProjectorResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r OpenProjectorRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return OpenProjectorResponse{}, err + } + return r.Receive() +} + +// OpenProjectorResponse : Response for OpenProjectorRequest. +// +// Since obs-websocket version: 4.8.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#openprojector +type OpenProjectorResponse struct { + _response `json:",squash"` +} + +// TriggerHotkeyByNameRequest : Executes hotkey routine, identified by hotkey unique name. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#triggerhotkeybyname +type TriggerHotkeyByNameRequest struct { + // Unique name of the hotkey, as defined when registering the hotkey (e.g. "ReplayBuffer.Save"). + // Required: Yes. + HotkeyName string `json:"hotkeyName"` + _request `json:",squash"` + response chan TriggerHotkeyByNameResponse +} + +// NewTriggerHotkeyByNameRequest returns a new TriggerHotkeyByNameRequest. +func NewTriggerHotkeyByNameRequest(hotkeyName string) TriggerHotkeyByNameRequest { + return TriggerHotkeyByNameRequest{ + hotkeyName, + _request{ + ID_: GetMessageID(), + Type_: "TriggerHotkeyByName", + err: make(chan error, 1), + }, + make(chan TriggerHotkeyByNameResponse, 1), + } +} + +// Send sends the request. +func (r *TriggerHotkeyByNameRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp TriggerHotkeyByNameResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r TriggerHotkeyByNameRequest) Receive() (Response, error) { + if !r.sent { + return TriggerHotkeyByNameResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return TriggerHotkeyByNameResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return TriggerHotkeyByNameResponse{}, err + case <-time.After(receiveTimeout): + return TriggerHotkeyByNameResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r TriggerHotkeyByNameRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return TriggerHotkeyByNameResponse{}, err + } + return r.Receive() +} + +// TriggerHotkeyByNameResponse : Response for TriggerHotkeyByNameRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#triggerhotkeybyname +type TriggerHotkeyByNameResponse struct { + _response `json:",squash"` +} + +// TriggerHotkeyBySequenceRequest : Executes hotkey routine, identified by bound combination of keys +// A single key combination might trigger multiple hotkey routines depending on user settings. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#triggerhotkeybysequence +type TriggerHotkeyBySequenceRequest struct { + // Main key identifier (e.g. `OBS_KEY_A` for key "A"). + // Available identifiers [here](https://github.com/obsproject/obs-studio/blob/master/libobs/obs-hotkeys.h). + // Required: Yes. + KeyID string `json:"keyId"` + // Optional key modifiers object. + // False entries can be ommitted. + // Required: No. + KeyModifiers map[string]interface{} `json:"keyModifiers"` + // Trigger Shift Key. + // Required: Yes. + KeyModifiersShift bool `json:"keyModifiers.shift"` + // Trigger Alt Key. + // Required: Yes. + KeyModifiersAlt bool `json:"keyModifiers.alt"` + // Trigger Control (Ctrl) Key. + // Required: Yes. + KeyModifiersControl bool `json:"keyModifiers.control"` + // Trigger Command Key (Mac). + // Required: Yes. + KeyModifiersCommand bool `json:"keyModifiers.command"` + _request `json:",squash"` + response chan TriggerHotkeyBySequenceResponse +} + +// NewTriggerHotkeyBySequenceRequest returns a new TriggerHotkeyBySequenceRequest. +func NewTriggerHotkeyBySequenceRequest( + keyID string, + keyModifiers map[string]interface{}, + keyModifiersShift bool, + keyModifiersAlt bool, + keyModifiersControl bool, + keyModifiersCommand bool, +) TriggerHotkeyBySequenceRequest { + return TriggerHotkeyBySequenceRequest{ + keyID, + keyModifiers, + keyModifiersShift, + keyModifiersAlt, + keyModifiersControl, + keyModifiersCommand, + _request{ + ID_: GetMessageID(), + Type_: "TriggerHotkeyBySequence", + err: make(chan error, 1), + }, + make(chan TriggerHotkeyBySequenceResponse, 1), + } +} + +// Send sends the request. +func (r *TriggerHotkeyBySequenceRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp TriggerHotkeyBySequenceResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r TriggerHotkeyBySequenceRequest) Receive() (Response, error) { + if !r.sent { + return TriggerHotkeyBySequenceResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return TriggerHotkeyBySequenceResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return TriggerHotkeyBySequenceResponse{}, err + case <-time.After(receiveTimeout): + return TriggerHotkeyBySequenceResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r TriggerHotkeyBySequenceRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return TriggerHotkeyBySequenceResponse{}, err + } + return r.Receive() +} + +// TriggerHotkeyBySequenceResponse : Response for TriggerHotkeyBySequenceRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#triggerhotkeybysequence +type TriggerHotkeyBySequenceResponse struct { + _response `json:",squash"` +} + +// ExecuteBatchRequest : Executes a list of requests sequentially (one-by-one on the same thread). +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#executebatch +type ExecuteBatchRequest struct { + // Array of requests to perform. + // Executed in order. + // Required: Yes. + Requests []map[string]interface{} `json:"requests"` + // Request type. + // Eg. + // `GetVersion`. + // Required: Yes. + RequestsRequestType string `json:"requests.*.request-type"` + // ID of the individual request. + // Can be any string and not required to be unique. + // Defaults to empty string if not specified. + // Required: No. + RequestsMessageID string `json:"requests.*.message-id"` + // Stop processing batch requests if one returns a failure. + // Required: No. + AbortOnFail bool `json:"abortOnFail"` + _request `json:",squash"` + response chan ExecuteBatchResponse +} + +// NewExecuteBatchRequest returns a new ExecuteBatchRequest. +func NewExecuteBatchRequest( + requests []map[string]interface{}, + requestsRequestType string, + requestsMessageID string, + abortOnFail bool, +) ExecuteBatchRequest { + return ExecuteBatchRequest{ + requests, + requestsRequestType, + requestsMessageID, + abortOnFail, + _request{ + ID_: GetMessageID(), + Type_: "ExecuteBatch", + err: make(chan error, 1), + }, + make(chan ExecuteBatchResponse, 1), + } +} + +// Send sends the request. +func (r *ExecuteBatchRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp ExecuteBatchResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r ExecuteBatchRequest) Receive() (Response, error) { + if !r.sent { + return ExecuteBatchResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return ExecuteBatchResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return ExecuteBatchResponse{}, err + case <-time.After(receiveTimeout): + return ExecuteBatchResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r ExecuteBatchRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return ExecuteBatchResponse{}, err + } + return r.Receive() +} + +// ExecuteBatchResponse : Response for ExecuteBatchRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#executebatch +type ExecuteBatchResponse struct { + // Batch requests results, ordered sequentially. + // Required: Yes. + Results []map[string]interface{} `json:"results"` + // ID of the individual request which was originally provided by the client. + // Required: Yes. + ResultsMessageID string `json:"results.*.message-id"` + // Status response as string. + // Either `ok` or `error`. + // Required: Yes. + ResultsStatus string `json:"results.*.status"` + // Error message accompanying an `error` status. + // Required: No. + ResultsError string `json:"results.*.error"` + _response `json:",squash"` +} diff --git a/requests_media_control.go b/requests_media_control.go new file mode 100644 index 0000000..07dcba3 --- /dev/null +++ b/requests_media_control.go @@ -0,0 +1,964 @@ +package obsws + +import ( + "errors" + "time" +) + +// This file is automatically generated. +// https://github.com/christopher-dG/go-obs-websocket/blob/master/codegen/protocol.py + +// PlayPauseMediaRequest : Pause or play a media source +// Supports ffmpeg and vlc media sources (as of OBS v25.0.8). +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#playpausemedia +type PlayPauseMediaRequest struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + // Whether to pause or play the source. + // `false` for play, `true` for pause. + // Required: Yes. + PlayPause bool `json:"playPause"` + _request `json:",squash"` + response chan PlayPauseMediaResponse +} + +// NewPlayPauseMediaRequest returns a new PlayPauseMediaRequest. +func NewPlayPauseMediaRequest( + sourceName string, + playPause bool, +) PlayPauseMediaRequest { + return PlayPauseMediaRequest{ + sourceName, + playPause, + _request{ + ID_: GetMessageID(), + Type_: "PlayPauseMedia", + err: make(chan error, 1), + }, + make(chan PlayPauseMediaResponse, 1), + } +} + +// Send sends the request. +func (r *PlayPauseMediaRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp PlayPauseMediaResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r PlayPauseMediaRequest) Receive() (Response, error) { + if !r.sent { + return PlayPauseMediaResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return PlayPauseMediaResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return PlayPauseMediaResponse{}, err + case <-time.After(receiveTimeout): + return PlayPauseMediaResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r PlayPauseMediaRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return PlayPauseMediaResponse{}, err + } + return r.Receive() +} + +// PlayPauseMediaResponse : Response for PlayPauseMediaRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#playpausemedia +type PlayPauseMediaResponse struct { + _response `json:",squash"` +} + +// RestartMediaRequest : Restart a media source +// Supports ffmpeg and vlc media sources (as of OBS v25.0.8). +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#restartmedia +type RestartMediaRequest struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + _request `json:",squash"` + response chan RestartMediaResponse +} + +// NewRestartMediaRequest returns a new RestartMediaRequest. +func NewRestartMediaRequest(sourceName string) RestartMediaRequest { + return RestartMediaRequest{ + sourceName, + _request{ + ID_: GetMessageID(), + Type_: "RestartMedia", + err: make(chan error, 1), + }, + make(chan RestartMediaResponse, 1), + } +} + +// Send sends the request. +func (r *RestartMediaRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp RestartMediaResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r RestartMediaRequest) Receive() (Response, error) { + if !r.sent { + return RestartMediaResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return RestartMediaResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return RestartMediaResponse{}, err + case <-time.After(receiveTimeout): + return RestartMediaResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r RestartMediaRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return RestartMediaResponse{}, err + } + return r.Receive() +} + +// RestartMediaResponse : Response for RestartMediaRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#restartmedia +type RestartMediaResponse struct { + _response `json:",squash"` +} + +// StopMediaRequest : Stop a media source +// Supports ffmpeg and vlc media sources (as of OBS v25.0.8). +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#stopmedia +type StopMediaRequest struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + _request `json:",squash"` + response chan StopMediaResponse +} + +// NewStopMediaRequest returns a new StopMediaRequest. +func NewStopMediaRequest(sourceName string) StopMediaRequest { + return StopMediaRequest{ + sourceName, + _request{ + ID_: GetMessageID(), + Type_: "StopMedia", + err: make(chan error, 1), + }, + make(chan StopMediaResponse, 1), + } +} + +// Send sends the request. +func (r *StopMediaRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp StopMediaResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r StopMediaRequest) Receive() (Response, error) { + if !r.sent { + return StopMediaResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return StopMediaResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return StopMediaResponse{}, err + case <-time.After(receiveTimeout): + return StopMediaResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r StopMediaRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return StopMediaResponse{}, err + } + return r.Receive() +} + +// StopMediaResponse : Response for StopMediaRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#stopmedia +type StopMediaResponse struct { + _response `json:",squash"` +} + +// NextMediaRequest : Skip to the next media item in the playlist +// Supports only vlc media source (as of OBS v25.0.8). +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#nextmedia +type NextMediaRequest struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + _request `json:",squash"` + response chan NextMediaResponse +} + +// NewNextMediaRequest returns a new NextMediaRequest. +func NewNextMediaRequest(sourceName string) NextMediaRequest { + return NextMediaRequest{ + sourceName, + _request{ + ID_: GetMessageID(), + Type_: "NextMedia", + err: make(chan error, 1), + }, + make(chan NextMediaResponse, 1), + } +} + +// Send sends the request. +func (r *NextMediaRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp NextMediaResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r NextMediaRequest) Receive() (Response, error) { + if !r.sent { + return NextMediaResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return NextMediaResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return NextMediaResponse{}, err + case <-time.After(receiveTimeout): + return NextMediaResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r NextMediaRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return NextMediaResponse{}, err + } + return r.Receive() +} + +// NextMediaResponse : Response for NextMediaRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#nextmedia +type NextMediaResponse struct { + _response `json:",squash"` +} + +// PreviousMediaRequest : Go to the previous media item in the playlist +// Supports only vlc media source (as of OBS v25.0.8). +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#previousmedia +type PreviousMediaRequest struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + _request `json:",squash"` + response chan PreviousMediaResponse +} + +// NewPreviousMediaRequest returns a new PreviousMediaRequest. +func NewPreviousMediaRequest(sourceName string) PreviousMediaRequest { + return PreviousMediaRequest{ + sourceName, + _request{ + ID_: GetMessageID(), + Type_: "PreviousMedia", + err: make(chan error, 1), + }, + make(chan PreviousMediaResponse, 1), + } +} + +// Send sends the request. +func (r *PreviousMediaRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp PreviousMediaResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r PreviousMediaRequest) Receive() (Response, error) { + if !r.sent { + return PreviousMediaResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return PreviousMediaResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return PreviousMediaResponse{}, err + case <-time.After(receiveTimeout): + return PreviousMediaResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r PreviousMediaRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return PreviousMediaResponse{}, err + } + return r.Receive() +} + +// PreviousMediaResponse : Response for PreviousMediaRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#previousmedia +type PreviousMediaResponse struct { + _response `json:",squash"` +} + +// GetMediaDurationRequest : Get the length of media in milliseconds +// Supports ffmpeg and vlc media sources (as of OBS v25.0.8) +// Note: For some reason, for the first 5 or so seconds that the media is playing, the total duration can be off by upwards of 50ms. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getmediaduration +type GetMediaDurationRequest struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + _request `json:",squash"` + response chan GetMediaDurationResponse +} + +// NewGetMediaDurationRequest returns a new GetMediaDurationRequest. +func NewGetMediaDurationRequest(sourceName string) GetMediaDurationRequest { + return GetMediaDurationRequest{ + sourceName, + _request{ + ID_: GetMessageID(), + Type_: "GetMediaDuration", + err: make(chan error, 1), + }, + make(chan GetMediaDurationResponse, 1), + } +} + +// Send sends the request. +func (r *GetMediaDurationRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp GetMediaDurationResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r GetMediaDurationRequest) Receive() (Response, error) { + if !r.sent { + return GetMediaDurationResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetMediaDurationResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetMediaDurationResponse{}, err + case <-time.After(receiveTimeout): + return GetMediaDurationResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r GetMediaDurationRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return GetMediaDurationResponse{}, err + } + return r.Receive() +} + +// GetMediaDurationResponse : Response for GetMediaDurationRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getmediaduration +type GetMediaDurationResponse struct { + // The total length of media in milliseconds.. + // Required: Yes. + MediaDuration int `json:"mediaDuration"` + _response `json:",squash"` +} + +// GetMediaTimeRequest : Get the current timestamp of media in milliseconds +// Supports ffmpeg and vlc media sources (as of OBS v25.0.8). +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getmediatime +type GetMediaTimeRequest struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + _request `json:",squash"` + response chan GetMediaTimeResponse +} + +// NewGetMediaTimeRequest returns a new GetMediaTimeRequest. +func NewGetMediaTimeRequest(sourceName string) GetMediaTimeRequest { + return GetMediaTimeRequest{ + sourceName, + _request{ + ID_: GetMessageID(), + Type_: "GetMediaTime", + err: make(chan error, 1), + }, + make(chan GetMediaTimeResponse, 1), + } +} + +// Send sends the request. +func (r *GetMediaTimeRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp GetMediaTimeResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r GetMediaTimeRequest) Receive() (Response, error) { + if !r.sent { + return GetMediaTimeResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetMediaTimeResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetMediaTimeResponse{}, err + case <-time.After(receiveTimeout): + return GetMediaTimeResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r GetMediaTimeRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return GetMediaTimeResponse{}, err + } + return r.Receive() +} + +// GetMediaTimeResponse : Response for GetMediaTimeRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getmediatime +type GetMediaTimeResponse struct { + // The time in milliseconds since the start of the media. + // Required: Yes. + Timestamp int `json:"timestamp"` + _response `json:",squash"` +} + +// SetMediaTimeRequest : Set the timestamp of a media source +// Supports ffmpeg and vlc media sources (as of OBS v25.0.8). +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#setmediatime +type SetMediaTimeRequest struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + // Milliseconds to set the timestamp to. + // Required: Yes. + Timestamp int `json:"timestamp"` + _request `json:",squash"` + response chan SetMediaTimeResponse +} + +// NewSetMediaTimeRequest returns a new SetMediaTimeRequest. +func NewSetMediaTimeRequest( + sourceName string, + timestamp int, +) SetMediaTimeRequest { + return SetMediaTimeRequest{ + sourceName, + timestamp, + _request{ + ID_: GetMessageID(), + Type_: "SetMediaTime", + err: make(chan error, 1), + }, + make(chan SetMediaTimeResponse, 1), + } +} + +// Send sends the request. +func (r *SetMediaTimeRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp SetMediaTimeResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r SetMediaTimeRequest) Receive() (Response, error) { + if !r.sent { + return SetMediaTimeResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return SetMediaTimeResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return SetMediaTimeResponse{}, err + case <-time.After(receiveTimeout): + return SetMediaTimeResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r SetMediaTimeRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return SetMediaTimeResponse{}, err + } + return r.Receive() +} + +// SetMediaTimeResponse : Response for SetMediaTimeRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#setmediatime +type SetMediaTimeResponse struct { + _response `json:",squash"` +} + +// ScrubMediaRequest : Scrub media using a supplied offset +// Supports ffmpeg and vlc media sources (as of OBS v25.0.8) +// Note: Due to processing/network delays, this request is not perfect +// The processing rate of this request has also not been tested. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#scrubmedia +type ScrubMediaRequest struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + // Millisecond offset (positive or negative) to offset the current media position. + // Required: Yes. + TimeOffset int `json:"timeOffset"` + _request `json:",squash"` + response chan ScrubMediaResponse +} + +// NewScrubMediaRequest returns a new ScrubMediaRequest. +func NewScrubMediaRequest( + sourceName string, + timeOffset int, +) ScrubMediaRequest { + return ScrubMediaRequest{ + sourceName, + timeOffset, + _request{ + ID_: GetMessageID(), + Type_: "ScrubMedia", + err: make(chan error, 1), + }, + make(chan ScrubMediaResponse, 1), + } +} + +// Send sends the request. +func (r *ScrubMediaRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp ScrubMediaResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r ScrubMediaRequest) Receive() (Response, error) { + if !r.sent { + return ScrubMediaResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return ScrubMediaResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return ScrubMediaResponse{}, err + case <-time.After(receiveTimeout): + return ScrubMediaResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r ScrubMediaRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return ScrubMediaResponse{}, err + } + return r.Receive() +} + +// ScrubMediaResponse : Response for ScrubMediaRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#scrubmedia +type ScrubMediaResponse struct { + _response `json:",squash"` +} + +// GetMediaStateRequest : Get the current playing state of a media source +// Supports ffmpeg and vlc media sources (as of OBS v25.0.8). +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getmediastate +type GetMediaStateRequest struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + _request `json:",squash"` + response chan GetMediaStateResponse +} + +// NewGetMediaStateRequest returns a new GetMediaStateRequest. +func NewGetMediaStateRequest(sourceName string) GetMediaStateRequest { + return GetMediaStateRequest{ + sourceName, + _request{ + ID_: GetMessageID(), + Type_: "GetMediaState", + err: make(chan error, 1), + }, + make(chan GetMediaStateResponse, 1), + } +} + +// Send sends the request. +func (r *GetMediaStateRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp GetMediaStateResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r GetMediaStateRequest) Receive() (Response, error) { + if !r.sent { + return GetMediaStateResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetMediaStateResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetMediaStateResponse{}, err + case <-time.After(receiveTimeout): + return GetMediaStateResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r GetMediaStateRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return GetMediaStateResponse{}, err + } + return r.Receive() +} + +// GetMediaStateResponse : Response for GetMediaStateRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getmediastate +type GetMediaStateResponse struct { + // The media state of the provided source. + // States: `none`, `playing`, `opening`, `buffering`, `paused`, `stopped`, `ended`, `error`, `unknown`. + // Required: Yes. + MediaState string `json:"mediaState"` + _response `json:",squash"` +} diff --git a/requests_outputs.go b/requests_outputs.go index c5a17c4..c19d483 100644 --- a/requests_outputs.go +++ b/requests_outputs.go @@ -55,7 +55,7 @@ func (r *ListOutputsRequest) Send(c Client) error { } // Receive waits for the response. -func (r ListOutputsRequest) Receive() (ListOutputsResponse, error) { +func (r ListOutputsRequest) Receive() (Response, error) { if !r.sent { return ListOutputsResponse{}, ErrNotSent } @@ -79,7 +79,7 @@ func (r ListOutputsRequest) Receive() (ListOutputsResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r ListOutputsRequest) SendReceive(c Client) (ListOutputsResponse, error) { +func (r ListOutputsRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return ListOutputsResponse{}, err } @@ -149,7 +149,7 @@ func (r *GetOutputInfoRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetOutputInfoRequest) Receive() (GetOutputInfoResponse, error) { +func (r GetOutputInfoRequest) Receive() (Response, error) { if !r.sent { return GetOutputInfoResponse{}, ErrNotSent } @@ -173,7 +173,7 @@ func (r GetOutputInfoRequest) Receive() (GetOutputInfoResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r GetOutputInfoRequest) SendReceive(c Client) (GetOutputInfoResponse, error) { +func (r GetOutputInfoRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetOutputInfoResponse{}, err } @@ -192,7 +192,10 @@ type GetOutputInfoResponse struct { _response `json:",squash"` } -// StartOutputRequest : Start an output. +// StartOutputRequest : +// +// Note: Controlling outputs is an experimental feature of obs-websocket +// Some plugins which add outputs to OBS may not function properly when they are controlled in this way. // // Since obs-websocket version: 4.7.0. // @@ -243,7 +246,7 @@ func (r *StartOutputRequest) Send(c Client) error { } // Receive waits for the response. -func (r StartOutputRequest) Receive() (StartOutputResponse, error) { +func (r StartOutputRequest) Receive() (Response, error) { if !r.sent { return StartOutputResponse{}, ErrNotSent } @@ -267,7 +270,7 @@ func (r StartOutputRequest) Receive() (StartOutputResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r StartOutputRequest) SendReceive(c Client) (StartOutputResponse, error) { +func (r StartOutputRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return StartOutputResponse{}, err } @@ -283,7 +286,10 @@ type StartOutputResponse struct { _response `json:",squash"` } -// StopOutputRequest : Stop an output. +// StopOutputRequest : +// +// Note: Controlling outputs is an experimental feature of obs-websocket +// Some plugins which add outputs to OBS may not function properly when they are controlled in this way. // // Since obs-websocket version: 4.7.0. // @@ -341,7 +347,7 @@ func (r *StopOutputRequest) Send(c Client) error { } // Receive waits for the response. -func (r StopOutputRequest) Receive() (StopOutputResponse, error) { +func (r StopOutputRequest) Receive() (Response, error) { if !r.sent { return StopOutputResponse{}, ErrNotSent } @@ -365,7 +371,7 @@ func (r StopOutputRequest) Receive() (StopOutputResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r StopOutputRequest) SendReceive(c Client) (StopOutputResponse, error) { +func (r StopOutputRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return StopOutputResponse{}, err } diff --git a/requests_profiles.go b/requests_profiles.go index 75c7dd6..a0ccc18 100644 --- a/requests_profiles.go +++ b/requests_profiles.go @@ -59,7 +59,7 @@ func (r *SetCurrentProfileRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetCurrentProfileRequest) Receive() (SetCurrentProfileResponse, error) { +func (r SetCurrentProfileRequest) Receive() (Response, error) { if !r.sent { return SetCurrentProfileResponse{}, ErrNotSent } @@ -83,7 +83,7 @@ func (r SetCurrentProfileRequest) Receive() (SetCurrentProfileResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r SetCurrentProfileRequest) SendReceive(c Client) (SetCurrentProfileResponse, error) { +func (r SetCurrentProfileRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetCurrentProfileResponse{}, err } @@ -146,7 +146,7 @@ func (r *GetCurrentProfileRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetCurrentProfileRequest) Receive() (GetCurrentProfileResponse, error) { +func (r GetCurrentProfileRequest) Receive() (Response, error) { if !r.sent { return GetCurrentProfileResponse{}, ErrNotSent } @@ -170,7 +170,7 @@ func (r GetCurrentProfileRequest) Receive() (GetCurrentProfileResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r GetCurrentProfileRequest) SendReceive(c Client) (GetCurrentProfileResponse, error) { +func (r GetCurrentProfileRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetCurrentProfileResponse{}, err } @@ -236,7 +236,7 @@ func (r *ListProfilesRequest) Send(c Client) error { } // Receive waits for the response. -func (r ListProfilesRequest) Receive() (ListProfilesResponse, error) { +func (r ListProfilesRequest) Receive() (Response, error) { if !r.sent { return ListProfilesResponse{}, ErrNotSent } @@ -260,7 +260,7 @@ func (r ListProfilesRequest) Receive() (ListProfilesResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r ListProfilesRequest) SendReceive(c Client) (ListProfilesResponse, error) { +func (r ListProfilesRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return ListProfilesResponse{}, err } @@ -275,6 +275,9 @@ func (r ListProfilesRequest) SendReceive(c Client) (ListProfilesResponse, error) type ListProfilesResponse struct { // List of available profiles. // Required: Yes. - Profiles []map[string]interface{} `json:"profiles"` - _response `json:",squash"` + Profiles []map[string]interface{} `json:"profiles"` + // Filter name. + // Required: Yes. + ProfilesProfileName string `json:"profiles.*.profile-name"` + _response `json:",squash"` } diff --git a/requests_recording.go b/requests_recording.go index dd97588..30ad4d8 100644 --- a/requests_recording.go +++ b/requests_recording.go @@ -8,7 +8,106 @@ import ( // This file is automatically generated. // https://github.com/christopher-dG/go-obs-websocket/blob/master/codegen/protocol.py -// StartStopRecordingRequest : Toggle recording on or off. +// GetRecordingStatusRequest : Get current recording status. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getrecordingstatus +type GetRecordingStatusRequest struct { + _request `json:",squash"` + response chan GetRecordingStatusResponse +} + +// NewGetRecordingStatusRequest returns a new GetRecordingStatusRequest. +func NewGetRecordingStatusRequest() GetRecordingStatusRequest { + return GetRecordingStatusRequest{ + _request{ + ID_: GetMessageID(), + Type_: "GetRecordingStatus", + err: make(chan error, 1), + }, + make(chan GetRecordingStatusResponse, 1), + } +} + +// Send sends the request. +func (r *GetRecordingStatusRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp GetRecordingStatusResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r GetRecordingStatusRequest) Receive() (Response, error) { + if !r.sent { + return GetRecordingStatusResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetRecordingStatusResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetRecordingStatusResponse{}, err + case <-time.After(receiveTimeout): + return GetRecordingStatusResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r GetRecordingStatusRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return GetRecordingStatusResponse{}, err + } + return r.Receive() +} + +// GetRecordingStatusResponse : Response for GetRecordingStatusRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getrecordingstatus +type GetRecordingStatusResponse struct { + // Current recording status. + // Required: Yes. + IsRecording bool `json:"isRecording"` + // Whether the recording is paused or not. + // Required: Yes. + IsRecordingPaused bool `json:"isRecordingPaused"` + // Time elapsed since recording started (only present if currently recording). + // Required: No. + RecordTimecode string `json:"recordTimecode"` + // Absolute path to the recording file (only present if currently recording). + // Required: No. + RecordingFilename string `json:"recordingFilename"` + _response `json:",squash"` +} + +// StartStopRecordingRequest : Toggle recording on or off (depending on the current recording state). // // Since obs-websocket version: 0.3. // @@ -55,7 +154,7 @@ func (r *StartStopRecordingRequest) Send(c Client) error { } // Receive waits for the response. -func (r StartStopRecordingRequest) Receive() (StartStopRecordingResponse, error) { +func (r StartStopRecordingRequest) Receive() (Response, error) { if !r.sent { return StartStopRecordingResponse{}, ErrNotSent } @@ -79,7 +178,7 @@ func (r StartStopRecordingRequest) Receive() (StartStopRecordingResponse, error) } // SendReceive sends the request then immediately waits for the response. -func (r StartStopRecordingRequest) SendReceive(c Client) (StartStopRecordingResponse, error) { +func (r StartStopRecordingRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return StartStopRecordingResponse{}, err } @@ -143,7 +242,7 @@ func (r *StartRecordingRequest) Send(c Client) error { } // Receive waits for the response. -func (r StartRecordingRequest) Receive() (StartRecordingResponse, error) { +func (r StartRecordingRequest) Receive() (Response, error) { if !r.sent { return StartRecordingResponse{}, ErrNotSent } @@ -167,7 +266,7 @@ func (r StartRecordingRequest) Receive() (StartRecordingResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r StartRecordingRequest) SendReceive(c Client) (StartRecordingResponse, error) { +func (r StartRecordingRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return StartRecordingResponse{}, err } @@ -231,7 +330,7 @@ func (r *StopRecordingRequest) Send(c Client) error { } // Receive waits for the response. -func (r StopRecordingRequest) Receive() (StopRecordingResponse, error) { +func (r StopRecordingRequest) Receive() (Response, error) { if !r.sent { return StopRecordingResponse{}, ErrNotSent } @@ -255,7 +354,7 @@ func (r StopRecordingRequest) Receive() (StopRecordingResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r StopRecordingRequest) SendReceive(c Client) (StopRecordingResponse, error) { +func (r StopRecordingRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return StopRecordingResponse{}, err } @@ -319,7 +418,7 @@ func (r *PauseRecordingRequest) Send(c Client) error { } // Receive waits for the response. -func (r PauseRecordingRequest) Receive() (PauseRecordingResponse, error) { +func (r PauseRecordingRequest) Receive() (Response, error) { if !r.sent { return PauseRecordingResponse{}, ErrNotSent } @@ -343,7 +442,7 @@ func (r PauseRecordingRequest) Receive() (PauseRecordingResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r PauseRecordingRequest) SendReceive(c Client) (PauseRecordingResponse, error) { +func (r PauseRecordingRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return PauseRecordingResponse{}, err } @@ -407,7 +506,7 @@ func (r *ResumeRecordingRequest) Send(c Client) error { } // Receive waits for the response. -func (r ResumeRecordingRequest) Receive() (ResumeRecordingResponse, error) { +func (r ResumeRecordingRequest) Receive() (Response, error) { if !r.sent { return ResumeRecordingResponse{}, ErrNotSent } @@ -431,7 +530,7 @@ func (r ResumeRecordingRequest) Receive() (ResumeRecordingResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r ResumeRecordingRequest) SendReceive(c Client) (ResumeRecordingResponse, error) { +func (r ResumeRecordingRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return ResumeRecordingResponse{}, err } @@ -449,7 +548,7 @@ type ResumeRecordingResponse struct { // SetRecordingFolderRequest : // -// Please note: if `SetRecordingFolder` is called while a recording is +// Note: If `SetRecordingFolder` is called while a recording is // in progress, the change won't be applied immediately and will be // effective on the next recording. // @@ -502,7 +601,7 @@ func (r *SetRecordingFolderRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetRecordingFolderRequest) Receive() (SetRecordingFolderResponse, error) { +func (r SetRecordingFolderRequest) Receive() (Response, error) { if !r.sent { return SetRecordingFolderResponse{}, ErrNotSent } @@ -526,7 +625,7 @@ func (r SetRecordingFolderRequest) Receive() (SetRecordingFolderResponse, error) } // SendReceive sends the request then immediately waits for the response. -func (r SetRecordingFolderRequest) SendReceive(c Client) (SetRecordingFolderResponse, error) { +func (r SetRecordingFolderRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetRecordingFolderResponse{}, err } @@ -589,7 +688,7 @@ func (r *GetRecordingFolderRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetRecordingFolderRequest) Receive() (GetRecordingFolderResponse, error) { +func (r GetRecordingFolderRequest) Receive() (Response, error) { if !r.sent { return GetRecordingFolderResponse{}, ErrNotSent } @@ -613,7 +712,7 @@ func (r GetRecordingFolderRequest) Receive() (GetRecordingFolderResponse, error) } // SendReceive sends the request then immediately waits for the response. -func (r GetRecordingFolderRequest) SendReceive(c Client) (GetRecordingFolderResponse, error) { +func (r GetRecordingFolderRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetRecordingFolderResponse{}, err } diff --git a/requests_replay_buffer.go b/requests_replay_buffer.go index 9f90a50..7b095a1 100644 --- a/requests_replay_buffer.go +++ b/requests_replay_buffer.go @@ -8,7 +8,97 @@ import ( // This file is automatically generated. // https://github.com/christopher-dG/go-obs-websocket/blob/master/codegen/protocol.py -// StartStopReplayBufferRequest : Toggle the Replay Buffer on/off. +// GetReplayBufferStatusRequest : Get the status of the OBS replay buffer. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getreplaybufferstatus +type GetReplayBufferStatusRequest struct { + _request `json:",squash"` + response chan GetReplayBufferStatusResponse +} + +// NewGetReplayBufferStatusRequest returns a new GetReplayBufferStatusRequest. +func NewGetReplayBufferStatusRequest() GetReplayBufferStatusRequest { + return GetReplayBufferStatusRequest{ + _request{ + ID_: GetMessageID(), + Type_: "GetReplayBufferStatus", + err: make(chan error, 1), + }, + make(chan GetReplayBufferStatusResponse, 1), + } +} + +// Send sends the request. +func (r *GetReplayBufferStatusRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp GetReplayBufferStatusResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r GetReplayBufferStatusRequest) Receive() (Response, error) { + if !r.sent { + return GetReplayBufferStatusResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetReplayBufferStatusResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetReplayBufferStatusResponse{}, err + case <-time.After(receiveTimeout): + return GetReplayBufferStatusResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r GetReplayBufferStatusRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return GetReplayBufferStatusResponse{}, err + } + return r.Receive() +} + +// GetReplayBufferStatusResponse : Response for GetReplayBufferStatusRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getreplaybufferstatus +type GetReplayBufferStatusResponse struct { + // Current recording status. + // Required: Yes. + IsReplayBufferActive bool `json:"isReplayBufferActive"` + _response `json:",squash"` +} + +// StartStopReplayBufferRequest : Toggle the Replay Buffer on/off (depending on the current state of the replay buffer). // // Since obs-websocket version: 4.2.0. // @@ -55,7 +145,7 @@ func (r *StartStopReplayBufferRequest) Send(c Client) error { } // Receive waits for the response. -func (r StartStopReplayBufferRequest) Receive() (StartStopReplayBufferResponse, error) { +func (r StartStopReplayBufferRequest) Receive() (Response, error) { if !r.sent { return StartStopReplayBufferResponse{}, ErrNotSent } @@ -79,7 +169,7 @@ func (r StartStopReplayBufferRequest) Receive() (StartStopReplayBufferResponse, } // SendReceive sends the request then immediately waits for the response. -func (r StartStopReplayBufferRequest) SendReceive(c Client) (StartStopReplayBufferResponse, error) { +func (r StartStopReplayBufferRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return StartStopReplayBufferResponse{}, err } @@ -146,7 +236,7 @@ func (r *StartReplayBufferRequest) Send(c Client) error { } // Receive waits for the response. -func (r StartReplayBufferRequest) Receive() (StartReplayBufferResponse, error) { +func (r StartReplayBufferRequest) Receive() (Response, error) { if !r.sent { return StartReplayBufferResponse{}, ErrNotSent } @@ -170,7 +260,7 @@ func (r StartReplayBufferRequest) Receive() (StartReplayBufferResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r StartReplayBufferRequest) SendReceive(c Client) (StartReplayBufferResponse, error) { +func (r StartReplayBufferRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return StartReplayBufferResponse{}, err } @@ -234,7 +324,7 @@ func (r *StopReplayBufferRequest) Send(c Client) error { } // Receive waits for the response. -func (r StopReplayBufferRequest) Receive() (StopReplayBufferResponse, error) { +func (r StopReplayBufferRequest) Receive() (Response, error) { if !r.sent { return StopReplayBufferResponse{}, ErrNotSent } @@ -258,7 +348,7 @@ func (r StopReplayBufferRequest) Receive() (StopReplayBufferResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r StopReplayBufferRequest) SendReceive(c Client) (StopReplayBufferResponse, error) { +func (r StopReplayBufferRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return StopReplayBufferResponse{}, err } @@ -324,7 +414,7 @@ func (r *SaveReplayBufferRequest) Send(c Client) error { } // Receive waits for the response. -func (r SaveReplayBufferRequest) Receive() (SaveReplayBufferResponse, error) { +func (r SaveReplayBufferRequest) Receive() (Response, error) { if !r.sent { return SaveReplayBufferResponse{}, ErrNotSent } @@ -348,7 +438,7 @@ func (r SaveReplayBufferRequest) Receive() (SaveReplayBufferResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r SaveReplayBufferRequest) SendReceive(c Client) (SaveReplayBufferResponse, error) { +func (r SaveReplayBufferRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SaveReplayBufferResponse{}, err } diff --git a/requests_scene_collections.go b/requests_scene_collections.go index acdc822..f9b55db 100644 --- a/requests_scene_collections.go +++ b/requests_scene_collections.go @@ -59,7 +59,7 @@ func (r *SetCurrentSceneCollectionRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetCurrentSceneCollectionRequest) Receive() (SetCurrentSceneCollectionResponse, error) { +func (r SetCurrentSceneCollectionRequest) Receive() (Response, error) { if !r.sent { return SetCurrentSceneCollectionResponse{}, ErrNotSent } @@ -83,7 +83,7 @@ func (r SetCurrentSceneCollectionRequest) Receive() (SetCurrentSceneCollectionRe } // SendReceive sends the request then immediately waits for the response. -func (r SetCurrentSceneCollectionRequest) SendReceive(c Client) (SetCurrentSceneCollectionResponse, error) { +func (r SetCurrentSceneCollectionRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetCurrentSceneCollectionResponse{}, err } @@ -146,7 +146,7 @@ func (r *GetCurrentSceneCollectionRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetCurrentSceneCollectionRequest) Receive() (GetCurrentSceneCollectionResponse, error) { +func (r GetCurrentSceneCollectionRequest) Receive() (Response, error) { if !r.sent { return GetCurrentSceneCollectionResponse{}, ErrNotSent } @@ -170,7 +170,7 @@ func (r GetCurrentSceneCollectionRequest) Receive() (GetCurrentSceneCollectionRe } // SendReceive sends the request then immediately waits for the response. -func (r GetCurrentSceneCollectionRequest) SendReceive(c Client) (GetCurrentSceneCollectionResponse, error) { +func (r GetCurrentSceneCollectionRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetCurrentSceneCollectionResponse{}, err } @@ -236,7 +236,7 @@ func (r *ListSceneCollectionsRequest) Send(c Client) error { } // Receive waits for the response. -func (r ListSceneCollectionsRequest) Receive() (ListSceneCollectionsResponse, error) { +func (r ListSceneCollectionsRequest) Receive() (Response, error) { if !r.sent { return ListSceneCollectionsResponse{}, ErrNotSent } @@ -260,7 +260,7 @@ func (r ListSceneCollectionsRequest) Receive() (ListSceneCollectionsResponse, er } // SendReceive sends the request then immediately waits for the response. -func (r ListSceneCollectionsRequest) SendReceive(c Client) (ListSceneCollectionsResponse, error) { +func (r ListSceneCollectionsRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return ListSceneCollectionsResponse{}, err } @@ -275,6 +275,6 @@ func (r ListSceneCollectionsRequest) SendReceive(c Client) (ListSceneCollections type ListSceneCollectionsResponse struct { // Scene collections list. // Required: Yes. - SceneCollections []string `json:"scene-collections"` + SceneCollections []*ScenesCollection `json:"scene-collections"` _response `json:",squash"` } diff --git a/requests_scene_items.go b/requests_scene_items.go index b54d9d1..b7df4e6 100644 --- a/requests_scene_items.go +++ b/requests_scene_items.go @@ -8,6 +8,118 @@ import ( // This file is automatically generated. // https://github.com/christopher-dG/go-obs-websocket/blob/master/codegen/protocol.py +// GetSceneItemListRequest : Get a list of all scene items in a scene. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getsceneitemlist +type GetSceneItemListRequest struct { + // Name of the scene to get the list of scene items from. + // Defaults to the current scene if not specified. + // Required: No. + SceneName string `json:"sceneName"` + _request `json:",squash"` + response chan GetSceneItemListResponse +} + +// NewGetSceneItemListRequest returns a new GetSceneItemListRequest. +func NewGetSceneItemListRequest(sceneName string) GetSceneItemListRequest { + return GetSceneItemListRequest{ + sceneName, + _request{ + ID_: GetMessageID(), + Type_: "GetSceneItemList", + err: make(chan error, 1), + }, + make(chan GetSceneItemListResponse, 1), + } +} + +// Send sends the request. +func (r *GetSceneItemListRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp GetSceneItemListResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r GetSceneItemListRequest) Receive() (Response, error) { + if !r.sent { + return GetSceneItemListResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetSceneItemListResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetSceneItemListResponse{}, err + case <-time.After(receiveTimeout): + return GetSceneItemListResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r GetSceneItemListRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return GetSceneItemListResponse{}, err + } + return r.Receive() +} + +// GetSceneItemListResponse : Response for GetSceneItemListRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getsceneitemlist +type GetSceneItemListResponse struct { + // Name of the requested (or current) scene. + // Required: Yes. + SceneName string `json:"sceneName"` + // Array of scene items. + // Required: Yes. + SceneItems []map[string]interface{} `json:"sceneItems"` + // Unique item id of the source item. + // Required: Yes. + SceneItemsItemID int `json:"sceneItems.*.itemId"` + // ID if the scene item's source. + // For example `vlc_source` or `image_source`. + // Required: Yes. + SceneItemsSourceKind string `json:"sceneItems.*.sourceKind"` + // Name of the scene item's source. + // Required: Yes. + SceneItemsSourceName string `json:"sceneItems.*.sourceName"` + // Type of the scene item's source. + // Either `input`, `group`, or `scene`. + // Required: Yes. + SceneItemsSourceType string `json:"sceneItems.*.sourceType"` + _response `json:",squash"` +} + // GetSceneItemPropertiesRequest : Gets the scene specific properties of the specified source item. // Coordinates are relative to the item's parent (the scene or group it belongs to). // @@ -15,13 +127,19 @@ import ( // // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getsceneitemproperties type GetSceneItemPropertiesRequest struct { - // the name of the scene that the source item belongs to. + // Name of the scene the scene item belongs to. // Defaults to the current scene. // Required: No. SceneName string `json:"scene-name"` - // The name of the source. + // Scene Item name (if this field is a string) or specification (if it is an object). // Required: Yes. - Item string `json:"item"` + Item interface{} `json:"item"` + // Scene Item name (if the `item` field is an object). + // Required: No. + ItemName string `json:"item.name"` + // Scene Item ID (if the `item` field is an object). + // Required: No. + ItemID int `json:"item.id"` _request `json:",squash"` response chan GetSceneItemPropertiesResponse } @@ -29,11 +147,15 @@ type GetSceneItemPropertiesRequest struct { // NewGetSceneItemPropertiesRequest returns a new GetSceneItemPropertiesRequest. func NewGetSceneItemPropertiesRequest( sceneName string, - item string, + item interface{}, + itemName string, + itemID int, ) GetSceneItemPropertiesRequest { return GetSceneItemPropertiesRequest{ sceneName, item, + itemName, + itemID, _request{ ID_: GetMessageID(), Type_: "GetSceneItemProperties", @@ -68,7 +190,7 @@ func (r *GetSceneItemPropertiesRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetSceneItemPropertiesRequest) Receive() (GetSceneItemPropertiesResponse, error) { +func (r GetSceneItemPropertiesRequest) Receive() (Response, error) { if !r.sent { return GetSceneItemPropertiesResponse{}, ErrNotSent } @@ -92,7 +214,7 @@ func (r GetSceneItemPropertiesRequest) Receive() (GetSceneItemPropertiesResponse } // SendReceive sends the request then immediately waits for the response. -func (r GetSceneItemPropertiesRequest) SendReceive(c Client) (GetSceneItemPropertiesResponse, error) { +func (r GetSceneItemPropertiesRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetSceneItemPropertiesResponse{}, err } @@ -105,16 +227,20 @@ func (r GetSceneItemPropertiesRequest) SendReceive(c Client) (GetSceneItemProper // // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getsceneitemproperties type GetSceneItemPropertiesResponse struct { - // The name of the source. + // Scene Item name. // Required: Yes. Name string `json:"name"` + // Scene Item ID. + // Required: Yes. + ItemID int `json:"itemId"` // The x position of the source from the left. // Required: Yes. - PositionX int `json:"position.x"` + PositionX float64 `json:"position.x"` // The y position of the source from the top. // Required: Yes. - PositionY int `json:"position.y"` + PositionY float64 `json:"position.y"` // The point on the source that the item is manipulated from. + // The sum of 1=Left or 2=Right, and 4=Top or 8=Bottom, or omit to center on that axis. // Required: Yes. PositionAlignment int `json:"position.alignment"` // The clockwise rotation of the item in degrees around the point of alignment. @@ -141,6 +267,9 @@ type GetSceneItemPropertiesResponse struct { // If the source is visible. // Required: Yes. Visible bool `json:"visible"` + // If the source is muted. + // Required: Yes. + Muted bool `json:"muted"` // If the source's transform is locked. // Required: Yes. Locked bool `json:"locked"` @@ -168,8 +297,14 @@ type GetSceneItemPropertiesResponse struct { Width float64 `json:"width"` // Scene item height (base source height multiplied by the vertical scaling factor). // Required: Yes. - Height float64 `json:"height"` - _response `json:",squash"` + Height float64 `json:"height"` + // Name of the item's parent (if this item belongs to a group). + // Required: No. + ParentGroupName string `json:"parentGroupName"` + // List of children (if this item is a group). + // Required: No. + GroupChildren []*SceneItemTransform `json:"groupChildren"` + _response `json:",squash"` } // SetSceneItemPropertiesRequest : Sets the scene specific properties of a source @@ -180,19 +315,25 @@ type GetSceneItemPropertiesResponse struct { // // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#setsceneitemproperties type SetSceneItemPropertiesRequest struct { - // the name of the scene that the source item belongs to. + // Name of the scene the source item belongs to. // Defaults to the current scene. // Required: No. SceneName string `json:"scene-name"` - // The name of the source. + // Scene Item name (if this field is a string) or specification (if it is an object). // Required: Yes. - Item string `json:"item"` + Item interface{} `json:"item"` + // Scene Item name (if the `item` field is an object). + // Required: No. + ItemName string `json:"item.name"` + // Scene Item ID (if the `item` field is an object). + // Required: No. + ItemID int `json:"item.id"` // The new x position of the source. // Required: No. - PositionX int `json:"position.x"` + PositionX float64 `json:"position.x"` // The new y position of the source. // Required: No. - PositionY int `json:"position.y"` + PositionY float64 `json:"position.y"` // The new alignment of the source. // Required: No. PositionAlignment int `json:"position.alignment"` @@ -246,9 +387,11 @@ type SetSceneItemPropertiesRequest struct { // NewSetSceneItemPropertiesRequest returns a new SetSceneItemPropertiesRequest. func NewSetSceneItemPropertiesRequest( sceneName string, - item string, - positionX int, - positionY int, + item interface{}, + itemName string, + itemID int, + positionX float64, + positionY float64, positionAlignment int, rotation float64, scaleX float64, @@ -267,6 +410,8 @@ func NewSetSceneItemPropertiesRequest( return SetSceneItemPropertiesRequest{ sceneName, item, + itemName, + itemID, positionX, positionY, positionAlignment, @@ -317,7 +462,7 @@ func (r *SetSceneItemPropertiesRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetSceneItemPropertiesRequest) Receive() (SetSceneItemPropertiesResponse, error) { +func (r SetSceneItemPropertiesRequest) Receive() (Response, error) { if !r.sent { return SetSceneItemPropertiesResponse{}, ErrNotSent } @@ -341,7 +486,7 @@ func (r SetSceneItemPropertiesRequest) Receive() (SetSceneItemPropertiesResponse } // SendReceive sends the request then immediately waits for the response. -func (r SetSceneItemPropertiesRequest) SendReceive(c Client) (SetSceneItemPropertiesResponse, error) { +func (r SetSceneItemPropertiesRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetSceneItemPropertiesResponse{}, err } @@ -363,13 +508,19 @@ type SetSceneItemPropertiesResponse struct { // // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#resetsceneitem type ResetSceneItemRequest struct { - // Name of the scene the source belongs to. + // Name of the scene the scene item belongs to. // Defaults to the current scene. // Required: No. SceneName string `json:"scene-name"` - // Name of the source item. + // Scene Item name (if this field is a string) or specification (if it is an object). // Required: Yes. - Item string `json:"item"` + Item interface{} `json:"item"` + // Scene Item name (if the `item` field is an object). + // Required: No. + ItemName string `json:"item.name"` + // Scene Item ID (if the `item` field is an object). + // Required: No. + ItemID int `json:"item.id"` _request `json:",squash"` response chan ResetSceneItemResponse } @@ -377,11 +528,15 @@ type ResetSceneItemRequest struct { // NewResetSceneItemRequest returns a new ResetSceneItemRequest. func NewResetSceneItemRequest( sceneName string, - item string, + item interface{}, + itemName string, + itemID int, ) ResetSceneItemRequest { return ResetSceneItemRequest{ sceneName, item, + itemName, + itemID, _request{ ID_: GetMessageID(), Type_: "ResetSceneItem", @@ -416,7 +571,7 @@ func (r *ResetSceneItemRequest) Send(c Client) error { } // Receive waits for the response. -func (r ResetSceneItemRequest) Receive() (ResetSceneItemResponse, error) { +func (r ResetSceneItemRequest) Receive() (Response, error) { if !r.sent { return ResetSceneItemResponse{}, ErrNotSent } @@ -440,7 +595,7 @@ func (r ResetSceneItemRequest) Receive() (ResetSceneItemResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r ResetSceneItemRequest) SendReceive(c Client) (ResetSceneItemResponse, error) { +func (r ResetSceneItemRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return ResetSceneItemResponse{}, err } @@ -462,30 +617,35 @@ type ResetSceneItemResponse struct { // // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#setsceneitemrender type SetSceneItemRenderRequest struct { - // Scene item name in the specified scene. - // Required: Yes. - Source string `json:"source"` - // true = shown ; false = hidden. - // Required: Yes. - Render bool `json:"render"` - // Name of the scene where the source resides. + // Name of the scene the scene item belongs to. // Defaults to the currently active scene. // Required: No. SceneName string `json:"scene-name"` - _request `json:",squash"` - response chan SetSceneItemRenderResponse + // Scene Item name. + // Required: No. + Source string `json:"source"` + // Scene Item id. + // Required: No. + Item int `json:"item"` + // true = shown ; false = hidden. + // Required: Yes. + Render bool `json:"render"` + _request `json:",squash"` + response chan SetSceneItemRenderResponse } // NewSetSceneItemRenderRequest returns a new SetSceneItemRenderRequest. func NewSetSceneItemRenderRequest( + sceneName string, source string, + item int, render bool, - sceneName string, ) SetSceneItemRenderRequest { return SetSceneItemRenderRequest{ + sceneName, source, + item, render, - sceneName, _request{ ID_: GetMessageID(), Type_: "SetSceneItemRender", @@ -520,7 +680,7 @@ func (r *SetSceneItemRenderRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetSceneItemRenderRequest) Receive() (SetSceneItemRenderResponse, error) { +func (r SetSceneItemRenderRequest) Receive() (Response, error) { if !r.sent { return SetSceneItemRenderResponse{}, ErrNotSent } @@ -544,7 +704,7 @@ func (r SetSceneItemRenderRequest) Receive() (SetSceneItemRenderResponse, error) } // SendReceive sends the request then immediately waits for the response. -func (r SetSceneItemRenderRequest) SendReceive(c Client) (SetSceneItemRenderResponse, error) { +func (r SetSceneItemRenderRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetSceneItemRenderResponse{}, err } @@ -566,11 +726,11 @@ type SetSceneItemRenderResponse struct { // // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#setsceneitemposition type SetSceneItemPositionRequest struct { - // The name of the scene that the source item belongs to. + // Name of the scene the scene item belongs to. // Defaults to the current scene. // Required: No. SceneName string `json:"scene-name"` - // The name of the source item. + // Scene Item name. // Required: Yes. Item string `json:"item"` // X coordinate. @@ -629,7 +789,7 @@ func (r *SetSceneItemPositionRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetSceneItemPositionRequest) Receive() (SetSceneItemPositionResponse, error) { +func (r SetSceneItemPositionRequest) Receive() (Response, error) { if !r.sent { return SetSceneItemPositionResponse{}, ErrNotSent } @@ -653,7 +813,7 @@ func (r SetSceneItemPositionRequest) Receive() (SetSceneItemPositionResponse, er } // SendReceive sends the request then immediately waits for the response. -func (r SetSceneItemPositionRequest) SendReceive(c Client) (SetSceneItemPositionResponse, error) { +func (r SetSceneItemPositionRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetSceneItemPositionResponse{}, err } @@ -675,11 +835,11 @@ type SetSceneItemPositionResponse struct { // // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#setsceneitemtransform type SetSceneItemTransformRequest struct { - // The name of the scene that the source item belongs to. + // Name of the scene the scene item belongs to. // Defaults to the current scene. // Required: No. SceneName string `json:"scene-name"` - // The name of the source item. + // Scene Item name. // Required: Yes. Item string `json:"item"` // Width scale factor. @@ -743,7 +903,7 @@ func (r *SetSceneItemTransformRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetSceneItemTransformRequest) Receive() (SetSceneItemTransformResponse, error) { +func (r SetSceneItemTransformRequest) Receive() (Response, error) { if !r.sent { return SetSceneItemTransformResponse{}, ErrNotSent } @@ -767,7 +927,7 @@ func (r SetSceneItemTransformRequest) Receive() (SetSceneItemTransformResponse, } // SendReceive sends the request then immediately waits for the response. -func (r SetSceneItemTransformRequest) SendReceive(c Client) (SetSceneItemTransformResponse, error) { +func (r SetSceneItemTransformRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetSceneItemTransformResponse{}, err } @@ -789,11 +949,11 @@ type SetSceneItemTransformResponse struct { // // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#setsceneitemcrop type SetSceneItemCropRequest struct { - // the name of the scene that the source item belongs to. + // Name of the scene the scene item belongs to. // Defaults to the current scene. // Required: No. SceneName string `json:"scene-name"` - // The name of the source. + // Scene Item name. // Required: Yes. Item string `json:"item"` // Pixel position of the top of the source item. @@ -862,7 +1022,7 @@ func (r *SetSceneItemCropRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetSceneItemCropRequest) Receive() (SetSceneItemCropResponse, error) { +func (r SetSceneItemCropRequest) Receive() (Response, error) { if !r.sent { return SetSceneItemCropResponse{}, ErrNotSent } @@ -886,7 +1046,7 @@ func (r SetSceneItemCropRequest) Receive() (SetSceneItemCropResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r SetSceneItemCropRequest) SendReceive(c Client) (SetSceneItemCropResponse, error) { +func (r SetSceneItemCropRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetSceneItemCropResponse{}, err } @@ -908,17 +1068,17 @@ type SetSceneItemCropResponse struct { // // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#deletesceneitem type DeleteSceneItemRequest struct { - // Name of the scene the source belongs to. + // Name of the scene the scene item belongs to. // Defaults to the current scene. // Required: No. Scene string `json:"scene"` - // item to delete (required). + // Scene item to delete (required). // Required: Yes. Item map[string]interface{} `json:"item"` - // name of the scene item (prefer `id`, including both is acceptable). + // Scene Item name (prefer `id`, including both is acceptable). // Required: Yes. ItemName string `json:"item.name"` - // id of the scene item. + // Scene Item ID. // Required: Yes. ItemID int `json:"item.id"` _request `json:",squash"` @@ -971,7 +1131,7 @@ func (r *DeleteSceneItemRequest) Send(c Client) error { } // Receive waits for the response. -func (r DeleteSceneItemRequest) Receive() (DeleteSceneItemResponse, error) { +func (r DeleteSceneItemRequest) Receive() (Response, error) { if !r.sent { return DeleteSceneItemResponse{}, ErrNotSent } @@ -995,7 +1155,7 @@ func (r DeleteSceneItemRequest) Receive() (DeleteSceneItemResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r DeleteSceneItemRequest) SendReceive(c Client) (DeleteSceneItemResponse, error) { +func (r DeleteSceneItemRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return DeleteSceneItemResponse{}, err } @@ -1011,6 +1171,114 @@ type DeleteSceneItemResponse struct { _response `json:",squash"` } +// AddSceneItemRequest : Creates a scene item in a scene +// In other words, this is how you add a source into a scene. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#addsceneitem +type AddSceneItemRequest struct { + // Name of the scene to create the scene item in. + // Required: Yes. + SceneName string `json:"sceneName"` + // Name of the source to be added. + // Required: Yes. + SourceName string `json:"sourceName"` + // Whether to make the sceneitem visible on creation or not. + // Default `true`. + // Required: Yes. + SetVisible bool `json:"setVisible"` + _request `json:",squash"` + response chan AddSceneItemResponse +} + +// NewAddSceneItemRequest returns a new AddSceneItemRequest. +func NewAddSceneItemRequest( + sceneName string, + sourceName string, + setVisible bool, +) AddSceneItemRequest { + return AddSceneItemRequest{ + sceneName, + sourceName, + setVisible, + _request{ + ID_: GetMessageID(), + Type_: "AddSceneItem", + err: make(chan error, 1), + }, + make(chan AddSceneItemResponse, 1), + } +} + +// Send sends the request. +func (r *AddSceneItemRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp AddSceneItemResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r AddSceneItemRequest) Receive() (Response, error) { + if !r.sent { + return AddSceneItemResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return AddSceneItemResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return AddSceneItemResponse{}, err + case <-time.After(receiveTimeout): + return AddSceneItemResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r AddSceneItemRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return AddSceneItemResponse{}, err + } + return r.Receive() +} + +// AddSceneItemResponse : Response for AddSceneItemRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#addsceneitem +type AddSceneItemResponse struct { + // Numerical ID of the created scene item. + // Required: Yes. + ItemID int `json:"itemId"` + _response `json:",squash"` +} + // DuplicateSceneItemRequest : Duplicates a scene item. // // Since obs-websocket version: 4.5.0. @@ -1025,13 +1293,13 @@ type DuplicateSceneItemRequest struct { // Defaults to the current scene. // Required: No. ToScene string `json:"toScene"` - // item to duplicate (required). + // Scene Item to duplicate from the source scene (required). // Required: Yes. Item map[string]interface{} `json:"item"` - // name of the scene item (prefer `id`, including both is acceptable). + // Scene Item name (prefer `id`, including both is acceptable). // Required: Yes. ItemName string `json:"item.name"` - // id of the scene item. + // Scene Item ID. // Required: Yes. ItemID int `json:"item.id"` _request `json:",squash"` @@ -1086,7 +1354,7 @@ func (r *DuplicateSceneItemRequest) Send(c Client) error { } // Receive waits for the response. -func (r DuplicateSceneItemRequest) Receive() (DuplicateSceneItemResponse, error) { +func (r DuplicateSceneItemRequest) Receive() (Response, error) { if !r.sent { return DuplicateSceneItemResponse{}, ErrNotSent } @@ -1110,7 +1378,7 @@ func (r DuplicateSceneItemRequest) Receive() (DuplicateSceneItemResponse, error) } // SendReceive sends the request then immediately waits for the response. -func (r DuplicateSceneItemRequest) SendReceive(c Client) (DuplicateSceneItemResponse, error) { +func (r DuplicateSceneItemRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return DuplicateSceneItemResponse{}, err } diff --git a/requests_scenes.go b/requests_scenes.go index 5eb6b74..67dabc0 100644 --- a/requests_scenes.go +++ b/requests_scenes.go @@ -59,7 +59,7 @@ func (r *SetCurrentSceneRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetCurrentSceneRequest) Receive() (SetCurrentSceneResponse, error) { +func (r SetCurrentSceneRequest) Receive() (Response, error) { if !r.sent { return SetCurrentSceneResponse{}, ErrNotSent } @@ -83,7 +83,7 @@ func (r SetCurrentSceneRequest) Receive() (SetCurrentSceneResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r SetCurrentSceneRequest) SendReceive(c Client) (SetCurrentSceneResponse, error) { +func (r SetCurrentSceneRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetCurrentSceneResponse{}, err } @@ -146,7 +146,7 @@ func (r *GetCurrentSceneRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetCurrentSceneRequest) Receive() (GetCurrentSceneResponse, error) { +func (r GetCurrentSceneRequest) Receive() (Response, error) { if !r.sent { return GetCurrentSceneResponse{}, ErrNotSent } @@ -170,7 +170,7 @@ func (r GetCurrentSceneRequest) Receive() (GetCurrentSceneResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r GetCurrentSceneRequest) SendReceive(c Client) (GetCurrentSceneResponse, error) { +func (r GetCurrentSceneRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetCurrentSceneResponse{}, err } @@ -239,7 +239,7 @@ func (r *GetSceneListRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetSceneListRequest) Receive() (GetSceneListResponse, error) { +func (r GetSceneListRequest) Receive() (Response, error) { if !r.sent { return GetSceneListResponse{}, ErrNotSent } @@ -263,7 +263,7 @@ func (r GetSceneListRequest) Receive() (GetSceneListResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r GetSceneListRequest) SendReceive(c Client) (GetSceneListResponse, error) { +func (r GetSceneListRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetSceneListResponse{}, err } @@ -279,12 +279,103 @@ type GetSceneListResponse struct { // Name of the currently active scene. // Required: Yes. CurrentScene string `json:"current-scene"` - // Ordered list of the current profile's scenes (See `[GetCurrentScene](#getcurrentscene)` for more information). + // Ordered list of the current profile's scenes (See [GetCurrentScene](#getcurrentscene) for more information). // Required: Yes. Scenes []*Scene `json:"scenes"` _response `json:",squash"` } +// CreateSceneRequest : Create a new scene scene. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#createscene +type CreateSceneRequest struct { + // Name of the scene to create. + // Required: Yes. + SceneName string `json:"sceneName"` + _request `json:",squash"` + response chan CreateSceneResponse +} + +// NewCreateSceneRequest returns a new CreateSceneRequest. +func NewCreateSceneRequest(sceneName string) CreateSceneRequest { + return CreateSceneRequest{ + sceneName, + _request{ + ID_: GetMessageID(), + Type_: "CreateScene", + err: make(chan error, 1), + }, + make(chan CreateSceneResponse, 1), + } +} + +// Send sends the request. +func (r *CreateSceneRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp CreateSceneResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r CreateSceneRequest) Receive() (Response, error) { + if !r.sent { + return CreateSceneResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return CreateSceneResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return CreateSceneResponse{}, err + case <-time.After(receiveTimeout): + return CreateSceneResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r CreateSceneRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return CreateSceneResponse{}, err + } + return r.Receive() +} + +// CreateSceneResponse : Response for CreateSceneRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#createscene +type CreateSceneResponse struct { + _response `json:",squash"` +} + // ReorderSceneItemsRequest : Changes the order of scene items in the requested scene. // // Since obs-websocket version: 4.5.0. @@ -301,11 +392,11 @@ type ReorderSceneItemsRequest struct { // Id of a specific scene item. // Unique on a scene by scene basis. // Required: No. - ItemsID int `json:"items[].id"` + ItemsID int `json:"items.*.id"` // Name of a scene item. // Sufficiently unique if no scene items share sources within the scene. // Required: No. - ItemsName string `json:"items[].name"` + ItemsName string `json:"items.*.name"` _request `json:",squash"` response chan ReorderSceneItemsResponse } @@ -356,7 +447,7 @@ func (r *ReorderSceneItemsRequest) Send(c Client) error { } // Receive waits for the response. -func (r ReorderSceneItemsRequest) Receive() (ReorderSceneItemsResponse, error) { +func (r ReorderSceneItemsRequest) Receive() (Response, error) { if !r.sent { return ReorderSceneItemsResponse{}, ErrNotSent } @@ -380,7 +471,7 @@ func (r ReorderSceneItemsRequest) Receive() (ReorderSceneItemsResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r ReorderSceneItemsRequest) SendReceive(c Client) (ReorderSceneItemsResponse, error) { +func (r ReorderSceneItemsRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return ReorderSceneItemsResponse{}, err } @@ -395,3 +486,297 @@ func (r ReorderSceneItemsRequest) SendReceive(c Client) (ReorderSceneItemsRespon type ReorderSceneItemsResponse struct { _response `json:",squash"` } + +// SetSceneTransitionOverrideRequest : Set a scene to use a specific transition override. +// +// Since obs-websocket version: 4.8.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#setscenetransitionoverride +type SetSceneTransitionOverrideRequest struct { + // Name of the scene to switch to. + // Required: Yes. + SceneName string `json:"sceneName"` + // Name of the transition to use. + // Required: Yes. + TransitionName string `json:"transitionName"` + // Duration in milliseconds of the transition if transition is not fixed. + // Defaults to the current duration specified in the UI if there is no current override and this value is not given. + // Required: No. + TransitionDuration int `json:"transitionDuration"` + _request `json:",squash"` + response chan SetSceneTransitionOverrideResponse +} + +// NewSetSceneTransitionOverrideRequest returns a new SetSceneTransitionOverrideRequest. +func NewSetSceneTransitionOverrideRequest( + sceneName string, + transitionName string, + transitionDuration int, +) SetSceneTransitionOverrideRequest { + return SetSceneTransitionOverrideRequest{ + sceneName, + transitionName, + transitionDuration, + _request{ + ID_: GetMessageID(), + Type_: "SetSceneTransitionOverride", + err: make(chan error, 1), + }, + make(chan SetSceneTransitionOverrideResponse, 1), + } +} + +// Send sends the request. +func (r *SetSceneTransitionOverrideRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp SetSceneTransitionOverrideResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r SetSceneTransitionOverrideRequest) Receive() (Response, error) { + if !r.sent { + return SetSceneTransitionOverrideResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return SetSceneTransitionOverrideResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return SetSceneTransitionOverrideResponse{}, err + case <-time.After(receiveTimeout): + return SetSceneTransitionOverrideResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r SetSceneTransitionOverrideRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return SetSceneTransitionOverrideResponse{}, err + } + return r.Receive() +} + +// SetSceneTransitionOverrideResponse : Response for SetSceneTransitionOverrideRequest. +// +// Since obs-websocket version: 4.8.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#setscenetransitionoverride +type SetSceneTransitionOverrideResponse struct { + _response `json:",squash"` +} + +// RemoveSceneTransitionOverrideRequest : Remove any transition override on a scene. +// +// Since obs-websocket version: 4.8.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#removescenetransitionoverride +type RemoveSceneTransitionOverrideRequest struct { + // Name of the scene to switch to. + // Required: Yes. + SceneName string `json:"sceneName"` + _request `json:",squash"` + response chan RemoveSceneTransitionOverrideResponse +} + +// NewRemoveSceneTransitionOverrideRequest returns a new RemoveSceneTransitionOverrideRequest. +func NewRemoveSceneTransitionOverrideRequest(sceneName string) RemoveSceneTransitionOverrideRequest { + return RemoveSceneTransitionOverrideRequest{ + sceneName, + _request{ + ID_: GetMessageID(), + Type_: "RemoveSceneTransitionOverride", + err: make(chan error, 1), + }, + make(chan RemoveSceneTransitionOverrideResponse, 1), + } +} + +// Send sends the request. +func (r *RemoveSceneTransitionOverrideRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp RemoveSceneTransitionOverrideResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r RemoveSceneTransitionOverrideRequest) Receive() (Response, error) { + if !r.sent { + return RemoveSceneTransitionOverrideResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return RemoveSceneTransitionOverrideResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return RemoveSceneTransitionOverrideResponse{}, err + case <-time.After(receiveTimeout): + return RemoveSceneTransitionOverrideResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r RemoveSceneTransitionOverrideRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return RemoveSceneTransitionOverrideResponse{}, err + } + return r.Receive() +} + +// RemoveSceneTransitionOverrideResponse : Response for RemoveSceneTransitionOverrideRequest. +// +// Since obs-websocket version: 4.8.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#removescenetransitionoverride +type RemoveSceneTransitionOverrideResponse struct { + _response `json:",squash"` +} + +// GetSceneTransitionOverrideRequest : Get the current scene transition override. +// +// Since obs-websocket version: 4.8.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getscenetransitionoverride +type GetSceneTransitionOverrideRequest struct { + // Name of the scene to switch to. + // Required: Yes. + SceneName string `json:"sceneName"` + _request `json:",squash"` + response chan GetSceneTransitionOverrideResponse +} + +// NewGetSceneTransitionOverrideRequest returns a new GetSceneTransitionOverrideRequest. +func NewGetSceneTransitionOverrideRequest(sceneName string) GetSceneTransitionOverrideRequest { + return GetSceneTransitionOverrideRequest{ + sceneName, + _request{ + ID_: GetMessageID(), + Type_: "GetSceneTransitionOverride", + err: make(chan error, 1), + }, + make(chan GetSceneTransitionOverrideResponse, 1), + } +} + +// Send sends the request. +func (r *GetSceneTransitionOverrideRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp GetSceneTransitionOverrideResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r GetSceneTransitionOverrideRequest) Receive() (Response, error) { + if !r.sent { + return GetSceneTransitionOverrideResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetSceneTransitionOverrideResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetSceneTransitionOverrideResponse{}, err + case <-time.After(receiveTimeout): + return GetSceneTransitionOverrideResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r GetSceneTransitionOverrideRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return GetSceneTransitionOverrideResponse{}, err + } + return r.Receive() +} + +// GetSceneTransitionOverrideResponse : Response for GetSceneTransitionOverrideRequest. +// +// Since obs-websocket version: 4.8.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getscenetransitionoverride +type GetSceneTransitionOverrideResponse struct { + // Name of the current overriding transition. + // Empty string if no override is set. + // Required: Yes. + TransitionName string `json:"transitionName"` + // Transition duration. + // `-1` if no override is set. + // Required: Yes. + TransitionDuration int `json:"transitionDuration"` + _response `json:",squash"` +} diff --git a/requests_sources.go b/requests_sources.go index d26e165..a7dfab2 100644 --- a/requests_sources.go +++ b/requests_sources.go @@ -8,6 +8,224 @@ import ( // This file is automatically generated. // https://github.com/christopher-dG/go-obs-websocket/blob/master/codegen/protocol.py +// GetMediaSourcesListRequest : List the media state of all media sources (vlc and media source). +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getmediasourceslist +type GetMediaSourcesListRequest struct { + _request `json:",squash"` + response chan GetMediaSourcesListResponse +} + +// NewGetMediaSourcesListRequest returns a new GetMediaSourcesListRequest. +func NewGetMediaSourcesListRequest() GetMediaSourcesListRequest { + return GetMediaSourcesListRequest{ + _request{ + ID_: GetMessageID(), + Type_: "GetMediaSourcesList", + err: make(chan error, 1), + }, + make(chan GetMediaSourcesListResponse, 1), + } +} + +// Send sends the request. +func (r *GetMediaSourcesListRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp GetMediaSourcesListResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r GetMediaSourcesListRequest) Receive() (Response, error) { + if !r.sent { + return GetMediaSourcesListResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetMediaSourcesListResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetMediaSourcesListResponse{}, err + case <-time.After(receiveTimeout): + return GetMediaSourcesListResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r GetMediaSourcesListRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return GetMediaSourcesListResponse{}, err + } + return r.Receive() +} + +// GetMediaSourcesListResponse : Response for GetMediaSourcesListRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getmediasourceslist +type GetMediaSourcesListResponse struct { + // Array of sources. + // Required: Yes. + MediaSources []map[string]interface{} `json:"mediaSources"` + // Unique source name. + // Required: Yes. + MediaSourcesSourceName string `json:"mediaSources.*.sourceName"` + // Unique source internal type (a.k.a `ffmpeg_source` or `vlc_source`). + // Required: Yes. + MediaSourcesSourceKind string `json:"mediaSources.*.sourceKind"` + // The current state of media for that source. + // States: `none`, `playing`, `opening`, `buffering`, `paused`, `stopped`, `ended`, `error`, `unknown`. + // Required: Yes. + MediaSourcesMediaState string `json:"mediaSources.*.mediaState"` + _response `json:",squash"` +} + +// CreateSourceRequest : Create a source and add it as a sceneitem to a scene. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#createsource +type CreateSourceRequest struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + // Source kind, Eg. + // `vlc_source`. + // Required: Yes. + SourceKind string `json:"sourceKind"` + // Scene to add the new source to. + // Required: Yes. + SceneName string `json:"sceneName"` + // Source settings data. + // Required: No. + SourceSettings map[string]interface{} `json:"sourceSettings"` + // Set the created SceneItem as visible or not. + // Defaults to true. + // Required: No. + SetVisible bool `json:"setVisible"` + _request `json:",squash"` + response chan CreateSourceResponse +} + +// NewCreateSourceRequest returns a new CreateSourceRequest. +func NewCreateSourceRequest( + sourceName string, + sourceKind string, + sceneName string, + sourceSettings map[string]interface{}, + setVisible bool, +) CreateSourceRequest { + return CreateSourceRequest{ + sourceName, + sourceKind, + sceneName, + sourceSettings, + setVisible, + _request{ + ID_: GetMessageID(), + Type_: "CreateSource", + err: make(chan error, 1), + }, + make(chan CreateSourceResponse, 1), + } +} + +// Send sends the request. +func (r *CreateSourceRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp CreateSourceResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r CreateSourceRequest) Receive() (Response, error) { + if !r.sent { + return CreateSourceResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return CreateSourceResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return CreateSourceResponse{}, err + case <-time.After(receiveTimeout): + return CreateSourceResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r CreateSourceRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return CreateSourceResponse{}, err + } + return r.Receive() +} + +// CreateSourceResponse : Response for CreateSourceRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#createsource +type CreateSourceResponse struct { + // ID of the SceneItem in the scene. + // Required: Yes. + ItemID int `json:"itemId"` + _response `json:",squash"` +} + // GetSourcesListRequest : List all sources available in the running OBS instance. // // Since obs-websocket version: 4.3.0. @@ -55,7 +273,7 @@ func (r *GetSourcesListRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetSourcesListRequest) Receive() (GetSourcesListResponse, error) { +func (r GetSourcesListRequest) Receive() (Response, error) { if !r.sent { return GetSourcesListResponse{}, ErrNotSent } @@ -79,7 +297,7 @@ func (r GetSourcesListRequest) Receive() (GetSourcesListResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r GetSourcesListRequest) SendReceive(c Client) (GetSourcesListResponse, error) { +func (r GetSourcesListRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetSourcesListResponse{}, err } @@ -98,7 +316,7 @@ type GetSourcesListResponse struct { // Unique source name. // Required: Yes. SourcesName string `json:"sources.*.name"` - // Non-unique source internal type (a.k.a type id). + // Non-unique source internal type (a.k.a kind). // Required: Yes. SourcesTypeID string `json:"sources.*.typeId"` // Source type. @@ -155,7 +373,7 @@ func (r *GetSourceTypesListRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetSourceTypesListRequest) Receive() (GetSourceTypesListResponse, error) { +func (r GetSourceTypesListRequest) Receive() (Response, error) { if !r.sent { return GetSourceTypesListResponse{}, ErrNotSent } @@ -179,7 +397,7 @@ func (r GetSourceTypesListRequest) Receive() (GetSourceTypesListResponse, error) } // SendReceive sends the request then immediately waits for the response. -func (r GetSourceTypesListRequest) SendReceive(c Client) (GetSourceTypesListResponse, error) { +func (r GetSourceTypesListRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetSourceTypesListResponse{}, err } @@ -235,7 +453,8 @@ type GetSourceTypesListResponse struct { _response `json:",squash"` } -// GetVolumeRequest : Get the volume of the specified source. +// GetVolumeRequest : Get the volume of the specified source +// Default response uses mul format, NOT SLIDER PERCENTAGE. // // Since obs-websocket version: 4.0.0. // @@ -243,15 +462,22 @@ type GetSourceTypesListResponse struct { type GetVolumeRequest struct { // Source name. // Required: Yes. - Source string `json:"source"` - _request `json:",squash"` - response chan GetVolumeResponse + Source string `json:"source"` + // Output volume in decibels of attenuation instead of amplitude/mul. + // Required: No. + UseDecibel bool `json:"useDecibel"` + _request `json:",squash"` + response chan GetVolumeResponse } // NewGetVolumeRequest returns a new GetVolumeRequest. -func NewGetVolumeRequest(source string) GetVolumeRequest { +func NewGetVolumeRequest( + source string, + useDecibel bool, +) GetVolumeRequest { return GetVolumeRequest{ source, + useDecibel, _request{ ID_: GetMessageID(), Type_: "GetVolume", @@ -286,7 +512,7 @@ func (r *GetVolumeRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetVolumeRequest) Receive() (GetVolumeResponse, error) { +func (r GetVolumeRequest) Receive() (Response, error) { if !r.sent { return GetVolumeResponse{}, ErrNotSent } @@ -310,7 +536,7 @@ func (r GetVolumeRequest) Receive() (GetVolumeResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r GetVolumeRequest) SendReceive(c Client) (GetVolumeResponse, error) { +func (r GetVolumeRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetVolumeResponse{}, err } @@ -327,7 +553,7 @@ type GetVolumeResponse struct { // Required: Yes. Name string `json:"name"` // Volume of the source. - // Between `0.0` and `1.0`. + // Between `0.0` and `20.0` if using mul, under `26.0` if using dB. // Required: Yes. Volume float64 `json:"volume"` // Indicates whether the source is muted. @@ -336,7 +562,8 @@ type GetVolumeResponse struct { _response `json:",squash"` } -// SetVolumeRequest : Set the volume of the specified source. +// SetVolumeRequest : Set the volume of the specified source +// Default request format uses mul, NOT SLIDER PERCENTAGE. // // Since obs-websocket version: 4.0.0. // @@ -346,21 +573,28 @@ type SetVolumeRequest struct { // Required: Yes. Source string `json:"source"` // Desired volume. - // Must be between `0.0` and `1.0`. + // Must be between `0.0` and `20.0` for mul, and under 26.0 for dB. + // OBS will interpret dB values under -100.0 as Inf. + // Note: The OBS volume sliders only reach a maximum of 1.0mul/0.0dB, however OBS actually supports larger values. // Required: Yes. - Volume float64 `json:"volume"` - _request `json:",squash"` - response chan SetVolumeResponse + Volume float64 `json:"volume"` + // Interperet `volume` data as decibels instead of amplitude/mul. + // Required: No. + UseDecibel bool `json:"useDecibel"` + _request `json:",squash"` + response chan SetVolumeResponse } // NewSetVolumeRequest returns a new SetVolumeRequest. func NewSetVolumeRequest( source string, volume float64, + useDecibel bool, ) SetVolumeRequest { return SetVolumeRequest{ source, volume, + useDecibel, _request{ ID_: GetMessageID(), Type_: "SetVolume", @@ -395,7 +629,7 @@ func (r *SetVolumeRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetVolumeRequest) Receive() (SetVolumeResponse, error) { +func (r SetVolumeRequest) Receive() (Response, error) { if !r.sent { return SetVolumeResponse{}, ErrNotSent } @@ -419,7 +653,7 @@ func (r SetVolumeRequest) Receive() (SetVolumeResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r SetVolumeRequest) SendReceive(c Client) (SetVolumeResponse, error) { +func (r SetVolumeRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetVolumeResponse{}, err } @@ -486,7 +720,7 @@ func (r *GetMuteRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetMuteRequest) Receive() (GetMuteResponse, error) { +func (r GetMuteRequest) Receive() (Response, error) { if !r.sent { return GetMuteResponse{}, ErrNotSent } @@ -510,7 +744,7 @@ func (r GetMuteRequest) Receive() (GetMuteResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r GetMuteRequest) SendReceive(c Client) (GetMuteResponse, error) { +func (r GetMuteRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetMuteResponse{}, err } @@ -590,7 +824,7 @@ func (r *SetMuteRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetMuteRequest) Receive() (SetMuteResponse, error) { +func (r SetMuteRequest) Receive() (Response, error) { if !r.sent { return SetMuteResponse{}, ErrNotSent } @@ -614,7 +848,7 @@ func (r SetMuteRequest) Receive() (SetMuteResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r SetMuteRequest) SendReceive(c Client) (SetMuteResponse, error) { +func (r SetMuteRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetMuteResponse{}, err } @@ -681,7 +915,7 @@ func (r *ToggleMuteRequest) Send(c Client) error { } // Receive waits for the response. -func (r ToggleMuteRequest) Receive() (ToggleMuteResponse, error) { +func (r ToggleMuteRequest) Receive() (Response, error) { if !r.sent { return ToggleMuteResponse{}, ErrNotSent } @@ -705,7 +939,7 @@ func (r ToggleMuteRequest) Receive() (ToggleMuteResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r ToggleMuteRequest) SendReceive(c Client) (ToggleMuteResponse, error) { +func (r ToggleMuteRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return ToggleMuteResponse{}, err } @@ -721,41 +955,34 @@ type ToggleMuteResponse struct { _response `json:",squash"` } -// SetSyncOffsetRequest : Set the audio sync offset of a specified source. +// GetAudioActiveRequest : Get the audio's active status of a specified source. // -// Since obs-websocket version: 4.2.0. +// Since obs-websocket version: 4.9.0. // -// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#setsyncoffset -type SetSyncOffsetRequest struct { +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getaudioactive +type GetAudioActiveRequest struct { // Source name. // Required: Yes. - Source string `json:"source"` - // The desired audio sync offset (in nanoseconds). - // Required: Yes. - Offset int `json:"offset"` - _request `json:",squash"` - response chan SetSyncOffsetResponse + SourceName string `json:"sourceName"` + _request `json:",squash"` + response chan GetAudioActiveResponse } -// NewSetSyncOffsetRequest returns a new SetSyncOffsetRequest. -func NewSetSyncOffsetRequest( - source string, - offset int, -) SetSyncOffsetRequest { - return SetSyncOffsetRequest{ - source, - offset, +// NewGetAudioActiveRequest returns a new GetAudioActiveRequest. +func NewGetAudioActiveRequest(sourceName string) GetAudioActiveRequest { + return GetAudioActiveRequest{ + sourceName, _request{ ID_: GetMessageID(), - Type_: "SetSyncOffset", + Type_: "GetAudioActive", err: make(chan error, 1), }, - make(chan SetSyncOffsetResponse, 1), + make(chan GetAudioActiveResponse, 1), } } // Send sends the request. -func (r *SetSyncOffsetRequest) Send(c Client) error { +func (r *GetAudioActiveRequest) Send(c Client) error { if r.sent { return ErrAlreadySent } @@ -766,7 +993,7 @@ func (r *SetSyncOffsetRequest) Send(c Client) error { r.sent = true go func() { m := <-future - var resp SetSyncOffsetResponse + var resp GetAudioActiveResponse if err = mapToStruct(m, &resp); err != nil { r.err <- err } else if resp.Status() != StatusOK { @@ -779,74 +1006,86 @@ func (r *SetSyncOffsetRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetSyncOffsetRequest) Receive() (SetSyncOffsetResponse, error) { +func (r GetAudioActiveRequest) Receive() (Response, error) { if !r.sent { - return SetSyncOffsetResponse{}, ErrNotSent + return GetAudioActiveResponse{}, ErrNotSent } if receiveTimeout == 0 { select { case resp := <-r.response: return resp, nil case err := <-r.err: - return SetSyncOffsetResponse{}, err + return GetAudioActiveResponse{}, err } } else { select { case resp := <-r.response: return resp, nil case err := <-r.err: - return SetSyncOffsetResponse{}, err + return GetAudioActiveResponse{}, err case <-time.After(receiveTimeout): - return SetSyncOffsetResponse{}, ErrReceiveTimeout + return GetAudioActiveResponse{}, ErrReceiveTimeout } } } // SendReceive sends the request then immediately waits for the response. -func (r SetSyncOffsetRequest) SendReceive(c Client) (SetSyncOffsetResponse, error) { +func (r GetAudioActiveRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { - return SetSyncOffsetResponse{}, err + return GetAudioActiveResponse{}, err } return r.Receive() } -// SetSyncOffsetResponse : Response for SetSyncOffsetRequest. +// GetAudioActiveResponse : Response for GetAudioActiveRequest. // -// Since obs-websocket version: 4.2.0. +// Since obs-websocket version: 4.9.0. // -// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#setsyncoffset -type SetSyncOffsetResponse struct { - _response `json:",squash"` +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getaudioactive +type GetAudioActiveResponse struct { + // Audio active status of the source. + // Required: Yes. + AudioActive bool `json:"audioActive"` + _response `json:",squash"` } -// GetSyncOffsetRequest : Get the audio sync offset of a specified source. +// SetSourceNameRequest : // -// Since obs-websocket version: 4.2.0. +// Note: If the new name already exists as a source, obs-websocket will return an error. // -// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getsyncoffset -type GetSyncOffsetRequest struct { +// Since obs-websocket version: 4.8.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#setsourcename +type SetSourceNameRequest struct { // Source name. // Required: Yes. - Source string `json:"source"` + SourceName string `json:"sourceName"` + // New source name. + // Required: Yes. + NewName string `json:"newName"` _request `json:",squash"` - response chan GetSyncOffsetResponse + response chan SetSourceNameResponse } -// NewGetSyncOffsetRequest returns a new GetSyncOffsetRequest. -func NewGetSyncOffsetRequest(source string) GetSyncOffsetRequest { - return GetSyncOffsetRequest{ - source, +// NewSetSourceNameRequest returns a new SetSourceNameRequest. +func NewSetSourceNameRequest( + sourceName string, + newName string, +) SetSourceNameRequest { + return SetSourceNameRequest{ + sourceName, + newName, _request{ ID_: GetMessageID(), - Type_: "GetSyncOffset", + Type_: "SetSourceName", err: make(chan error, 1), }, - make(chan GetSyncOffsetResponse, 1), + make(chan SetSourceNameResponse, 1), } } // Send sends the request. -func (r *GetSyncOffsetRequest) Send(c Client) error { +func (r *SetSourceNameRequest) Send(c Client) error { if r.sent { return ErrAlreadySent } @@ -857,7 +1096,7 @@ func (r *GetSyncOffsetRequest) Send(c Client) error { r.sent = true go func() { m := <-future - var resp GetSyncOffsetResponse + var resp SetSourceNameResponse if err = mapToStruct(m, &resp); err != nil { r.err <- err } else if resp.Status() != StatusOK { @@ -870,77 +1109,266 @@ func (r *GetSyncOffsetRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetSyncOffsetRequest) Receive() (GetSyncOffsetResponse, error) { +func (r SetSourceNameRequest) Receive() (Response, error) { if !r.sent { - return GetSyncOffsetResponse{}, ErrNotSent + return SetSourceNameResponse{}, ErrNotSent } if receiveTimeout == 0 { select { case resp := <-r.response: return resp, nil case err := <-r.err: - return GetSyncOffsetResponse{}, err + return SetSourceNameResponse{}, err } } else { select { case resp := <-r.response: return resp, nil case err := <-r.err: - return GetSyncOffsetResponse{}, err + return SetSourceNameResponse{}, err case <-time.After(receiveTimeout): - return GetSyncOffsetResponse{}, ErrReceiveTimeout + return SetSourceNameResponse{}, ErrReceiveTimeout } } } // SendReceive sends the request then immediately waits for the response. -func (r GetSyncOffsetRequest) SendReceive(c Client) (GetSyncOffsetResponse, error) { +func (r SetSourceNameRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { - return GetSyncOffsetResponse{}, err + return SetSourceNameResponse{}, err } return r.Receive() } -// GetSyncOffsetResponse : Response for GetSyncOffsetRequest. +// SetSourceNameResponse : Response for SetSourceNameRequest. // -// Since obs-websocket version: 4.2.0. +// Since obs-websocket version: 4.8.0. // -// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getsyncoffset -type GetSyncOffsetResponse struct { - // Source name. - // Required: Yes. - Name string `json:"name"` - // The audio sync offset (in nanoseconds). - // Required: Yes. - Offset int `json:"offset"` +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#setsourcename +type SetSourceNameResponse struct { _response `json:",squash"` } -// GetSourceSettingsRequest : Get settings of the specified source. +// SetSyncOffsetRequest : Set the audio sync offset of a specified source. // -// Since obs-websocket version: 4.3.0. +// Since obs-websocket version: 4.2.0. // -// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getsourcesettings -type GetSourceSettingsRequest struct { +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#setsyncoffset +type SetSyncOffsetRequest struct { // Source name. // Required: Yes. - SourceName string `json:"sourceName"` - // Type of the specified source. - // Useful for type-checking if you expect a specific settings schema. - // Required: No. - SourceType string `json:"sourceType"` - _request `json:",squash"` - response chan GetSourceSettingsResponse + Source string `json:"source"` + // The desired audio sync offset (in nanoseconds). + // Required: Yes. + Offset int `json:"offset"` + _request `json:",squash"` + response chan SetSyncOffsetResponse } -// NewGetSourceSettingsRequest returns a new GetSourceSettingsRequest. -func NewGetSourceSettingsRequest( - sourceName string, - sourceType string, -) GetSourceSettingsRequest { - return GetSourceSettingsRequest{ - sourceName, - sourceType, +// NewSetSyncOffsetRequest returns a new SetSyncOffsetRequest. +func NewSetSyncOffsetRequest( + source string, + offset int, +) SetSyncOffsetRequest { + return SetSyncOffsetRequest{ + source, + offset, + _request{ + ID_: GetMessageID(), + Type_: "SetSyncOffset", + err: make(chan error, 1), + }, + make(chan SetSyncOffsetResponse, 1), + } +} + +// Send sends the request. +func (r *SetSyncOffsetRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp SetSyncOffsetResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r SetSyncOffsetRequest) Receive() (Response, error) { + if !r.sent { + return SetSyncOffsetResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return SetSyncOffsetResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return SetSyncOffsetResponse{}, err + case <-time.After(receiveTimeout): + return SetSyncOffsetResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r SetSyncOffsetRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return SetSyncOffsetResponse{}, err + } + return r.Receive() +} + +// SetSyncOffsetResponse : Response for SetSyncOffsetRequest. +// +// Since obs-websocket version: 4.2.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#setsyncoffset +type SetSyncOffsetResponse struct { + _response `json:",squash"` +} + +// GetSyncOffsetRequest : Get the audio sync offset of a specified source. +// +// Since obs-websocket version: 4.2.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getsyncoffset +type GetSyncOffsetRequest struct { + // Source name. + // Required: Yes. + Source string `json:"source"` + _request `json:",squash"` + response chan GetSyncOffsetResponse +} + +// NewGetSyncOffsetRequest returns a new GetSyncOffsetRequest. +func NewGetSyncOffsetRequest(source string) GetSyncOffsetRequest { + return GetSyncOffsetRequest{ + source, + _request{ + ID_: GetMessageID(), + Type_: "GetSyncOffset", + err: make(chan error, 1), + }, + make(chan GetSyncOffsetResponse, 1), + } +} + +// Send sends the request. +func (r *GetSyncOffsetRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp GetSyncOffsetResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r GetSyncOffsetRequest) Receive() (Response, error) { + if !r.sent { + return GetSyncOffsetResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetSyncOffsetResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetSyncOffsetResponse{}, err + case <-time.After(receiveTimeout): + return GetSyncOffsetResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r GetSyncOffsetRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return GetSyncOffsetResponse{}, err + } + return r.Receive() +} + +// GetSyncOffsetResponse : Response for GetSyncOffsetRequest. +// +// Since obs-websocket version: 4.2.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getsyncoffset +type GetSyncOffsetResponse struct { + // Source name. + // Required: Yes. + Name string `json:"name"` + // The audio sync offset (in nanoseconds). + // Required: Yes. + Offset int `json:"offset"` + _response `json:",squash"` +} + +// GetSourceSettingsRequest : Get settings of the specified source. +// +// Since obs-websocket version: 4.3.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getsourcesettings +type GetSourceSettingsRequest struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + // Type of the specified source. + // Useful for type-checking if you expect a specific settings schema. + // Required: No. + SourceType string `json:"sourceType"` + _request `json:",squash"` + response chan GetSourceSettingsResponse +} + +// NewGetSourceSettingsRequest returns a new GetSourceSettingsRequest. +func NewGetSourceSettingsRequest( + sourceName string, + sourceType string, +) GetSourceSettingsRequest { + return GetSourceSettingsRequest{ + sourceName, + sourceType, _request{ ID_: GetMessageID(), Type_: "GetSourceSettings", @@ -975,7 +1403,7 @@ func (r *GetSourceSettingsRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetSourceSettingsRequest) Receive() (GetSourceSettingsResponse, error) { +func (r GetSourceSettingsRequest) Receive() (Response, error) { if !r.sent { return GetSourceSettingsResponse{}, ErrNotSent } @@ -999,7 +1427,7 @@ func (r GetSourceSettingsRequest) Receive() (GetSourceSettingsResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r GetSourceSettingsRequest) SendReceive(c Client) (GetSourceSettingsResponse, error) { +func (r GetSourceSettingsRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetSourceSettingsResponse{}, err } @@ -1088,7 +1516,7 @@ func (r *SetSourceSettingsRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetSourceSettingsRequest) Receive() (SetSourceSettingsResponse, error) { +func (r SetSourceSettingsRequest) Receive() (Response, error) { if !r.sent { return SetSourceSettingsResponse{}, ErrNotSent } @@ -1112,7 +1540,7 @@ func (r SetSourceSettingsRequest) Receive() (SetSourceSettingsResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r SetSourceSettingsRequest) SendReceive(c Client) (SetSourceSettingsResponse, error) { +func (r SetSourceSettingsRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetSourceSettingsResponse{}, err } @@ -1188,7 +1616,7 @@ func (r *GetTextGDIPlusPropertiesRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetTextGDIPlusPropertiesRequest) Receive() (GetTextGDIPlusPropertiesResponse, error) { +func (r GetTextGDIPlusPropertiesRequest) Receive() (Response, error) { if !r.sent { return GetTextGDIPlusPropertiesResponse{}, ErrNotSent } @@ -1212,7 +1640,7 @@ func (r GetTextGDIPlusPropertiesRequest) Receive() (GetTextGDIPlusPropertiesResp } // SendReceive sends the request then immediately waits for the response. -func (r GetTextGDIPlusPropertiesRequest) SendReceive(c Client) (GetTextGDIPlusPropertiesResponse, error) { +func (r GetTextGDIPlusPropertiesRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetTextGDIPlusPropertiesResponse{}, err } @@ -1233,10 +1661,10 @@ type GetTextGDIPlusPropertiesResponse struct { Align string `json:"align"` // Background color. // Required: Yes. - BkColor int `json:"bk-color"` + BkColor int `json:"bk_color"` // Background opacity (0-100). // Required: Yes. - BkOpacity int `json:"bk-opacity"` + BkOpacity int `json:"bk_opacity"` // Chat log. // Required: Yes. Chatlog bool `json:"chatlog"` @@ -1328,10 +1756,10 @@ type SetTextGDIPlusPropertiesRequest struct { Align string `json:"align"` // Background color. // Required: No. - BkColor int `json:"bk-color"` + BkColor int `json:"bk_color"` // Background opacity (0-100). // Required: No. - BkOpacity int `json:"bk-opacity"` + BkOpacity int `json:"bk_opacity"` // Chat log. // Required: No. Chatlog bool `json:"chatlog"` @@ -1509,7 +1937,7 @@ func (r *SetTextGDIPlusPropertiesRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetTextGDIPlusPropertiesRequest) Receive() (SetTextGDIPlusPropertiesResponse, error) { +func (r SetTextGDIPlusPropertiesRequest) Receive() (Response, error) { if !r.sent { return SetTextGDIPlusPropertiesResponse{}, ErrNotSent } @@ -1533,7 +1961,7 @@ func (r SetTextGDIPlusPropertiesRequest) Receive() (SetTextGDIPlusPropertiesResp } // SendReceive sends the request then immediately waits for the response. -func (r SetTextGDIPlusPropertiesRequest) SendReceive(c Client) (SetTextGDIPlusPropertiesResponse, error) { +func (r SetTextGDIPlusPropertiesRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetTextGDIPlusPropertiesResponse{}, err } @@ -1600,7 +2028,7 @@ func (r *GetTextFreetype2PropertiesRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetTextFreetype2PropertiesRequest) Receive() (GetTextFreetype2PropertiesResponse, error) { +func (r GetTextFreetype2PropertiesRequest) Receive() (Response, error) { if !r.sent { return GetTextFreetype2PropertiesResponse{}, ErrNotSent } @@ -1624,7 +2052,7 @@ func (r GetTextFreetype2PropertiesRequest) Receive() (GetTextFreetype2Properties } // SendReceive sends the request then immediately waits for the response. -func (r GetTextFreetype2PropertiesRequest) SendReceive(c Client) (GetTextFreetype2PropertiesResponse, error) { +func (r GetTextFreetype2PropertiesRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetTextFreetype2PropertiesResponse{}, err } @@ -1820,7 +2248,7 @@ func (r *SetTextFreetype2PropertiesRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetTextFreetype2PropertiesRequest) Receive() (SetTextFreetype2PropertiesResponse, error) { +func (r SetTextFreetype2PropertiesRequest) Receive() (Response, error) { if !r.sent { return SetTextFreetype2PropertiesResponse{}, ErrNotSent } @@ -1844,7 +2272,7 @@ func (r SetTextFreetype2PropertiesRequest) Receive() (SetTextFreetype2Properties } // SendReceive sends the request then immediately waits for the response. -func (r SetTextFreetype2PropertiesRequest) SendReceive(c Client) (SetTextFreetype2PropertiesResponse, error) { +func (r SetTextFreetype2PropertiesRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetTextFreetype2PropertiesResponse{}, err } @@ -1911,7 +2339,7 @@ func (r *GetBrowserSourcePropertiesRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetBrowserSourcePropertiesRequest) Receive() (GetBrowserSourcePropertiesResponse, error) { +func (r GetBrowserSourcePropertiesRequest) Receive() (Response, error) { if !r.sent { return GetBrowserSourcePropertiesResponse{}, ErrNotSent } @@ -1935,7 +2363,7 @@ func (r GetBrowserSourcePropertiesRequest) Receive() (GetBrowserSourceProperties } // SendReceive sends the request then immediately waits for the response. -func (r GetBrowserSourcePropertiesRequest) SendReceive(c Client) (GetBrowserSourcePropertiesResponse, error) { +func (r GetBrowserSourcePropertiesRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetBrowserSourcePropertiesResponse{}, err } @@ -2076,7 +2504,7 @@ func (r *SetBrowserSourcePropertiesRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetBrowserSourcePropertiesRequest) Receive() (SetBrowserSourcePropertiesResponse, error) { +func (r SetBrowserSourcePropertiesRequest) Receive() (Response, error) { if !r.sent { return SetBrowserSourcePropertiesResponse{}, ErrNotSent } @@ -2100,7 +2528,7 @@ func (r SetBrowserSourcePropertiesRequest) Receive() (SetBrowserSourceProperties } // SendReceive sends the request then immediately waits for the response. -func (r SetBrowserSourcePropertiesRequest) SendReceive(c Client) (SetBrowserSourcePropertiesResponse, error) { +func (r SetBrowserSourcePropertiesRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetBrowserSourcePropertiesResponse{}, err } @@ -2163,7 +2591,7 @@ func (r *GetSpecialSourcesRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetSpecialSourcesRequest) Receive() (GetSpecialSourcesResponse, error) { +func (r GetSpecialSourcesRequest) Receive() (Response, error) { if !r.sent { return GetSpecialSourcesResponse{}, ErrNotSent } @@ -2187,7 +2615,7 @@ func (r GetSpecialSourcesRequest) Receive() (GetSpecialSourcesResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r GetSpecialSourcesRequest) SendReceive(c Client) (GetSpecialSourcesResponse, error) { +func (r GetSpecialSourcesRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetSpecialSourcesResponse{}, err } @@ -2269,7 +2697,7 @@ func (r *GetSourceFiltersRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetSourceFiltersRequest) Receive() (GetSourceFiltersResponse, error) { +func (r GetSourceFiltersRequest) Receive() (Response, error) { if !r.sent { return GetSourceFiltersResponse{}, ErrNotSent } @@ -2293,7 +2721,7 @@ func (r GetSourceFiltersRequest) Receive() (GetSourceFiltersResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r GetSourceFiltersRequest) SendReceive(c Client) (GetSourceFiltersResponse, error) { +func (r GetSourceFiltersRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetSourceFiltersResponse{}, err } @@ -2382,7 +2810,7 @@ func (r *GetSourceFilterInfoRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetSourceFilterInfoRequest) Receive() (GetSourceFilterInfoResponse, error) { +func (r GetSourceFilterInfoRequest) Receive() (Response, error) { if !r.sent { return GetSourceFilterInfoResponse{}, ErrNotSent } @@ -2406,7 +2834,7 @@ func (r GetSourceFilterInfoRequest) Receive() (GetSourceFilterInfoResponse, erro } // SendReceive sends the request then immediately waits for the response. -func (r GetSourceFilterInfoRequest) SendReceive(c Client) (GetSourceFilterInfoResponse, error) { +func (r GetSourceFilterInfoRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetSourceFilterInfoResponse{}, err } @@ -2503,7 +2931,7 @@ func (r *AddFilterToSourceRequest) Send(c Client) error { } // Receive waits for the response. -func (r AddFilterToSourceRequest) Receive() (AddFilterToSourceResponse, error) { +func (r AddFilterToSourceRequest) Receive() (Response, error) { if !r.sent { return AddFilterToSourceResponse{}, ErrNotSent } @@ -2527,7 +2955,7 @@ func (r AddFilterToSourceRequest) Receive() (AddFilterToSourceResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r AddFilterToSourceRequest) SendReceive(c Client) (AddFilterToSourceResponse, error) { +func (r AddFilterToSourceRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return AddFilterToSourceResponse{}, err } @@ -2601,7 +3029,7 @@ func (r *RemoveFilterFromSourceRequest) Send(c Client) error { } // Receive waits for the response. -func (r RemoveFilterFromSourceRequest) Receive() (RemoveFilterFromSourceResponse, error) { +func (r RemoveFilterFromSourceRequest) Receive() (Response, error) { if !r.sent { return RemoveFilterFromSourceResponse{}, ErrNotSent } @@ -2625,7 +3053,7 @@ func (r RemoveFilterFromSourceRequest) Receive() (RemoveFilterFromSourceResponse } // SendReceive sends the request then immediately waits for the response. -func (r RemoveFilterFromSourceRequest) SendReceive(c Client) (RemoveFilterFromSourceResponse, error) { +func (r RemoveFilterFromSourceRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return RemoveFilterFromSourceResponse{}, err } @@ -2704,7 +3132,7 @@ func (r *ReorderSourceFilterRequest) Send(c Client) error { } // Receive waits for the response. -func (r ReorderSourceFilterRequest) Receive() (ReorderSourceFilterResponse, error) { +func (r ReorderSourceFilterRequest) Receive() (Response, error) { if !r.sent { return ReorderSourceFilterResponse{}, ErrNotSent } @@ -2728,7 +3156,7 @@ func (r ReorderSourceFilterRequest) Receive() (ReorderSourceFilterResponse, erro } // SendReceive sends the request then immediately waits for the response. -func (r ReorderSourceFilterRequest) SendReceive(c Client) (ReorderSourceFilterResponse, error) { +func (r ReorderSourceFilterRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return ReorderSourceFilterResponse{}, err } @@ -2808,7 +3236,7 @@ func (r *MoveSourceFilterRequest) Send(c Client) error { } // Receive waits for the response. -func (r MoveSourceFilterRequest) Receive() (MoveSourceFilterResponse, error) { +func (r MoveSourceFilterRequest) Receive() (Response, error) { if !r.sent { return MoveSourceFilterResponse{}, ErrNotSent } @@ -2832,7 +3260,7 @@ func (r MoveSourceFilterRequest) Receive() (MoveSourceFilterResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r MoveSourceFilterRequest) SendReceive(c Client) (MoveSourceFilterResponse, error) { +func (r MoveSourceFilterRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return MoveSourceFilterResponse{}, err } @@ -2912,7 +3340,7 @@ func (r *SetSourceFilterSettingsRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetSourceFilterSettingsRequest) Receive() (SetSourceFilterSettingsResponse, error) { +func (r SetSourceFilterSettingsRequest) Receive() (Response, error) { if !r.sent { return SetSourceFilterSettingsResponse{}, ErrNotSent } @@ -2936,7 +3364,7 @@ func (r SetSourceFilterSettingsRequest) Receive() (SetSourceFilterSettingsRespon } // SendReceive sends the request then immediately waits for the response. -func (r SetSourceFilterSettingsRequest) SendReceive(c Client) (SetSourceFilterSettingsResponse, error) { +func (r SetSourceFilterSettingsRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetSourceFilterSettingsResponse{}, err } @@ -3015,7 +3443,7 @@ func (r *SetSourceFilterVisibilityRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetSourceFilterVisibilityRequest) Receive() (SetSourceFilterVisibilityResponse, error) { +func (r SetSourceFilterVisibilityRequest) Receive() (Response, error) { if !r.sent { return SetSourceFilterVisibilityResponse{}, ErrNotSent } @@ -3039,7 +3467,7 @@ func (r SetSourceFilterVisibilityRequest) Receive() (SetSourceFilterVisibilityRe } // SendReceive sends the request then immediately waits for the response. -func (r SetSourceFilterVisibilityRequest) SendReceive(c Client) (SetSourceFilterVisibilityResponse, error) { +func (r SetSourceFilterVisibilityRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetSourceFilterVisibilityResponse{}, err } @@ -3055,6 +3483,299 @@ type SetSourceFilterVisibilityResponse struct { _response `json:",squash"` } +// GetAudioMonitorTypeRequest : Get the audio monitoring type of the specified source. +// +// Since obs-websocket version: 4.8.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getaudiomonitortype +type GetAudioMonitorTypeRequest struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + _request `json:",squash"` + response chan GetAudioMonitorTypeResponse +} + +// NewGetAudioMonitorTypeRequest returns a new GetAudioMonitorTypeRequest. +func NewGetAudioMonitorTypeRequest(sourceName string) GetAudioMonitorTypeRequest { + return GetAudioMonitorTypeRequest{ + sourceName, + _request{ + ID_: GetMessageID(), + Type_: "GetAudioMonitorType", + err: make(chan error, 1), + }, + make(chan GetAudioMonitorTypeResponse, 1), + } +} + +// Send sends the request. +func (r *GetAudioMonitorTypeRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp GetAudioMonitorTypeResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r GetAudioMonitorTypeRequest) Receive() (Response, error) { + if !r.sent { + return GetAudioMonitorTypeResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetAudioMonitorTypeResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetAudioMonitorTypeResponse{}, err + case <-time.After(receiveTimeout): + return GetAudioMonitorTypeResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r GetAudioMonitorTypeRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return GetAudioMonitorTypeResponse{}, err + } + return r.Receive() +} + +// GetAudioMonitorTypeResponse : Response for GetAudioMonitorTypeRequest. +// +// Since obs-websocket version: 4.8.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getaudiomonitortype +type GetAudioMonitorTypeResponse struct { + // The monitor type in use. + // Options: `none`, `monitorOnly`, `monitorAndOutput`. + // Required: Yes. + MonitorType string `json:"monitorType"` + _response `json:",squash"` +} + +// SetAudioMonitorTypeRequest : Set the audio monitoring type of the specified source. +// +// Since obs-websocket version: 4.8.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#setaudiomonitortype +type SetAudioMonitorTypeRequest struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + // The monitor type to use. + // Options: `none`, `monitorOnly`, `monitorAndOutput`. + // Required: Yes. + MonitorType string `json:"monitorType"` + _request `json:",squash"` + response chan SetAudioMonitorTypeResponse +} + +// NewSetAudioMonitorTypeRequest returns a new SetAudioMonitorTypeRequest. +func NewSetAudioMonitorTypeRequest( + sourceName string, + monitorType string, +) SetAudioMonitorTypeRequest { + return SetAudioMonitorTypeRequest{ + sourceName, + monitorType, + _request{ + ID_: GetMessageID(), + Type_: "SetAudioMonitorType", + err: make(chan error, 1), + }, + make(chan SetAudioMonitorTypeResponse, 1), + } +} + +// Send sends the request. +func (r *SetAudioMonitorTypeRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp SetAudioMonitorTypeResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r SetAudioMonitorTypeRequest) Receive() (Response, error) { + if !r.sent { + return SetAudioMonitorTypeResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return SetAudioMonitorTypeResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return SetAudioMonitorTypeResponse{}, err + case <-time.After(receiveTimeout): + return SetAudioMonitorTypeResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r SetAudioMonitorTypeRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return SetAudioMonitorTypeResponse{}, err + } + return r.Receive() +} + +// SetAudioMonitorTypeResponse : Response for SetAudioMonitorTypeRequest. +// +// Since obs-websocket version: 4.8.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#setaudiomonitortype +type SetAudioMonitorTypeResponse struct { + _response `json:",squash"` +} + +// GetSourceDefaultSettingsRequest : Get the default settings for a given source type. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getsourcedefaultsettings +type GetSourceDefaultSettingsRequest struct { + // Source kind. + // Also called "source id" in libobs terminology. + // Required: Yes. + SourceKind string `json:"sourceKind"` + _request `json:",squash"` + response chan GetSourceDefaultSettingsResponse +} + +// NewGetSourceDefaultSettingsRequest returns a new GetSourceDefaultSettingsRequest. +func NewGetSourceDefaultSettingsRequest(sourceKind string) GetSourceDefaultSettingsRequest { + return GetSourceDefaultSettingsRequest{ + sourceKind, + _request{ + ID_: GetMessageID(), + Type_: "GetSourceDefaultSettings", + err: make(chan error, 1), + }, + make(chan GetSourceDefaultSettingsResponse, 1), + } +} + +// Send sends the request. +func (r *GetSourceDefaultSettingsRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp GetSourceDefaultSettingsResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r GetSourceDefaultSettingsRequest) Receive() (Response, error) { + if !r.sent { + return GetSourceDefaultSettingsResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetSourceDefaultSettingsResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetSourceDefaultSettingsResponse{}, err + case <-time.After(receiveTimeout): + return GetSourceDefaultSettingsResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r GetSourceDefaultSettingsRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return GetSourceDefaultSettingsResponse{}, err + } + return r.Receive() +} + +// GetSourceDefaultSettingsResponse : Response for GetSourceDefaultSettingsRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getsourcedefaultsettings +type GetSourceDefaultSettingsResponse struct { + // Source kind. + // Same value as the `sourceKind` parameter. + // Required: Yes. + SourceKind string `json:"sourceKind"` + // Settings object for source. + // Required: Yes. + DefaultSettings map[string]interface{} `json:"defaultSettings"` + _response `json:",squash"` +} + // TakeSourceScreenshotRequest : // // At least `embedPictureFormat` or `saveToFilePath` must be specified. @@ -3068,8 +3789,9 @@ type SetSourceFilterVisibilityResponse struct { // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#takesourcescreenshot type TakeSourceScreenshotRequest struct { // Source name. - // Note that, since scenes are also sources, you can also provide a scene name. - // Required: Yes. + // Note: Since scenes are also sources, you can also provide a scene name. + // If not provided, the currently active scene is used. + // Required: No. SourceName string `json:"sourceName"` // Format of the Data URI encoded picture. // Can be "png", "jpg", "jpeg" or "bmp" (or any other value supported by Qt's Image module). @@ -3080,6 +3802,15 @@ type TakeSourceScreenshotRequest struct { // Can be a relative path. // Required: No. SaveToFilePath string `json:"saveToFilePath"` + // Format to save the image file as (one of the values provided in the `supported-image-export-formats` response field of `GetVersion`). + // If not specified, tries to guess based on file extension. + // Required: No. + FileFormat string `json:"fileFormat"` + // Compression ratio between -1 and 100 to write the image with. + // -1 is automatic, 1 is smallest file/most compression, 100 is largest file/least compression. + // Varies with image type. + // Required: No. + CompressionQuality int `json:"compressionQuality"` // Screenshot width. // Defaults to the source's base width. // Required: No. @@ -3097,6 +3828,8 @@ func NewTakeSourceScreenshotRequest( sourceName string, embedPictureFormat string, saveToFilePath string, + fileFormat string, + compressionQuality int, width int, height int, ) TakeSourceScreenshotRequest { @@ -3104,6 +3837,8 @@ func NewTakeSourceScreenshotRequest( sourceName, embedPictureFormat, saveToFilePath, + fileFormat, + compressionQuality, width, height, _request{ @@ -3140,7 +3875,7 @@ func (r *TakeSourceScreenshotRequest) Send(c Client) error { } // Receive waits for the response. -func (r TakeSourceScreenshotRequest) Receive() (TakeSourceScreenshotResponse, error) { +func (r TakeSourceScreenshotRequest) Receive() (Response, error) { if !r.sent { return TakeSourceScreenshotResponse{}, ErrNotSent } @@ -3164,7 +3899,7 @@ func (r TakeSourceScreenshotRequest) Receive() (TakeSourceScreenshotResponse, er } // SendReceive sends the request then immediately waits for the response. -func (r TakeSourceScreenshotRequest) SendReceive(c Client) (TakeSourceScreenshotResponse, error) { +func (r TakeSourceScreenshotRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return TakeSourceScreenshotResponse{}, err } @@ -3188,3 +3923,94 @@ type TakeSourceScreenshotResponse struct { ImageFile string `json:"imageFile"` _response `json:",squash"` } + +// RefreshBrowserSourceRequest : Refreshes the specified browser source. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#refreshbrowsersource +type RefreshBrowserSourceRequest struct { + // Source name. + // Required: Yes. + SourceName string `json:"sourceName"` + _request `json:",squash"` + response chan RefreshBrowserSourceResponse +} + +// NewRefreshBrowserSourceRequest returns a new RefreshBrowserSourceRequest. +func NewRefreshBrowserSourceRequest(sourceName string) RefreshBrowserSourceRequest { + return RefreshBrowserSourceRequest{ + sourceName, + _request{ + ID_: GetMessageID(), + Type_: "RefreshBrowserSource", + err: make(chan error, 1), + }, + make(chan RefreshBrowserSourceResponse, 1), + } +} + +// Send sends the request. +func (r *RefreshBrowserSourceRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp RefreshBrowserSourceResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r RefreshBrowserSourceRequest) Receive() (Response, error) { + if !r.sent { + return RefreshBrowserSourceResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return RefreshBrowserSourceResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return RefreshBrowserSourceResponse{}, err + case <-time.After(receiveTimeout): + return RefreshBrowserSourceResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r RefreshBrowserSourceRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return RefreshBrowserSourceResponse{}, err + } + return r.Receive() +} + +// RefreshBrowserSourceResponse : Response for RefreshBrowserSourceRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#refreshbrowsersource +type RefreshBrowserSourceResponse struct { + _response `json:",squash"` +} diff --git a/requests_streaming.go b/requests_streaming.go index 88be62a..1652142 100644 --- a/requests_streaming.go +++ b/requests_streaming.go @@ -55,7 +55,7 @@ func (r *GetStreamingStatusRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetStreamingStatusRequest) Receive() (GetStreamingStatusResponse, error) { +func (r GetStreamingStatusRequest) Receive() (Response, error) { if !r.sent { return GetStreamingStatusResponse{}, ErrNotSent } @@ -79,7 +79,7 @@ func (r GetStreamingStatusRequest) Receive() (GetStreamingStatusResponse, error) } // SendReceive sends the request then immediately waits for the response. -func (r GetStreamingStatusRequest) SendReceive(c Client) (GetStreamingStatusResponse, error) { +func (r GetStreamingStatusRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetStreamingStatusResponse{}, err } @@ -98,20 +98,23 @@ type GetStreamingStatusResponse struct { // Current recording status. // Required: Yes. Recording bool `json:"recording"` + // If recording is paused. + // Required: Yes. + RecordingPaused bool `json:"recording-paused"` + // Always false. + // Retrocompatibility with OBSRemote. + // Required: Yes. + PreviewOnly bool `json:"preview-only"` // Time elapsed since streaming started (only present if currently streaming). // Required: No. StreamTimecode string `json:"stream-timecode"` // Time elapsed since recording started (only present if currently recording). // Required: No. RecTimecode string `json:"rec-timecode"` - // Always false. - // Retrocompatibility with OBSRemote. - // Required: Yes. - PreviewOnly bool `json:"preview-only"` _response `json:",squash"` } -// StartStopStreamingRequest : Toggle streaming on or off. +// StartStopStreamingRequest : Toggle streaming on or off (depending on the current stream state). // // Since obs-websocket version: 0.3. // @@ -158,7 +161,7 @@ func (r *StartStopStreamingRequest) Send(c Client) error { } // Receive waits for the response. -func (r StartStopStreamingRequest) Receive() (StartStopStreamingResponse, error) { +func (r StartStopStreamingRequest) Receive() (Response, error) { if !r.sent { return StartStopStreamingResponse{}, ErrNotSent } @@ -182,7 +185,7 @@ func (r StartStopStreamingRequest) Receive() (StartStopStreamingResponse, error) } // SendReceive sends the request then immediately waits for the response. -func (r StartStopStreamingRequest) SendReceive(c Client) (StartStopStreamingResponse, error) { +func (r StartStopStreamingRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return StartStopStreamingResponse{}, err } @@ -206,7 +209,7 @@ type StartStopStreamingResponse struct { // https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#startstreaming type StartStreamingRequest struct { // Special stream configuration. - // Please note: these won't be saved to OBS' configuration. + // Note: these won't be saved to OBS' configuration. // Required: No. Stream map[string]interface{} `json:"stream"` // If specified ensures the type of stream matches the given type (usually 'rtmp_custom' or 'rtmp_common'). @@ -229,13 +232,13 @@ type StartStreamingRequest struct { StreamSettingsKey string `json:"stream.settings.key"` // Indicates whether authentication should be used when connecting to the streaming server. // Required: No. - StreamSettingsUseAuth bool `json:"stream.settings.use-auth"` + StreamSettingsUseAuth bool `json:"stream.settings.use_auth"` // If authentication is enabled, the username for the streaming server. - // Ignored if `use-auth` is not set to `true`. + // Ignored if `use_auth` is not set to `true`. // Required: No. StreamSettingsUsername string `json:"stream.settings.username"` // If authentication is enabled, the password for the streaming server. - // Ignored if `use-auth` is not set to `true`. + // Ignored if `use_auth` is not set to `true`. // Required: No. StreamSettingsPassword string `json:"stream.settings.password"` _request `json:",squash"` @@ -298,7 +301,7 @@ func (r *StartStreamingRequest) Send(c Client) error { } // Receive waits for the response. -func (r StartStreamingRequest) Receive() (StartStreamingResponse, error) { +func (r StartStreamingRequest) Receive() (Response, error) { if !r.sent { return StartStreamingResponse{}, ErrNotSent } @@ -322,7 +325,7 @@ func (r StartStreamingRequest) Receive() (StartStreamingResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r StartStreamingRequest) SendReceive(c Client) (StartStreamingResponse, error) { +func (r StartStreamingRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return StartStreamingResponse{}, err } @@ -386,7 +389,7 @@ func (r *StopStreamingRequest) Send(c Client) error { } // Receive waits for the response. -func (r StopStreamingRequest) Receive() (StopStreamingResponse, error) { +func (r StopStreamingRequest) Receive() (Response, error) { if !r.sent { return StopStreamingResponse{}, ErrNotSent } @@ -410,7 +413,7 @@ func (r StopStreamingRequest) Receive() (StopStreamingResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r StopStreamingRequest) SendReceive(c Client) (StopStreamingResponse, error) { +func (r StopStreamingRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return StopStreamingResponse{}, err } @@ -450,7 +453,7 @@ type SetStreamSettingsRequest struct { SettingsKey string `json:"settings.key"` // Indicates whether authentication should be used when connecting to the streaming server. // Required: No. - SettingsUseAuth bool `json:"settings.use-auth"` + SettingsUseAuth bool `json:"settings.use_auth"` // The username for the streaming service. // Required: No. SettingsUsername string `json:"settings.username"` @@ -518,7 +521,7 @@ func (r *SetStreamSettingsRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetStreamSettingsRequest) Receive() (SetStreamSettingsResponse, error) { +func (r SetStreamSettingsRequest) Receive() (Response, error) { if !r.sent { return SetStreamSettingsResponse{}, ErrNotSent } @@ -542,7 +545,7 @@ func (r SetStreamSettingsRequest) Receive() (SetStreamSettingsResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r SetStreamSettingsRequest) SendReceive(c Client) (SetStreamSettingsResponse, error) { +func (r SetStreamSettingsRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetStreamSettingsResponse{}, err } @@ -605,7 +608,7 @@ func (r *GetStreamSettingsRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetStreamSettingsRequest) Receive() (GetStreamSettingsResponse, error) { +func (r GetStreamSettingsRequest) Receive() (Response, error) { if !r.sent { return GetStreamSettingsResponse{}, ErrNotSent } @@ -629,7 +632,7 @@ func (r GetStreamSettingsRequest) Receive() (GetStreamSettingsResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r GetStreamSettingsRequest) SendReceive(c Client) (GetStreamSettingsResponse, error) { +func (r GetStreamSettingsRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetStreamSettingsResponse{}, err } @@ -657,13 +660,13 @@ type GetStreamSettingsResponse struct { SettingsKey string `json:"settings.key"` // Indicates whether authentication should be used when connecting to the streaming server. // Required: Yes. - SettingsUseAuth bool `json:"settings.use-auth"` + SettingsUseAuth bool `json:"settings.use_auth"` // The username to use when accessing the streaming server. - // Only present if `use-auth` is `true`. + // Only present if `use_auth` is `true`. // Required: Yes. SettingsUsername string `json:"settings.username"` // The password to use when accessing the streaming server. - // Only present if `use-auth` is `true`. + // Only present if `use_auth` is `true`. // Required: Yes. SettingsPassword string `json:"settings.password"` _response `json:",squash"` @@ -716,7 +719,7 @@ func (r *SaveStreamSettingsRequest) Send(c Client) error { } // Receive waits for the response. -func (r SaveStreamSettingsRequest) Receive() (SaveStreamSettingsResponse, error) { +func (r SaveStreamSettingsRequest) Receive() (Response, error) { if !r.sent { return SaveStreamSettingsResponse{}, ErrNotSent } @@ -740,7 +743,7 @@ func (r SaveStreamSettingsRequest) Receive() (SaveStreamSettingsResponse, error) } // SendReceive sends the request then immediately waits for the response. -func (r SaveStreamSettingsRequest) SendReceive(c Client) (SaveStreamSettingsResponse, error) { +func (r SaveStreamSettingsRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SaveStreamSettingsResponse{}, err } @@ -757,7 +760,6 @@ type SaveStreamSettingsResponse struct { } // SendCaptionsRequest : Send the provided text as embedded CEA-608 caption data. -// As of OBS Studio 23.1, captions are not yet available on Linux. // // Since obs-websocket version: 4.6.0. // @@ -808,7 +810,7 @@ func (r *SendCaptionsRequest) Send(c Client) error { } // Receive waits for the response. -func (r SendCaptionsRequest) Receive() (SendCaptionsResponse, error) { +func (r SendCaptionsRequest) Receive() (Response, error) { if !r.sent { return SendCaptionsResponse{}, ErrNotSent } @@ -832,7 +834,7 @@ func (r SendCaptionsRequest) Receive() (SendCaptionsResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r SendCaptionsRequest) SendReceive(c Client) (SendCaptionsResponse, error) { +func (r SendCaptionsRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SendCaptionsResponse{}, err } diff --git a/requests_studio_mode.go b/requests_studio_mode.go index 456017b..e23af69 100644 --- a/requests_studio_mode.go +++ b/requests_studio_mode.go @@ -55,7 +55,7 @@ func (r *GetStudioModeStatusRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetStudioModeStatusRequest) Receive() (GetStudioModeStatusResponse, error) { +func (r GetStudioModeStatusRequest) Receive() (Response, error) { if !r.sent { return GetStudioModeStatusResponse{}, ErrNotSent } @@ -79,7 +79,7 @@ func (r GetStudioModeStatusRequest) Receive() (GetStudioModeStatusResponse, erro } // SendReceive sends the request then immediately waits for the response. -func (r GetStudioModeStatusRequest) SendReceive(c Client) (GetStudioModeStatusResponse, error) { +func (r GetStudioModeStatusRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetStudioModeStatusResponse{}, err } @@ -146,7 +146,7 @@ func (r *GetPreviewSceneRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetPreviewSceneRequest) Receive() (GetPreviewSceneResponse, error) { +func (r GetPreviewSceneRequest) Receive() (Response, error) { if !r.sent { return GetPreviewSceneResponse{}, ErrNotSent } @@ -170,7 +170,7 @@ func (r GetPreviewSceneRequest) Receive() (GetPreviewSceneResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r GetPreviewSceneRequest) SendReceive(c Client) (GetPreviewSceneResponse, error) { +func (r GetPreviewSceneRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetPreviewSceneResponse{}, err } @@ -243,7 +243,7 @@ func (r *SetPreviewSceneRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetPreviewSceneRequest) Receive() (SetPreviewSceneResponse, error) { +func (r SetPreviewSceneRequest) Receive() (Response, error) { if !r.sent { return SetPreviewSceneResponse{}, ErrNotSent } @@ -267,7 +267,7 @@ func (r SetPreviewSceneRequest) Receive() (SetPreviewSceneResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r SetPreviewSceneRequest) SendReceive(c Client) (SetPreviewSceneResponse, error) { +func (r SetPreviewSceneRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetPreviewSceneResponse{}, err } @@ -348,7 +348,7 @@ func (r *TransitionToProgramRequest) Send(c Client) error { } // Receive waits for the response. -func (r TransitionToProgramRequest) Receive() (TransitionToProgramResponse, error) { +func (r TransitionToProgramRequest) Receive() (Response, error) { if !r.sent { return TransitionToProgramResponse{}, ErrNotSent } @@ -372,7 +372,7 @@ func (r TransitionToProgramRequest) Receive() (TransitionToProgramResponse, erro } // SendReceive sends the request then immediately waits for the response. -func (r TransitionToProgramRequest) SendReceive(c Client) (TransitionToProgramResponse, error) { +func (r TransitionToProgramRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return TransitionToProgramResponse{}, err } @@ -435,7 +435,7 @@ func (r *EnableStudioModeRequest) Send(c Client) error { } // Receive waits for the response. -func (r EnableStudioModeRequest) Receive() (EnableStudioModeResponse, error) { +func (r EnableStudioModeRequest) Receive() (Response, error) { if !r.sent { return EnableStudioModeResponse{}, ErrNotSent } @@ -459,7 +459,7 @@ func (r EnableStudioModeRequest) Receive() (EnableStudioModeResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r EnableStudioModeRequest) SendReceive(c Client) (EnableStudioModeResponse, error) { +func (r EnableStudioModeRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return EnableStudioModeResponse{}, err } @@ -522,7 +522,7 @@ func (r *DisableStudioModeRequest) Send(c Client) error { } // Receive waits for the response. -func (r DisableStudioModeRequest) Receive() (DisableStudioModeResponse, error) { +func (r DisableStudioModeRequest) Receive() (Response, error) { if !r.sent { return DisableStudioModeResponse{}, ErrNotSent } @@ -546,7 +546,7 @@ func (r DisableStudioModeRequest) Receive() (DisableStudioModeResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r DisableStudioModeRequest) SendReceive(c Client) (DisableStudioModeResponse, error) { +func (r DisableStudioModeRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return DisableStudioModeResponse{}, err } @@ -562,7 +562,7 @@ type DisableStudioModeResponse struct { _response `json:",squash"` } -// ToggleStudioModeRequest : Toggles Studio Mode. +// ToggleStudioModeRequest : Toggles Studio Mode (depending on the current state of studio mode). // // Since obs-websocket version: 4.1.0. // @@ -609,7 +609,7 @@ func (r *ToggleStudioModeRequest) Send(c Client) error { } // Receive waits for the response. -func (r ToggleStudioModeRequest) Receive() (ToggleStudioModeResponse, error) { +func (r ToggleStudioModeRequest) Receive() (Response, error) { if !r.sent { return ToggleStudioModeResponse{}, ErrNotSent } @@ -633,7 +633,7 @@ func (r ToggleStudioModeRequest) Receive() (ToggleStudioModeResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r ToggleStudioModeRequest) SendReceive(c Client) (ToggleStudioModeResponse, error) { +func (r ToggleStudioModeRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return ToggleStudioModeResponse{}, err } diff --git a/requests_transitions.go b/requests_transitions.go index 8ad30f6..1682bc1 100644 --- a/requests_transitions.go +++ b/requests_transitions.go @@ -55,7 +55,7 @@ func (r *GetTransitionListRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetTransitionListRequest) Receive() (GetTransitionListResponse, error) { +func (r GetTransitionListRequest) Receive() (Response, error) { if !r.sent { return GetTransitionListResponse{}, ErrNotSent } @@ -79,7 +79,7 @@ func (r GetTransitionListRequest) Receive() (GetTransitionListResponse, error) { } // SendReceive sends the request then immediately waits for the response. -func (r GetTransitionListRequest) SendReceive(c Client) (GetTransitionListResponse, error) { +func (r GetTransitionListRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetTransitionListResponse{}, err } @@ -151,7 +151,7 @@ func (r *GetCurrentTransitionRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetCurrentTransitionRequest) Receive() (GetCurrentTransitionResponse, error) { +func (r GetCurrentTransitionRequest) Receive() (Response, error) { if !r.sent { return GetCurrentTransitionResponse{}, ErrNotSent } @@ -175,7 +175,7 @@ func (r GetCurrentTransitionRequest) Receive() (GetCurrentTransitionResponse, er } // SendReceive sends the request then immediately waits for the response. -func (r GetCurrentTransitionRequest) SendReceive(c Client) (GetCurrentTransitionResponse, error) { +func (r GetCurrentTransitionRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetCurrentTransitionResponse{}, err } @@ -248,7 +248,7 @@ func (r *SetCurrentTransitionRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetCurrentTransitionRequest) Receive() (SetCurrentTransitionResponse, error) { +func (r SetCurrentTransitionRequest) Receive() (Response, error) { if !r.sent { return SetCurrentTransitionResponse{}, ErrNotSent } @@ -272,7 +272,7 @@ func (r SetCurrentTransitionRequest) Receive() (SetCurrentTransitionResponse, er } // SendReceive sends the request then immediately waits for the response. -func (r SetCurrentTransitionRequest) SendReceive(c Client) (SetCurrentTransitionResponse, error) { +func (r SetCurrentTransitionRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetCurrentTransitionResponse{}, err } @@ -339,7 +339,7 @@ func (r *SetTransitionDurationRequest) Send(c Client) error { } // Receive waits for the response. -func (r SetTransitionDurationRequest) Receive() (SetTransitionDurationResponse, error) { +func (r SetTransitionDurationRequest) Receive() (Response, error) { if !r.sent { return SetTransitionDurationResponse{}, ErrNotSent } @@ -363,7 +363,7 @@ func (r SetTransitionDurationRequest) Receive() (SetTransitionDurationResponse, } // SendReceive sends the request then immediately waits for the response. -func (r SetTransitionDurationRequest) SendReceive(c Client) (SetTransitionDurationResponse, error) { +func (r SetTransitionDurationRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return SetTransitionDurationResponse{}, err } @@ -426,7 +426,7 @@ func (r *GetTransitionDurationRequest) Send(c Client) error { } // Receive waits for the response. -func (r GetTransitionDurationRequest) Receive() (GetTransitionDurationResponse, error) { +func (r GetTransitionDurationRequest) Receive() (Response, error) { if !r.sent { return GetTransitionDurationResponse{}, ErrNotSent } @@ -450,7 +450,7 @@ func (r GetTransitionDurationRequest) Receive() (GetTransitionDurationResponse, } // SendReceive sends the request then immediately waits for the response. -func (r GetTransitionDurationRequest) SendReceive(c Client) (GetTransitionDurationResponse, error) { +func (r GetTransitionDurationRequest) SendReceive(c Client) (Response, error) { if err := r.Send(c); err != nil { return GetTransitionDurationResponse{}, err } @@ -468,3 +468,481 @@ type GetTransitionDurationResponse struct { TransitionDuration int `json:"transition-duration"` _response `json:",squash"` } + +// GetTransitionPositionRequest : Get the position of the current transition. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#gettransitionposition +type GetTransitionPositionRequest struct { + _request `json:",squash"` + response chan GetTransitionPositionResponse +} + +// NewGetTransitionPositionRequest returns a new GetTransitionPositionRequest. +func NewGetTransitionPositionRequest() GetTransitionPositionRequest { + return GetTransitionPositionRequest{ + _request{ + ID_: GetMessageID(), + Type_: "GetTransitionPosition", + err: make(chan error, 1), + }, + make(chan GetTransitionPositionResponse, 1), + } +} + +// Send sends the request. +func (r *GetTransitionPositionRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp GetTransitionPositionResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r GetTransitionPositionRequest) Receive() (Response, error) { + if !r.sent { + return GetTransitionPositionResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetTransitionPositionResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetTransitionPositionResponse{}, err + case <-time.After(receiveTimeout): + return GetTransitionPositionResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r GetTransitionPositionRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return GetTransitionPositionResponse{}, err + } + return r.Receive() +} + +// GetTransitionPositionResponse : Response for GetTransitionPositionRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#gettransitionposition +type GetTransitionPositionResponse struct { + // current transition position. + // This value will be between 0.0 and 1.0. + // Note: Transition returns 1.0 when not active. + // Required: Yes. + Position float64 `json:"position"` + _response `json:",squash"` +} + +// GetTransitionSettingsRequest : Get the current settings of a transition. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#gettransitionsettings +type GetTransitionSettingsRequest struct { + // Transition name. + // Required: Yes. + TransitionName string `json:"transitionName"` + _request `json:",squash"` + response chan GetTransitionSettingsResponse +} + +// NewGetTransitionSettingsRequest returns a new GetTransitionSettingsRequest. +func NewGetTransitionSettingsRequest(transitionName string) GetTransitionSettingsRequest { + return GetTransitionSettingsRequest{ + transitionName, + _request{ + ID_: GetMessageID(), + Type_: "GetTransitionSettings", + err: make(chan error, 1), + }, + make(chan GetTransitionSettingsResponse, 1), + } +} + +// Send sends the request. +func (r *GetTransitionSettingsRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp GetTransitionSettingsResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r GetTransitionSettingsRequest) Receive() (Response, error) { + if !r.sent { + return GetTransitionSettingsResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetTransitionSettingsResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return GetTransitionSettingsResponse{}, err + case <-time.After(receiveTimeout): + return GetTransitionSettingsResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r GetTransitionSettingsRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return GetTransitionSettingsResponse{}, err + } + return r.Receive() +} + +// GetTransitionSettingsResponse : Response for GetTransitionSettingsRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#gettransitionsettings +type GetTransitionSettingsResponse struct { + // Current transition settings. + // Required: Yes. + TransitionSettings map[string]interface{} `json:"transitionSettings"` + _response `json:",squash"` +} + +// SetTransitionSettingsRequest : Change the current settings of a transition. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#settransitionsettings +type SetTransitionSettingsRequest struct { + // Transition name. + // Required: Yes. + TransitionName string `json:"transitionName"` + // Transition settings (they can be partial). + // Required: Yes. + TransitionSettings map[string]interface{} `json:"transitionSettings"` + _request `json:",squash"` + response chan SetTransitionSettingsResponse +} + +// NewSetTransitionSettingsRequest returns a new SetTransitionSettingsRequest. +func NewSetTransitionSettingsRequest( + transitionName string, + transitionSettings map[string]interface{}, +) SetTransitionSettingsRequest { + return SetTransitionSettingsRequest{ + transitionName, + transitionSettings, + _request{ + ID_: GetMessageID(), + Type_: "SetTransitionSettings", + err: make(chan error, 1), + }, + make(chan SetTransitionSettingsResponse, 1), + } +} + +// Send sends the request. +func (r *SetTransitionSettingsRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp SetTransitionSettingsResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r SetTransitionSettingsRequest) Receive() (Response, error) { + if !r.sent { + return SetTransitionSettingsResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return SetTransitionSettingsResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return SetTransitionSettingsResponse{}, err + case <-time.After(receiveTimeout): + return SetTransitionSettingsResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r SetTransitionSettingsRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return SetTransitionSettingsResponse{}, err + } + return r.Receive() +} + +// SetTransitionSettingsResponse : Response for SetTransitionSettingsRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#settransitionsettings +type SetTransitionSettingsResponse struct { + // Updated transition settings. + // Required: Yes. + TransitionSettings map[string]interface{} `json:"transitionSettings"` + _response `json:",squash"` +} + +// ReleaseTBarRequest : Release the T-Bar (like a user releasing their mouse button after moving it). +// *YOU MUST CALL THIS if you called `SetTBarPosition` with the `release` parameter set to `false`.*. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#releasetbar +type ReleaseTBarRequest struct { + _request `json:",squash"` + response chan ReleaseTBarResponse +} + +// NewReleaseTBarRequest returns a new ReleaseTBarRequest. +func NewReleaseTBarRequest() ReleaseTBarRequest { + return ReleaseTBarRequest{ + _request{ + ID_: GetMessageID(), + Type_: "ReleaseTBar", + err: make(chan error, 1), + }, + make(chan ReleaseTBarResponse, 1), + } +} + +// Send sends the request. +func (r *ReleaseTBarRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp ReleaseTBarResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r ReleaseTBarRequest) Receive() (Response, error) { + if !r.sent { + return ReleaseTBarResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return ReleaseTBarResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return ReleaseTBarResponse{}, err + case <-time.After(receiveTimeout): + return ReleaseTBarResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r ReleaseTBarRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return ReleaseTBarResponse{}, err + } + return r.Receive() +} + +// ReleaseTBarResponse : Response for ReleaseTBarRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#releasetbar +type ReleaseTBarResponse struct { + _response `json:",squash"` +} + +// SetTBarPositionRequest : +// +// If your code needs to perform multiple successive T-Bar moves (e.g. : in an animation, or in response to a user moving a T-Bar control in your User Interface), set `release` to false and call `ReleaseTBar` later once the animation/interaction is over. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#settbarposition +type SetTBarPositionRequest struct { + // T-Bar position. + // This value must be between 0.0 and 1.0. + // Required: Yes. + Position float64 `json:"position"` + // Whether or not the T-Bar gets released automatically after setting its new position (like a user releasing their mouse button after moving the T-Bar). + // Call `ReleaseTBar` manually if you set `release` to false. + // Defaults to true. + // Required: No. + Release bool `json:"release"` + _request `json:",squash"` + response chan SetTBarPositionResponse +} + +// NewSetTBarPositionRequest returns a new SetTBarPositionRequest. +func NewSetTBarPositionRequest( + position float64, + release bool, +) SetTBarPositionRequest { + return SetTBarPositionRequest{ + position, + release, + _request{ + ID_: GetMessageID(), + Type_: "SetTBarPosition", + err: make(chan error, 1), + }, + make(chan SetTBarPositionResponse, 1), + } +} + +// Send sends the request. +func (r *SetTBarPositionRequest) Send(c Client) error { + if r.sent { + return ErrAlreadySent + } + future, err := c.SendRequest(r) + if err != nil { + return err + } + r.sent = true + go func() { + m := <-future + var resp SetTBarPositionResponse + if err = mapToStruct(m, &resp); err != nil { + r.err <- err + } else if resp.Status() != StatusOK { + r.err <- errors.New(resp.Error()) + } else { + r.response <- resp + } + }() + return nil +} + +// Receive waits for the response. +func (r SetTBarPositionRequest) Receive() (Response, error) { + if !r.sent { + return SetTBarPositionResponse{}, ErrNotSent + } + if receiveTimeout == 0 { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return SetTBarPositionResponse{}, err + } + } else { + select { + case resp := <-r.response: + return resp, nil + case err := <-r.err: + return SetTBarPositionResponse{}, err + case <-time.After(receiveTimeout): + return SetTBarPositionResponse{}, ErrReceiveTimeout + } + } +} + +// SendReceive sends the request then immediately waits for the response. +func (r SetTBarPositionRequest) SendReceive(c Client) (Response, error) { + if err := r.Send(c); err != nil { + return SetTBarPositionResponse{}, err + } + return r.Receive() +} + +// SetTBarPositionResponse : Response for SetTBarPositionRequest. +// +// Since obs-websocket version: 4.9.0. +// +// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#settbarposition +type SetTBarPositionResponse struct { + _response `json:",squash"` +} diff --git a/types.go b/types.go index a192ef5..00a93c2 100644 --- a/types.go +++ b/types.go @@ -13,8 +13,11 @@ type OBSStats struct { } type Scene struct { - Name string `json:"name"` - Sources []*SceneItem `json:"sources"` + Name string `json:"name"` +} + +type ScenesCollection struct { + Name string `json:"sc-name"` } type SceneItem struct {