Use bit rate instead of resolution in making dedup decision.

Keep lower resolution movie if it is higher bit rate.
This commit is contained in:
Bill Thiede 2019-11-25 08:47:04 -08:00
parent 974d9386fb
commit 150bdfddef
2 changed files with 76 additions and 6 deletions

View File

@ -324,6 +324,16 @@ pub struct Movie {
}
impl Movie {
fn min_bit_rate(&self) -> Option<usize> {
if self.files.is_empty() {
None
} else {
Some(self.files.iter().fold(usize::max_value(), |acc, (_, cmd)| {
std::cmp::min(acc, cmd.bit_rate)
}))
}
}
fn min_resolution(&self) -> Option<Resolution> {
if self.files.is_empty() {
None
@ -371,8 +381,8 @@ impl Movies {
let mut dupes = Vec::new();
for (_parent, mut movies) in movie_counter.into_iter() {
if movies.len() > 1 {
// Sort, smallest movie first.
movies.sort_by(|a, b| a.min_resolution().cmp(&b.min_resolution()));
// Sort, lowest bit_rate movie first
movies.sort_by(|a, b| a.min_bit_rate().cmp(&b.min_bit_rate()));
// Flip order, we care about the largest.
movies.reverse();
// Take the largest image, return the rest for removal.

View File

@ -49,7 +49,7 @@ fn test_simple_library() {
);
}
fn build_tuple<R>(path: &str, res: R) -> (String, CompactMetadata)
fn build_tuple<R>(path: &str, res: R, bit_rate: usize) -> (String, CompactMetadata)
where
R: Into<Resolution>,
{
@ -58,7 +58,7 @@ where
path.to_string(),
CompactMetadata {
filename: format!("./{}", path),
bit_rate: 1,
bit_rate,
duration: 1.0,
format_name: "test_format".to_string(),
size: 1,
@ -72,14 +72,14 @@ where
)
}
fn build_movie<R>(paths: Vec<(&str, R)>) -> Movie
fn build_movie<R>(paths: Vec<(&str, R, usize)>) -> Movie
where
R: Into<Resolution>,
{
Movie {
files: paths
.into_iter()
.map(|(path, res)| build_tuple(path, res))
.map(|(path, res, bit_rate)| build_tuple(path, res, bit_rate))
.collect(),
}
}
@ -89,26 +89,32 @@ fn build_complex_metadata() -> HashMap<String, CompactMetadata> {
build_tuple(
"One Movie With Year (2019)/abcdef123456789.mkv",
(1920, 1080),
1,
),
build_tuple(
"One Movie With Two Parts (2019)/abcdef123456789 part 1.mkv",
(1280, 720),
1,
),
build_tuple(
"One Movie With Two Parts (2019)/abcdef123456789 part 2.mkv",
(1280, 720),
1,
),
build_tuple(
"Two Movies With Multi Parts (2019)/abcdef123456789 part 1.mkv",
(1280, 720),
1000,
),
build_tuple(
"Two Movies With Multi Parts (2019)/abcdef123456789 part 2.mkv",
(1280, 720),
1000,
),
build_tuple(
"Two Movies With Multi Parts (2019)/somethingelse.mkv",
(1920, 1080),
5000,
),
]
.into_iter()
@ -121,30 +127,36 @@ fn build_complex_movies() -> Movies {
build_movie(vec![(
"One Movie With Year (2019)/abcdef123456789.mkv",
(1920, 1080),
1,
)]),
build_movie(vec![
(
"One Movie With Two Parts (2019)/abcdef123456789 part 1.mkv",
(1280, 720),
1,
),
(
"One Movie With Two Parts (2019)/abcdef123456789 part 2.mkv",
(1280, 720),
1,
),
]),
build_movie(vec![
(
"Two Movies With Multi Parts (2019)/abcdef123456789 part 1.mkv",
(1280, 720),
1000,
),
(
"Two Movies With Multi Parts (2019)/abcdef123456789 part 2.mkv",
(1280, 720),
1000,
),
]),
build_movie(vec![(
"Two Movies With Multi Parts (2019)/somethingelse.mkv",
(1920, 1080),
5000,
)]),
],
};
@ -192,15 +204,18 @@ fn test_duplicate_candidates() -> Result<(), Box<dyn Error>> {
build_movie(vec![(
"Two Movies With Multi Parts (2019)/somethingelse.mkv",
(1920, 1080),
5000,
)]),
vec![build_movie(vec![
(
"Two Movies With Multi Parts (2019)/abcdef123456789 part 1.mkv",
(1280, 720),
1000,
),
(
"Two Movies With Multi Parts (2019)/abcdef123456789 part 2.mkv",
(1280, 720),
1000,
),
])],
)];
@ -215,10 +230,12 @@ fn test_fullmetal() -> Result<(), Box<dyn Error>> {
build_movie(vec![(
"Full Metal Jacket (1987)/Full Metal Jacket.mp4",
(1280, 720),
2581935,
)]),
build_movie(vec![(
"Full Metal Jacket (1987)/1776f8e2fb614a6fb77a66cde601bb45.mkv",
(1920, 1080),
5719802,
)]),
],
};
@ -235,10 +252,53 @@ fn test_fullmetal() -> Result<(), Box<dyn Error>> {
build_movie(vec![(
"Full Metal Jacket (1987)/1776f8e2fb614a6fb77a66cde601bb45.mkv",
(1920, 1080),
5719802,
)]),
vec![build_movie(vec![(
"Full Metal Jacket (1987)/Full Metal Jacket.mp4",
(1280, 720),
2581935,
)])],
)];
validate_duplicates(got, want);
Ok(())
}
#[test]
fn test_keep_lower_res_higher_bit_rate() -> Result<(), Box<dyn Error>> {
let mut movies = Movies {
movies: vec![
build_movie(vec![(
"X Men The Last Stand (2006)/X.Men.The.Last.Stand.2006.1080p.BluRay.x264.DTS-ES.PRoDJi.mkv",
(1920, 800),
11349705,
)]),
build_movie(vec![(
"X Men The Last Stand (2006)/948f08a4ba784626ac13de77b77559dd.mkv",
(1920, 1080),
6574160,
)]),
],
};
movies.movies.sort_by(|a, b| {
a.files
.first()
.unwrap()
.0
.partial_cmp(&b.files.first().unwrap().0)
.unwrap()
});
let got = movies.duplicate_candidates();
let want = vec![(
build_movie(vec![(
"X Men The Last Stand (2006)/X.Men.The.Last.Stand.2006.1080p.BluRay.x264.DTS-ES.PRoDJi.mkv",
(1920, 800),
11349705,
)]),
vec![build_movie(vec![(
"X Men The Last Stand (2006)/948f08a4ba784626ac13de77b77559dd.mkv",
(1920, 1080),
6574160,
)])],
)];
validate_duplicates(got, want);