Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ Contributions are sorted by their number of commits

Contributors:
Grant Likely
Fabio Ferrari
Norihiro Kamae
Luuk Verhagen
Jonata Bolzan Loss
Fabio Ferrari
Jim Hauxwell
Jason Lanclos
Eric Schmidt
Anthony Roberts
106 changes: 106 additions & 0 deletions data/locale/en-US.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
PTZ.Source="Source"
PTZ.Cameras="Cameras"
PTZ.Devices="Devices"
PTZ.AddDevice.Tooltip="Add Device"
PTZ.RemoveDevice.Tooltip="Remove Device"
PTZ.About.Info="<html><head/><body><p>OBS PTZ Controls Plugin<br>%1<br>By Grant Likely &lt;grant.likely@secretlab.ca&gt;</p><p><a href=\"https://obsproject.com/forum/resources/ptz-controls.1284/\"><span style=\" text-decoration: underline; color:#7f7fff;\">https://obsproject.com/forum/resources/ptz-controls.1284/</a></p><p><a href=\"https://github.com/glikely/obs-ptz\"><span style=\" text-decoration: underline; color:#7f7fff;\">https://github.com/glikely/obs-ptz</span></a></p><p>Contributors:<br/>Fabio Ferrari<br/>Norihiro Kamae<br/>Luuk Verhagen<br/>Jonata Bolzan Loss<br/>Jim Hauxwell<br/>Jason Lanclos<br/>Eric Schmidt<br/>Anthony Roberts</p></body></html>"
PTZ.Action.Properties.Tooltip="Open PTZ properties"
PTZ.Action.PowerOn="Power On"
PTZ.Action.PowerOff="Power Off"
PTZ.Action.PanTiltUpLeft="PTZ move camera up & left"
PTZ.Action.PanTiltLeft="PTZ move camera left"
PTZ.Action.PanTiltDownLeft="PTZ move camera down & left"
PTZ.Action.PanTiltUpRight="PTZ move camera up & right"
PTZ.Action.PanTiltRight="PTZ move camera right"
PTZ.Action.PanTiltDownRight="PTZ move camera down & right"
PTZ.Action.PanTiltUp="PTZ move camera up"
PTZ.Action.PanTiltDown="PTZ move camera down"
PTZ.Action.ZoomWide="PTZ Zoom Camera Out"
PTZ.Action.ZoomTele="PTZ Zoom Camera In"
PTZ.Action.FocusAutoToggle="PTZ Toggle Autofocus"
PTZ.Action.FocusAutoOn="PTZ Set Autofocus On"
PTZ.Action.FocusAutoOff="PTZ Set Autofocus Off"
PTZ.Action.FocusNear="PTZ Focus Near"
PTZ.Action.FocusFar="PTZ Focus Far"
PTZ.Action.FocusOneTouch="PTZ One touch focus trigger"
PTZ.Action.SelectPrev="PTZ Select previous device"
PTZ.Action.SelectNext="PTZ Select next device"
PTZ.Action.Preset.Save="Save Preset"
PTZ.Action.Preset.Clear="Clear Preset"
PTZ.Action.Preset.RecallNum="PTZ Memory Recall #%1"
PTZ.Action.Preset.SaveNum="PTZ Memory Save #%1"
PTZ.Action.Preset.Add.Tooltip="Add Preset"
PTZ.Action.Preset.MoveUp.Tooltip="Move Preset Up"
PTZ.Action.Preset.MoveDown.Tooltip="Move Preset Down"
PTZ.Action.Preset.Remove.Tooltip="Remove selected preset"
PTZ.Action.WhiteBalance.OnePushTrigger="Trigger One-Push White Balance"
PTZ.Dock.Name="PTZ Controls"
PTZ.Dock.Lock.Name="Movement Locked"
PTZ.Dock.Lock.Description="Camera locked to prevent movement while live. Click to unlock")
PTZ.Dock.OnscreenJoystick="Onscreen Joystick"
PTZ.PresetNum="Preset %1"
PTZ.Device.DefaultName="PTZ Device"
PTZ.Device.NoSource="---select source---"
PTZ.Device.Connection="Connection"
PTZ.Device.CameraSettings="Camera Settings"
PTZ.Device.MaxPresets="Maximum number of presets"
PTZ.Device.PanTiltMaxSpeed="Pan/Tilt Max Speed"
PTZ.Device.ZoomMaxSpeed="Zoom Max Speed"
PTZ.Device.FocusMaxSpeed="Focus Max Speed"
PTZ.Device.Hostname="Host"
PTZ.Device.TCPPort="TCP Port"
PTZ.Device.UDPPort="UDP Port"
PTZ.Device.Username="Username"
PTZ.Device.Password="Password"
PTZ.Device.SerialPort="Serial Port"
PTZ.Device.SerialBaud="Baud Rate"
PTZ.Device.DeviceID="Device ID"
PTZ.Pelco.Name="Pelco"
PTZ.PelcoD.Name="Pelco-D"
PTZ.PelcoP.Name="Pelco-P"
PTZ.Pelco.UsePelcoD="Use Pelco-D"
PTZ.UVC.Name="USB Camera (UVC)"
PTZ.ONVIF.Name="ONVIF (experimental)"
PTZ.ONVIF.Warning="Warning: ONVIF support is experimental"
PTZ.Visca.TCP.Name="VISCA TCP"
PTZ.Visca.TCP.HostPortName="VISCA/TCP %1:%2"
PTZ.Visca.TCP.Description="VISCA TCP Connection"
PTZ.Visca.Serial.Name="VISCA Serial"
PTZ.Visca.Serial.Description="VISCA Serial Connection"
PTZ.Visca.UDP.Name="VISCA UDP"
PTZ.Visca.UDP.HostPortName="VISCA/UDP %1:%2"
PTZ.Visca.UDP.Description="VISCA UDP Connection"
PTZ.Visca.UDP.QuirkNoSeq="Don't use sequence numbers"
PTZ.Visca.ID="VISCA ID"
PTZ.Visca.PanMaxSpeed="Pan Maximum Speed (default 24)"
PTZ.Visca.TiltMaxSpeed="Tilt Maximum Speed (default 20)"
PTZ.Visca.ZoomMaxSpeed="Zoom Maximum Speed (default 7)"
PTZ.Visca.FocusMaxSpeed="Focus Maximum Speed (default 7)"
PTZ.Device.ProtocolTraceToLog="Write protocol trace to OBS log file\nRun OBS with --verbose to use this option\nWarning: this option generates very large logs.\nOnly use it for debugging"
PTZ.WhiteBalance="White Balance"
PTZ.WhiteBalance.Mode="Mode"
PTZ.WhiteBalance.Auto="Auto"
PTZ.WhiteBalance.Indoor="Indoor"
PTZ.WhiteBalance.Outdoor="Outdoor"
PTZ.WhiteBalance.OnePush="One Push"
PTZ.WhiteBalance.AutoTrace="Auto Tracing"
PTZ.WhiteBalance.Manual="Manual"
PTZ.WhiteBalance.OnePushButton="One Push Whitebalance"
PTZ.Settings.Title="PTZ Settings"
PTZ.Settings.General="General"
PTZ.Settings.JoystickControl="Joystick Control"
PTZ.Settings.Speed="Speed"
PTZ.Settings.DeadzoneSize="Deadzone Size"
PTZ.Settings.DeadzoneSlider.Tooltip="Set this value higher if the camera position drifts when the joystick is centered"
PTZ.Settings.Autoselect="Auto select active camera"
PTZ.Settings.Autoselect.Tooltip="Auto selects the active camera from the current scene on scene changes. In Studio Mode, this will select a camera from the Preview scene"
PTZ.Settings.LiveMoveLock="Lockout live PTZ moves in studio mode"
PTZ.Settings.LiveMoveLock.Tooltip="Disable movement controls for cameras in the currently active program scene. This protects against accidental camera moves on the live stream"
PTZ.Settings.SpeedRamp="Dynamic speed ramping"
PTZ.Settings.SpeedRamp.Tooltip="When dynamics speed ramping is enabled, camera movements will start slowly and gradually get faster for as long as the button is held down. It allows for both precision control and fast moves from the same control"
PTZ.Settings.PTZDevices="PTZ Devices"
PTZ.Settings.CameraAutoselect="Auto Select Camera"
PTZ.Settings.BlockLiveMoves="Block Live Camera Moves"
PTZ.Settings.Advanced="Advanced settings"
PTZ.Settings.Joystick.AxisNum="Axis %1 [%2]"
PTZ.Settings.Joystick.ButtonNum="Button %1 [%2]"
2 changes: 1 addition & 1 deletion scripts/update-authors.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ Contributions are sorted by their number of commits

