improved mimetype resolution
This commit is contained in:
parent
8ca648b94a
commit
5c0e9063f4
3 changed files with 98 additions and 17 deletions
|
@ -303,36 +303,44 @@ public class MetadataHandler implements MethodChannel.MethodCallHandler {
|
|||
private void getCatalogMetadata(MethodCall call, MethodChannel.Result result) {
|
||||
String mimeType = call.argument("mimeType");
|
||||
String uri = call.argument("uri");
|
||||
String extension = call.argument("extension");
|
||||
|
||||
Map<String, Object> metadataMap = new HashMap<>(getCatalogMetadataByImageMetadataReader(uri, mimeType));
|
||||
Map<String, Object> metadataMap = new HashMap<>(getCatalogMetadataByImageMetadataReader(uri, mimeType, extension));
|
||||
if (isVideo(mimeType)) {
|
||||
metadataMap.putAll(getVideoCatalogMetadataByMediaMetadataRetriever(uri));
|
||||
}
|
||||
|
||||
if (metadataMap.isEmpty()) {
|
||||
result.error("getCatalogMetadata-failure", "failed to get catalog metadata for uri=" + uri, null);
|
||||
result.error("getCatalogMetadata-failure", "failed to get catalog metadata for uri=" + uri + ", extension=" + extension, null);
|
||||
} else {
|
||||
result.success(metadataMap);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Object> getCatalogMetadataByImageMetadataReader(String uri, String mimeType) {
|
||||
private Map<String, Object> getCatalogMetadataByImageMetadataReader(String uri, String mimeType, String extension) {
|
||||
Map<String, Object> metadataMap = new HashMap<>();
|
||||
|
||||
// as of metadata-extractor 2.14.0, MP2T files are not supported
|
||||
if (MimeTypes.MP2T.equals(mimeType)) return metadataMap;
|
||||
// as of metadata-extractor v2.14.0, MP2T/WBMP files are not supported
|
||||
if (MimeTypes.MP2T.equals(mimeType) || MimeTypes.WBMP.equals(mimeType)) return metadataMap;
|
||||
|
||||
try (InputStream is = StorageUtils.openInputStream(context, Uri.parse(uri))) {
|
||||
Metadata metadata = ImageMetadataReader.readMetadata(is);
|
||||
|
||||
// File type
|
||||
for (FileTypeDirectory dir : metadata.getDirectoriesOfType(FileTypeDirectory.class)) {
|
||||
// the reported `mimeType` (e.g. from Media Store) is sometimes incorrect
|
||||
// file extension is unreliable
|
||||
// `metadata-extractor` sometimes detect the the wrong mime type (e.g. `pef` file as `tiff`)
|
||||
// the content resolver / media store sometimes report the wrong mime type (e.g. `png` file as `jpeg`)
|
||||
// `context.getContentResolver().getType()` sometimes return incorrect value
|
||||
// `MediaMetadataRetriever.setDataSource()` sometimes fail with `status = 0x80000000`
|
||||
if (dir.containsTag(FileTypeDirectory.TAG_DETECTED_FILE_MIME_TYPE)) {
|
||||
metadataMap.put(KEY_MIME_TYPE, dir.getString(FileTypeDirectory.TAG_DETECTED_FILE_MIME_TYPE));
|
||||
String detectedMimeType = dir.getString(FileTypeDirectory.TAG_DETECTED_FILE_MIME_TYPE);
|
||||
if (detectedMimeType != null && !detectedMimeType.equals(mimeType)) {
|
||||
// file extension is unreliable, but we use it as a tie breaker
|
||||
String extensionMimeType = MimeTypes.getMimeTypeForExtension(extension.toLowerCase());
|
||||
if (detectedMimeType.equals(extensionMimeType)) {
|
||||
metadataMap.put(KEY_MIME_TYPE, detectedMimeType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -385,7 +393,7 @@ public class MetadataHandler implements MethodChannel.MethodCallHandler {
|
|||
}
|
||||
}
|
||||
} catch (Exception | NoClassDefFoundError e) {
|
||||
Log.w(LOG_TAG, "failed to get catalog metadata by ImageMetadataReader for uri=" + uri, e);
|
||||
Log.w(LOG_TAG, "failed to get catalog metadata by ImageMetadataReader for uri=" + uri + ", mimeType=" + mimeType, e);
|
||||
}
|
||||
return metadataMap;
|
||||
}
|
||||
|
|
|
@ -1,27 +1,99 @@
|
|||
package deckers.thibault.aves.utils
|
||||
|
||||
import java.util.*
|
||||
|
||||
object MimeTypes {
|
||||
const val IMAGE = "image"
|
||||
|
||||
// generic raster
|
||||
const val BMP = "image/bmp"
|
||||
const val GIF = "image/gif"
|
||||
const val HEIC = "image/heic"
|
||||
const val HEIF = "image/heif"
|
||||
const val ICO = "image/x-icon"
|
||||
const val JPEG = "image/jpeg"
|
||||
const val PCX = "image/x-pcx"
|
||||
const val PNG = "image/png"
|
||||
const val PSD = "image/x-photoshop" // aka "image/vnd.adobe.photoshop"
|
||||
const val TIFF = "image/tiff"
|
||||
const val WBMP = "image/vnd.wap.wbmp"
|
||||
const val WEBP = "image/webp"
|
||||
|
||||
const val HEIC = "image/heic"
|
||||
const val HEIF = "image/heif"
|
||||
const val PSD = "image/x-photoshop" // .psd
|
||||
// raw raster
|
||||
const val ARW = "image/x-sony-arw"
|
||||
const val CR2 = "image/x-canon-cr2"
|
||||
const val CRW = "image/x-canon-crw"
|
||||
const val DCR = "image/x-kodak-dcr"
|
||||
const val DNG = "image/x-adobe-dng"
|
||||
const val ERF = "image/x-epson-erf"
|
||||
const val K25 = "image/x-kodak-k25"
|
||||
const val KDC = "image/x-kodak-kdc"
|
||||
const val MRW = "image/x-minolta-mrw"
|
||||
const val NEF = "image/x-nikon-nef"
|
||||
const val NRW = "image/x-nikon-nrw"
|
||||
const val ORF = "image/x-olympus-orf"
|
||||
const val PEF = "image/x-pentax-pef"
|
||||
const val RAF = "image/x-fuji-raf"
|
||||
const val RAW = "image/x-panasonic-raw"
|
||||
const val RW2 = "image/x-panasonic-rw2"
|
||||
const val SR2 = "image/x-sony-sr2"
|
||||
const val SRF = "image/x-sony-srf"
|
||||
const val SRW = "image/x-samsung-srw"
|
||||
const val X3F = "image/x-sigma-x3f"
|
||||
|
||||
const val DNG = "image/x-adobe-dng" // .dng
|
||||
|
||||
const val SVG = "image/svg+xml" // .svg
|
||||
// vector
|
||||
const val SVG = "image/svg+xml"
|
||||
|
||||
const val VIDEO = "video"
|
||||
|
||||
const val AVI = "video/avi"
|
||||
const val MP2T = "video/mp2t" // .m2ts
|
||||
const val MOV = "video/quicktime"
|
||||
const val MP2T = "video/mp2t"
|
||||
const val MP4 = "video/mp4"
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getMimeTypeForExtension(extension: String?): String? = when (extension?.toLowerCase(Locale.ROOT)) {
|
||||
// generic raster
|
||||
".bmp" -> BMP
|
||||
".gif" -> GIF
|
||||
".heic" -> HEIC
|
||||
".heif" -> HEIF
|
||||
".ico" -> ICO
|
||||
".jpg", ".jpeg", ".jpe" -> JPEG
|
||||
".pcx" -> PCX
|
||||
".png" -> PNG
|
||||
".psd" -> PSD
|
||||
".tiff", ".tif" -> TIFF
|
||||
".wbmp" -> WBMP
|
||||
".webp" -> WEBP
|
||||
// raw raster
|
||||
".arw" -> ARW
|
||||
".cr2" -> CR2
|
||||
".crw" -> CRW
|
||||
".dcr" -> DCR
|
||||
".dng" -> DNG
|
||||
".erf" -> ERF
|
||||
".k25" -> K25
|
||||
".kdc" -> KDC
|
||||
".mrw" -> MRW
|
||||
".nef" -> NEF
|
||||
".nrw" -> NRW
|
||||
".orf" -> ORF
|
||||
".pef" -> PEF
|
||||
".raf" -> RAF
|
||||
".raw" -> RAW
|
||||
".rw2" -> RW2
|
||||
".sr2" -> SR2
|
||||
".srf" -> SRF
|
||||
".srw" -> SRW
|
||||
".x3f" -> X3F
|
||||
// vector
|
||||
".svg" -> SVG
|
||||
// video
|
||||
".avi" -> AVI
|
||||
".m2ts" -> MP2T
|
||||
".mov", ".qt" -> MOV
|
||||
".mp4", ".m4a", ".m4p", ".m4b", ".m4r", ".m4v" -> MP4
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ class MetadataService {
|
|||
final result = await platform.invokeMethod('getCatalogMetadata', <String, dynamic>{
|
||||
'mimeType': entry.mimeType,
|
||||
'uri': entry.uri,
|
||||
'extension': entry.extension,
|
||||
}) as Map;
|
||||
result['contentId'] = entry.contentId;
|
||||
return CatalogMetadata.fromMap(result);
|
||||
|
|
Loading…
Reference in a new issue