refactoring moved videoMetadata extraction to seperate service

This commit is contained in:
Abhinav 2022-02-28 13:42:21 +05:30
parent e49a7f9ec9
commit a98d35ad66
4 changed files with 82 additions and 83 deletions

View file

@ -5,6 +5,7 @@ import piexif from 'piexifjs';
import { FileTypeInfo } from 'types/upload';
import { logError } from 'utils/sentry';
import { ParsedExtractedMetadata } from './metadataService';
import { getUNIXTime } from 'utils/upload';
const EXIF_TAGS_NEEDED = [
'DateTimeOriginal',
@ -128,22 +129,6 @@ export async function getRawExif(
return exifData;
}
export function getUNIXTime(dateTime: Date) {
try {
if (!dateTime) {
return null;
}
const unixTime = dateTime.getTime() * 1000;
if (unixTime <= 0) {
return null;
} else {
return unixTime;
}
} catch (e) {
logError(e, 'getUNIXTime failed', { dateTime });
}
}
function getEXIFLocation(exifData): Location {
if (!exifData.latitude || !exifData.longitude) {
return NULL_LOCATION;

View file

@ -1,6 +1,6 @@
import { FILE_TYPE } from 'constants/file';
import { logError } from 'utils/sentry';
import { getExifData, getUNIXTime } from './exifService';
import { getExifData } from './exifService';
import {
Metadata,
ParsedMetadataJSON,
@ -9,15 +9,7 @@ import {
} from 'types/upload';
import { NULL_LOCATION } from 'constants/upload';
import { splitFilenameAndExtension } from 'utils/file';
import ffmpegService from 'services/ffmpegService';
enum VideoMetadata {
CREATION_TIME = 'creation_time',
APPLE_CONTENT_IDENTIFIER = 'com.apple.quicktime.content.identifier',
APPLE_LIVE_PHOTO_IDENTIFIER = 'com.apple.quicktime.live-photo.auto',
APPLE_CREATION_DATE = 'com.apple.quicktime.creationdate',
APPLE_LOCATION_ISO = 'com.apple.quicktime.location.ISO6709',
}
import { getVideoMetadata } from './videoMetadataService';
interface ParsedMetadataJSONWithTitle {
title: string;
@ -43,7 +35,7 @@ export async function extractMetadata(
if (fileTypeInfo.fileType === FILE_TYPE.IMAGE) {
extractedMetadata = await getExifData(receivedFile, fileTypeInfo);
} else if (fileTypeInfo.fileType === FILE_TYPE.VIDEO) {
extractedMetadata = await ffmpegService.extractMetadata(receivedFile);
extractedMetadata = await getVideoMetadata(receivedFile);
}
const metadata: Metadata = {
@ -135,59 +127,3 @@ export async function parseMetadataJSON(
// ignore
}
}
export function parseFFmpegExtractedMetadata(encodedMetadata: Uint8Array) {
const metadataString = new TextDecoder().decode(encodedMetadata);
const metadataPropertyArray = metadataString.split('\n');
const metadataKeyValueArray = metadataPropertyArray.map((property) =>
property.split('=')
);
const validKeyValuePairs = metadataKeyValueArray.filter(
(keyValueArray) => keyValueArray.length === 2
) as Array<[string, string]>;
const metadataMap = Object.fromEntries(validKeyValuePairs);
const location = parseAppleISOLocation(
metadataMap[VideoMetadata.APPLE_LOCATION_ISO]
);
const creationTime = parseCreationTime(
metadataMap[VideoMetadata.APPLE_CREATION_DATE] ??
metadataMap[VideoMetadata.CREATION_TIME]
);
const parsedMetadata: ParsedExtractedMetadata = {
creationTime,
location: {
latitude: location.latitude,
longitude: location.longitude,
},
};
return parsedMetadata;
}
function parseAppleISOLocation(isoLocation: string) {
let location = NULL_LOCATION;
if (isoLocation) {
const [latitude, longitude] = isoLocation
.match(/(\+|-)\d+\.*\d+/g)
.map((x) => parseFloat(x));
location = { latitude, longitude };
}
return location;
}
function parseCreationTime(creationTime: string) {
let dateTime = null;
if (creationTime) {
dateTime = new Date(creationTime);
if (isNaN(dateTime.getTime())) {
dateTime = null;
}
}
if (dateTime) {
dateTime = getUNIXTime(dateTime);
}
return dateTime;
}

View file

@ -0,0 +1,66 @@
import { NULL_LOCATION } from 'constants/upload';
import ffmpegService from 'services/ffmpegService';
import { getUNIXTime } from 'utils/upload';
import { ParsedExtractedMetadata } from './metadataService';
enum VideoMetadata {
CREATION_TIME = 'creation_time',
APPLE_CONTENT_IDENTIFIER = 'com.apple.quicktime.content.identifier',
APPLE_LIVE_PHOTO_IDENTIFIER = 'com.apple.quicktime.live-photo.auto',
APPLE_CREATION_DATE = 'com.apple.quicktime.creationdate',
APPLE_LOCATION_ISO = 'com.apple.quicktime.location.ISO6709',
}
export function getVideoMetadata(file: File) {
return ffmpegService.extractMetadata(file);
}
export function parseFFmpegExtractedMetadata(encodedMetadata: Uint8Array) {
const metadataString = new TextDecoder().decode(encodedMetadata);
const metadataPropertyArray = metadataString.split('\n');
const metadataKeyValueArray = metadataPropertyArray.map((property) =>
property.split('=')
);
const validKeyValuePairs = metadataKeyValueArray.filter(
(keyValueArray) => keyValueArray.length === 2
) as Array<[string, string]>;
const metadataMap = Object.fromEntries(validKeyValuePairs);
const location = parseAppleISOLocation(
metadataMap[VideoMetadata.APPLE_LOCATION_ISO]
);
const creationTime = parseCreationTime(
metadataMap[VideoMetadata.APPLE_CREATION_DATE] ??
metadataMap[VideoMetadata.CREATION_TIME]
);
const parsedMetadata: ParsedExtractedMetadata = {
creationTime,
location: {
latitude: location.latitude,
longitude: location.longitude,
},
};
return parsedMetadata;
}
function parseAppleISOLocation(isoLocation: string) {
let location = NULL_LOCATION;
if (isoLocation) {
const [latitude, longitude] = isoLocation
.match(/(\+|-)\d+\.*\d+/g)
.map((x) => parseFloat(x));
location = { latitude, longitude };
}
return location;
}
function parseCreationTime(creationTime: string) {
let dateTime = null;
if (creationTime) {
dateTime = getUNIXTime(new Date(creationTime));
}
return dateTime;
}

View file

@ -49,3 +49,15 @@ export function segregateMetadataAndMediaFiles(
});
return { mediaFiles, metadataJSONFiles };
}
export function getUNIXTime(dateTime: Date) {
if (!dateTime || isNaN(dateTime.getTime())) {
return null;
}
const unixTime = dateTime.getTime() * 1000;
if (unixTime <= 0) {
return null;
} else {
return unixTime;
}
}