obs studio start and record

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
tangrila

obs studio start and record

26 Dec 2016, 06:13

Hello so this code here is meant to start obs if it isnt already and then send it a obs configured hotkey in order to start recording
on every loop it checks its recording by reading the obs log file if it isn't - it starts. The problem is that it runs fine with the first instance of obs, but when it is closed and reopened, the RunWait line doesn't really wait for the new instance to load and goes directly to this - If (process_PID != ErrorLevel) - which screws up the next if - it executes the hotkey before the program is loaded.

Any ideas why it ignores the Wait in RunWait ?

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

#persistent
SetTitleMatchMode,2

/*
	Summary
		The script runs indefinetely every N seconds
			Checks if obs is running if not, runs it
				Starts recording
			Checks the latest RECORDING line in
			the latest log created by obs
			If said line contains STOP
				Starts recording
*/

LoopEveryThisSeconds = 10000 ; set the intervals the script should run
RecordHotKey = F9 ; set configured hotkey from obs here
ObsBit = 32 ; set bit version here 32/64
ObsPath = D:\Programs\obs-studio\bin\%ObsBit%bit ; set your path to obs executable here
LogPath = %A_AppData%\obs-studio\logs
line_regex = Recording\s(\w+)
InitialRun := false
; MsgBox %LogPath% ; debug path

SetTimer, obs, %LoopEveryThisSeconds%
obs:
	; runs obs if not already running
	Process,Exist, obs%ObsBit%.exe ; Sets errorlevel to process PID
    	IfWinNotExist, % "ahk_pid " errorlevel ; Expression for ahk_pid
	{
		RunWait, %ObsPath%\obs%ObsBit%.exe, , , ErrorLevel
	}
	
	If (process_PID != ErrorLevel)
	{
		InitialRun := false
	}
	; gets the process PID 
	process_PID = %ErrorLevel%
	
	; finds the latest log file
	Loop %LogPath%\*.*, 0, 1
	{
		MostRecentLog := (A_Index = 1 ? A_LoopFileFullPath : MostRecentLog)
		FileGetTime MostRecentLogTime, %MostRecentLog%, C
		MostRecentLog := (A_LoopFileTimeModified > MostRecentLogTime ? A_LoopFileFullPath : MostRecentLog)
	}
	; MsgBox %MostRecentLog% debug latest log path
	
	; reads every line from the latest log
	Loop, read, %MostRecentLog%
	{
		RegExMatch(A_LoopReadLine, line_regex, line)
		; line1 holds the captured group 
	}
	
	; MsgBox %line1% ; debug regex match\
	If (line1 == "Stop" || !InitialRun)
	{
		InitialRun := true
		ControlSend, ,{%RecordHotKey%},ahk_pid %process_PID%
	}
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: obs studio start and record

26 Dec 2016, 08:47

One possibility, maybe this line requires 'DetectHiddenWindows, On'.

Code: Select all

    	IfWinNotExist, % "ahk_pid " errorlevel ; Expression for ahk_pid
I wrote a script that did something similar, to start/stop OBS Studio recording, from within Internet Explorer.

Code: Select all

;[Acc functions]
;Acc library (MSAA) and AccViewer download links - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=6&t=26201

#IfWinActive ahk_class IEFrame ;internet explorer
Numpad7:: ;test - internet explorer (obs studio) - click button
Numpad9:: ;test - internet explorer (obs studio) - click button
NumpadEnd:: ;test - internet explorer (obs studio) - click button
NumpadHome:: ;test - internet explorer (obs studio) - click button
WinGet, hWnd, ID, OBS 0. ahk_class Qt5QWindowIcon
ControlGet, hCtl, Hwnd,, Qt5QWindowIcon10, % "ahk_id " hWnd
vAccPath := "client.push_button2"
oAcc := Acc_Get("Object", vAccPath, 0, "ahk_id " hCtl)
vText := oAcc.accName(0)

if InStr(vText, "Start")
	if A_ThisHotkey contains % "Home,7"
	{
		oAcc.accDoDefaultAction(0)
		ToolTip, STARTED
	}
	else
		MsgBox, % "error"

