Add support to remove overlaps.

This commit is contained in:
Kavin 2022-10-25 09:31:12 +01:00
parent 1b9c18ea31
commit e00d754521
No known key found for this signature in database
GPG key ID: 49451E4482CC5BCD
2 changed files with 104 additions and 14 deletions

View file

@ -28,9 +28,9 @@ pub async fn skip_segments(
let hc = hash.clone(); let hc = hash.clone();
let cat: Vec<String> = serde_json::from_str(categories.unwrap_or("[]")).unwrap(); let cat: Vec<String> = serde_json::from_str(categories.unwrap_or("[\"sponsor\"]")).unwrap();
if cat.is_empty() && categories.is_some() { if cat.is_empty() {
return content::RawJson( return content::RawJson(
"[]".to_string(), "[]".to_string(),
); );
@ -62,26 +62,51 @@ pub async fn skip_segments(
// Create map of Sponsors - Hash, Sponsor // Create map of Sponsors - Hash, Sponsor
let mut sponsors: HashMap<String, Sponsor> = HashMap::new(); let mut sponsors: HashMap<String, Sponsor> = HashMap::new();
for result in results { for result in &results {
let sponsor = { let sponsor = {
sponsors.entry(result.hashed_video_id.clone()).or_insert(Sponsor { sponsors.entry(result.hashed_video_id.clone()).or_insert(Sponsor {
hash: result.hashed_video_id, hash: result.hashed_video_id.clone(),
video_id: result.video_id, video_id: result.video_id.clone(),
segments: Vec::new(), segments: Vec::new(),
}) })
}; };
sponsor.segments.push(Segment { let segment = Segment {
uuid: result.uuid, uuid: result.uuid.clone(),
action_type: result.action_type, action_type: result.action_type.clone(),
category: result.category, category: result.category.clone(),
description: result.description, description: result.description.clone(),
locked: result.locked, locked: result.locked,
segment: vec![result.start_time, result.end_time], segment: vec![result.start_time, result.end_time],
user_id: result.user_id, user_id: result.user_id.clone(),
video_duration: result.video_duration, video_duration: result.video_duration,
votes: result.votes, votes: result.votes,
}); };
let hash = result.hashed_video_id.clone();
let mut found_similar = false;
for seg in &sponsor.segments {
if is_overlap(&segment, &seg.category, seg.segment[0], seg.segment[1]) {
found_similar = true;
break;
}
}
if found_similar {
continue;
}
let mut similar_segments = similar_segments(&segment, &hash, &results);
similar_segments.push(segment.clone());
let best_segment = best_segment(&similar_segments);
// Add if not already in sponsor
if !sponsor.segments.contains(&best_segment) {
sponsor.segments.push(best_segment);
}
} }
if !sponsors.is_empty() { if !sponsors.is_empty() {
@ -102,3 +127,62 @@ pub async fn skip_segments(
return content::RawJson(resp); return content::RawJson(resp);
} }
fn similar_segments(segment: &Segment, hash: &str, segments: &Vec<SponsorTime>) -> Vec<Segment> {
let mut similar_segments: Vec<Segment> = Vec::new();
for seg in segments {
if seg.uuid == segment.uuid {
continue;
}
if seg.hashed_video_id != hash {
continue;
}
let is_similar = is_overlap(segment, &seg.category, seg.start_time, seg.end_time);
if is_similar {
similar_segments.push(Segment {
uuid: seg.uuid.clone(),
action_type: seg.action_type.clone(),
category: seg.category.clone(),
description: seg.description.clone(),
locked: seg.locked,
segment: vec![seg.start_time, seg.end_time],
user_id: seg.user_id.clone(),
video_duration: seg.video_duration,
votes: seg.votes,
});
}
}
similar_segments
}
fn is_overlap(seg: &Segment, cat: &str, start: f32, end: f32) -> bool {
if seg.category != cat {
return false;
}
if seg.segment[0] > start && seg.segment[1] < end {
return true;
}
let overlap = f32::min(seg.segment[1], end) - f32::max(seg.segment[0], start);
let duration = f32::max(seg.segment[1], end) - f32::min(seg.segment[0], start);
overlap / duration > 0.1
}
fn best_segment(segments: &Vec<Segment>) -> Segment {
let mut best_segment = segments[0].clone();
let mut best_votes = segments[0].votes;
for segment in segments {
if segment.votes > best_votes {
best_segment = segment.clone();
best_votes = segment.votes;
}
}
best_segment
}

View file

@ -1,6 +1,6 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Sponsor { pub struct Sponsor {
pub hash: String, pub hash: String,
#[serde(rename = "videoID")] #[serde(rename = "videoID")]
@ -8,7 +8,7 @@ pub struct Sponsor {
pub segments: Vec<Segment>, pub segments: Vec<Segment>,
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Segment { pub struct Segment {
#[serde(rename = "UUID")] #[serde(rename = "UUID")]
pub uuid: String, pub uuid: String,
@ -24,3 +24,9 @@ pub struct Segment {
pub video_duration: f32, pub video_duration: f32,
pub votes: i32, pub votes: i32,
} }
impl PartialEq for Segment {
fn eq(&self, other: &Self) -> bool {
self.uuid == other.uuid
}
}