obsws-ruby/lib/obsws/req.rb
onyx-and-iris aafcd185d0 patch bump
add full request payload to logger.

raise OBSWSError if auth enabled but no password provided

add example tasks to rake file

add logging section to README
2022-11-25 17:57:56 +00:00

904 lines
25 KiB
Ruby

require "waitutil"
require_relative "base"
require_relative "error"
require_relative "util"
require_relative "mixin"
module OBSWS
module Requests
class Client
include Error
include Mixin::TearDown
include Mixin::OPCodes
def initialize(**kwargs)
@base_client = Base.new(**kwargs)
LOGGER.info("#{self} succesfully identified with server")
@base_client.add_observer(self)
@response = { requestId: 0 }
end
def to_s
"#{self.class.name.split("::").last(2).join("::")}"
end
def run
yield
ensure
close
WaitUtil.wait_for_condition(
"driver to close",
delay_sec: 0.01,
timeout_sec: 1
) { @base_client.closed }
end
def update(op_code, data)
@response = data if op_code == Mixin::OPCodes::REQUESTRESPONSE
end
def call(req, data = nil)
id = rand(1..1000)
@base_client.req(id, req, data)
WaitUtil.wait_for_condition(
"reponse id to match request id",
delay_sec: 0.001,
timeout_sec: 3
) { @response[:requestId] == id }
if !@response[:requestStatus][:result]
error = [
"Request #{@response[:requestType]} returned code #{@response[:requestStatus][:code]}"
]
if @response[:requestStatus].key?(:comment)
error += ["With message: #{@response[:requestStatus][:comment]}"]
end
raise OBSWSError.new(error.join("\n"))
end
@response[:responseData]
rescue WaitUtil::TimeoutError
msg = "no response with matching id received"
LOGGER.error(msg)
raise OBSWSError.new(msg)
end
def get_version
resp = call("GetVersion")
Mixin::Response.new(resp, resp.keys)
end
def get_stats
resp = call("GetStats")
Mixin::Response.new(resp, resp.keys)
end
def broadcast_custom_event(data)
call("BroadcastCustomEvent", data)
end
def call_vendor_request(name, type_, data = nil)
payload = { vendorName: name, requestType: type_ }
payload[:requestData] = data if data
resp = call("CallVendorRequest", payload)
Mixin::Response.new(resp, resp.keys)
end
def get_hotkey_list
resp = call("GetHotkeyList")
Mixin::Response.new(resp, resp.keys)
end
def trigger_hotkey_by_name(name)
payload = { hotkeyName: name }
call("TriggerHotkeyByName", payload)
end
def trigger_hotkey_by_key_sequence(
key_id,
press_shift,
press_ctrl,
press_alt,
press_cmd
)
payload = {
keyId: key_id,
keyModifiers: {
shift: press_shift,
control: press_ctrl,
alt: press_alt,
cmd: press_cmd
}
}
call("TriggerHotkeyByKeySequence", payload)
end
def sleep(sleep_millis = nil, sleep_frames = nil)
payload = { sleepMillis: sleep_millis, sleepFrames: sleep_frames }
call("Sleep", payload)
end
def get_persistent_data(realm, slot_name)
payload = { realm: realm, slotName: slot_name }
resp = call("GetPersistentData", payload)
Mixin::Response.new(resp, resp.keys)
end
def set_persistent_data(realm, slot_name, slot_value)
payload = { realm: realm, slotName: slot_name, slotValue: slot_value }
call("SetPersistentData", payload)
end
def get_scene_collection_list
resp = call("GetSceneCollectionList")
Mixin::Response.new(resp, resp.keys)
end
def set_current_scene_collection(name)
payload = { sceneCollectionName: name }
call("SetCurrentSceneCollection", payload)
end
def create_scene_collection(name)
payload = { sceneCollectionName: name }
call("CreateSceneCollection", payload)
end
def get_profile_list
resp = call("GetProfileList")
Mixin::Response.new(resp, resp.keys)
end
def set_current_profile(name)
payload = { profileName: name }
call("SetCurrentProfile", payload)
end
def create_profile(name)
payload = { profileName: name }
call("CreateProfile", payload)
end
def remove_profile(name)
payload = { profileName: name }
call("RemoveProfile", payload)
end
def get_profile_parameter(category, name)
payload = { parameterCategory: category, parameterName: name }
resp = call("GetProfileParameter", payload)
Mixin::Response.new(resp, resp.keys)
end
def set_profile_parameter(category, name, value)
payload = {
parameterCategory: category,
parameterName: name,
parameterValue: value
}
call("SetProfileParameter", payload)
end
def get_video_settings
resp = call("GetVideoSettings")
Mixin::Response.new(resp, resp.keys)
end
def set_video_settings(
numerator,
denominator,
base_width,
base_height,
out_width,
out_height
)
payload = {
fpsNumerator: numerator,
fpsDenominator: denominator,
baseWidth: base_width,
baseHeight: base_height,
outputWidth: out_width,
outputHeight: out_height
}
call("SetVideoSettings", payload)
end
def get_stream_service_settings
resp = call("GetStreamServiceSettings")
Mixin::Response.new(resp, resp.keys)
end
def set_stream_service_settings(ss_type, ss_settings)
payload = {
streamServiceType: ss_type,
streamServiceSettings: ss_settings
}
call("SetStreamServiceSettings", payload)
end
def get_record_directory
resp = call("GetRecordDirectory")
Mixin::Response.new(resp, resp.keys)
end
def get_source_active(name)
payload = { sourceName: name }
resp = call("GetSourceActive", payload)
Mixin::Response.new(resp, resp.keys)
end
def get_source_screenshot(name, img_format, width, height, quality)
payload = {
sourceName: name,
imageFormat: img_format,
imageWidth: width,
imageHeight: height,
imageCompressionQuality: quality
}
resp = call("GetSourceScreenshot", payload)
Mixin::Response.new(resp, resp.keys)
end
def save_source_screenshot(
name,
img_format,
file_path,
width,
height,
quality
)
payload = {
sourceName: name,
imageFormat: img_format,
imageFilePath: file_path,
imageWidth: width,
imageHeight: height,
imageCompressionQuality: quality
}
resp = call("SaveSourceScreenshot", payload)
Mixin::Response.new(resp, resp.keys)
end
def get_scene_list
resp = call("GetSceneList")
Mixin::Response.new(resp, resp.keys)
end
def get_group_list
resp = call("GetGroupList")
Mixin::Response.new(resp, resp.keys)
end
def get_current_program_scene
resp = call("GetCurrentProgramScene")
Mixin::Response.new(resp, resp.keys)
end
def set_current_program_scene(name)
payload = { sceneName: name }
call("SetCurrentProgramScene", payload)
end
def get_current_preview_scene
resp = call("GetCurrentPreviewScene")
Mixin::Response.new(resp, resp.keys)
end
def set_current_preview_scene(name)
payload = { sceneName: name }
call("SetCurrentPreviewScene", payload)
end
def create_scene(name)
payload = { sceneName: name }
call("CreateScene", payload)
end
def remove_scene(name)
payload = { sceneName: name }
call("RemoveScene", payload)
end
def set_scene_name(old_name, new_name)
payload = { sceneName: old_name, newSceneName: new_name }
call("SetSceneName", payload)
end
def get_scene_scene_transition_override(name)
payload = { sceneName: name }
resp = call("GetSceneSceneTransitionOverride", payload)
Mixin::Response.new(resp, resp.keys)
end
def set_scene_scene_transition_override(scene_name, tr_name, tr_duration)
payload = {
sceneName: scene_name,
transitionName: tr_name,
transitionDuration: tr_duration
}
call("SetSceneSceneTransitionOverride", payload)
end
def get_input_list(kind = nil)
payload = { inputKind: kind }
resp = call("GetInputList", payload)
Mixin::Response.new(resp, resp.keys)
end
def get_input_kind_list(unversioned)
payload = { unversioned: unversioned }
resp = call("GetInputKindList", payload)
Mixin::Response.new(resp, resp.keys)
end
def get_special_inputs
resp = call("GetSpecialInputs")
Mixin::Response.new(resp, resp.keys)
end
def create_input(
scene_name,
input_name,
input_kind,
input_settings,
scene_item_enabled
)
payload = {
sceneName: scene_name,
inputName: input_name,
inputKind: input_kind,
inputSettings: input_settings,
sceneItemEnabled: scene_item_enabled
}
resp = call("CreateInput", payload)
Mixin::Response.new(resp, resp.keys)
end
def remove_input(name)
payload = { inputName: name }
call("RemoveInput", payload)
end
def set_input_name(old_name, new_name)
payload = { inputName: old_name, newInputName: new_name }
call("SetInputName", payload)
end
def get_input_default_settings(kind)
payload = { inputKind: kind }
resp = call("GetInputDefaultSettings", payload)
Mixin::Response.new(resp, resp.keys)
end
def get_input_settings(name)
payload = { inputName: name }
resp = call("GetInputSettings", payload)
Mixin::Response.new(resp, resp.keys)
end
def set_input_settings(name, settings, overlay)
payload = { inputName: name, inputSettings: settings, overlay: overlay }
call("SetInputSettings", payload)
end
def get_input_mute(name)
payload = { inputName: name }
resp = call("GetInputMute", payload)
Mixin::Response.new(resp, resp.keys)
end
def set_input_mute(name, muted)
payload = { inputName: name, inputMuted: muted }
call("SetInputMute", payload)
end
def toggle_input_mute(name)
payload = { inputName: name }
resp = call("ToggleInputMute", payload)
Mixin::Response.new(resp, resp.keys)
end
def get_input_volume(name)
payload = { inputName: name }
resp = call("GetInputVolume", payload)
Mixin::Response.new(resp, resp.keys)
end
def set_input_volume(name, vol_mul = nil, vol_db = nil)
payload = {
inputName: name,
inputVolumeMul: vol_mul,
inputVolumeDb: vol_db
}
call("SetInputVolume", payload)
end
def get_input_audio_balance(name)
payload = { inputName: name }
resp = call("GetInputAudioBalance", payload)
Mixin::Response.new(resp, resp.keys)
end
def set_input_audio_balance(name, balance)
payload = { inputName: name, inputAudioBalance: balance }
call("SetInputAudioBalance", payload)
end
def get_input_audio_sync_offset(name)
payload = { inputName: name }
resp = call("GetInputAudioSyncOffset", payload)
Mixin::Response.new(resp, resp.keys)
end
def set_input_audio_sync_offset(name, offset)
payload = { inputName: name, inputAudioSyncOffset: offset }
call("SetInputAudioSyncOffset", payload)
end
def get_input_audio_monitor_type(name)
payload = { inputName: name }
resp = call("GetInputAudioMonitorType", payload)
Mixin::Response.new(resp, resp.keys)
end
def set_input_audio_monitor_type(name, mon_type)
payload = { inputName: name, monitorType: mon_type }
call("SetInputAudioMonitorType", payload)
end
def get_input_audio_tracks(name)
payload = { inputName: name }
resp = call("GetInputAudioTracks", payload)
Mixin::Response.new(resp, resp.keys)
end
def set_input_audio_tracks(name, track)
payload = { inputName: name, inputAudioTracks: track }
call("SetInputAudioTracks", payload)
end
def get_input_properties_list_property_items(input_name, prop_name)
payload = { inputName: input_name, propertyName: prop_name }
resp = call("GetInputPropertiesListPropertyItems", payload)
Mixin::Response.new(resp, resp.keys)
end
def press_input_properties_button(input_name, prop_name)
payload = { inputName: input_name, propertyName: prop_name }
call("PressInputPropertiesButton", payload)
end
def get_transition_kind_list
resp = call("GetTransitionKindList")
Mixin::Response.new(resp, resp.keys)
end
def get_scene_transition_list
resp = call("GetSceneTransitionList")
Mixin::Response.new(resp, resp.keys)
end
def get_current_scene_transition
resp = call("GetCurrentSceneTransition")
Mixin::Response.new(resp, resp.keys)
end
def set_current_scene_transition(name)
payload = { transitionName: name }
call("SetCurrentSceneTransition", payload)
end
def set_current_scene_transition_duration(duration)
payload = { transitionDuration: duration }
call("SetCurrentSceneTransitionDuration", payload)
end
def set_current_scene_transition_settings(settings, overlay = nil)
payload = { transitionSettings: settings, overlay: overlay }
call("SetCurrentSceneTransitionSettings", payload)
end
def get_current_scene_transition_cursor
resp = call("GetCurrentSceneTransitionCursor")
Mixin::Response.new(resp, resp.keys)
end
def trigger_studio_mode_transition
call("TriggerStudioModeTransition")
end
def set_t_bar_position(pos, release = nil)
payload = { position: pos, release: release }
call("SetTBarPosition", payload)
end
def get_source_filter_list(name)
payload = { sourceName: name }
resp = call("GetSourceFilterList", payload)
Mixin::Response.new(resp, resp.keys)
end
def get_source_filter_default_settings(kind)
payload = { filterKind: kind }
resp = call("GetSourceFilterDefaultSettings", payload)
Mixin::Response.new(resp, resp.keys)
end
def create_source_filter(
source_name,
filter_name,
filter_kind,
filter_settings = nil
)
payload = {
sourceName: source_name,
filterName: filter_name,
filterKind: filter_kind,
filterSettings: filter_settings
}
call("CreateSourceFilter", payload)
end
def remove_source_filter(source_name, filter_name)
payload = { sourceName: source_name, filterName: filter_name }
call("RemoveSourceFilter", payload)
end
def set_source_filter_name(source_name, old_filter_name, new_filter_name)
payload = {
sourceName: source_name,
filterName: old_filter_name,
newFilterName: new_filter_name
}
call("SetSourceFilterName", payload)
end
def get_source_filter(source_name, filter_name)
payload = { sourceName: source_name, filterName: filter_name }
resp = call("GetSourceFilter", payload)
Mixin::Response.new(resp, resp.keys)
end
def set_source_filter_index(source_name, filter_name, filter_index)
payload = {
sourceName: source_name,
filterName: filter_name,
filterIndex: filter_index
}
call("SetSourceFilterIndex", payload)
end
def set_source_filter_settings(
source_name,
filter_name,
settings,
overlay = nil
)
payload = {
sourceName: source_name,
filterName: filter_name,
filterSettings: settings,
overlay: overlay
}
call("SetSourceFilterSettings", payload)
end
def set_source_filter_enabled(source_name, filter_name, enabled)
payload = {
sourceName: source_name,
filterName: filter_name,
filterEnabled: enabled
}
call("SetSourceFilterEnabled", payload)
end
def get_scene_item_list(name)
payload = { sceneName: name }
resp = call("GetSceneItemList", payload)
Mixin::Response.new(resp, resp.keys)
end
def get_group_scene_item_list(name)
payload = { sceneName: name }
resp = call("GetGroupSceneItemList", payload)
Mixin::Response.new(resp, resp.keys)
end
def get_scene_item_id(scene_name, source_name, offset = nil)
payload = {
sceneName: scene_name,
sourceName: source_name,
searchOffset: offset
}
resp = call("GetSceneItemId", payload)
Mixin::Response.new(resp, resp.keys)
end
def create_scene_item(scene_name, source_name, enabled = nil)
payload = {
sceneName: scene_name,
sourceName: source_name,
sceneItemEnabled: enabled
}
resp = call("CreateSceneItem", payload)
Mixin::Response.new(resp, resp.keys)
end
def remove_scene_item(scene_name, item_id)
payload = { sceneName: scene_name, sceneItemId: item_id }
call("RemoveSceneItem", payload)
end
def duplicate_scene_item(scene_name, item_id, dest_scene_name = nil)
payload = {
sceneName: scene_name,
sceneItemId: item_id,
destinationSceneName: dest_scene_name
}
resp = call("DuplicateSceneItem", payload)
Mixin::Response.new(resp, resp.keys)
end
def get_scene_item_transform(scene_name, item_id)
payload = { sceneName: scene_name, sceneItemId: item_id }
resp = call("GetSceneItemTransform", payload)
Mixin::Response.new(resp, resp.keys)
end
def set_scene_item_transform(scene_name, item_id, transform)
payload = {
sceneName: scene_name,
sceneItemId: item_id,
sceneItemTransform: transform
}
call("SetSceneItemTransform", payload)
end
def get_scene_item_enabled(scene_name, item_id)
payload = { sceneName: scene_name, sceneItemId: item_id }
resp = call("GetSceneItemEnabled", payload)
Mixin::Response.new(resp, resp.keys)
end
def set_scene_item_enabled(scene_name, item_id, enabled)
payload = {
sceneName: scene_name,
sceneItemId: item_id,
sceneItemEnabled: enabled
}
call("SetSceneItemEnabled", payload)
end
def get_scene_item_locked(scene_name, item_id)
payload = { sceneName: scene_name, sceneItemId: item_id }
resp = call("GetSceneItemLocked", payload)
Mixin::Response.new(resp, resp.keys)
end
def set_scene_item_locked(scene_name, item_id, locked)
payload = {
sceneName: scene_name,
sceneItemId: item_id,
sceneItemLocked: locked
}
call("SetSceneItemLocked", payload)
end
def get_scene_item_index(scene_name, item_id)
payload = { sceneName: scene_name, sceneItemId: item_id }
resp = call("GetSceneItemIndex", payload)
Mixin::Response.new(resp, resp.keys)
end
def set_scene_item_index(scene_name, item_id, item_index)
payload = {
sceneName: scene_name,
sceneItemId: item_id,
sceneItemLocked: item_index
}
call("SetSceneItemIndex", payload)
end
def get_scene_item_blend_mode(scene_name, item_id)
payload = { sceneName: scene_name, sceneItemId: item_id }
resp = call("GetSceneItemBlendMode", payload)
Mixin::Response.new(resp, resp.keys)
end
def set_scene_item_blend_mode(scene_name, item_id, blend)
payload = {
sceneName: scene_name,
sceneItemId: item_id,
sceneItemBlendMode: blend
}
call("SetSceneItemBlendMode", payload)
end
def get_virtual_cam_status
resp = call("GetVirtualCamStatus")
Mixin::Response.new(resp, resp.keys)
end
def toggle_virtual_cam
resp = call("ToggleVirtualCam")
Mixin::Response.new(resp, resp.keys)
end
def start_virtual_cam
call("StartVirtualCam")
end
def stop_virtual_cam
call("StopVirtualCam")
end
def get_replay_buffer_status
resp = call("GetReplayBufferStatus")
Mixin::Response.new(resp, resp.keys)
end
def toggle_replay_buffer
resp = call("ToggleReplayBuffer")
Mixin::Response.new(resp, resp.keys)
end
def start_replay_buffer
call("StartReplayBuffer")
end
def stop_replay_buffer
call("StopReplayBuffer")
end
def save_replay_buffer
call("SaveReplayBuffer")
end
def get_last_replay_buffer_replay
resp = call("GetLastReplayBufferReplay")
Mixin::Response.new(resp, resp.keys)
end
def get_output_list
resp = call("GetOutputList")
Mixin::Response.new(resp, resp.keys)
end
def get_output_status(name)
payload = { outputName: name }
resp = call("GetOutputStatus", payload)
Mixin::Response.new(resp, resp.keys)
end
def toggle_output(name)
payload = { outputName: name }
resp = call("ToggleOutput", payload)
Mixin::Response.new(resp, resp.keys)
end
def start_output(name)
payload = { outputName: name }
call("StartOutput", payload)
end
def stop_output(name)
payload = { outputName: name }
call("StopOutput", payload)
end
def get_output_settings(name)
payload = { outputName: name }
resp = call("GetOutputSettings", payload)
Mixin::Response.new(resp, resp.keys)
end
def set_output_settings(name, settings)
payload = { outputName: name, outputSettings: settings }
call("SetOutputSettings", payload)
end
def get_stream_status
resp = call("GetStreamStatus")
Mixin::Response.new(resp, resp.keys)
end
def toggle_stream
resp = call("ToggleStream")
Mixin::Response.new(resp, resp.keys)
end
def start_stream
call("StartStream")
end
def stop_stream
call("StopStream")
end
def send_stream_caption(caption)
call("SendStreamCaption")
end
def get_record_status
resp = call("GetRecordStatus")
Mixin::Response.new(resp, resp.keys)
end
def toggle_record
call("ToggleRecord")
end
def start_record
call("StartRecord")
end
def stop_record
resp = call("StopRecord")
Mixin::Response.new(resp, resp.keys)
end
def toggle_record_pause
call("ToggleRecordPause")
end
def pause_record
call("PauseRecord")
end
def resume_record
call("ResumeRecord")
end
def get_media_input_status(name)
payload = { inputName: name }
resp = call("GetMediaInputStatus", payload)
Mixin::Response.new(resp, resp.keys)
end
def set_media_input_cursor(name, cursor)
payload = { inputName: name, mediaCursor: cursor }
call("SetMediaInputCursor", payload)
end
def offset_media_input_cursor(name, offset)
payload = { inputName: name, mediaCursorOffset: offset }
call("OffsetMediaInputCursor", payload)
end
def trigger_media_input_action(name, action)
payload = { inputName: name, mediaAction: action }
call("TriggerMediaInputAction", payload)
end
def get_studio_mode_enabled
resp = call("GetStudioModeEnabled")
Mixin::Response.new(resp, resp.keys)
end
def set_studio_mode_enabled(enabled)
payload = { studioModeEnabled: enabled }
call("SetStudioModeEnabled", payload)
end
def open_input_properties_dialog(name)
payload = { inputName: name }
call("OpenInputPropertiesDialog", payload)
end
def open_input_filters_dialog(name)
payload = { inputName: name }
call("OpenInputFiltersDialog", payload)
end
def open_input_interact_dialog(name)
payload = { inputName: name }
call("OpenInputInteractDialog", payload)
end
def get_monitor_list
resp = call("GetMonitorList")
Mixin::Response.new(resp, resp.keys)
end
end
end
end