dupe checker select by codec

Added ability to select scenes in the duplicate checker based on preferred video codec. Added dropdown menu to select preferred video codec.
This commit is contained in:
yer 2024-09-21 16:53:13 -04:00
parent 476688c84d
commit 7fe6469b75
2 changed files with 123 additions and 0 deletions

View file

@ -48,6 +48,7 @@ import { objectTitle } from "src/core/files";
const CLASSNAME = "duplicate-checker";
const defaultDurationDiff = "1";
const defaultSelectedCodec = "hevc";
export const SceneDuplicateChecker: React.FC = () => {
const intl = useIntl();
@ -59,6 +60,7 @@ export const SceneDuplicateChecker: React.FC = () => {
const durationDiff = Number.parseFloat(
query.get("durationDiff") ?? defaultDurationDiff
);
let SelectedCodec = query.get("SelectedCodec") ?? defaultSelectedCodec;
const [currentPageSize, setCurrentPageSize] = useState(pageSize);
const [isMultiDelete, setIsMultiDelete] = useState(false);
@ -177,6 +179,19 @@ export const SceneDuplicateChecker: React.FC = () => {
});
};
const findSmallestScene = (group: GQL.SlimSceneDataFragment[]) => {
// Get maximum file size of a scene
const totalSize = (scene: GQL.SlimSceneDataFragment) => {
return scene.files.reduce((prev: number, f) => Math.max(prev, f.size), 0);
};
// Find scene object with minimum total size
return group.reduce((smallest, scene) => {
const smallestSize = totalSize(smallest);
const currentSize = totalSize(scene);
return currentSize < smallestSize ? scene : smallest;
});
};
const findLargestResolutionScene = (group: GQL.SlimSceneDataFragment[]) => {
// Get maximum resolution of a scene
const sceneResolution = (scene: GQL.SlimSceneDataFragment) => {
@ -259,6 +274,53 @@ export const SceneDuplicateChecker: React.FC = () => {
setCheckedScenes(checkedArray);
};
const onSelectSmallestClick = () => {
setSelectedScenes([]);
const checkedArray: Record<string, boolean> = {};
filteredScenes.forEach((group) => {
if (chkSafeSelect && !checkSameCodec(group)) {
return;
}
// Find smallest scene in group a
const smallest = findSmallestScene(group);
group.forEach((scene) => {
if (scene !== smallest) {
checkedArray[scene.id] = true;
}
});
});
setCheckedScenes(checkedArray);
};
const onSelectCodecClick = () => {
setSelectedScenes([]);
const checkedArray: Record<string, boolean> = {};
filteredScenes.forEach((group) => {
if (chkSafeSelect && !checkSameCodec(group)) {
return;
}
// select scenes where codec is not preferred
let hasCodec = false;
group.forEach((scene) => {
if (scene.files[0]?.video_codec != SelectedCodec) {
checkedArray[scene.id] = true;
} else if (scene.files[0]?.video_codec == SelectedCodec) {
hasCodec = true;
}
});
if (!hasCodec) {
// when no scenes with preferred codec are in the group select nothing
group.forEach((scene) => {
checkedArray[scene.id] = false;
});
}
});
setCheckedScenes(checkedArray);
};
const onSelectLargestResolutionClick = () => {
setSelectedScenes([]);
const checkedArray: Record<string, boolean> = {};
@ -750,6 +812,47 @@ export const SceneDuplicateChecker: React.FC = () => {
</Col>
</Row>
</Form.Group>
<Form.Group>
<Row noGutters>
<Form.Label>
<FormattedMessage id="dupe_check.select_all_but_specified_codec.title" />
</Form.Label>
<Col xs="auto">
<Form.Control
as="select"
onChange={(e) =>
setQuery({
SelectedCodec:
e.currentTarget.value === defaultSelectedCodec
? undefined
: e.currentTarget.value,
page: undefined,
})
}
defaultValue={SelectedCodec}
className="input-control ml-4"
>
<option value={"av1"}>
{intl.formatMessage({
id: "dupe_check.select_all_but_specified_codec.av1",
})}
</option>
<option value={"hevc"}>
{intl.formatMessage({
id: "dupe_check.select_all_but_specified_codec.hevc",
})}
</option>
<option value={"h264"}>
{intl.formatMessage({
id: "dupe_check.select_all_but_specified_codec.h264",
})}
</option>
</Form.Control>
</Col>
</Row>
</Form.Group>
<Form.Group>
<Row noGutters>
<Col xs="12">
@ -762,6 +865,12 @@ export const SceneDuplicateChecker: React.FC = () => {
{intl.formatMessage({ id: "dupe_check.select_none" })}
</Dropdown.Item>
<Dropdown.Item onClick={() => onSelectCodecClick()}>
{intl.formatMessage({
id: "dupe_check.select_all_but_specified_codec.label",
})}
</Dropdown.Item>
<Dropdown.Item
onClick={() => onSelectLargestResolutionClick()}
>
@ -776,6 +885,12 @@ export const SceneDuplicateChecker: React.FC = () => {
})}
</Dropdown.Item>
<Dropdown.Item onClick={() => onSelectSmallestClick()}>
{intl.formatMessage({
id: "dupe_check.select_all_but_smallest_file",
})}
</Dropdown.Item>
<Dropdown.Item onClick={() => onSelectByAge(true)}>
{intl.formatMessage({
id: "dupe_check.select_oldest",

View file

@ -993,7 +993,15 @@
"medium": "Medium"
},
"search_accuracy_label": "Search Accuracy",
"select_all_but_specified_codec": {
"title": "Preferred video codec",
"label": "Select every file in each group, except for the file with the preferred codec",
"av1": "av1",
"hevc": "hevc",
"h264": "h264"
},
"select_all_but_largest_file": "Select every file in each duplicated group, except the largest file",
"select_all_but_smallest_file": "Select every file in each duplicated group, except the smallest file",
"select_all_but_largest_resolution": "Select every file in each duplicated group, except the file with highest resolution",
"select_none": "Select None",
"select_oldest": "Select the oldest file in the duplicate group",