boris-behav-obs 9.7.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of boris-behav-obs might be problematic. Click here for more details.
- boris/__init__.py +26 -0
- boris/__main__.py +25 -0
- boris/about.py +143 -0
- boris/add_modifier.py +635 -0
- boris/add_modifier_ui.py +303 -0
- boris/advanced_event_filtering.py +455 -0
- boris/analysis_plugins/__init__.py +0 -0
- boris/analysis_plugins/_latency.py +59 -0
- boris/analysis_plugins/irr_cohen_kappa.py +109 -0
- boris/analysis_plugins/irr_cohen_kappa_with_modifiers.py +112 -0
- boris/analysis_plugins/irr_weighted_cohen_kappa.py +157 -0
- boris/analysis_plugins/irr_weighted_cohen_kappa_with_modifiers.py +162 -0
- boris/analysis_plugins/list_of_dataframe_columns.py +22 -0
- boris/analysis_plugins/number_of_occurences.py +22 -0
- boris/analysis_plugins/number_of_occurences_by_independent_variable.py +54 -0
- boris/analysis_plugins/time_budget.py +61 -0
- boris/behav_coding_map_creator.py +1110 -0
- boris/behavior_binary_table.py +305 -0
- boris/behaviors_coding_map.py +239 -0
- boris/boris_cli.py +340 -0
- boris/cmd_arguments.py +49 -0
- boris/coding_pad.py +280 -0
- boris/config.py +785 -0
- boris/config_file.py +356 -0
- boris/connections.py +409 -0
- boris/converters.py +333 -0
- boris/converters_ui.py +225 -0
- boris/cooccurence.py +250 -0
- boris/core.py +5901 -0
- boris/core_qrc.py +15958 -0
- boris/core_ui.py +1107 -0
- boris/db_functions.py +324 -0
- boris/dev.py +134 -0
- boris/dialog.py +1108 -0
- boris/duration_widget.py +238 -0
- boris/edit_event.py +245 -0
- boris/edit_event_ui.py +233 -0
- boris/event_operations.py +1040 -0
- boris/events_cursor.py +61 -0
- boris/events_snapshots.py +596 -0
- boris/exclusion_matrix.py +141 -0
- boris/export_events.py +1006 -0
- boris/export_observation.py +1203 -0
- boris/external_processes.py +332 -0
- boris/geometric_measurement.py +941 -0
- boris/gui_utilities.py +135 -0
- boris/image_overlay.py +72 -0
- boris/import_observations.py +242 -0
- boris/ipc_mpv.py +325 -0
- boris/irr.py +634 -0
- boris/latency.py +244 -0
- boris/measurement_widget.py +161 -0
- boris/media_file.py +115 -0
- boris/menu_options.py +213 -0
- boris/modifier_coding_map_creator.py +1013 -0
- boris/modifiers_coding_map.py +157 -0
- boris/mpv.py +2016 -0
- boris/mpv2.py +2193 -0
- boris/observation.py +1453 -0
- boris/observation_operations.py +2538 -0
- boris/observation_ui.py +679 -0
- boris/observations_list.py +337 -0
- boris/otx_parser.py +442 -0
- boris/param_panel.py +201 -0
- boris/param_panel_ui.py +305 -0
- boris/player_dock_widget.py +198 -0
- boris/plot_data_module.py +536 -0
- boris/plot_events.py +634 -0
- boris/plot_events_rt.py +237 -0
- boris/plot_spectrogram_rt.py +316 -0
- boris/plot_waveform_rt.py +230 -0
- boris/plugins.py +431 -0
- boris/portion/__init__.py +31 -0
- boris/portion/const.py +95 -0
- boris/portion/dict.py +365 -0
- boris/portion/func.py +52 -0
- boris/portion/interval.py +581 -0
- boris/portion/io.py +181 -0
- boris/preferences.py +510 -0
- boris/preferences_ui.py +770 -0
- boris/project.py +2007 -0
- boris/project_functions.py +2041 -0
- boris/project_import_export.py +1096 -0
- boris/project_ui.py +794 -0
- boris/qrc_boris.py +10389 -0
- boris/qrc_boris5.py +2579 -0
- boris/select_modifiers.py +312 -0
- boris/select_observations.py +210 -0
- boris/select_subj_behav.py +286 -0
- boris/state_events.py +197 -0
- boris/subjects_pad.py +106 -0
- boris/synthetic_time_budget.py +290 -0
- boris/time_budget_functions.py +1136 -0
- boris/time_budget_widget.py +1039 -0
- boris/transitions.py +365 -0
- boris/utilities.py +1810 -0
- boris/version.py +24 -0
- boris/video_equalizer.py +159 -0
- boris/video_equalizer_ui.py +248 -0
- boris/video_operations.py +310 -0
- boris/view_df.py +104 -0
- boris/view_df_ui.py +75 -0
- boris/write_event.py +538 -0
- boris_behav_obs-9.7.7.dist-info/METADATA +139 -0
- boris_behav_obs-9.7.7.dist-info/RECORD +109 -0
- boris_behav_obs-9.7.7.dist-info/WHEEL +5 -0
- boris_behav_obs-9.7.7.dist-info/entry_points.txt +2 -0
- boris_behav_obs-9.7.7.dist-info/licenses/LICENSE.TXT +674 -0
- boris_behav_obs-9.7.7.dist-info/top_level.txt +1 -0
boris/ipc_mpv.py
ADDED
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
"""
|
|
2
|
+
BORIS
|
|
3
|
+
Behavioral Observation Research Interactive Software
|
|
4
|
+
Copyright 2012-2025 Olivier Friard
|
|
5
|
+
|
|
6
|
+
This file is part of BORIS.
|
|
7
|
+
|
|
8
|
+
BORIS is free software; you can redistribute it and/or modify
|
|
9
|
+
it under the terms of the GNU General Public License as published by
|
|
10
|
+
the Free Software Foundation; either version 3 of the License, or
|
|
11
|
+
any later version.
|
|
12
|
+
|
|
13
|
+
BORIS is distributed in the hope that it will be useful,
|
|
14
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
GNU General Public License for more details.
|
|
17
|
+
|
|
18
|
+
You should have received a copy of the GNU General Public License
|
|
19
|
+
along with this program; if not see <http://www.gnu.org/licenses/>.
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
import socket
|
|
24
|
+
import json
|
|
25
|
+
import subprocess
|
|
26
|
+
|
|
27
|
+
import logging
|
|
28
|
+
import config as cfg
|
|
29
|
+
|
|
30
|
+
logger = logging.getLogger(__name__)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class IPC_MPV:
|
|
34
|
+
"""
|
|
35
|
+
class for managing mpv through Inter Process Communication (IPC)
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
media_durations: list = []
|
|
39
|
+
cumul_media_durations: list = []
|
|
40
|
+
fps: list = []
|
|
41
|
+
_pause: bool = False
|
|
42
|
+
|
|
43
|
+
def __init__(self, socket_path: str = cfg.MPV_SOCKET, parent=None):
|
|
44
|
+
# print(f"{parent=}")
|
|
45
|
+
self.socket_path = socket_path
|
|
46
|
+
self.process = None
|
|
47
|
+
# self.sock = None
|
|
48
|
+
self.init_mpv()
|
|
49
|
+
# self.init_socket()
|
|
50
|
+
|
|
51
|
+
def init_mpv(self):
|
|
52
|
+
"""
|
|
53
|
+
Start mpv process and embed it in the PySide6 application.
|
|
54
|
+
"""
|
|
55
|
+
logger.info("Start mpv ipc process")
|
|
56
|
+
# print(f"{self.winId()=}")
|
|
57
|
+
self.process = subprocess.Popen(
|
|
58
|
+
[
|
|
59
|
+
"mpv",
|
|
60
|
+
"--ontop",
|
|
61
|
+
"--no-border",
|
|
62
|
+
"--osc=no", # no on screen commands
|
|
63
|
+
"--input-ipc-server=" + self.socket_path,
|
|
64
|
+
# "--wid=" + str(int(self.winId())), # Embed in the widget
|
|
65
|
+
"--idle=yes", # Keeps mpv running with no video
|
|
66
|
+
"--keep-open=always",
|
|
67
|
+
"--input-default-bindings=no",
|
|
68
|
+
"--input-vo-keyboard=no",
|
|
69
|
+
],
|
|
70
|
+
stdout=subprocess.PIPE,
|
|
71
|
+
stderr=subprocess.PIPE,
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
def send_command(self, command):
|
|
75
|
+
"""
|
|
76
|
+
Send a JSON command to the mpv IPC server.
|
|
77
|
+
"""
|
|
78
|
+
# print(f"send command: {command}")
|
|
79
|
+
try:
|
|
80
|
+
# Create a Unix socket
|
|
81
|
+
with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as client:
|
|
82
|
+
# Connect to the MPV IPC server
|
|
83
|
+
client.connect(self.socket_path)
|
|
84
|
+
# Send the JSON command
|
|
85
|
+
# print(f"{json.dumps(command).encode('utf-8')=}")
|
|
86
|
+
client.sendall(json.dumps(command).encode("utf-8") + b"\n")
|
|
87
|
+
# Receive the response
|
|
88
|
+
response = client.recv(2000)
|
|
89
|
+
|
|
90
|
+
# print(f"{response=}")
|
|
91
|
+
# Parse the response as JSON
|
|
92
|
+
response_data = json.loads(response.decode("utf-8"))
|
|
93
|
+
if response_data["error"] != "success":
|
|
94
|
+
logging.warning(f"send command: {command} response data: {response_data}")
|
|
95
|
+
# Return the 'data' field which contains the playback position
|
|
96
|
+
return response_data.get("data")
|
|
97
|
+
except FileNotFoundError:
|
|
98
|
+
logger.critical("Error: Socket file not found.")
|
|
99
|
+
except Exception as e:
|
|
100
|
+
logger.critical(f"An error occurred: {e}")
|
|
101
|
+
return None
|
|
102
|
+
|
|
103
|
+
@property
|
|
104
|
+
def time_pos(self):
|
|
105
|
+
time_pos = self.send_command({"command": ["get_property", "time-pos"]})
|
|
106
|
+
return time_pos
|
|
107
|
+
|
|
108
|
+
@property
|
|
109
|
+
def duration(self):
|
|
110
|
+
duration_ = self.send_command({"command": ["get_property", "duration"]})
|
|
111
|
+
return duration_
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
def video_zoom(self):
|
|
115
|
+
return self.send_command({"command": ["get_property", "video-zoom"]})
|
|
116
|
+
|
|
117
|
+
@video_zoom.setter
|
|
118
|
+
def video_zoom(self, value):
|
|
119
|
+
self.send_command({"command": ["set_property", "video-zoom", value]})
|
|
120
|
+
return
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
def pause(self):
|
|
124
|
+
return self.send_command({"command": ["get_property", "pause"]})
|
|
125
|
+
|
|
126
|
+
@pause.setter
|
|
127
|
+
def pause(self, value):
|
|
128
|
+
return self.send_command({"command": ["set_property", "pause", value]})
|
|
129
|
+
|
|
130
|
+
@property
|
|
131
|
+
def estimated_frame_number(self):
|
|
132
|
+
return self.send_command({"command": ["get_property", "estimated-frame-number"]})
|
|
133
|
+
|
|
134
|
+
def stop(self):
|
|
135
|
+
self.send_command({"command": ["stop"]})
|
|
136
|
+
return
|
|
137
|
+
|
|
138
|
+
@property
|
|
139
|
+
def playlist(self):
|
|
140
|
+
return self.send_command({"command": ["get_property", "playlist"]})
|
|
141
|
+
|
|
142
|
+
def playlist_next(self):
|
|
143
|
+
self.send_command({"command": ["playlist-next"]})
|
|
144
|
+
return
|
|
145
|
+
|
|
146
|
+
def playlist_prev(self):
|
|
147
|
+
self.send_command({"command": ["playlist-prev"]})
|
|
148
|
+
return
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def playlist_pos(self):
|
|
152
|
+
return self.send_command({"command": ["get_property", "playlist-pos"]})
|
|
153
|
+
|
|
154
|
+
@playlist_pos.setter
|
|
155
|
+
def playlist_pos(self, value):
|
|
156
|
+
return self.send_command({"command": ["set_property", "playlist-pos", value]})
|
|
157
|
+
|
|
158
|
+
@property
|
|
159
|
+
def playlist_count(self):
|
|
160
|
+
return self.send_command({"command": ["get_property", "playlist-count"]})
|
|
161
|
+
|
|
162
|
+
def playlist_append(self, media):
|
|
163
|
+
return self.send_command({"command": ["loadfile", media, "append"]})
|
|
164
|
+
|
|
165
|
+
def wait_until_playing(self):
|
|
166
|
+
return
|
|
167
|
+
|
|
168
|
+
def seek(self, value, mode: str):
|
|
169
|
+
self.send_command({"command": ["seek", value, mode]})
|
|
170
|
+
return
|
|
171
|
+
|
|
172
|
+
@property
|
|
173
|
+
def playback_time(self):
|
|
174
|
+
playback_time_ = self.send_command({"command": ["get_property", "playback-time"]})
|
|
175
|
+
return playback_time_
|
|
176
|
+
|
|
177
|
+
def frame_step(self):
|
|
178
|
+
self.send_command({"command": ["frame-step"]})
|
|
179
|
+
return
|
|
180
|
+
|
|
181
|
+
def frame_back_step(self):
|
|
182
|
+
self.send_command({"command": ["frame-back-step"]})
|
|
183
|
+
return
|
|
184
|
+
|
|
185
|
+
def screenshot_to_file(self, value):
|
|
186
|
+
self.send_command({"command": ["screenshot-to-file", value, "video"]})
|
|
187
|
+
return
|
|
188
|
+
|
|
189
|
+
@property
|
|
190
|
+
def speed(self):
|
|
191
|
+
return self.send_command({"command": ["get_property", "speed"]})
|
|
192
|
+
|
|
193
|
+
@speed.setter
|
|
194
|
+
def speed(self, value):
|
|
195
|
+
self.send_command({"command": ["set_property", "speed", value]})
|
|
196
|
+
return
|
|
197
|
+
|
|
198
|
+
@property
|
|
199
|
+
def video_rotate(self):
|
|
200
|
+
return self.send_command({"command": ["get_property", "video-rotate"]})
|
|
201
|
+
|
|
202
|
+
@video_rotate.setter
|
|
203
|
+
def video_rotate(self, value):
|
|
204
|
+
self.send_command({"command": ["set_property", "video-rotate", value]})
|
|
205
|
+
return
|
|
206
|
+
|
|
207
|
+
@property
|
|
208
|
+
def sub_visibility(self):
|
|
209
|
+
return self.send_command({"command": ["get_property", "sub-visibility"]})
|
|
210
|
+
|
|
211
|
+
@sub_visibility.setter
|
|
212
|
+
def sub_visibility(self, value):
|
|
213
|
+
self.send_command({"command": ["set_property", "sub-visibility", value]})
|
|
214
|
+
return
|
|
215
|
+
|
|
216
|
+
@property
|
|
217
|
+
def brightness(self):
|
|
218
|
+
return self.send_command({"command": ["get_property", "brightness"]})
|
|
219
|
+
|
|
220
|
+
@brightness.setter
|
|
221
|
+
def brightness(self, value):
|
|
222
|
+
self.send_command({"command": ["set_property", "brightness", value]})
|
|
223
|
+
return
|
|
224
|
+
|
|
225
|
+
@property
|
|
226
|
+
def contrast(self):
|
|
227
|
+
return self.send_command({"command": ["get_property", "contrast"]})
|
|
228
|
+
|
|
229
|
+
@contrast.setter
|
|
230
|
+
def contrast(self, value):
|
|
231
|
+
self.send_command({"command": ["set_property", "contrast", value]})
|
|
232
|
+
return
|
|
233
|
+
|
|
234
|
+
@property
|
|
235
|
+
def saturation(self):
|
|
236
|
+
return self.send_command({"command": ["get_property", "saturation"]})
|
|
237
|
+
|
|
238
|
+
@saturation.setter
|
|
239
|
+
def saturation(self, value):
|
|
240
|
+
self.send_command({"command": ["set_property", "saturation", value]})
|
|
241
|
+
return
|
|
242
|
+
|
|
243
|
+
@property
|
|
244
|
+
def gamma(self):
|
|
245
|
+
return self.send_command({"command": ["get_property", "gamma"]})
|
|
246
|
+
|
|
247
|
+
@gamma.setter
|
|
248
|
+
def gamma(self, value):
|
|
249
|
+
self.send_command({"command": ["set_property", "gamma", value]})
|
|
250
|
+
return
|
|
251
|
+
|
|
252
|
+
@property
|
|
253
|
+
def hue(self):
|
|
254
|
+
return self.send_command({"command": ["get_property", "hue"]})
|
|
255
|
+
|
|
256
|
+
@hue.setter
|
|
257
|
+
def hue(self, value):
|
|
258
|
+
self.send_command({"command": ["set_property", "hue", value]})
|
|
259
|
+
return
|
|
260
|
+
|
|
261
|
+
@property
|
|
262
|
+
def container_fps(self):
|
|
263
|
+
return self.send_command({"command": ["get_property", "container-fps"]})
|
|
264
|
+
|
|
265
|
+
@property
|
|
266
|
+
def width(self):
|
|
267
|
+
return self.send_command({"command": ["get_property", "width"]})
|
|
268
|
+
|
|
269
|
+
@property
|
|
270
|
+
def height(self):
|
|
271
|
+
return self.send_command({"command": ["get_property", "height"]})
|
|
272
|
+
|
|
273
|
+
@property
|
|
274
|
+
def video_format(self):
|
|
275
|
+
return self.send_command({"command": ["get_property", "video-format"]})
|
|
276
|
+
|
|
277
|
+
@property
|
|
278
|
+
def deinterlace(self):
|
|
279
|
+
return self.send_command({"command": ["get_property", "deinterlace"]})
|
|
280
|
+
|
|
281
|
+
@deinterlace.setter
|
|
282
|
+
def deinterlace(self, value):
|
|
283
|
+
self.send_command({"command": ["set_property", "deinterlace", value]})
|
|
284
|
+
return
|
|
285
|
+
|
|
286
|
+
@property
|
|
287
|
+
def audio_bitrate(self):
|
|
288
|
+
return self.send_command({"command": ["get_property", "audio-bitrate"]})
|
|
289
|
+
|
|
290
|
+
@property
|
|
291
|
+
def eof_reached(self):
|
|
292
|
+
return self.send_command({"command": ["get_property", "eof-reached"]})
|
|
293
|
+
|
|
294
|
+
@property
|
|
295
|
+
def core_idle(self):
|
|
296
|
+
return self.send_command({"command": ["get_property", "core-idle"]})
|
|
297
|
+
|
|
298
|
+
@property
|
|
299
|
+
def video_pan_x(self):
|
|
300
|
+
return self.send_command({"command": ["get_property", "video-pan-x"]})
|
|
301
|
+
|
|
302
|
+
@video_pan_x.setter
|
|
303
|
+
def video_pan_x(self, value):
|
|
304
|
+
self.send_command({"command": ["set_property", "video-pan-x", value]})
|
|
305
|
+
return
|
|
306
|
+
|
|
307
|
+
@property
|
|
308
|
+
def video_pan_y(self):
|
|
309
|
+
return self.send_command({"command": ["get_property", "video-pan-y"]})
|
|
310
|
+
|
|
311
|
+
@video_pan_y.setter
|
|
312
|
+
def video_pan_y(self, value):
|
|
313
|
+
self.send_command({"command": ["set_property", "video-pan-y", value]})
|
|
314
|
+
return
|
|
315
|
+
|
|
316
|
+
"""
|
|
317
|
+
@property
|
|
318
|
+
def xxx(self):
|
|
319
|
+
return self.send_command({"command": ["get_property", "xxx"]})
|
|
320
|
+
|
|
321
|
+
@xxx.setter
|
|
322
|
+
def xxx(self, value):
|
|
323
|
+
self.send_command({"command": ["set_property", "xxx", value]})
|
|
324
|
+
return
|
|
325
|
+
"""
|