if InStr(vText, "Stop")
	if A_ThisHotkey contains % "End,1"
	{
		oAcc.accDoDefaultAction(0)
		ToolTip, ENDED
		Sleep, 2000
		Loop, 10
		{
			Sleep, 1000
			vText := oAcc.accName(0)
			if (vText = "Start Recording")
				break
		}
		ToolTip
	}
	else
		MsgBox, % "error"
return
#IfWinActive
Last edited by jeeswg on 03 Dec 2018, 17:45, edited 3 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
tangrila
Posts: 1
Joined: 27 Dec 2016, 20:20

Re: obs studio start and record

27 Dec 2016, 20:30

thanks for the input. Haven't tried with DetectHiddenWindows,
but I did manage to make it work by putting two If statements -
  • one checking if ErrorLevel is 0
  • one to check if obs exists before trying to start recording
here's the code now

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

#persistent
SetTitleMatchMode,2

/*
	Summary
		The script runs indefinetely every N seconds
			Checks if obs is running if not, runs it
				Starts recording
			Checks the latest RECORDING line in
			the latest log created by obs
			If said line contains STOP
				Starts recording
	Note: put the script in the folder that
		contains the obs executable.
		To make the script run upon startup place a
		shortcut of it in: 
			(OS DRIVE)C:\users\%UserProfile%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
*/

LoopEveryThisSeconds = 10000 ; set the intervals the script should run
RecordHotKey = F9 ; set configured hotkey from obs here
ObsBit = 32 ; set bit version here 32/64
ObsPath = C:\Program Files (x86)\obs-studio\bin\%ObsBit%bit ; set your path to obs executable here
LogPath = %A_AppData%\obs-studio\logs
line_regex = Recording\s(\w+)
InitialRun := false
; MsgBox %LogPath% ; debug path

SetTimer, obs, %LoopEveryThisSeconds%
obs:
	; runs obs if not already running
	If (ErrorLevel == 0)
	{
		Process,Exist, obs%ObsBit%.exe ; Sets ErrorLevel to process PID
		IfWinNotExist, % "ahk_pid " ErrorLevel
		{
			RunWait, %ObsPath%\obs%ObsBit%.exe, , Min, ErrorLevel
			If (process_PID != ErrorLevel)
			{
				Reload
			}
		}
	}
	
	; gets the process PID 
	process_PID = %ErrorLevel%
	
	; finds the latest log file
	Loop %LogPath%\*.*, 0, 1
	{
		MostRecentLog := (A_Index = 1 ? A_LoopFileFullPath : MostRecentLog)
		FileGetTime MostRecentLogTime, %MostRecentLog%, C
		MostRecentLog := (A_LoopFileTimeModified > MostRecentLogTime ? A_LoopFileFullPath : MostRecentLog)
	}
	; MsgBox %MostRecentLog% debug latest log path
	
	; reads every line from the latest log
	Loop, read, %MostRecentLog%
	{
		RegExMatch(A_LoopReadLine, line_regex, line)
		; line1 holds the captured group 
	}
	
	; MsgBox %line1% ; debug regex match\
	If (line1 == "Stop" || !InitialRun)
	{
		IfWinExist, % "ahk_pid " process_PID
		{
			InitialRun = true
			ControlSend, ,{%RecordHotKey%}, ahk_pid %process_PID%
		}
	}
	
znewman

Re: obs studio start and record

08 Feb 2017, 16:45

Hi Everyone, New to AHK and this code that you provided does a great job at starting the recording but would you guys be able to help me out by showing me how to make OBS continuously start a recording then stop it after 20sec then start a new recording and repeat? "RecordHotKey2" is my stop key.

Thanks in advance!

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

#persistent
SetTitleMatchMode,2

/*
	Summary
		The script runs indefinetely every N seconds
			Checks if obs is running if not, runs it
				Starts recording
			Checks the latest RECORDING line in
			the latest log created by obs
			If said line contains STOP
				Starts recording
	Note: put the script in the folder that
		contains the obs executable.
		To make the script run upon startup place a
		shortcut of it in: 
			(OS DRIVE)C:\users\%UserProfile%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
*/
LoopEveryThisSeconds = 20000 ; set the intervals the script should run
RecordHotKey = F9 ; set configured hotkey from obs here
RecordHotKey2 = F8 ; set configured hotkey from obs here
ObsBit = 64 ; set bit version here 32/64
ObsPath = C:\Program Files (x86)\obs-studio\bin\64bit ; set your path to obs executable here
LogPath = C:\Users\znewman\AppData\Roaming\obs-studio\logs
line_regex = Recording\s(\w+)
InitialRun := false
; MsgBox %LogPath% ; debug path

