diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataHandler.kt index 83fcecd10..ed5a8bcd6 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataHandler.kt @@ -200,6 +200,20 @@ class MetadataHandler(private val context: Context) : MethodCallHandler { return dirMap } + // set `KEY_DATE_MILLIS` from these fields (by precedence): + // - ME / Exif / DATETIME_ORIGINAL + // - ME / Exif / DATETIME + // - EI / Exif / DATETIME_ORIGINAL + // - EI / Exif / DATETIME + // - ME / XMP / xmp:CreateDate + // - ME / XMP / photoshop:DateCreated + // - MMR / METADATA_KEY_DATE + // set `KEY_XMP_TITLE_DESCRIPTION` from these fields (by precedence): + // - ME / XMP / dc:title + // - ME / XMP / dc:description + // set `KEY_XMP_SUBJECTS` from these fields (by precedence): + // - ME / XMP / dc:subject + // - ME / IPTC / keywords private fun getCatalogMetadata(call: MethodCall, result: MethodChannel.Result) { val mimeType = call.argument("mimeType") val uri = call.argument("uri")?.let { Uri.parse(it) } @@ -211,24 +225,14 @@ class MetadataHandler(private val context: Context) : MethodCallHandler { } val metadataMap = HashMap(getCatalogMetadataByMetadataExtractor(uri, mimeType, path, sizeBytes)) - if (isVideo(mimeType)) { - metadataMap.putAll(getVideoCatalogMetadataByMediaMetadataRetriever(uri)) + if (isMultimedia(mimeType)) { + metadataMap.putAll(getMultimediaCatalogMetadataByMediaMetadataRetriever(uri)) } // report success even when empty result.success(metadataMap) } - // set `KEY_DATE_MILLIS` from these fields (by precedence): - // - Exif / DATETIME_ORIGINAL - // - Exif / DATETIME - // - XMP / xmp:CreateDate - // set `KEY_XMP_TITLE_DESCRIPTION` from these fields (by precedence): - // - XMP / dc:title - // - XMP / dc:description - // set `KEY_XMP_SUBJECTS` from these fields (by precedence): - // - XMP / dc:subject - // - IPTC / keywords private fun getCatalogMetadataByMetadataExtractor(uri: Uri, mimeType: String, path: String?, sizeBytes: Long?): Map { val metadataMap = HashMap() @@ -301,6 +305,9 @@ class MetadataHandler(private val context: Context) : MethodCallHandler { } if (!metadataMap.containsKey(KEY_DATE_MILLIS)) { xmpMeta.getSafeDateMillis(XMP.XMP_SCHEMA_NS, XMP.CREATE_DATE_PROP_NAME) { metadataMap[KEY_DATE_MILLIS] = it } + if (!metadataMap.containsKey(KEY_DATE_MILLIS)) { + xmpMeta.getSafeDateMillis(XMP.PHOTOSHOP_SCHEMA_NS, XMP.PS_DATE_CREATED_PROP_NAME) { metadataMap[KEY_DATE_MILLIS] = it } + } } // identification of panorama (aka photo sphere) @@ -381,22 +388,26 @@ class MetadataHandler(private val context: Context) : MethodCallHandler { return metadataMap } - private fun getVideoCatalogMetadataByMediaMetadataRetriever(uri: Uri): Map { + private fun getMultimediaCatalogMetadataByMediaMetadataRetriever(uri: Uri): Map { val metadataMap = HashMap() val retriever = StorageUtils.openMetadataRetriever(context, uri) ?: return metadataMap try { retriever.getSafeInt(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION) { metadataMap[KEY_ROTATION_DEGREES] = it } - retriever.getSafeDateMillis(MediaMetadataRetriever.METADATA_KEY_DATE) { metadataMap[KEY_DATE_MILLIS] = it } + if (!metadataMap.containsKey(KEY_DATE_MILLIS)) { + retriever.getSafeDateMillis(MediaMetadataRetriever.METADATA_KEY_DATE) { metadataMap[KEY_DATE_MILLIS] = it } + } - val locationString = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_LOCATION) - if (locationString != null) { - val matcher = Metadata.VIDEO_LOCATION_PATTERN.matcher(locationString) - if (matcher.find() && matcher.groupCount() >= 2) { - val latitude = matcher.group(1)?.toDoubleOrNull() - val longitude = matcher.group(2)?.toDoubleOrNull() - if (latitude != null && longitude != null) { - metadataMap[KEY_LATITUDE] = latitude - metadataMap[KEY_LONGITUDE] = longitude + if (!metadataMap.containsKey(KEY_LATITUDE)) { + val locationString = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_LOCATION) + if (locationString != null) { + val matcher = Metadata.VIDEO_LOCATION_PATTERN.matcher(locationString) + if (matcher.find() && matcher.groupCount() >= 2) { + val latitude = matcher.group(1)?.toDoubleOrNull() + val longitude = matcher.group(2)?.toDoubleOrNull() + if (latitude != null && longitude != null) { + metadataMap[KEY_LATITUDE] = latitude + metadataMap[KEY_LONGITUDE] = longitude + } } } } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/XMP.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/XMP.kt index 9572a76d6..1953e7d9e 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/XMP.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/XMP.kt @@ -10,12 +10,14 @@ object XMP { private val LOG_TAG = LogUtils.createTag(XMP::class.java) const val DC_SCHEMA_NS = "http://purl.org/dc/elements/1.1/" + const val PHOTOSHOP_SCHEMA_NS = "http://ns.adobe.com/photoshop/1.0/" const val XMP_SCHEMA_NS = "http://ns.adobe.com/xap/1.0/" const val IMG_SCHEMA_NS = "http://ns.adobe.com/xap/1.0/g/img/" const val SUBJECT_PROP_NAME = "dc:subject" const val TITLE_PROP_NAME = "dc:title" const val DESCRIPTION_PROP_NAME = "dc:description" + const val PS_DATE_CREATED_PROP_NAME = "photoshop:DateCreated"; const val CREATE_DATE_PROP_NAME = "xmp:CreateDate" const val THUMBNAIL_PROP_NAME = "xmp:Thumbnails" const val THUMBNAIL_IMAGE_PROP_NAME = "xmpGImg:image"