Contributors:
EOF
git log --pretty=format:%an template/master.. | sort | uniq -c | sort -nr | cut -c8- >> AUTHORS
git log --pretty=format:%an template/master.. | sort | uniq -c | sort -nr | sed -e 's/^[ 0-9]*/ /g' >> AUTHORS
135 changes: 76 additions & 59 deletions src/ptz-controls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,16 @@
#include "ptz.h"

QStringList ptz_joy_action_names = {
"None",
"Pan",
"Tilt",
"Zoom",
"Previous Camera",
"Next Camera",
"Previous Preset",
"Next Preset",
"Recall Preset"
};
"None", "Pan", "Tilt", "Zoom", "Previous Camera", "Next Camera", "Previous Preset",
"Next Preset", "Recall Preset"};

void ptz_load_controls(void)
{
const auto main_window = static_cast<QMainWindow *>(obs_frontend_get_main_window());
obs_frontend_push_ui_translation(obs_module_get_string);
auto *ctrls = new PTZControls(main_window);

if (!obs_frontend_add_dock_by_id("ptz-dock", "PTZ Controls", ctrls))
if (!obs_frontend_add_dock_by_id("ptz-dock", obs_module_text("PTZ.Dock.Name"), ctrls))
blog(LOG_ERROR, "failed to add PTZ controls dock");

obs_frontend_pop_ui_translation();
Expand Down Expand Up @@ -229,24 +221,27 @@ PTZControls::PTZControls(QWidget *parent) : QWidget(parent), ui(new Ui::PTZContr
if (pressed)
ptzctrl->on_focusButton_auto_clicked(false);
};
registerHotkey("PTZ.PanTiltUpLeft", "PTZ Pan camera up & left", cb, ui->panTiltButton_upleft);
registerHotkey("PTZ.PanTiltLeft", "PTZ Pan camera left", cb, ui->panTiltButton_left);
registerHotkey("PTZ.PanTiltDownLeft", "PTZ Pan camera down & left", cb, ui->panTiltButton_downleft);
registerHotkey("PTZ.PanTiltUpRight", "PTZ Pan camera up & right", cb, ui->panTiltButton_upright);
registerHotkey("PTZ.PanTiltRight", "PTZ Pan camera right", cb, ui->panTiltButton_right);
registerHotkey("PTZ.PanTiltDownRight", "PTZ Pan camera down & right", cb, ui->panTiltButton_downright);
registerHotkey("PTZ.PanTiltUp", "PTZ Tilt camera up", cb, ui->panTiltButton_up);
registerHotkey("PTZ.PanTiltDown", "PTZ Tilt camera down", cb, ui->panTiltButton_down);
registerHotkey("PTZ.ZoomWide", "PTZ Zoom camera out (wide)", cb, ui->zoomButton_wide);
registerHotkey("PTZ.ZoomTele", "PTZ Zoom camera in (telefocal)", cb, ui->zoomButton_tele);
registerHotkey("PTZ.FocusAutoToggle", "PTZ Toggle Autofocus", autofocustogglecb, this);
registerHotkey("PTZ.FocusAutoOn", "PTZ Set Autofocus On", autofocusoncb, this);
registerHotkey("PTZ.FocusAutoOff", "PTZ Set Autofocus Off", autofocusoffcb, this);
registerHotkey("PTZ.FocusNear", "PTZ Focus far", cb, ui->focusButton_far);
registerHotkey("PTZ.FocusFar", "PTZ Focus near", cb, ui->focusButton_near);
registerHotkey("PTZ.FocusOneTouch", "PTZ One touch focus trigger", cb, ui->focusButton_onetouch);
registerHotkey("PTZ.SelectPrev", "PTZ Select previous device in list", prevcb, ui->cameraList);
registerHotkey("PTZ.SelectNext", "PTZ Select next device in list", nextcb, ui->cameraList);
registerHotkey("PTZ.PanTiltUpLeft", obs_module_text("PTZ.Action.PanTiltUpLeft"), cb, ui->panTiltButton_upleft);
registerHotkey("PTZ.PanTiltLeft", obs_module_text("PTZ.Action.PanTiltLeft"), cb, ui->panTiltButton_left);
registerHotkey("PTZ.PanTiltDownLeft", obs_module_text("PTZ.Action.PanTiltDownLeft"), cb,
ui->panTiltButton_downleft);
registerHotkey("PTZ.PanTiltUpRight", obs_module_text("PTZ.Action.PanTiltUpRight"), cb,
ui->panTiltButton_upright);
registerHotkey("PTZ.PanTiltRight", obs_module_text("PTZ.Action.PanTiltRight"), cb, ui->panTiltButton_right);
registerHotkey("PTZ.PanTiltDownRight", obs_module_text("PTZ.Action.PanTiltDownRight"), cb,
ui->panTiltButton_downright);
registerHotkey("PTZ.PanTiltUp", obs_module_text("PTZ.Action.PanTiltUp"), cb, ui->panTiltButton_up);
registerHotkey("PTZ.PanTiltDown", obs_module_text("PTZ.Action.PanTiltDown"), cb, ui->panTiltButton_down);
registerHotkey("PTZ.ZoomWide", obs_module_text("PTZ.Action.ZoomWide"), cb, ui->zoomButton_wide);
registerHotkey("PTZ.ZoomTele", obs_module_text("PTZ.Action.ZoomTele"), cb, ui->zoomButton_tele);
registerHotkey("PTZ.FocusAutoToggle", obs_module_text("PTZ.Action.FocusAutoToggle"), autofocustogglecb, this);
registerHotkey("PTZ.FocusAutoOn", obs_module_text("PTZ.Action.FocusAutoOn"), autofocusoncb, this);
registerHotkey("PTZ.FocusAutoOff", obs_module_text("PTZ.Action.FocusAutoOff"), autofocusoffcb, this);
registerHotkey("PTZ.FocusNear", obs_module_text("PTZ.Action.FocusNear"), cb, ui->focusButton_far);
registerHotkey("PTZ.FocusFar", obs_module_text("PTZ.Action.FocusFar"), cb, ui->focusButton_near);
registerHotkey("PTZ.FocusOneTouch", obs_module_text("PTZ.Action.FocusOneTouch"), cb, ui->focusButton_onetouch);
registerHotkey("PTZ.SelectPrev", obs_module_text("PTZ.Action.SelectPrev"), prevcb, ui->cameraList);
registerHotkey("PTZ.SelectNext", obs_module_text("PTZ.Action.SelectNext"), nextcb, ui->cameraList);

auto preset_recall_cb = [](void *ptz_data, obs_hotkey_id hotkey, obs_hotkey_t *, bool pressed) {
PTZControls *ptzctrl = static_cast<PTZControls *>(ptz_data);
Expand All @@ -264,11 +259,11 @@ PTZControls::PTZControls(QWidget *parent) : QWidget(parent), ui(new Ui::PTZContr

for (int i = 0; i < 16; i++) {
auto name = QString("PTZ.Recall%1").arg(i + 1);
auto description = QString("PTZ Memory Recall #%1").arg(i + 1);
auto description = QString(obs_module_text("PTZ.Action.Preset.RecallNum")).arg(i + 1);
auto hotkey = registerHotkey(QT_TO_UTF8(name), QT_TO_UTF8(description), preset_recall_cb, this);
preset_hotkey_map[hotkey] = i;
name = QString("PTZ.Save%1").arg(i + 1);
description = QString("PTZ Memory Save #%1").arg(i + 1);
description = QString(obs_module_text("PTZ.Action.Preset.SaveNum")).arg(i + 1);
hotkey = registerHotkey(QT_TO_UTF8(name), QT_TO_UTF8(description), preset_set_cb, this);
preset_hotkey_map[hotkey] = i;
}
Expand Down Expand Up @@ -931,7 +926,7 @@ void PTZControls::on_pantiltStack_customContextMenuRequested(const QPoint &pos)
QMenu menu;
bool enabled = (ui->pantiltStack->currentIndex() != 0);

QAction *touchpadAction = menu.addAction("Onscreen Joystick");
QAction *touchpadAction = menu.addAction(obs_module_text("PTZ.Dock.OnscreenJoystick"));
touchpadAction->setCheckable(true);
touchpadAction->setChecked(enabled);
QAction *action = menu.exec(globalpos);
Expand All @@ -946,27 +941,15 @@ void PTZControls::on_presetListView_customContextMenuRequested(const QPoint &pos
{
QPoint globalpos = ui->presetListView->mapToGlobal(pos);
QModelIndex index = ui->presetListView->indexAt(pos);
PTZDevice *ptz = currCamera();
if (!ptz)
return;

QMenu presetContext;
QAction *renameAction = presetContext.addAction("Rename");
QAction *setAction = presetContext.addAction("Save Preset");
QAction *resetAction = presetContext.addAction("Clear Preset");
presetContext.addAction(ui->actionPresetAdd);
if (index.isValid())
if (index.isValid()) {
presetContext.addAction(ui->actionPresetRename);
presetContext.addAction(ui->actionPresetSave);
presetContext.addAction(ui->actionPresetClear);
presetContext.addAction(ui->actionPresetRemove);
QAction *action = presetContext.exec(globalpos);

if (action == renameAction) {
ui->presetListView->edit(index);
} else if (action == setAction) {
ptz->memory_set(presetIndexToId(index));
} else if (action == resetAction) {
ptz->memory_reset(presetIndexToId(index));
ui->presetListView->model()->setData(index, "");
}
presetContext.addAction(ui->actionPresetAdd);
presetContext.exec(globalpos);
}

void PTZControls::on_cameraList_doubleClicked(const QModelIndex &index)
Expand All @@ -986,24 +969,25 @@ void PTZControls::on_cameraList_customContextMenuRequested(const QPoint &pos)
if (ptz) {
OBSData settings = ptz->get_settings();
bool power_on = obs_data_get_bool(settings, "power_on");
powerAction = context.addAction(power_on ? "Power Off" : "Power On");
powerAction =
context.addAction(obs_module_text(power_on ? "PTZ.Action.PowerOff" : "PTZ.Action.PowerOn"));

bool wb_onepush = (obs_data_get_int(settings, "wb_mode") == 3);
if (wb_onepush)
wbOnetouchAction = context.addAction("Trigger One-Push White Balance");
wbOnetouchAction = context.addAction(obs_module_text("PTZ.Action.WhiteBalance.OnePushTrigger"));
context.addSeparator();
}
QAction *autoselectAction = context.addAction("Auto Select Camera");
QAction *autoselectAction = context.addAction(obs_module_text("PTZ.Settings.CameraAutoselect"));
autoselectAction->setCheckable(true);
autoselectAction->setChecked(autoselectEnabled());
connect(autoselectAction, SIGNAL(toggled(bool)), this, SLOT(setAutoselectEnabled(bool)));
if (obs_frontend_preview_program_mode_active()) {
QAction *blockliveAction = context.addAction("Block Live Camera Moves");
QAction *blockliveAction = context.addAction(obs_module_text("PTZ.Settings.BlockLiveMoves"));
blockliveAction->setCheckable(true);
blockliveAction->setChecked(liveMovesDisabled());
connect(blockliveAction, SIGNAL(toggled(bool)), this, SLOT(setDisableLiveMoves(bool)));
}
QAction *propertiesAction = context.addAction("Properties");
context.addAction(ui->actionProperties);
QAction *action = context.exec(globalpos);

OBSData setdata = obs_data_create();
Expand All @@ -1018,11 +1002,14 @@ void PTZControls::on_cameraList_customContextMenuRequested(const QPoint &pos)
} else if (action == wbOnetouchAction) {
obs_data_set_bool(setdata, "wb_onepush_trigger", true);
ptz->set_settings(setdata);
} else if (action == propertiesAction) {
ptz_settings_show(ptzDeviceList.getDeviceId(ui->cameraList->currentIndex()));
}
}

void PTZControls::on_actionProperties_triggered()
{
ptz_settings_show(ptzDeviceList.getDeviceId(ui->cameraList->currentIndex()));
}

void PTZControls::on_actionPresetAdd_triggered()
{
auto model = ui->presetListView->model();
Expand Down Expand Up @@ -1068,6 +1055,36 @@ void PTZControls::on_actionPresetMoveDown_triggered()
presetUpdateActions();
}

void PTZControls::on_actionPresetRename_triggered()
{
auto model = ui->presetListView->model();
auto index = ui->presetListView->currentIndex();
if (!model || !index.isValid())
return;
ui->presetListView->edit(index);
}

void PTZControls::on_actionPresetSave_triggered()
{
auto model = ui->presetListView->model();
auto index = ui->presetListView->currentIndex();
PTZDevice *ptz = currCamera();
if (!model || !index.isValid() || !ptz)
return;
ptz->memory_set(presetIndexToId(index));
}

void PTZControls::on_actionPresetClear_triggered()
{
auto model = ui->presetListView->model();
auto index = ui->presetListView->currentIndex();
PTZDevice *ptz = currCamera();
if (!model || !index.isValid() || !ptz)
return;
ptz->memory_reset(presetIndexToId(index));
ui->presetListView->model()->setData(index, "");
}

PTZDeviceListDelegate::PTZDeviceListDelegate(QObject *parent) : QStyledItemDelegate(parent) {}

QSize PTZDeviceListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
Expand All @@ -1092,8 +1109,8 @@ PTZDeviceListItem::PTZDeviceListItem(PTZDevice *ptz_) : ptz(ptz_)
lock = new QCheckBox();
lock->setProperty("class", "checkbox-icon indicator-lock");
lock->setChecked(ptz->isLive());
lock->setAccessibleName("PTZ.Device.Lock");
lock->setAccessibleDescription("PTZ.Device.LockDescription");
lock->setAccessibleName(obs_module_text("PTZ.Dock.Lock.Name"));
lock->setAccessibleDescription(obs_module_text("PTZ.Dock.Lock.Description"));

label = new QLabel(ptz->objectName());

Expand Down
4 changes: 4 additions & 0 deletions src/ptz-controls.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,14 @@ private slots:
void on_presetListView_customContextMenuRequested(const QPoint &pos);
void on_cameraList_doubleClicked(const QModelIndex &index);
void on_cameraList_customContextMenuRequested(const QPoint &pos);
void on_actionProperties_triggered();
void on_actionPresetAdd_triggered();
void on_actionPresetRemove_triggered();
void on_actionPresetMoveUp_triggered();
void on_actionPresetMoveDown_triggered();
void on_actionPresetSave_triggered();
void on_actionPresetClear_triggered();
void on_actionPresetRename_triggered();

void accelTimerHandler();

Expand Down
Loading