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 4b9ec136d..21e275e5e 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 @@ -74,6 +74,7 @@ class MetadataHandler(private val context: Context) : MethodCallHandler { "getExifInterfaceMetadata" -> GlobalScope.launch { getExifInterfaceMetadata(call, Coresult(result)) } "getMediaMetadataRetrieverMetadata" -> GlobalScope.launch { getMediaMetadataRetrieverMetadata(call, Coresult(result)) } "getBitmapFactoryInfo" -> GlobalScope.launch { getBitmapFactoryInfo(call, Coresult(result)) } + "getMetadataExtractorSummary" -> GlobalScope.launch { getMetadataExtractorSummary(call, Coresult(result)) } "getEmbeddedPictures" -> GlobalScope.launch { getEmbeddedPictures(call, Coresult(result)) } "getExifThumbnails" -> GlobalScope.launch { getExifThumbnails(call, Coresult(result)) } "getXmpThumbnails" -> GlobalScope.launch { getXmpThumbnails(call, Coresult(result)) } @@ -544,6 +545,49 @@ class MetadataHandler(private val context: Context) : MethodCallHandler { result.success(metadataMap) } + private fun getMetadataExtractorSummary(call: MethodCall, result: MethodChannel.Result) { + val uri = call.argument("uri")?.let { Uri.parse(it) } + if (uri == null) { + result.error("getMetadataExtractorSummary-args", "failed because of missing arguments", null) + return + } + + val metadataMap = HashMap() + try { + StorageUtils.openInputStream(context, uri)?.use { input -> + val metadata = ImageMetadataReader.readMetadata(input) + metadataMap["mimeType"] = metadata.getDirectoriesOfType(FileTypeDirectory::class.java).joinToString { dir -> + if (dir.containsTag(FileTypeDirectory.TAG_DETECTED_FILE_MIME_TYPE)) { + dir.getString(FileTypeDirectory.TAG_DETECTED_FILE_MIME_TYPE) + } else "" + } + metadataMap["typeName"] = metadata.getDirectoriesOfType(FileTypeDirectory::class.java).joinToString { dir -> + if (dir.containsTag(FileTypeDirectory.TAG_DETECTED_FILE_TYPE_NAME)) { + dir.getString(FileTypeDirectory.TAG_DETECTED_FILE_TYPE_NAME) + } else "" + } + for (dir in metadata.directories) { + val dirName = dir.name ?: "" + var index = 0 + while (metadataMap.containsKey("$dirName ($index)")) index++ + var value = "${dir.tagCount} tags" + dir.parent?.let { value += ", parent: ${it.name}" } + metadataMap["$dirName ($index)"] = value + } + } + } catch (e: Exception) { + Log.w(LOG_TAG, "failed to get metadata by metadata-extractor for uri=$uri", e) + } catch (e: NoClassDefFoundError) { + Log.w(LOG_TAG, "failed to get metadata by metadata-extractor for uri=$uri", e) + } + + if (metadataMap.isNotEmpty()) { + result.success(metadataMap) + } else { + result.error("getMetadataExtractorSummary-failure", "failed to get metadata for uri=$uri", null) + } + } + private fun getEmbeddedPictures(call: MethodCall, result: MethodChannel.Result) { val uri = call.argument("uri")?.let { Uri.parse(it) } if (uri == null) { diff --git a/lib/services/metadata_service.dart b/lib/services/metadata_service.dart index 5bbed1ddb..43a4998b1 100644 --- a/lib/services/metadata_service.dart +++ b/lib/services/metadata_service.dart @@ -130,6 +130,19 @@ class MetadataService { return {}; } + static Future getMetadataExtractorSummary(ImageEntry entry) async { + try { + // return map with the mime type and tag count for each directory found by `metadata-extractor` + final result = await platform.invokeMethod('getMetadataExtractorSummary', { + 'uri': entry.uri, + }) as Map; + return result; + } on PlatformException catch (e) { + debugPrint('getMetadataExtractorSummary failed with code=${e.code}, exception=${e.message}, details=${e.details}'); + } + return {}; + } + static Future> getEmbeddedPictures(String uri) async { try { final result = await platform.invokeMethod('getEmbeddedPictures', { diff --git a/lib/widgets/fullscreen/debug/metadata.dart b/lib/widgets/fullscreen/debug/metadata.dart index f05fbf623..d4b03340f 100644 --- a/lib/widgets/fullscreen/debug/metadata.dart +++ b/lib/widgets/fullscreen/debug/metadata.dart @@ -18,7 +18,7 @@ class MetadataTab extends StatefulWidget { } class _MetadataTabState extends State { - Future _bitmapFactoryLoader, _contentResolverMetadataLoader, _exifInterfaceMetadataLoader, _mediaMetadataLoader; + Future _bitmapFactoryLoader, _contentResolverMetadataLoader, _exifInterfaceMetadataLoader, _mediaMetadataLoader, _metadataExtractorLoader; // MediaStore timestamp keys static const secondTimestampKeys = ['date_added', 'date_modified', 'date_expires', 'isPlayed']; @@ -37,6 +37,7 @@ class _MetadataTabState extends State { _contentResolverMetadataLoader = MetadataService.getContentResolverMetadata(entry); _exifInterfaceMetadataLoader = MetadataService.getExifInterfaceMetadata(entry); _mediaMetadataLoader = MetadataService.getMediaMetadataRetrieverMetadata(entry); + _metadataExtractorLoader = MetadataService.getMetadataExtractorSummary(entry); setState(() {}); } @@ -94,6 +95,10 @@ class _MetadataTabState extends State { future: _mediaMetadataLoader, builder: (context, snapshot) => builder(context, snapshot, 'Media Metadata Retriever'), ), + FutureBuilder( + future: _metadataExtractorLoader, + builder: (context, snapshot) => builder(context, snapshot, 'Metadata Extractor'), + ), ], ); }