SetTimer, obs, %LoopEveryThisSeconds%
obs:
	; runs obs if not already running
	If (ErrorLevel == 0)
	{
		Process,Exist, obs%ObsBit%.exe ; Sets ErrorLevel to process PID
		IfWinNotExist, % "ahk_pid " ErrorLevel
		{
			RunWait, %ObsPath%\obs%ObsBit%.exe, , Min, ErrorLevel
			If (process_PID != ErrorLevel)
			{
				Reload
			}
		}
	}
	
	; gets the process PID 
	process_PID = %ErrorLevel%
	
	; finds the latest log file
	Loop %LogPath%\*.*, 0, 1
	{
		MostRecentLog := (A_Index = 1 ? A_LoopFileFullPath : MostRecentLog)
		FileGetTime MostRecentLogTime, %MostRecentLog%, C
		MostRecentLog := (A_LoopFileTimeModified > MostRecentLogTime ? A_LoopFileFullPath : MostRecentLog)
	}
	; MsgBox %MostRecentLog% debug latest log path
	
	; reads every line from the latest log
	Loop, read, %MostRecentLog%
	{
		RegExMatch(A_LoopReadLine, line_regex, line)
		; line1 holds the captured group 
	}
	
	; MsgBox %line1% ; debug regex match\
	If (line1 == "Stop" || !InitialRun)
	{
		IfWinExist, % "ahk_pid " process_PID
		{
			InitialRun = true
			ControlSend, ,{%RecordHotKey%}, ahk_pid %process_PID%
		}
	}
4GForce
Posts: 553
Joined: 25 Jan 2017, 03:18
Contact:

Re: obs studio start and record

09 Feb 2017, 01:26

Did I miss something or thats not the purpose of RunWait ...

You are using it improperly ... Its not meant to wait for the called .exe to RUN .... It actually waits for it to END !!!

