in source/controlplaneapi/infrastructure/lambda/Replay/shared/ReplayEngine.py [0:0]
def _create_replay(self):
self.__mark_replay_in_progress()
self._replay_to_be_processed = self.__event['ReplayRequest']
# Get Segments with Features. OptoStart and OptoEndtime of Segments will be Maps by default.
self.get_all_segments_with_features()
# If We are dealing with Clip Based Features, we are done with Collecting the segments having Features, just push to DDB
if not self._is_replay_duration_based():
self._persist_replay_metadata(self._segment_feature_maping)
else:
print('Duration based, calculating total duration of chosen Segments')
debuginfo = []
replay_request_duration = self.__event['ReplayRequest']['DurationbasedSummarization']['Duration'] * 60 # In Secs
# For Duration based, we need to check if the Sum of Segment Clip Duration is more than the Duration asked for in the
# Reply Request. If yes, we calculate scores and pick the best segments. If no, we simply push the segments into DDB
duration_result, duration = self._does_total_duration_of_all_segments_exceed_configured()
if not duration_result:
debuginfo.append(f"Total duration {duration} secs of chosen Segments within Replay Request duration {replay_request_duration} secs. Not calculating Scores and weights.")
self._persist_replay_metadata(self._segment_feature_maping, debuginfo)
print(f"Total duration {duration} secs of chosen Segments is less than Replay Request duration {replay_request_duration} secs.")
debuginfo.append(f"Total duration {duration} secs of chosen Segments is less than Replay Request duration {replay_request_duration} secs.")
else:
# If no Equal Distribution is sought, pick segments based on High Scores, duration
if not self.__event['ReplayRequest']['DurationbasedSummarization']['EqualDistribution']:
print(f'Calculate Scores based on Weights .. total duration was {duration}')
self._calculate_segment_scores_basedon_weights(self._segment_feature_maping)
print("--------")
print(self._segment_feature_maping)
# After each Segment has been scored, sort them in Desc based on Score
sorted_segments = sorted(self._segment_feature_maping, key=lambda x: x['Score'], reverse=True)
print("--------AFTER SORT----------")
print(sorted_segments)
# Find which segments needs to be Removed to meet the Duration Requirements in Replay Request
total_duration_all = 0
total_duration = 0
final_segments = []
for segment in sorted_segments:
segment_duration = self._get_segment_duration_in_secs(segment)
total_duration_all += segment_duration
if total_duration + segment_duration <= replay_request_duration:
final_segments.append(segment)
total_duration += segment_duration
else:
print(f"Ignoring the segment - StartTime {segment['Start']}, EndTime {segment['End']} - to avoid exceeding the replay request duration limit {replay_request_duration} secs")
debuginfo.append(f"Ignoring segment - StartTime {segment['Start']}, EndTime {segment['End']} Segment Duration {segment_duration} secs - to avoid exceeding the replay duration limit of {replay_request_duration} secs.")
debuginfo.append(f"Duration if all segments considered would be {total_duration_all} secs")
# Finally Sort the Segments based on the Start time in Asc Order
sorted_final_segments = sorted(final_segments, key=lambda x: x['Start'], reverse=False)
self._persist_replay_metadata(sorted_final_segments, debuginfo)
else:
# Because Equal Distrbution is being asked for,
# We will distribute the total segment duration into Multiple TimeGroups and Group segments within them based on Segment Start time.
# Within each TimeGroup, we will Score the Segments based on Weights and
# pick the Highest Scoring Segment by adhering to the Duration which will be the TimeGroup Duration
# Each Time Group will also have an Absolute time representation.
# For example, first Timegroup would be from 0 - 292 secs, 2nd from 292 to 584 secs .. the last one(t6th) from 1460 to 1752 Secs
# We will select segments whose StartTime falls in these Absolute time ranges to get a Equal Distribution
first_segment = self._all_segments_with_features[0]
last_segment = self._all_segments_with_features[len(self._all_segments_with_features) - 1]
start_of_first_segment_secs = first_segment['OptoStart'][self._audio_track] if self._is_segment_optimized(first_segment) else first_segment['Start']
end_of_last_segment_secs = last_segment['OptoEnd'][self._audio_track] if self._is_segment_optimized(last_segment) else last_segment['End']
debuginfo.append(f"First Seg starts at {start_of_first_segment_secs} secs")
debuginfo.append(f"Last Seg Ends at {end_of_last_segment_secs} secs")
total_segment_duration_in_secs = end_of_last_segment_secs - start_of_first_segment_secs
debuginfo.append(f"total_segment_duration_in_secs = {total_segment_duration_in_secs} secs")
total_segment_duration_in_hrs = (end_of_last_segment_secs - start_of_first_segment_secs) / 3600 # Hours
debuginfo.append(f"total_segment_duration_in_hrs = {total_segment_duration_in_hrs} hrs")
# Find how many Time Groups we need. If we have more than 1 Hr lets divide into multiple groups.
if total_segment_duration_in_secs > 3600:
no_of_time_groups = (math.ceil(total_segment_duration_in_hrs)* 2) + TIMEGROUP_MULTIPLIER
else:
no_of_time_groups = TIMEGROUP_MULTIPLIER
debuginfo.append(f"no_of_time_groups = {no_of_time_groups}")
# Calculate the TimeGroup time based on the Replay Request Duration
timegroup_time_in_secs = replay_request_duration / no_of_time_groups
debuginfo.append(f"timegroup_time_in_secs = {timegroup_time_in_secs}")
# This represents the absolute time that should be added up for all TimeGroups
time_frame_in_time_group = round(total_segment_duration_in_secs / no_of_time_groups, 2)
# Create a Dict of time groups with a Start and End time
# We will find segments which fall in them next
time_groups = []
total = 0
for x in range(no_of_time_groups):
if x == 0:
time_groups.append({
"TimeGroupStartInSecs": start_of_first_segment_secs,
"TimeGroupEndInSecs": start_of_first_segment_secs + time_frame_in_time_group,
})
total += start_of_first_segment_secs + time_frame_in_time_group
else:
time_groups.append({
"TimeGroupStartInSecs": total,
"TimeGroupEndInSecs": total + time_frame_in_time_group,
})
total += time_frame_in_time_group
print(time_groups)
final_segments_across_timegroups = []
# TimeGroups will be Asc Order by Default based on how its Constructed above
for timegroup in time_groups:
segments_within_timegroup = self._get_segments_with_features_within_timegroup(timegroup)
print(f'Calculate Scores based on Weights .. ')
self._calculate_segment_scores_basedon_weights(segments_within_timegroup)
# After each Segment has been scored, sort them in Desc based on Score
sorted_segments = sorted(segments_within_timegroup, key=lambda x: x['Score'], reverse=True)
# Find which segments needs to be Removed to meet the Duration Requirements in Replay Request
total_duration_all = 0
total_duration = 0
final_segments = []
for segment in sorted_segments:
segment_duration = self._get_segment_duration_in_secs(segment)
total_duration_all += segment_duration
if total_duration + segment_duration <= timegroup_time_in_secs:
final_segments.append(segment)
total_duration += segment_duration
else:
print(f"Ignoring the segment - StartTime {segment['Start']}, EndTime {segment['End']} - to avoid exceeding the timegroup duration limit {timegroup_time_in_secs} secs")
#debuginfo.append(f"Ignoring the segment - StartTime {segment['Start']}, EndTime {segment['End']} Segment Duration {segment_duration} secs - to avoid exceeding the replay duration limit of {timegroup_time_in_secs} secs.")
#debuginfo.append(f"Duration if all segments within this timegroup considered would be {total_duration_all} secs")
# Finally Sort the Segments based on the Start time in Asc Order
sorted_final_segments = sorted(final_segments, key=lambda x: x['Start'], reverse=False)
final_segments_across_timegroups.extend(sorted_final_segments)
# Persist all segment+features across all timegroups
self._persist_replay_metadata(final_segments_across_timegroups, debuginfo)