Skip to content

Commit 1de3ebe

Browse files
committed
feat: Update OBS capture window after finding/starting game instance
1 parent 1b7d151 commit 1de3ebe

3 files changed

Lines changed: 38 additions & 4 deletions

File tree

BF2AutoSpectator/common/config.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class Config(metaclass=Singleton):
2828
__controller_base_uri: str
2929
__control_obs: bool
3030
__obs_url: str
31+
__obs_source_name: str
3132

3233
__resolution: str
3334
__debug_screenshot: bool
@@ -42,7 +43,7 @@ class Config(metaclass=Singleton):
4243

4344
def set_options(self, player_name: str, player_pass: str, server_ip: str, server_port: str, server_pass: str,
4445
server_mod: str, game_path: str, tesseract_path: str, limit_rtl: bool, instance_rtl: int, map_load_delay: int,
45-
use_controller: bool, controller_base_uri: str, control_obs: bool, obs_url: str,
46+
use_controller: bool, controller_base_uri: str, control_obs: bool, obs_url: str, obs_source_name: str,
4647
resolution: str, debug_screenshot: bool,
4748
min_iterations_on_player: int, max_iterations_on_player: int,
4849
max_iterations_on_default_camera_view: int, lockup_iterations_on_spawn_menu: int):
@@ -63,6 +64,7 @@ def set_options(self, player_name: str, player_pass: str, server_ip: str, server
6364
self.__controller_base_uri = controller_base_uri
6465
self.__control_obs = control_obs
6566
self.__obs_url = obs_url
67+
self.__obs_source_name = obs_source_name
6668

6769
self.__resolution = resolution
6870

@@ -139,6 +141,9 @@ def control_obs(self) -> bool:
139141
def get_obs_url(self) -> str:
140142
return self.__obs_url
141143

144+
def get_obs_source_name(self) -> str:
145+
return self.__obs_source_name
146+
142147
def get_resolution(self) -> str:
143148
return self.__resolution
144149

BF2AutoSpectator/remote/obs_client.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
from dataclasses import dataclass
12
from typing import Optional
23
from urllib.parse import urlparse
34

45
import obsws_python as obs
56

67
from BF2AutoSpectator.common.exceptions import ClientNotConnectedException
8+
from BF2AutoSpectator.common.logger import logger
79

810

911
class OBSClient:
@@ -46,6 +48,26 @@ def stop_stream(self) -> None:
4648

4749
self.obs.stop_stream()
4850

51+
def set_capture_window(self, input_name: str, executable: str, title: str) -> None:
52+
self.__ensure_connected()
53+
54+
resp = self.__try_get_input_settings(input_name)
55+
if resp is not None and resp.input_settings.get('capture_mode') == 'window':
56+
self.obs.set_input_settings(input_name, {
57+
'window': self.__format_window_title(executable, title)
58+
}, True)
59+
60+
def __try_get_input_settings(self, input_name: str) -> Optional[dataclass]:
61+
try:
62+
return self.obs.get_input_settings(input_name)
63+
except obs.reqs.OBSSDKRequestError as e:
64+
logger.error(f'Failed to get input settings: {e}')
65+
4966
def __ensure_connected(self) -> None:
5067
if not hasattr(self, 'obs'):
5168
raise ClientNotConnectedException('OBSClient is not connected')
69+
70+
@staticmethod
71+
def __format_window_title(executable: str, title: str) -> str:
72+
escaped = title.replace(':', '#3A')
73+
return f'{escaped}:{escaped}:{executable}'

BF2AutoSpectator/spectate.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def run():
4646
parser.add_argument('--controller-base-uri', help='Base uri of web controller', type=str)
4747
parser.add_argument('--control-obs', dest='control_obs', action='store_true')
4848
parser.add_argument('--obs-url', help='OBS WebSocket URL in format "ws://:password@hostname:port"', type=str)
49+
parser.add_argument('--obs-source-name', help='OBS game source name', type=str, default='Battlefield 2')
4950
parser.add_argument('--no-rtl-limit', dest='limit_rtl', action='store_false')
5051
parser.add_argument('--debug-log', dest='debug_log', action='store_true')
5152
parser.add_argument('--debug-screenshot', dest='debug_screenshot', action='store_true')
@@ -72,6 +73,7 @@ def run():
7273
controller_base_uri=args.controller_base_uri,
7374
control_obs=args.control_obs,
7475
obs_url=args.obs_url,
76+
obs_source_name=args.obs_source_name,
7577
resolution=args.game_res,
7678
debug_screenshot=args.debug_screenshot,
7779
min_iterations_on_player=args.min_iterations_on_player,
@@ -128,8 +130,10 @@ def run():
128130
logger.info('Looking for an existing game instance')
129131
got_instance, correct_params, *_ = gim.find_instance(config.get_server_mod())
130132

131-
# Schedule restart if no instance was started/found
132-
if not got_instance:
133+
if got_instance and config.control_obs():
134+
logger.debug('Found existing game window, updating OBS capture window')
135+
obsc.set_capture_window(config.get_obs_source_name(), constants.BF2_EXE, gim.game_window.title)
136+
elif not got_instance:
133137
logger.info('Did not find any existing game instance, will launch a new one')
134138
gis.set_error_restart_required(True)
135139
elif not correct_params:
@@ -342,7 +346,10 @@ def run():
342346
logger.warning(f'Game restart itself with a different mod, updating config')
343347
config.set_server_mod(running_mod)
344348

345-
if not got_instance:
349+
if got_instance and correct_params and config.control_obs():
350+
logger.debug('Game instance launched, updating OBS capture window')
351+
obsc.set_capture_window(config.get_obs_source_name(), constants.BF2_EXE, gim.game_window.title)
352+
elif not got_instance:
346353
logger.error('Game instance was not launched, retrying')
347354
continue
348355
elif not correct_params:

0 commit comments

Comments
 (0)