Like stated in the docs, RunWait doesn't seem to wait for the .exe to end because that .exe spawns other processes and ends himself instantly.
I don't know about obs but you should know by looking at the task manager.
You would probably need to make other checks to know If obs is actually running ... ( and I can't see where you kill the process either )
https://autohotkey.com/docs/commands/Run.htm wrote: Remarks

Unlike Run, RunWait will wait until Target is closed or exits, at which time ErrorLevel will be set to the program's exit code (as a signed 32-bit integer). Some programs will appear to return immediately even though they are still running; these programs spawn another process.
:terms:
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: obs studio start and record

27 Dec 2018, 14:58

- I've tried to update this script to work for OBS Studio v22.0.2. The code sometimes works/sometimes fails. I haven't found a way to reliably click on the Start/Stop Recording button, in case anyone has any other ideas.
- accDoDefaultAction and WM_LBUTTONDOWN/WM_LBUTTONDBLCLK weren't working, although they did *something* to the button, changing its colour, and ControlClick was working often but not always.

Code: Select all

;[Acc functions]
;Acc library (MSAA) and AccViewer download links - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=6&t=26201
;[JEE_AccGetTextAll function]
;Acc: get text from all window/control elements - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=6&t=40615

;tested on OBS Studio v22.0.2
;not 100% reliable, works intermittently
q:: ;OBS Studio - toggle Start Recording/Stop Recording
SoundBeep
WinGet, hWnd, ID, OBS ahk_class Qt5QWindowIcon
ControlGet, hCtl, Hwnd,, Qt5QWindowIcon1, % "ahk_id " hWnd
oAcc := Acc_Get("Object", "4.1.2", 0, "ahk_id " hCtl)
vText := oAcc.accName(0)
if (vText = "Start Recording")
	ToolTip, STARTED
else if !(vText = "Stop Recording")
{
	MsgBox, % "ERROR"
	return
}
oRect := Acc_Location(oAcc)

;not working:
;oAcc.accDoDefaultAction(0)

;works intermittently:
WinGetPos, vWinX, vWinY,,, % "ahk_id " hWnd
vPos := Format("x{:i} y{:i}", oRect.x+oRect.w/2-vWinX, oRect.y+oRect.h/2-vWinY)
ControlClick, % vPos, % "ahk_id " hWnd

;not working but WM_LBUTTONDOWN highlights button sometimes:
;WinGetClientPos(vWinX, vWinY,,, "ahk_id " hWnd)
;vPosX := oRect.x+oRect.w/2-vWinX
;vPosY := oRect.y+oRect.h/2-vWinY
;PostMessage, 0x201, 0, % (vPosX & 0xFFFF)|(vPosY<<16),, % "ahk_id " hWnd ;WM_LBUTTONDOWN := 0x201
;PostMessage, 0x202, 0, % (vPosX & 0xFFFF)|(vPosY<<16),, % "ahk_id " hWnd ;WM_LBUTTONUP := 0x202
;PostMessage, 0x203, 0, % (vPosX & 0xFFFF)|(vPosY<<16),, % "ahk_id " hWnd ;WM_LBUTTONDBLCLK := 0x203

if (vText = "Stop Recording")
{
	Loop 100
	{
		Sleep, 100
		vText := oAcc.accName(0)
		if (vText = "Start Recording")
			break
	}
}
oAcc := oRect := ""
;MsgBox, % vText
SoundBeep
SoundBeep
return

;==================================================

/*
;commands as functions (AHK v2 functions for AHK v1) - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=37&t=29689

WinGetClientPos(ByRef X:="", ByRef Y:="", ByRef Width:="", ByRef Height:="", WinTitle:="", WinText:="", ExcludeTitle:="", ExcludeText:="")
{
	local hWnd, RECT
	hWnd := WinExist(WinTitle, WinText, ExcludeTitle, ExcludeText)
	VarSetCapacity(RECT, 16, 0)
	DllCall("user32\GetClientRect", "Ptr",hWnd, "Ptr",&RECT)
	DllCall("user32\ClientToScreen", "Ptr",hWnd, "Ptr",&RECT)
	X := NumGet(&RECT, 0, "Int"), Y := NumGet(&RECT, 4, "Int")
	Width := NumGet(&RECT, 8, "Int"), Height := NumGet(&RECT, 12, "Int")
}
*/
- Re. OBS Studio, this script is useful for minimising the window to the system tray, and showing it again.
Sending keystrokes to a background process (hidden) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=59070
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: obs studio start and record

16 Nov 2019, 20:30

I found a way to toggle 'Start Recording'/'Stop Recording', that has been working reliably for me, whether the window is visible or hidden.

It works like so:
- Create an Acc object for the Start/Stop Recording GUI element, by specifying an Acc path of 4.8.1.2 (obtained via the JEE_AccGetTextAll function).
- Use Acc_WindowFromObject to get a handle to the control that contains the GUI element.
- Use WinGetPos on the control, and Acc_Location on the element, to establish the centre of the GUI element relative to the control's top-left corner.
- Use ControlClick to send a right-click to the centre of the GUI element, to give keyboard focus to the element.
- Use ControlSend to send Space to the control, to toggle Start/Stop Recording.

Code: Select all

;[Acc functions]
;Acc library (MSAA) and AccViewer download links - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=6&t=26201
;[JEE_AccGetTextAll function]
;Acc: get text from all window/control elements - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=6&t=40615

q:: ;OBS Studio - toggle 'Start Recording'/'Stop Recording'
;tested on OBS Studio v24.0.3.0
DetectHiddenWindows, On
WinGet, hWnd, ID, OBS ahk_class Qt5QWindowIcon ahk_exe obs64.exe
oAcc := Acc_Get("Object", "4.8.1.2", 0, "ahk_id " hWnd)
;MsgBox, % oAcc.accName(0) "`r`n" oAcc.accValue(0)

vText := oAcc.accName(0)
if !(vText = "Start Recording")
&& !(vText = "Stop Recording")
{
	MsgBox, % "error: Start/Stop Recording GUI element not found:`r`n" vText
	oAcc := ""
	return
}
MsgBox, % vText

hCtl := Acc_WindowFromObject(oAcc)

WinGetPos, vCtlX, vCtlY,,, % "ahk_id " hCtl
oRect := Acc_Location(oAcc)
vPosX := Round(oRect.x + oRect.w/2) - vCtlX
vPosY := Round(oRect.y + oRect.h/2) - vCtlY
;CoordMode, Mouse, Screen
;MouseMove, % vCtlX+vPosX, % vCtlY+vPosY ;to visually confirm the coordinates
ControlClick, % "x" vPosX " y" vPosY, % "ahk_id " hCtl,, R ;right-click to focus the GUI element
ControlSend,, {Space}, % "ahk_id " hCtl ;space to 'click' on the GUI element

oAcc := oRect := ""
SoundBeep
return

Some notes re. experimenting:
- MouseClick worked, although required that the window was visible.
- ControlClick (left-click) worked intermittently, and required that the window was visible.
- ControlClick (left-click) *plus hover* appeared to work reliably, and required that the window was visible. I.e. use MouseMove to hover over the GUI element, and perhaps Sleep, for a time, before using ControlClick. (Note: MouseClick uses the hover principle in the source code.)
- oAcc.accDoDefaultAction(0) did not work, although toggled the appearance between highlighted and non-highlighted. The button is of type ROLE_SYSTEM_CHECKBUTTON (0x2C) (a checkbox), and using accDoDefaultAction toggles the checked state, STATE_SYSTEM_CHECKED (0x10).
- oAcc.accSelect(n, 0) did not work to focus the GUI element.

Some notes re. using OBS Studio via the keyboard:
- arrow keys/tab/shift+tab: navigate
- alt: hide/show selection rectangle, focus/unfocus the menu bar
- space: invoke the focused GUI element

Link:
[list of various OBS Studio threads]
automating OBS Studio (Open Broadcaster Software) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=61136
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Renets
Posts: 36
Joined: 12 Jul 2018, 13:11

Re: obs studio start and record

28 Jun 2020, 17:45

Hello! I needed to make this work as well, and dig into jeeswg tutorials and library, so much aprpeciated!

so, I tested the code posted here for it, but I found some inconsistencies, more, in theactual ControlClick, for me, it wasn't sending the Start/Stop action, with it, but I notice it was doing it but with the {Space}, so, to get it to work with the actual ControlClick I made this:

Code: Select all

q:: ;OBS Studio - toggle 'Start Recording'/'Stop Recording'. Modified by Renets
;tested on OBS Studio v25.0.9
DetectHiddenWindows, On

obs_wintitle:= "OBS ahk_class Qt5QWindowIcon ahk_exe obs64.exe"

WinGet, hWnd, ID, %obs_wintitle%
oAcc := Acc_Get("Object", "4.8.1.2", 0, "ahk_id " hWnd)

vText := oAcc.accName(0)    
if (!(vText = "Start Recording") && !(vText = "Stop Recording")){ ; Loocking for the text at the control at path "4.8.1.2"
	MsgBox, % "error: Start/Stop Recording GUI element not found:`r`n" vText
	oAcc := ""
	return
}
; MsgBox, % vText

WinGetPos, vAppX, vAppY, vAppW, vAppH, %obs_wintitle% ; Get the propieties from the OBS window

oRect := Acc_Location(oAcc)

; Get the coodinates to the control and adjust it to the very middle of it
vRelativeX_ClickMiddle := (oRect.x - vAppX) + (oRect.W/2)
vRelativeY_ClickMiddle := (oRect.Y - vAppY) + (oRect.H/2)

CoordMode, Mouse, Relative ; To be sure it is using a relative mode to the OBS app
; MouseMove, % vRelativeX_ClickMiddle, % vRelativeY_ClickMiddle ; Test to visually confirm the coordinates

ControlClick, % "x" vRelativeX_ClickMiddle " y" vRelativeY_ClickMiddle, % obs_wintitle , , left

; ControlSend,, {Space}, % obs_wintitle ;space to 'click' on the GUI element ; Last resort, sending a Space in the root of the app clicks automatically the Start Recording/Stop recording

SoundBeep
return

This way, it uses correctly the control click to the exact middle of the control
Anyway, thanks jeeswg for your aportations! :bravo:

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Google [Bot], sbrady19 and 134 guests