boris-behav-obs 9.7__tar.gz → 9.7.2__tar.gz
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.
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/PKG-INFO +2 -2
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/README.md +1 -1
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/cmd_arguments.py +2 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/config.py +8 -2
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/config_file.py +3 -3
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/core.py +123 -94
- boris_behav_obs-9.7.2/boris/ipc_mpv.py +304 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/observation_operations.py +173 -230
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/player_dock_widget.py +9 -4
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/preferences.py +6 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/preferences_ui.py +46 -28
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/project_functions.py +8 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/utilities.py +77 -56
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/version.py +2 -2
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/video_operations.py +1 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris_behav_obs.egg-info/PKG-INFO +2 -2
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris_behav_obs.egg-info/SOURCES.txt +1 -1
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/pyproject.toml +1 -8
- boris_behav_obs-9.7/boris/mpv-1.0.3.py +0 -2102
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/LICENSE.TXT +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/MANIFEST.in +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/README.TXT +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/__init__.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/__main__.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/about.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/add_modifier.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/add_modifier_ui.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/advanced_event_filtering.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/analysis_plugins/__init__.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/analysis_plugins/_latency.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/analysis_plugins/irr_cohen_kappa.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/analysis_plugins/irr_cohen_kappa_with_modifiers.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/analysis_plugins/irr_weighted_cohen_kappa.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/analysis_plugins/irr_weighted_cohen_kappa_with_modifiers.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/analysis_plugins/list_of_dataframe_columns.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/analysis_plugins/number_of_occurences.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/analysis_plugins/number_of_occurences_by_independent_variable.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/analysis_plugins/time_budget.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/behav_coding_map_creator.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/behavior_binary_table.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/behaviors_coding_map.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/boris_cli.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/coding_pad.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/connections.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/converters.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/converters_ui.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/cooccurence.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/core_qrc.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/core_ui.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/db_functions.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/dev.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/dialog.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/duration_widget.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/edit_event.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/edit_event_ui.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/event_operations.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/events_cursor.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/events_snapshots.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/exclusion_matrix.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/export_events.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/export_observation.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/external_processes.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/geometric_measurement.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/gui_utilities.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/image_overlay.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/import_observations.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/irr.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/latency.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/measurement_widget.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/media_file.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/menu_options.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/modifier_coding_map_creator.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/modifiers_coding_map.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/mpv.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/mpv2.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/observation.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/observation_ui.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/observations_list.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/otx_parser.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/param_panel.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/param_panel_ui.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/plot_data_module.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/plot_events.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/plot_events_rt.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/plot_spectrogram_rt.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/plot_waveform_rt.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/plugins.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/portion/__init__.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/portion/const.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/portion/dict.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/portion/func.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/portion/interval.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/portion/io.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/project.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/project_import_export.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/project_ui.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/qrc_boris.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/qrc_boris5.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/select_modifiers.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/select_observations.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/select_subj_behav.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/state_events.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/subjects_pad.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/synthetic_time_budget.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/time_budget_functions.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/time_budget_widget.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/transitions.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/video_equalizer.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/video_equalizer_ui.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/view_df.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/view_df_ui.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris/write_event.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris_behav_obs.egg-info/dependency_links.txt +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris_behav_obs.egg-info/entry_points.txt +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris_behav_obs.egg-info/requires.txt +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/boris_behav_obs.egg-info/top_level.txt +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/setup.cfg +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/tests/test_db_functions.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/tests/test_export_observation.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/tests/test_irr.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/tests/test_observation_gui.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/tests/test_otx_parser.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/tests/test_preferences_gui.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/tests/test_project_functions.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/tests/test_time_budget.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/tests/test_utilities.py +0 -0
- {boris_behav_obs-9.7 → boris_behav_obs-9.7.2}/tests/test_utilities2.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: boris-behav-obs
|
|
3
|
-
Version: 9.7
|
|
3
|
+
Version: 9.7.2
|
|
4
4
|
Summary: BORIS - Behavioral Observation Research Interactive Software
|
|
5
5
|
Author-email: Olivier Friard <olivier.friard@unito.it>
|
|
6
6
|
License-Expression: GPL-3.0-only
|
|
@@ -52,7 +52,7 @@ It provides also some analysis tools like time budget and some plotting function
|
|
|
52
52
|
<!-- The BO-RIS paper has more than [ citations](https://www.boris.unito.it/citations) in peer-reviewed scientific publications. -->
|
|
53
53
|
|
|
54
54
|
|
|
55
|
-
The BORIS paper has more than
|
|
55
|
+
The BORIS paper has more than 2407 citations in peer-reviewed scientific publications.
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
|
|
@@ -14,7 +14,7 @@ It provides also some analysis tools like time budget and some plotting function
|
|
|
14
14
|
<!-- The BO-RIS paper has more than [ citations](https://www.boris.unito.it/citations) in peer-reviewed scientific publications. -->
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
The BORIS paper has more than
|
|
17
|
+
The BORIS paper has more than 2407 citations in peer-reviewed scientific publications.
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
|
|
@@ -35,6 +35,8 @@ def parse_arguments():
|
|
|
35
35
|
parser.add_option("-n", "--nosplashscreen", action="store_true", default=False, help="No splash screen")
|
|
36
36
|
parser.add_option("-p", "--project", action="store", default="", dest="project", help="Project file")
|
|
37
37
|
parser.add_option("-o", "--observation", action="store", default="", dest="observation", help="Observation id")
|
|
38
|
+
parser.add_option("-i", "--ipc", action="store_true", default="", dest="ipc", help="MPV IPC mode")
|
|
39
|
+
|
|
38
40
|
parser.add_option(
|
|
39
41
|
"-f",
|
|
40
42
|
"--no-first-launch-dialog",
|
|
@@ -22,8 +22,7 @@ This file is part of BORIS.
|
|
|
22
22
|
|
|
23
23
|
programName: str = "BORIS"
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
MACOS_CODE = "darwin"
|
|
25
|
+
# socket for MPV IPC mode
|
|
27
26
|
MPV_SOCKET = "/tmp/mpvsocket"
|
|
28
27
|
|
|
29
28
|
|
|
@@ -133,6 +132,8 @@ POINT_EVENT_PLOT_COLOR = "black"
|
|
|
133
132
|
|
|
134
133
|
CHAR_FORBIDDEN_IN_MODIFIERS = "(|),`~"
|
|
135
134
|
|
|
135
|
+
FAST_FORWARD_DEFAULT_VALUE:float = 10.0
|
|
136
|
+
|
|
136
137
|
ADAPT_FAST_JUMP = "adapt_fast_jump"
|
|
137
138
|
ADAPT_FAST_JUMP_DEFAULT = False
|
|
138
139
|
|
|
@@ -420,6 +421,10 @@ MPV_HWDEC_AUTOSAFE = "auto-safe"
|
|
|
420
421
|
MPV_HWDEC_OPTIONS = (MPV_HWDEC_AUTO, MPV_HWDEC_AUTOSAFE, MPV_HWDEC_NO)
|
|
421
422
|
MPV_HWDEC_DEFAULT_VALUE = MPV_HWDEC_AUTO
|
|
422
423
|
|
|
424
|
+
# frame step size (disabled)
|
|
425
|
+
# FRAME_STEP_SIZE: str = "frame_step_size"
|
|
426
|
+
# FRAME_STEP_SIZE_DEFAULT_VALUE: int = 1
|
|
427
|
+
|
|
423
428
|
ANALYSIS_PLUGINS = "analysis_plugins"
|
|
424
429
|
EXCLUDED_PLUGINS = "excluded_plugins"
|
|
425
430
|
PERSONAL_PLUGINS_DIR = "personal_plugins_dir"
|
|
@@ -731,6 +736,7 @@ INIT_PARAM = {
|
|
|
731
736
|
MPV_HWDEC: MPV_HWDEC_DEFAULT_VALUE,
|
|
732
737
|
PROJECT_FILE_INDENTATION: PROJECT_FILE_INDENTATION_DEFAULT_VALUE,
|
|
733
738
|
f"{MEDIA} tw fields": MEDIA_TW_EVENTS_FIELDS_DEFAULT,
|
|
739
|
+
# FRAME_STEP_SIZE: FRAME_STEP_SIZE_DEFAULT_VALUE,
|
|
734
740
|
}
|
|
735
741
|
|
|
736
742
|
SDIS_EXT = "sds"
|
|
@@ -82,11 +82,11 @@ def read(self):
|
|
|
82
82
|
|
|
83
83
|
logging.debug(f"time format: {self.timeFormat}")
|
|
84
84
|
|
|
85
|
-
self.fast =
|
|
85
|
+
self.fast = cfg.FAST_FORWARD_DEFAULT_VALUE
|
|
86
86
|
try:
|
|
87
|
-
self.fast =
|
|
87
|
+
self.fast = float(settings.value("Time/fast_forward_speed"))
|
|
88
88
|
except Exception:
|
|
89
|
-
self.fast =
|
|
89
|
+
self.fast = cfg.FAST_FORWARD_DEFAULT_VALUE
|
|
90
90
|
|
|
91
91
|
logging.debug(f"Time/fast_forward_speed: {self.fast}")
|
|
92
92
|
|
|
@@ -43,7 +43,6 @@ import locale
|
|
|
43
43
|
import tempfile
|
|
44
44
|
import time
|
|
45
45
|
import urllib.request
|
|
46
|
-
from typing import Union, Tuple
|
|
47
46
|
from decimal import Decimal as dec
|
|
48
47
|
from decimal import ROUND_DOWN
|
|
49
48
|
import gzip
|
|
@@ -150,7 +149,7 @@ if util.versiontuple(platform.python_version()) < util.versiontuple(MIN_PYTHON_V
|
|
|
150
149
|
logging.critical(msg)
|
|
151
150
|
sys.exit()
|
|
152
151
|
|
|
153
|
-
if sys.platform
|
|
152
|
+
if sys.platform.startswith("darwin"): # for MacOS
|
|
154
153
|
os.environ["LC_ALL"] = "en_US.UTF-8"
|
|
155
154
|
|
|
156
155
|
|
|
@@ -242,7 +241,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
242
241
|
current_player: int = 0 # id of the selected (left click) video player
|
|
243
242
|
|
|
244
243
|
mem_media_name: str = "" # record current media name. Use to check if media changed
|
|
245
|
-
mem_playlist_index:
|
|
244
|
+
mem_playlist_index: int | None = None
|
|
246
245
|
saved_state = None
|
|
247
246
|
user_move_slider: bool = False
|
|
248
247
|
observationId: str = "" # current observation id
|
|
@@ -400,7 +399,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
400
399
|
|
|
401
400
|
# if BORIS is running on Mac lock all dockwidget features
|
|
402
401
|
# because Qdockwidgets may have a strange behavior
|
|
403
|
-
if sys.platform
|
|
402
|
+
if sys.platform.startswith("darwin"):
|
|
404
403
|
self.action_block_dockwidgets.setChecked(True)
|
|
405
404
|
self.block_dockwidgets()
|
|
406
405
|
|
|
@@ -739,7 +738,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
739
738
|
text: str = "Behaviors to show in ethogram list",
|
|
740
739
|
table: str = cfg.ETHOGRAM,
|
|
741
740
|
behavior_type: list = cfg.STATE_EVENT_TYPES,
|
|
742
|
-
) ->
|
|
741
|
+
) -> tuple[bool, list]:
|
|
743
742
|
"""
|
|
744
743
|
allow user to:
|
|
745
744
|
filter behaviors in ethogram widget
|
|
@@ -1428,55 +1427,60 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
1428
1427
|
if not self.dw_player[player].player.playlist_count:
|
|
1429
1428
|
return
|
|
1430
1429
|
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
if
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
self.dw_player[player].player.seek(new_time_float, "absolute+exact")
|
|
1430
|
+
try:
|
|
1431
|
+
# one media
|
|
1432
|
+
if self.dw_player[player].player.playlist_count == 1:
|
|
1433
|
+
if new_time < self.dw_player[player].player.duration:
|
|
1434
|
+
new_time_float = round(float(new_time), 3)
|
|
1437
1435
|
|
|
1438
|
-
|
|
1439
|
-
self.
|
|
1440
|
-
round(self.dw_player[0].player.time_pos / self.dw_player[0].player.duration * (cfg.SLIDER_MAXIMUM - 1))
|
|
1441
|
-
)
|
|
1442
|
-
return 0
|
|
1443
|
-
else:
|
|
1444
|
-
return 1
|
|
1436
|
+
self.dw_player[player].player.seek(new_time_float, "absolute+exact")
|
|
1437
|
+
self.mpv_timer_out()
|
|
1445
1438
|
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
for idx, d in enumerate(self.dw_player[player].cumul_media_durations_sec[:-1]):
|
|
1450
|
-
if d <= new_time < self.dw_player[player].cumul_media_durations_sec[idx + 1]:
|
|
1451
|
-
self.dw_player[player].player.playlist_pos = idx
|
|
1452
|
-
time.sleep(0.5)
|
|
1453
|
-
|
|
1454
|
-
self.dw_player[player].player.seek(
|
|
1455
|
-
round(
|
|
1456
|
-
float(new_time)
|
|
1457
|
-
- sum(self.dw_player[player].media_durations[0 : self.dw_player[player].player.playlist_pos]) / 1000,
|
|
1458
|
-
3,
|
|
1459
|
-
),
|
|
1460
|
-
"absolute+exact",
|
|
1439
|
+
if player == 0 and not self.user_move_slider:
|
|
1440
|
+
self.video_slider.setValue(
|
|
1441
|
+
round(self.dw_player[0].player.time_pos / self.dw_player[0].player.duration * (cfg.SLIDER_MAXIMUM - 1))
|
|
1461
1442
|
)
|
|
1443
|
+
return 0
|
|
1444
|
+
else:
|
|
1445
|
+
return 1
|
|
1462
1446
|
|
|
1463
|
-
|
|
1447
|
+
# many media
|
|
1448
|
+
else:
|
|
1449
|
+
if new_time < self.dw_player[player].cumul_media_durations_sec[-1]:
|
|
1450
|
+
for idx, d in enumerate(self.dw_player[player].cumul_media_durations_sec[:-1]):
|
|
1451
|
+
if d <= new_time < self.dw_player[player].cumul_media_durations_sec[idx + 1]:
|
|
1452
|
+
self.dw_player[player].player.playlist_pos = idx
|
|
1453
|
+
time.sleep(0.5)
|
|
1454
|
+
|
|
1455
|
+
self.dw_player[player].player.seek(
|
|
1456
|
+
round(
|
|
1457
|
+
float(new_time)
|
|
1458
|
+
- sum(self.dw_player[player].media_durations[0 : self.dw_player[player].player.playlist_pos]) / 1000,
|
|
1459
|
+
3,
|
|
1460
|
+
),
|
|
1461
|
+
"absolute+exact",
|
|
1462
|
+
)
|
|
1464
1463
|
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1464
|
+
break
|
|
1465
|
+
|
|
1466
|
+
if player == 0 and not self.user_move_slider:
|
|
1467
|
+
self.video_slider.setValue(
|
|
1468
|
+
round(self.dw_player[0].player.time_pos / self.dw_player[0].player.duration * (cfg.SLIDER_MAXIMUM - 1))
|
|
1469
|
+
)
|
|
1470
|
+
return 0
|
|
1471
|
+
else:
|
|
1472
|
+
QMessageBox.warning(
|
|
1473
|
+
self,
|
|
1474
|
+
cfg.programName,
|
|
1475
|
+
(
|
|
1476
|
+
"The indicated position is greater than the total media duration "
|
|
1477
|
+
f"({util.seconds2time(self.dw_player[player].cumul_media_durations_sec[-1])})"
|
|
1478
|
+
),
|
|
1468
1479
|
)
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
cfg.programName,
|
|
1474
|
-
(
|
|
1475
|
-
"The indicated position is greater than the total media duration "
|
|
1476
|
-
f"({util.seconds2time(self.dw_player[player].cumul_media_durations_sec[-1])})"
|
|
1477
|
-
),
|
|
1478
|
-
)
|
|
1479
|
-
return 1
|
|
1480
|
+
return 1
|
|
1481
|
+
except Exception as e:
|
|
1482
|
+
print(f"error in seek mediaplayer function: {e}")
|
|
1483
|
+
return 0
|
|
1480
1484
|
|
|
1481
1485
|
def jump_to(self) -> None:
|
|
1482
1486
|
"""
|
|
@@ -3677,14 +3681,19 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
3677
3681
|
"""
|
|
3678
3682
|
show next frame
|
|
3679
3683
|
"""
|
|
3684
|
+
# frame_step_size = self.config_param.get(cfg.FRAME_STEP_SIZE, cfg.FRAME_STEP_SIZE_DEFAULT_VALUE)
|
|
3685
|
+
|
|
3680
3686
|
if self.playerType == cfg.IMAGES:
|
|
3681
3687
|
if self.image_idx < len(self.images_list) - 1:
|
|
3682
|
-
self.image_idx += 1
|
|
3688
|
+
self.image_idx += 1 # frame_step_size
|
|
3683
3689
|
self.extract_frame(self.dw_player[0])
|
|
3684
3690
|
|
|
3685
3691
|
if self.playerType == cfg.MEDIA:
|
|
3686
3692
|
for dw in self.dw_player:
|
|
3693
|
+
# for _ in range(frame_step_size):
|
|
3687
3694
|
dw.player.frame_step()
|
|
3695
|
+
# time.sleep(0.5)
|
|
3696
|
+
|
|
3688
3697
|
if self.geometric_measurements_mode:
|
|
3689
3698
|
self.extract_frame(dw)
|
|
3690
3699
|
|
|
@@ -3692,6 +3701,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
3692
3701
|
for idx in self.plot_data:
|
|
3693
3702
|
self.timer_plot_data_out(self.plot_data[idx])
|
|
3694
3703
|
|
|
3704
|
+
self.mpv_timer_out()
|
|
3705
|
+
|
|
3695
3706
|
if self.geometric_measurements_mode:
|
|
3696
3707
|
geometric_measurement.redraw_measurements(self)
|
|
3697
3708
|
|
|
@@ -3709,6 +3720,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
3709
3720
|
if self.playerType == cfg.MEDIA:
|
|
3710
3721
|
for dw in self.dw_player:
|
|
3711
3722
|
dw.player.frame_back_step()
|
|
3723
|
+
|
|
3712
3724
|
if self.geometric_measurements_mode:
|
|
3713
3725
|
self.extract_frame(dw)
|
|
3714
3726
|
|
|
@@ -3716,6 +3728,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
3716
3728
|
for idx in self.plot_data:
|
|
3717
3729
|
self.timer_plot_data_out(self.plot_data[idx])
|
|
3718
3730
|
|
|
3731
|
+
self.mpv_timer_out()
|
|
3732
|
+
|
|
3719
3733
|
if self.geometric_measurements_mode:
|
|
3720
3734
|
geometric_measurement.redraw_measurements(self)
|
|
3721
3735
|
|
|
@@ -3855,15 +3869,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
3855
3869
|
write_event.write_event(self, event, cumulative_time)
|
|
3856
3870
|
# write_event.write_event(self, event, self.getLaps())
|
|
3857
3871
|
|
|
3858
|
-
def get_frame_index(self, player_idx: int = 0) ->
|
|
3872
|
+
def get_frame_index(self, player_idx: int = 0) -> int | str:
|
|
3859
3873
|
"""
|
|
3860
3874
|
returns frame index for player player_idx
|
|
3861
3875
|
"""
|
|
3862
3876
|
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
else:
|
|
3866
|
-
estimated_frame_number = observation_operations.send_command({"command": ["get_property", "estimated_frame_number"]})
|
|
3877
|
+
estimated_frame_number = self.dw_player[player_idx].player.estimated_frame_number
|
|
3878
|
+
|
|
3867
3879
|
if estimated_frame_number is not None:
|
|
3868
3880
|
return estimated_frame_number
|
|
3869
3881
|
else:
|
|
@@ -3939,7 +3951,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
3939
3951
|
if self.dw_player[0].player.duration is None:
|
|
3940
3952
|
return
|
|
3941
3953
|
video_position = slider_position * self.dw_player[0].player.duration
|
|
3942
|
-
self.dw_player[0].player.command("seek", str(video_position), "absolute")
|
|
3954
|
+
# self.dw_player[0].player.command("seek", str(video_position), "absolute")
|
|
3955
|
+
self.dw_player[0].player.seek(video_position, "absolute")
|
|
3943
3956
|
|
|
3944
3957
|
self.plot_timer_out()
|
|
3945
3958
|
|
|
@@ -4132,7 +4145,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
4132
4145
|
self.dw_player[n_player].player.playlist_pos = self.dw_player[n_player].player.playlist_count - 1
|
|
4133
4146
|
self.seek_mediaplayer(self.dw_player[n_player].media_durations[-1], player=n_player)
|
|
4134
4147
|
|
|
4135
|
-
def mpv_timer_out(self, value:
|
|
4148
|
+
def mpv_timer_out(self, value: float | None = None, scroll_slider=True):
|
|
4136
4149
|
"""
|
|
4137
4150
|
print the media current position and total length for MPV player
|
|
4138
4151
|
scroll video slider to video position
|
|
@@ -4147,8 +4160,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
4147
4160
|
frame_idx = self.get_frame_index()
|
|
4148
4161
|
# frame_idx = 0
|
|
4149
4162
|
|
|
4150
|
-
if value is None:
|
|
4151
|
-
current_media_time_pos = 0
|
|
4163
|
+
if value is None: # ipc mpv
|
|
4164
|
+
current_media_time_pos = self.dw_player[0].player.time_pos
|
|
4152
4165
|
else:
|
|
4153
4166
|
current_media_time_pos = value
|
|
4154
4167
|
|
|
@@ -4186,22 +4199,19 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
4186
4199
|
|
|
4187
4200
|
ct0 = cumulative_time_pos
|
|
4188
4201
|
|
|
4189
|
-
if
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
ct = self.getLaps(n_player=n_player)
|
|
4202
|
+
if self.dw_player[0].player.time_pos is not None:
|
|
4203
|
+
for n_player in range(1, len(self.dw_player)):
|
|
4204
|
+
ct = self.getLaps(n_player=n_player)
|
|
4193
4205
|
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
>= 1
|
|
4198
|
-
):
|
|
4199
|
-
self.sync_time(n_player, ct0) # self.seek_mediaplayer(ct0, n_player)
|
|
4206
|
+
# sync players 2..8 if time diff >= 1 s
|
|
4207
|
+
if abs(ct0 - (ct + dec(self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.OFFSET][str(n_player + 1)]))) >= 1:
|
|
4208
|
+
self.sync_time(n_player, ct0) # self.seek_mediaplayer(ct0, n_player)
|
|
4200
4209
|
|
|
4201
4210
|
currentTimeOffset = dec(cumulative_time_pos + self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TIME_OFFSET])
|
|
4202
4211
|
|
|
4203
4212
|
all_media_duration = sum(self.dw_player[0].media_durations) / 1000
|
|
4204
4213
|
current_media_duration = self.dw_player[0].player.duration # mediaplayer_length
|
|
4214
|
+
|
|
4205
4215
|
self.mediaTotalLength = current_media_duration
|
|
4206
4216
|
|
|
4207
4217
|
# current state(s)
|
|
@@ -4301,6 +4311,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
4301
4311
|
|
|
4302
4312
|
self.actionPlay.setIcon(QIcon(f":/play_{gui_utilities.theme_mode()}"))
|
|
4303
4313
|
|
|
4314
|
+
print(f"{msg=}")
|
|
4315
|
+
|
|
4304
4316
|
if msg:
|
|
4305
4317
|
self.lb_current_media_time.setText(msg)
|
|
4306
4318
|
|
|
@@ -4317,14 +4329,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
4317
4329
|
|
|
4318
4330
|
logging.info("Media end reached")
|
|
4319
4331
|
|
|
4320
|
-
"""
|
|
4321
|
-
print(f"{self.dw_player[0].player.time_pos=}")
|
|
4322
|
-
print(f"{self.dw_player[0].player.pause=}")
|
|
4323
|
-
print(f"{self.dw_player[0].player.core_idle=}")
|
|
4324
|
-
print(f"{self.dw_player[0].player.eof_reached=}")
|
|
4325
|
-
print(f"{self.dw_player[0].player.playlist_pos=}")
|
|
4326
|
-
"""
|
|
4327
|
-
|
|
4328
4332
|
if self.pj[cfg.OBSERVATIONS][self.observationId][cfg.CLOSE_BEHAVIORS_BETWEEN_VIDEOS]:
|
|
4329
4333
|
if self.dw_player[0].player.eof_reached and self.dw_player[0].player.core_idle:
|
|
4330
4334
|
if self.dw_player[0].player.playlist_pos == len(self.dw_player[0].player.playlist) - 1:
|
|
@@ -4480,7 +4484,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
4480
4484
|
for x in self.pj[cfg.OBSERVATIONS][obs_id][cfg.EVENTS]
|
|
4481
4485
|
)
|
|
4482
4486
|
|
|
4483
|
-
def choose_behavior(self, obs_key) ->
|
|
4487
|
+
def choose_behavior(self, obs_key) -> None | str:
|
|
4484
4488
|
"""
|
|
4485
4489
|
fill listwidget with all behaviors coded by key
|
|
4486
4490
|
|
|
@@ -4512,7 +4516,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
4512
4516
|
else:
|
|
4513
4517
|
return None
|
|
4514
4518
|
|
|
4515
|
-
def choose_subject(self, subject_key) ->
|
|
4519
|
+
def choose_subject(self, subject_key) -> None | str:
|
|
4516
4520
|
"""
|
|
4517
4521
|
fill listwidget with all subjects coded by key
|
|
4518
4522
|
|
|
@@ -4594,18 +4598,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
4594
4598
|
|
|
4595
4599
|
if self.playerType == cfg.MEDIA:
|
|
4596
4600
|
# cumulative time
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
)
|
|
4601
|
-
else:
|
|
4602
|
-
time_pos = observation_operations.send_command({"command": ["get_property", "time-pos"]})
|
|
4603
|
-
# TODO: fix!
|
|
4604
|
-
return dec(time_pos)
|
|
4601
|
+
mem_laps = sum(self.dw_player[n_player].media_durations[0 : self.dw_player[n_player].player.playlist_pos]) + (
|
|
4602
|
+
0 if self.dw_player[n_player].player.time_pos is None else self.dw_player[n_player].player.time_pos * 1000
|
|
4603
|
+
)
|
|
4605
4604
|
|
|
4606
4605
|
return dec(str(round(mem_laps / 1000, 3)))
|
|
4607
4606
|
|
|
4608
|
-
def get_obs_time(self, n_player: int = 0) ->
|
|
4607
|
+
def get_obs_time(self, n_player: int = 0) -> tuple[dec, dec | None]:
|
|
4609
4608
|
"""
|
|
4610
4609
|
returns time in current media and cumulative time from begining of observation
|
|
4611
4610
|
do not add time offset
|
|
@@ -5389,6 +5388,18 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
5389
5388
|
"""
|
|
5390
5389
|
logging.debug("function: closeEvent")
|
|
5391
5390
|
|
|
5391
|
+
# close MPV in IPC mode
|
|
5392
|
+
if self.MPV_IPC_MODE:
|
|
5393
|
+
try:
|
|
5394
|
+
for idx, p in enumerate(self.dw_player):
|
|
5395
|
+
p.player.process.terminate()
|
|
5396
|
+
try:
|
|
5397
|
+
p.player.process.wait(timeout=3) # wait up to 3s
|
|
5398
|
+
except subprocess.TimeoutExpired:
|
|
5399
|
+
p.player.process.kill() # force if still alive
|
|
5400
|
+
except Exception as e:
|
|
5401
|
+
logging.warning(f"Error stopping MPV process #{idx}: {e}")
|
|
5402
|
+
|
|
5392
5403
|
# check if re-encoding
|
|
5393
5404
|
if self.processes:
|
|
5394
5405
|
if (
|
|
@@ -5442,6 +5453,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
5442
5453
|
check if first player ended
|
|
5443
5454
|
"""
|
|
5444
5455
|
|
|
5456
|
+
print("play_video")
|
|
5457
|
+
|
|
5445
5458
|
if self.geometric_measurements_mode:
|
|
5446
5459
|
return
|
|
5447
5460
|
|
|
@@ -5463,6 +5476,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
5463
5476
|
|
|
5464
5477
|
self.statusbar.showMessage("", 0)
|
|
5465
5478
|
|
|
5479
|
+
if self.ipc_mpv_timer is not None:
|
|
5480
|
+
self.ipc_mpv_timer.start()
|
|
5481
|
+
|
|
5466
5482
|
self.plot_timer.start()
|
|
5467
5483
|
|
|
5468
5484
|
# start all timer for plotting data
|
|
@@ -5494,6 +5510,10 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
5494
5510
|
for data_timer in self.ext_data_timer_list:
|
|
5495
5511
|
data_timer.stop()
|
|
5496
5512
|
|
|
5513
|
+
if self.ipc_mpv_timer is not None:
|
|
5514
|
+
self.ipc_mpv_timer.stop()
|
|
5515
|
+
self.mpv_timer_out()
|
|
5516
|
+
|
|
5497
5517
|
player.player.pause = True
|
|
5498
5518
|
|
|
5499
5519
|
self.lb_player_status.setText(msg)
|
|
@@ -5543,13 +5563,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
5543
5563
|
|
|
5544
5564
|
self.update_visualizations()
|
|
5545
5565
|
|
|
5546
|
-
# subtitles
|
|
5547
|
-
"""
|
|
5548
|
-
st_track_number = 0 if self.config_param[DISPLAY_SUBTITLES] else -1
|
|
5549
|
-
for player in self.dw_player:
|
|
5550
|
-
player.mediaplayer.video_set_spu(st_track_number)
|
|
5551
|
-
"""
|
|
5552
|
-
|
|
5553
5566
|
def jumpForward_activated(self):
|
|
5554
5567
|
"""
|
|
5555
5568
|
forward from current position
|
|
@@ -5806,6 +5819,22 @@ def main():
|
|
|
5806
5819
|
results.ptText.appendHtml(f"Some issues were found in the project<br><br>{msg}")
|
|
5807
5820
|
results.show()
|
|
5808
5821
|
|
|
5822
|
+
# check mpv IPC mode
|
|
5823
|
+
window.MPV_IPC_MODE = False
|
|
5824
|
+
if options.ipc or sys.platform.startswith("darwin"):
|
|
5825
|
+
window.MPV_IPC_MODE = True
|
|
5826
|
+
# check if mpv is available
|
|
5827
|
+
if not shutil.which("mpv"):
|
|
5828
|
+
logging.critical("The mpv command is not available on the path")
|
|
5829
|
+
QMessageBox.critical(
|
|
5830
|
+
None,
|
|
5831
|
+
cfg.programName,
|
|
5832
|
+
("The mpv command is not available on the path"),
|
|
5833
|
+
QMessageBox.Ok | QMessageBox.Default,
|
|
5834
|
+
QMessageBox.NoButton,
|
|
5835
|
+
)
|
|
5836
|
+
sys.exit()
|
|
5837
|
+
|
|
5809
5838
|
window.show()
|
|
5810
5839
|
window.raise_() # for overlapping widget (?)
|
|
5811
5840
|
|