boris-behav-obs 9.7__tar.gz → 9.7.1__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.
Files changed (127) hide show
  1. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/PKG-INFO +2 -2
  2. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/README.md +1 -1
  3. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/cmd_arguments.py +2 -0
  4. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/config.py +1 -2
  5. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/core.py +119 -86
  6. boris_behav_obs-9.7.1/boris/ipc_mpv.py +304 -0
  7. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/observation_operations.py +173 -230
  8. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/player_dock_widget.py +9 -4
  9. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/utilities.py +77 -56
  10. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/version.py +2 -2
  11. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/video_operations.py +1 -0
  12. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris_behav_obs.egg-info/PKG-INFO +2 -2
  13. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris_behav_obs.egg-info/SOURCES.txt +1 -1
  14. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/pyproject.toml +1 -8
  15. boris_behav_obs-9.7/boris/mpv-1.0.3.py +0 -2102
  16. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/LICENSE.TXT +0 -0
  17. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/MANIFEST.in +0 -0
  18. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/README.TXT +0 -0
  19. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/__init__.py +0 -0
  20. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/__main__.py +0 -0
  21. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/about.py +0 -0
  22. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/add_modifier.py +0 -0
  23. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/add_modifier_ui.py +0 -0
  24. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/advanced_event_filtering.py +0 -0
  25. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/analysis_plugins/__init__.py +0 -0
  26. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/analysis_plugins/_latency.py +0 -0
  27. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/analysis_plugins/irr_cohen_kappa.py +0 -0
  28. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/analysis_plugins/irr_cohen_kappa_with_modifiers.py +0 -0
  29. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/analysis_plugins/irr_weighted_cohen_kappa.py +0 -0
  30. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/analysis_plugins/irr_weighted_cohen_kappa_with_modifiers.py +0 -0
  31. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/analysis_plugins/list_of_dataframe_columns.py +0 -0
  32. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/analysis_plugins/number_of_occurences.py +0 -0
  33. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/analysis_plugins/number_of_occurences_by_independent_variable.py +0 -0
  34. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/analysis_plugins/time_budget.py +0 -0
  35. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/behav_coding_map_creator.py +0 -0
  36. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/behavior_binary_table.py +0 -0
  37. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/behaviors_coding_map.py +0 -0
  38. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/boris_cli.py +0 -0
  39. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/coding_pad.py +0 -0
  40. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/config_file.py +0 -0
  41. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/connections.py +0 -0
  42. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/converters.py +0 -0
  43. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/converters_ui.py +0 -0
  44. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/cooccurence.py +0 -0
  45. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/core_qrc.py +0 -0
  46. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/core_ui.py +0 -0
  47. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/db_functions.py +0 -0
  48. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/dev.py +0 -0
  49. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/dialog.py +0 -0
  50. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/duration_widget.py +0 -0
  51. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/edit_event.py +0 -0
  52. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/edit_event_ui.py +0 -0
  53. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/event_operations.py +0 -0
  54. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/events_cursor.py +0 -0
  55. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/events_snapshots.py +0 -0
  56. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/exclusion_matrix.py +0 -0
  57. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/export_events.py +0 -0
  58. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/export_observation.py +0 -0
  59. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/external_processes.py +0 -0
  60. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/geometric_measurement.py +0 -0
  61. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/gui_utilities.py +0 -0
  62. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/image_overlay.py +0 -0
  63. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/import_observations.py +0 -0
  64. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/irr.py +0 -0
  65. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/latency.py +0 -0
  66. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/measurement_widget.py +0 -0
  67. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/media_file.py +0 -0
  68. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/menu_options.py +0 -0
  69. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/modifier_coding_map_creator.py +0 -0
  70. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/modifiers_coding_map.py +0 -0
  71. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/mpv.py +0 -0
  72. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/mpv2.py +0 -0
  73. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/observation.py +0 -0
  74. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/observation_ui.py +0 -0
  75. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/observations_list.py +0 -0
  76. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/otx_parser.py +0 -0
  77. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/param_panel.py +0 -0
  78. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/param_panel_ui.py +0 -0
  79. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/plot_data_module.py +0 -0
  80. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/plot_events.py +0 -0
  81. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/plot_events_rt.py +0 -0
  82. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/plot_spectrogram_rt.py +0 -0
  83. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/plot_waveform_rt.py +0 -0
  84. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/plugins.py +0 -0
  85. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/portion/__init__.py +0 -0
  86. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/portion/const.py +0 -0
  87. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/portion/dict.py +0 -0
  88. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/portion/func.py +0 -0
  89. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/portion/interval.py +0 -0
  90. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/portion/io.py +0 -0
  91. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/preferences.py +0 -0
  92. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/preferences_ui.py +0 -0
  93. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/project.py +0 -0
  94. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/project_functions.py +0 -0
  95. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/project_import_export.py +0 -0
  96. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/project_ui.py +0 -0
  97. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/qrc_boris.py +0 -0
  98. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/qrc_boris5.py +0 -0
  99. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/select_modifiers.py +0 -0
  100. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/select_observations.py +0 -0
  101. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/select_subj_behav.py +0 -0
  102. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/state_events.py +0 -0
  103. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/subjects_pad.py +0 -0
  104. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/synthetic_time_budget.py +0 -0
  105. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/time_budget_functions.py +0 -0
  106. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/time_budget_widget.py +0 -0
  107. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/transitions.py +0 -0
  108. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/video_equalizer.py +0 -0
  109. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/video_equalizer_ui.py +0 -0
  110. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/view_df.py +0 -0
  111. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/view_df_ui.py +0 -0
  112. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris/write_event.py +0 -0
  113. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris_behav_obs.egg-info/dependency_links.txt +0 -0
  114. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris_behav_obs.egg-info/entry_points.txt +0 -0
  115. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris_behav_obs.egg-info/requires.txt +0 -0
  116. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/boris_behav_obs.egg-info/top_level.txt +0 -0
  117. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/setup.cfg +0 -0
  118. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/tests/test_db_functions.py +0 -0
  119. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/tests/test_export_observation.py +0 -0
  120. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/tests/test_irr.py +0 -0
  121. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/tests/test_observation_gui.py +0 -0
  122. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/tests/test_otx_parser.py +0 -0
  123. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/tests/test_preferences_gui.py +0 -0
  124. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/tests/test_project_functions.py +0 -0
  125. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/tests/test_time_budget.py +0 -0
  126. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/tests/test_utilities.py +0 -0
  127. {boris_behav_obs-9.7 → boris_behav_obs-9.7.1}/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.1
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 [![BORIS citations counter](https://penelope.unito.it/friard/boris_scopus_citations.png) citations](https://www.boris.unito.it/citations) in peer-reviewed scientific publications. -->
53
53
 
54
54
 
55
- The BORIS paper has more than 2337 citations in peer-reviewed scientific publications.
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 [![BORIS citations counter](https://penelope.unito.it/friard/boris_scopus_citations.png) citations](https://www.boris.unito.it/citations) in peer-reviewed scientific publications. -->
15
15
 
16
16
 
17
- The BORIS paper has more than 2337 citations in peer-reviewed scientific publications.
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
 
@@ -150,7 +150,7 @@ if util.versiontuple(platform.python_version()) < util.versiontuple(MIN_PYTHON_V
150
150
  logging.critical(msg)
151
151
  sys.exit()
152
152
 
153
- if sys.platform == "darwin": # for MacOS
153
+ if sys.platform.startswith("darwin"): # for MacOS
154
154
  os.environ["LC_ALL"] = "en_US.UTF-8"
155
155
 
156
156
 
@@ -400,7 +400,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
400
400
 
401
401
  # if BORIS is running on Mac lock all dockwidget features
402
402
  # because Qdockwidgets may have a strange behavior
403
- if sys.platform == "darwin":
403
+ if sys.platform.startswith("darwin"):
404
404
  self.action_block_dockwidgets.setChecked(True)
405
405
  self.block_dockwidgets()
406
406
 
@@ -1428,55 +1428,60 @@ class MainWindow(QMainWindow, Ui_MainWindow):
1428
1428
  if not self.dw_player[player].player.playlist_count:
1429
1429
  return
1430
1430
 
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)
1435
-
1436
- self.dw_player[player].player.seek(new_time_float, "absolute+exact")
1431
+ try:
1432
+ # one media
1433
+ if self.dw_player[player].player.playlist_count == 1:
1434
+ if new_time < self.dw_player[player].player.duration:
1435
+ new_time_float = round(float(new_time), 3)
1437
1436
 
1438
- if player == 0 and not self.user_move_slider:
1439
- self.video_slider.setValue(
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
1437
+ self.dw_player[player].player.seek(new_time_float, "absolute+exact")
1438
+ self.mpv_timer_out()
1445
1439
 
1446
- # many media
1447
- else:
1448
- if new_time < self.dw_player[player].cumul_media_durations_sec[-1]:
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",
1440
+ if player == 0 and not self.user_move_slider:
1441
+ self.video_slider.setValue(
1442
+ round(self.dw_player[0].player.time_pos / self.dw_player[0].player.duration * (cfg.SLIDER_MAXIMUM - 1))
1461
1443
  )
1444
+ return 0
1445
+ else:
1446
+ return 1
1447
+
1448
+ # many media
1449
+ else:
1450
+ if new_time < self.dw_player[player].cumul_media_durations_sec[-1]:
1451
+ for idx, d in enumerate(self.dw_player[player].cumul_media_durations_sec[:-1]):
1452
+ if d <= new_time < self.dw_player[player].cumul_media_durations_sec[idx + 1]:
1453
+ self.dw_player[player].player.playlist_pos = idx
1454
+ time.sleep(0.5)
1455
+
1456
+ self.dw_player[player].player.seek(
1457
+ round(
1458
+ float(new_time)
1459
+ - sum(self.dw_player[player].media_durations[0 : self.dw_player[player].player.playlist_pos]) / 1000,
1460
+ 3,
1461
+ ),
1462
+ "absolute+exact",
1463
+ )
1462
1464
 
1463
- break
1465
+ break
1464
1466
 
1465
- if player == 0 and not self.user_move_slider:
1466
- self.video_slider.setValue(
1467
- round(self.dw_player[0].player.time_pos / self.dw_player[0].player.duration * (cfg.SLIDER_MAXIMUM - 1))
1467
+ if player == 0 and not self.user_move_slider:
1468
+ self.video_slider.setValue(
1469
+ round(self.dw_player[0].player.time_pos / self.dw_player[0].player.duration * (cfg.SLIDER_MAXIMUM - 1))
1470
+ )
1471
+ return 0
1472
+ else:
1473
+ QMessageBox.warning(
1474
+ self,
1475
+ cfg.programName,
1476
+ (
1477
+ "The indicated position is greater than the total media duration "
1478
+ f"({util.seconds2time(self.dw_player[player].cumul_media_durations_sec[-1])})"
1479
+ ),
1468
1480
  )
1469
- return 0
1470
- else:
1471
- QMessageBox.warning(
1472
- self,
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
1481
+ return 1
1482
+ except Exception as e:
1483
+ print(f"error in seek mediaplayer function: {e}")
1484
+ return 0
1480
1485
 
1481
1486
  def jump_to(self) -> None:
1482
1487
  """
@@ -3685,6 +3690,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
3685
3690
  if self.playerType == cfg.MEDIA:
3686
3691
  for dw in self.dw_player:
3687
3692
  dw.player.frame_step()
3693
+
3688
3694
  if self.geometric_measurements_mode:
3689
3695
  self.extract_frame(dw)
3690
3696
 
@@ -3692,6 +3698,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
3692
3698
  for idx in self.plot_data:
3693
3699
  self.timer_plot_data_out(self.plot_data[idx])
3694
3700
 
3701
+ self.mpv_timer_out()
3702
+
3695
3703
  if self.geometric_measurements_mode:
3696
3704
  geometric_measurement.redraw_measurements(self)
3697
3705
 
@@ -3709,6 +3717,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
3709
3717
  if self.playerType == cfg.MEDIA:
3710
3718
  for dw in self.dw_player:
3711
3719
  dw.player.frame_back_step()
3720
+
3712
3721
  if self.geometric_measurements_mode:
3713
3722
  self.extract_frame(dw)
3714
3723
 
@@ -3716,6 +3725,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
3716
3725
  for idx in self.plot_data:
3717
3726
  self.timer_plot_data_out(self.plot_data[idx])
3718
3727
 
3728
+ self.mpv_timer_out()
3729
+
3719
3730
  if self.geometric_measurements_mode:
3720
3731
  geometric_measurement.redraw_measurements(self)
3721
3732
 
@@ -3860,10 +3871,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
3860
3871
  returns frame index for player player_idx
3861
3872
  """
3862
3873
 
3863
- if not sys.platform.startswith(cfg.MACOS_CODE):
3864
- estimated_frame_number = self.dw_player[player_idx].player.estimated_frame_number
3865
- else:
3866
- estimated_frame_number = observation_operations.send_command({"command": ["get_property", "estimated_frame_number"]})
3874
+ estimated_frame_number = self.dw_player[player_idx].player.estimated_frame_number
3875
+
3867
3876
  if estimated_frame_number is not None:
3868
3877
  return estimated_frame_number
3869
3878
  else:
@@ -3939,7 +3948,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
3939
3948
  if self.dw_player[0].player.duration is None:
3940
3949
  return
3941
3950
  video_position = slider_position * self.dw_player[0].player.duration
3942
- self.dw_player[0].player.command("seek", str(video_position), "absolute")
3951
+ # self.dw_player[0].player.command("seek", str(video_position), "absolute")
3952
+ self.dw_player[0].player.seek(video_position, "absolute")
3943
3953
 
3944
3954
  self.plot_timer_out()
3945
3955
 
@@ -4132,7 +4142,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
4132
4142
  self.dw_player[n_player].player.playlist_pos = self.dw_player[n_player].player.playlist_count - 1
4133
4143
  self.seek_mediaplayer(self.dw_player[n_player].media_durations[-1], player=n_player)
4134
4144
 
4135
- def mpv_timer_out(self, value: Union[float, None], scroll_slider=True):
4145
+ def mpv_timer_out(self, value: Union[float, None] = None, scroll_slider=True):
4136
4146
  """
4137
4147
  print the media current position and total length for MPV player
4138
4148
  scroll video slider to video position
@@ -4142,13 +4152,17 @@ class MainWindow(QMainWindow, Ui_MainWindow):
4142
4152
  if not self.observationId:
4143
4153
  return
4144
4154
 
4155
+ print("mpv timer out")
4156
+
4145
4157
  cumulative_time_pos = self.getLaps()
4158
+ print(f"{cumulative_time_pos=}")
4146
4159
  # get frame index
4147
4160
  frame_idx = self.get_frame_index()
4161
+ print(f"{frame_idx=}")
4148
4162
  # frame_idx = 0
4149
4163
 
4150
- if value is None:
4151
- current_media_time_pos = 0
4164
+ if value is None: # ipc mpv
4165
+ current_media_time_pos = self.dw_player[0].player.time_pos
4152
4166
  else:
4153
4167
  current_media_time_pos = value
4154
4168
 
@@ -4186,22 +4200,19 @@ class MainWindow(QMainWindow, Ui_MainWindow):
4186
4200
 
4187
4201
  ct0 = cumulative_time_pos
4188
4202
 
4189
- if not sys.platform.startswith(cfg.MACOS_CODE):
4190
- if self.dw_player[0].player.time_pos is not None:
4191
- for n_player in range(1, len(self.dw_player)):
4192
- ct = self.getLaps(n_player=n_player)
4203
+ if self.dw_player[0].player.time_pos is not None:
4204
+ for n_player in range(1, len(self.dw_player)):
4205
+ ct = self.getLaps(n_player=n_player)
4193
4206
 
4194
- # sync players 2..8 if time diff >= 1 s
4195
- if (
4196
- abs(ct0 - (ct + dec(self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.OFFSET][str(n_player + 1)])))
4197
- >= 1
4198
- ):
4199
- self.sync_time(n_player, ct0) # self.seek_mediaplayer(ct0, n_player)
4207
+ # sync players 2..8 if time diff >= 1 s
4208
+ if abs(ct0 - (ct + dec(self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.OFFSET][str(n_player + 1)]))) >= 1:
4209
+ self.sync_time(n_player, ct0) # self.seek_mediaplayer(ct0, n_player)
4200
4210
 
4201
4211
  currentTimeOffset = dec(cumulative_time_pos + self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TIME_OFFSET])
4202
4212
 
4203
4213
  all_media_duration = sum(self.dw_player[0].media_durations) / 1000
4204
4214
  current_media_duration = self.dw_player[0].player.duration # mediaplayer_length
4215
+
4205
4216
  self.mediaTotalLength = current_media_duration
4206
4217
 
4207
4218
  # current state(s)
@@ -4226,6 +4237,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
4226
4237
  self.show_current_states_in_subjects_table()
4227
4238
 
4228
4239
  # current media name
4240
+ print(f"{self.dw_player[0].player.playlist_pos=}")
4241
+ print(f"{self.dw_player[0].player.playlist=}")
4242
+
4229
4243
  if self.dw_player[0].player.playlist_pos is not None:
4230
4244
  current_media_name = Path(self.dw_player[0].player.playlist[self.dw_player[0].player.playlist_pos]["filename"]).name
4231
4245
  current_playlist_index = self.dw_player[0].player.playlist_pos
@@ -4301,6 +4315,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
4301
4315
 
4302
4316
  self.actionPlay.setIcon(QIcon(f":/play_{gui_utilities.theme_mode()}"))
4303
4317
 
4318
+ print(f"{msg=}")
4319
+
4304
4320
  if msg:
4305
4321
  self.lb_current_media_time.setText(msg)
4306
4322
 
@@ -4317,14 +4333,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
4317
4333
 
4318
4334
  logging.info("Media end reached")
4319
4335
 
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
4336
  if self.pj[cfg.OBSERVATIONS][self.observationId][cfg.CLOSE_BEHAVIORS_BETWEEN_VIDEOS]:
4329
4337
  if self.dw_player[0].player.eof_reached and self.dw_player[0].player.core_idle:
4330
4338
  if self.dw_player[0].player.playlist_pos == len(self.dw_player[0].player.playlist) - 1:
@@ -4594,14 +4602,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
4594
4602
 
4595
4603
  if self.playerType == cfg.MEDIA:
4596
4604
  # cumulative time
4597
- if not sys.platform.startswith(cfg.MACOS_CODE):
4598
- mem_laps = sum(self.dw_player[n_player].media_durations[0 : self.dw_player[n_player].player.playlist_pos]) + (
4599
- 0 if self.dw_player[n_player].player.time_pos is None else self.dw_player[n_player].player.time_pos * 1000
4600
- )
4601
- else:
4602
- time_pos = observation_operations.send_command({"command": ["get_property", "time-pos"]})
4603
- # TODO: fix!
4604
- return dec(time_pos)
4605
+ mem_laps = sum(self.dw_player[n_player].media_durations[0 : self.dw_player[n_player].player.playlist_pos]) + (
4606
+ 0 if self.dw_player[n_player].player.time_pos is None else self.dw_player[n_player].player.time_pos * 1000
4607
+ )
4605
4608
 
4606
4609
  return dec(str(round(mem_laps / 1000, 3)))
4607
4610
 
@@ -5389,6 +5392,18 @@ class MainWindow(QMainWindow, Ui_MainWindow):
5389
5392
  """
5390
5393
  logging.debug("function: closeEvent")
5391
5394
 
5395
+ # close MPV in IPC mode
5396
+ if self.MPV_IPC_MODE:
5397
+ try:
5398
+ for idx, p in enumerate(self.dw_player):
5399
+ p.player.process.terminate()
5400
+ try:
5401
+ p.player.process.wait(timeout=3) # wait up to 3s
5402
+ except subprocess.TimeoutExpired:
5403
+ p.player.process.kill() # force if still alive
5404
+ except Exception as e:
5405
+ logging.warning(f"Error stopping MPV process #{idx}: {e}")
5406
+
5392
5407
  # check if re-encoding
5393
5408
  if self.processes:
5394
5409
  if (
@@ -5442,6 +5457,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
5442
5457
  check if first player ended
5443
5458
  """
5444
5459
 
5460
+ print("play_video")
5461
+
5445
5462
  if self.geometric_measurements_mode:
5446
5463
  return
5447
5464
 
@@ -5463,6 +5480,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
5463
5480
 
5464
5481
  self.statusbar.showMessage("", 0)
5465
5482
 
5483
+ if self.ipc_mpv_timer is not None:
5484
+ self.ipc_mpv_timer.start()
5485
+
5466
5486
  self.plot_timer.start()
5467
5487
 
5468
5488
  # start all timer for plotting data
@@ -5494,6 +5514,10 @@ class MainWindow(QMainWindow, Ui_MainWindow):
5494
5514
  for data_timer in self.ext_data_timer_list:
5495
5515
  data_timer.stop()
5496
5516
 
5517
+ if self.ipc_mpv_timer is not None:
5518
+ self.ipc_mpv_timer.stop()
5519
+ self.mpv_timer_out()
5520
+
5497
5521
  player.player.pause = True
5498
5522
 
5499
5523
  self.lb_player_status.setText(msg)
@@ -5543,13 +5567,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
5543
5567
 
5544
5568
  self.update_visualizations()
5545
5569
 
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
5570
  def jumpForward_activated(self):
5554
5571
  """
5555
5572
  forward from current position
@@ -5806,6 +5823,22 @@ def main():
5806
5823
  results.ptText.appendHtml(f"Some issues were found in the project<br><br>{msg}")
5807
5824
  results.show()
5808
5825
 
5826
+ # check mpv IPC mode
5827
+ window.MPV_IPC_MODE = False
5828
+ if options.ipc or sys.platform.startswith("darwin"):
5829
+ window.MPV_IPC_MODE = True
5830
+ # check if mpv is available
5831
+ if not shutil.which("mpv"):
5832
+ logging.critical("The mpv command is not available on the path")
5833
+ QMessageBox.critical(
5834
+ None,
5835
+ cfg.programName,
5836
+ ("The mpv command is not available on the path"),
5837
+ QMessageBox.Ok | QMessageBox.Default,
5838
+ QMessageBox.NoButton,
5839
+ )
5840
+ sys.exit()
5841
+
5809
5842
  window.show()
5810
5843
  window.raise_() # for overlapping widget (?)
5811
5844