Support videos with C2PA info

This commit is contained in:
N-Pex 2025-11-14 13:00:06 +01:00
parent 69b950512f
commit 834a519f15
3 changed files with 77 additions and 44 deletions

View file

@ -45,23 +45,45 @@ onMounted(() => {
const a = attachment;
loadingProof.value = true;
metaStripped.value = true;
a.loadSrc()
.then((data) => {
if (data && data.data) {
return proofmode.proofCheckSource(data.data).then((res) => {
a.proof = res;
if (res?.integrity?.c2pa) {
// If we have proof, overwrite the flags
a.mediaMetadata = extractMediaMetadata(a.proof);
}
updateMetaStripped(a);
});
}
})
.catch(() => {})
.finally(() => {
loadingProof.value = false;
});
const isVideo = a.event.getContent().msgtype == "m.video";
if (isVideo) {
a.loadBlob()
.then((data) => {
if (data && data.data) {
return proofmode.proofCheckFile(new File([data.data], a.name)).then((res) => {
a.proof = res;
if (res?.integrity?.c2pa) {
// If we have proof, overwrite the flags
a.mediaMetadata = extractMediaMetadata(a.proof);
}
updateMetaStripped(a);
});
}
})
.catch(() => { })
.finally(() => {
loadingProof.value = false;
});
} else {
a.loadSrc()
.then((data) => {
if (data && data.data) {
return proofmode.proofCheckSource(data.data).then((res) => {
a.proof = res;
if (res?.integrity?.c2pa) {
// If we have proof, overwrite the flags
a.mediaMetadata = extractMediaMetadata(a.proof);
}
updateMetaStripped(a);
});
}
})
.catch(() => { })
.finally(() => {
loadingProof.value = false;
});
}
} else {
updateMetaStripped(attachment);
}

View file

@ -204,6 +204,8 @@ export class AttachmentManager {
}
});
attachment.thumbnail = thumb;
attachment.proof = await proofmode.proofCheckFile(file);
attachment.mediaMetadata = extractMediaMetadata(attachment.proof);
}
attachment.status = "loaded";

View file

@ -129,11 +129,11 @@ const pathsC2PASource = (): FlagValue[] => {
return [
{
path: "integrity/c2pa/manifest_info/manifests[]/assertions[label=stds.exif]/data/exif:Make",
transform: getExifMakeModelPrefixed,
transform: getMakeModel,
},
{
path: "integrity/c2pa/manifest_info/manifests[]/assertions[label=stds.exif]/data/exif:Model",
transform: getExifMakeModelPrefixed,
transform: getMakeModel,
},
{
path: "integrity/c2pa/manifest_info/manifests[]/assertions[label=c2pa.actions|c2pa.actions.v2]/data/actions[action=c2pa.created]/softwareAgent/name",
@ -141,6 +141,15 @@ const pathsC2PASource = (): FlagValue[] => {
{
path: "integrity/c2pa/manifest_info/manifests[]/assertions[label=c2pa.actions|c2pa.actions.v2]/data/actions[action=c2pa.created]/softwareAgent",
},
{
path: "integrity/c2pa/manifest_info/manifests[]/assertions[label=stds.exif]/data/tiff:Make",
transform: getMakeModel,
},
{
path: "integrity/c2pa/manifest_info/manifests[]/assertions[label=stds.exif]/data/tiff:Model",
transform: getMakeModel,
},
{
path: "integrity/c2pa/manifest_info/manifests[]/assertions[label=c2pa.actions|c2pa.actions.v2]/data/actions[action=c2pa.created]/../../../claim_generator",
},
@ -149,8 +158,8 @@ const pathsC2PASource = (): FlagValue[] => {
const pathsExifSource = (): FlagValue[] => {
return [
{ path: "integrity/exif/Make", transform: getExifMakeModelNoPrefix },
{ path: "integrity/exif/Model", transform: getExifMakeModelNoPrefix },
{ path: "integrity/exif/Make", transform: getMakeModel },
{ path: "integrity/exif/Model", transform: getMakeModel },
];
};
@ -181,6 +190,8 @@ const pathsC2PACamera = (): FlagValue[] => {
{ path: "integrity/c2pa/manifest_info/manifests[]/assertions[label=stds.exif]/data/exif:SceneType", matches: ["^1$", "^directly photographed image$"] },
{ path: "integrity/c2pa/manifest_info/manifests[]/assertions[label=stds.exif]/data/exif:LensMake" },
{ path: "integrity/c2pa/manifest_info/manifests[]/assertions[label=stds.exif]/data/exif:LensModel" },
{ path: "integrity/c2pa/manifest_info/manifests[]/assertions[label=stds.exif]/data/exifEX:LensMake" },
{ path: "integrity/c2pa/manifest_info/manifests[]/assertions[label=stds.exif]/data/exifEX:LensModel" },
];
};
@ -284,12 +295,28 @@ const pathsExifCreationDate = (): FlagValue[] => {
];
};
const getExifMakeModelNoPrefix = (ignoredvalue: any, match: FlagMatchRuleValue): string => {
return getExifMakeModel(match, "");
};
const getMakeModel = (ignoredval: string, match: FlagMatchRuleValue): string => {
let prefix: string = "";
const getExifMakeModelPrefixed = (ignoredvalue: any, match: FlagMatchRuleValue): string => {
return getExifMakeModel(match, "exif:");
const pathLeaf = match.path.at(0)?.path;
if (pathLeaf && pathLeaf.indexOf(":") >= 0) {
prefix = pathLeaf.substring(0, pathLeaf.indexOf(":") + 1);
}
// Make and model
let makeAndModel = "";
const make = extractFlagValues(`../${prefix}Make`, match.path)?.at(0)?.value as string;
const model = extractFlagValues(`../${prefix}Model`, match.path)?.at(0)?.value as string;
if (make) {
makeAndModel += getExifValue(make);
}
if (model) {
if (makeAndModel.length > 0) {
makeAndModel += ", ";
}
makeAndModel += getExifValue(model);
}
return makeAndModel;
};
const exifStringTransform = (value: any, match: FlagMatchRuleValue): string => {
@ -320,24 +347,6 @@ const exifStringTransform = (value: any, match: FlagMatchRuleValue): string => {
return value;
};
const getExifMakeModel = (match: FlagMatchRuleValue, prefix: string): string => {
// Make and model
let makeAndModel = "";
const make = extractFlagValues(`../${prefix}Make`, match.path)?.at(0)?.value as string;
const model = extractFlagValues(`../${prefix}Model`, match.path)?.at(0)?.value as string;
if (make) {
makeAndModel += getExifValue(make);
}
if (model) {
if (makeAndModel.length > 0) {
makeAndModel += ", ";
}
makeAndModel += getExifValue(model);
}
return makeAndModel;
};
const extractFlagValues = (flagPath: string, path: FlagMatchRulePathSegment[]): FlagMatchRuleValue[] => {
const getValues = (keys: string[], path: FlagMatchRulePathSegment[]): FlagMatchRuleValue[] | undefined => {
if (keys.length == 0 || path.length == 0) return undefined;