def session_coverage_extraction(sessionInfo: dict): """This function extracts the video coverage of the session. Note: it adds the session_coverage and the total_time_watched to the sessionInfo; intervals are added only if they have a duration of at least 5 secs (to improve performances) Args: sessionInfo (dict): The dictionary that will be populated with the computed statistic. """ MIN_INTERVALS_LENGTH_IN_SECONDS = 5.0 intervals = [] interval = [] start_interval = 0.0 end_interval = 0.0 current_action = '' previous_action = '' current_value1 = 0.0 # Muted intervals extraction is_muted = False is_paused = False start_muted_interval = 0.0 muted_intervals = [] play_pause_alive_jump_list = utils.purify_list( sessionInfo['data'], ['play', 'pause', 'alive', 'jump', 'speed', 'mute']) for record in play_pause_alive_jump_list: current_value1 = record['value1'] # Mute records must not interfere with coverage computation if record['type'] != 'mute': previous_action = current_action current_action = record['type'] if current_action == 'play': is_paused = False if previous_action != 'pause': # TODO check this start_interval = current_value1 start_muted_interval = current_value1 elif current_action == 'pause': is_paused = True if is_muted and (np.abs(end_interval - start_muted_interval) > MIN_INTERVALS_LENGTH_IN_SECONDS): muted_intervals = utils.add_interval( muted_intervals, [start_muted_interval, current_value1]) elif current_action == 'jump': end_interval = current_value1 # Add coverage interval if (np.abs(end_interval - start_interval) > MIN_INTERVALS_LENGTH_IN_SECONDS): intervals = utils.add_interval( intervals, [start_interval, end_interval]) # Add muted interval if is_muted and (not is_paused) and ( np.abs(end_interval - start_muted_interval) > MIN_INTERVALS_LENGTH_IN_SECONDS): muted_intervals = utils.add_interval( muted_intervals, [start_muted_interval, end_interval]) # Update coverage start_interval start_interval = record['value2'] # Update start_muted_interval start_muted_interval = record['value2'] elif current_action == 'alive': # Add a new interval only if we were playing if not is_paused: end_interval = current_value1 # Add coverage interval if (np.abs(end_interval - start_interval) > MIN_INTERVALS_LENGTH_IN_SECONDS): intervals = utils.add_interval( intervals, [start_interval, end_interval]) # Add muted interval if is_muted and (not is_paused) and ( np.abs(end_interval - start_muted_interval) > MIN_INTERVALS_LENGTH_IN_SECONDS): muted_intervals = utils.add_interval( muted_intervals, [start_muted_interval, end_interval]) elif current_action == 'speed': # TODO extract some info about speed, such as avg_speed pass else: if is_muted: # We are unmuting the video => add a new muted interval is_muted = False if (not is_paused) and ( np.abs(current_value1 - start_muted_interval) > MIN_INTERVALS_LENGTH_IN_SECONDS): muted_intervals = utils.add_interval( muted_intervals, [start_muted_interval, current_value1]) start_muted_interval = current_value1 else: # We are muting the video is_muted = True start_muted_interval = current_value1 # Add last interval if the session ends with a pause if current_action == 'pause': # Set the session end end_interval = current_value1 # Add coverage interval if (np.abs(end_interval - start_interval) > MIN_INTERVALS_LENGTH_IN_SECONDS): intervals = utils.add_interval(intervals, [start_interval, end_interval]) total_time_watched = 0. for interval in intervals: total_time_watched += interval[1] - interval[0] sessionInfo['session_coverage'] = intervals sessionInfo['total_time_watched'] = total_time_watched sessionInfo['muted_intervals'] = muted_intervals
def test_intervals_8_equals(self): test_interval = [10.0, 20.0] expected_output = self._intervals self.assertEqual(utils.add_interval(self._intervals, test_interval), expected_output)
def test_intervals_9_single_intersection_strict_start(self): test_interval = [5.0, 15.0] expected_output = [[5.0, 20.0]] + self._intervals[1:] self.assertEqual(utils.add_interval(self._intervals, test_interval), expected_output)
def test_intervals_5_external_strict_larger(self): test_interval = [9.0, 23.0] expected_output = [test_interval] + self._intervals[1:] self.assertEqual(utils.add_interval(self._intervals, test_interval), expected_output)
def test_intervals_7_external_strict_smaller_left(self): test_interval = [15.0, 20.0] expected_output = self._intervals self.assertEqual(utils.add_interval(self._intervals, test_interval), expected_output)
def test_intervals_3_disjoint_end(self): test_interval = [110.0, 120.0] expected_output = self._intervals + [test_interval] self.assertEqual(utils.add_interval(self._intervals, test_interval), expected_output)
def test_intervals_4_iternal_strict_smaller(self): test_interval = [12.0, 15.0] expected_output = self._intervals self.assertEqual(utils.add_interval(self._intervals, test_interval), expected_output)
def test_intervals_1_disjoint_start(self): test_interval = [0.0, 5.0] expected_output = [test_interval] + self._intervals self.assertEqual(utils.add_interval(self._intervals, test_interval), expected_output)
def test_intervals_2_disjoint_middle(self): test_interval = [23.0, 27.0] expected_output = self._intervals[:1] + [test_interval ] + self._intervals[1:] self.assertEqual(utils.add_interval(self._intervals, test_interval), expected_output)
def test_intervals_23_multiple_intersection_boundary_external_right(self): test_interval = [25.0, 80.0] expected_output = self._intervals[:1] + [[25.0, 80.0] ] + self._intervals[-1:] self.assertEqual(utils.add_interval(self._intervals, test_interval), expected_output)
def test_intervals_24_multiple_intersection_boundary_internal_both(self): test_interval = [40.0, 70.0] expected_output = self._intervals[:1] + [[30.0, 80.0] ] + self._intervals[-1:] self.assertEqual(utils.add_interval(self._intervals, test_interval), expected_output)
def test_intervals_18_multiple_intersection_strict_external(self): test_interval = [25.0, 85.0] expected_output = self._intervals[:1] + [[25.0, 85.0] ] + self._intervals[-1:] self.assertEqual(utils.add_interval(self._intervals, test_interval), expected_output)
def test_intervals_16_single_intersection_boundary_middle_right(self): test_interval = [25.0, 30.0] expected_output = self._intervals[:1] + [[25.0, 40.0] ] + self._intervals[2:] self.assertEqual(utils.add_interval(self._intervals, test_interval), expected_output)
def test_intervals_15_single_intersection_boundary_middle_left(self): test_interval = [60.0, 65.0] expected_output = self._intervals[:2] + [[50.0, 65.0] ] + self._intervals[3:] self.assertEqual(utils.add_interval(self._intervals, test_interval), expected_output)
def test_intervals_12_single_intersection_boundary_end(self): test_interval = [100.0, 105.0] expected_output = self._intervals[:-1] + [[90.0, 105.0]] self.assertEqual(utils.add_interval(self._intervals, test_interval), expected_output)
def test_intervals_10_single_intersection_strict_end(self): test_interval = [95.0, 105.0] expected_output = self._intervals[:-1] + [[90.0, 105.0]] self.assertEqual(utils.add_interval(self._intervals, test_interval), expected_output)