diff --git a/CHANGELOG.md b/CHANGELOG.md
index bd6b245cc..4a44dee6c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,10 @@ All notable changes to this project will be documented in this file.
- Accessibility: apply bold font system setting
+### Fixed
+
+- reading metadata for some MP4 files
+
## [v1.7.4] - 2022-11-11
### Added
diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt
index 70cc77434..d780a009e 100644
--- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt
+++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt
@@ -124,6 +124,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
val metadataMap = HashMap>()
var foundExif = false
var foundXmp = false
+ var foundMp4Uuid = false
fun processXmp(xmpMeta: XMPMeta, dirMap: MutableMap, allowMultiple: Boolean = false) {
if (foundXmp && !allowMultiple) return
@@ -209,11 +210,13 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
Metadata.openSafeInputStream(context, uri, mimeType, sizeBytes)?.use { input ->
val metadata = Helper.safeRead(input)
foundExif = metadata.directories.any { it is ExifDirectoryBase && it.tagCount > 0 }
+ foundMp4Uuid = metadata.directories.any { it is Mp4UuidBoxDirectory && it.tagCount > 0 }
val dirByName = metadata.directories.filter {
(it.tagCount > 0 || it.errorCount > 0)
&& it !is FileTypeDirectory
&& it !is AviDirectory
+ && !(it is XmpDirectory && it.tagCount == 1 && it.containsTag(XmpDirectory.TAG_XMP_VALUE_COUNT))
}.groupBy { dir -> dir.name }
for (dirEntry in dirByName) {
@@ -388,11 +391,13 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
}
XMP.checkHeic(context, mimeType, uri, foundXmp, ::fallbackProcessXmp)
- if (isLargeMp4(mimeType, sizeBytes)) {
- XMP.checkMp4(context, mimeType, uri) { dirs ->
- for (dir in dirs.filterIsInstance()) {
- fallbackProcessXmp(dir.xmpMeta)
- }
+ // `metadata-extractor` may fail to get UUID boxes for some MP4 files,
+ // so we always check with `mp4parser`, even for smaller files
+ XMP.checkMp4(context, mimeType, uri) { dirs ->
+ for (dir in dirs.filterIsInstance()) {
+ fallbackProcessXmp(dir.xmpMeta)
+ }
+ if (!foundMp4Uuid) {
for (dir in dirs.filterIsInstance()) {
processMp4Uuid(dir)
}
@@ -491,6 +496,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
var flags = (metadataMap[KEY_FLAGS] ?: 0) as Int
var foundExif = false
var foundXmp = false
+ var foundMp4Uuid = false
fun processXmp(xmpMeta: XMPMeta, allowMultiple: Boolean = false) {
if (foundXmp && !allowMultiple) return
@@ -543,6 +549,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
Metadata.openSafeInputStream(context, uri, mimeType, sizeBytes)?.use { input ->
val metadata = Helper.safeRead(input)
foundExif = metadata.directories.any { it is ExifDirectoryBase && it.tagCount > 0 }
+ foundMp4Uuid = metadata.directories.any { it is Mp4UuidBoxDirectory && it.tagCount > 0 }
// File type
for (dir in metadata.getDirectoriesOfType(FileTypeDirectory::class.java)) {
@@ -695,11 +702,13 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
}
XMP.checkHeic(context, mimeType, uri, foundXmp, ::processXmp)
- if (isLargeMp4(mimeType, sizeBytes)) {
- XMP.checkMp4(context, mimeType, uri) { dirs ->
- for (dir in dirs.filterIsInstance()) {
- processXmp(dir.xmpMeta)
- }
+ // `metadata-extractor` may fail to get UUID boxes for some MP4 files,
+ // so we always check with `mp4parser`, even for smaller files
+ XMP.checkMp4(context, mimeType, uri) { dirs ->
+ for (dir in dirs.filterIsInstance()) {
+ processXmp(dir.xmpMeta)
+ }
+ if (!foundMp4Uuid) {
for (dir in dirs.filterIsInstance()) {
processMp4Uuid(dir)
}
@@ -941,11 +950,11 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
}
XMP.checkHeic(context, mimeType, uri, foundXmp, ::processXmp)
- if (isLargeMp4(mimeType, sizeBytes)) {
- XMP.checkMp4(context, mimeType, uri) { dirs ->
- for (dir in dirs.filterIsInstance()) {
- processXmp(dir.xmpMeta)
- }
+ // `metadata-extractor` may fail to get UUID boxes for some MP4 files,
+ // so we always check with `mp4parser`, even for smaller files
+ XMP.checkMp4(context, mimeType, uri) { dirs ->
+ for (dir in dirs.filterIsInstance()) {
+ processXmp(dir.xmpMeta)
}
}
@@ -1026,11 +1035,11 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
}
XMP.checkHeic(context, mimeType, uri, foundXmp, ::processXmp)
- if (isLargeMp4(mimeType, sizeBytes)) {
- XMP.checkMp4(context, mimeType, uri) { dirs ->
- for (dir in dirs.filterIsInstance()) {
- processXmp(dir.xmpMeta)
- }
+ // `metadata-extractor` may fail to get UUID boxes for some MP4 files,
+ // so we always check with `mp4parser`, even for smaller files
+ XMP.checkMp4(context, mimeType, uri) { dirs ->
+ for (dir in dirs.filterIsInstance()) {
+ processXmp(dir.xmpMeta)
}
}
diff --git a/pubspec.lock b/pubspec.lock
index bb827f20f..89102e1ca 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -8,6 +8,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "47.0.0"
+ _flutterfire_internals:
+ dependency: transitive
+ description:
+ name: _flutterfire_internals
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.0.8"
analyzer:
dependency: transitive
description:
@@ -60,7 +67,7 @@ packages:
aves_report_platform:
dependency: "direct main"
description:
- path: "plugins/aves_report_console"
+ path: "plugins/aves_report_crashlytics"
relative: true
source: path
version: "0.0.1"
@@ -74,7 +81,7 @@ packages:
aves_services_platform:
dependency: "direct main"
description:
- path: "plugins/aves_services_none"
+ path: "plugins/aves_services_google"
relative: true
source: path
version: "0.0.1"
@@ -120,6 +127,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
+ cloud_firestore_platform_interface:
+ dependency: transitive
+ description:
+ name: cloud_firestore_platform_interface
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "5.8.5"
+ cloud_firestore_web:
+ dependency: transitive
+ description:
+ name: cloud_firestore_web
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "3.0.5"
collection:
dependency: "direct main"
description:
@@ -264,6 +285,41 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.2"
+ firebase_core:
+ dependency: transitive
+ description:
+ name: firebase_core
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.2.0"
+ firebase_core_platform_interface:
+ dependency: transitive
+ description:
+ name: firebase_core_platform_interface
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "4.5.2"
+ firebase_core_web:
+ dependency: transitive
+ description:
+ name: firebase_core_web
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.0.1"
+ firebase_crashlytics:
+ dependency: transitive
+ description:
+ name: firebase_crashlytics
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "3.0.5"
+ firebase_crashlytics_platform_interface:
+ dependency: transitive
+ description:
+ name: firebase_crashlytics_platform_interface
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "3.3.6"
flex_color_picker:
dependency: "direct main"
description:
@@ -342,6 +398,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.13"
+ flutter_plugin_android_lifecycle:
+ dependency: transitive
+ description:
+ name: flutter_plugin_android_lifecycle
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.0.7"
flutter_staggered_animations:
dependency: "direct main"
description:
@@ -385,6 +448,41 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
+ google_api_availability:
+ dependency: transitive
+ description:
+ name: google_api_availability
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "3.0.1"
+ google_maps_flutter:
+ dependency: transitive
+ description:
+ name: google_maps_flutter
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.2.1"
+ google_maps_flutter_android:
+ dependency: transitive
+ description:
+ name: google_maps_flutter_android
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.3.3"
+ google_maps_flutter_ios:
+ dependency: transitive
+ description:
+ name: google_maps_flutter_ios
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.1.12"
+ google_maps_flutter_platform_interface:
+ dependency: transitive
+ description:
+ name: google_maps_flutter_platform_interface
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.2.4"
highlight:
dependency: transitive
description:
@@ -947,6 +1045,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
+ stream_transform:
+ dependency: transitive
+ description:
+ name: stream_transform
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.1.0"
streams_channel:
dependency: "direct main"
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 7bf42b4a4..a7a721bb2 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -30,11 +30,11 @@ dependencies:
aves_report:
path: plugins/aves_report
aves_report_platform:
- path: plugins/aves_report_console
+ path: plugins/aves_report_crashlytics
aves_services:
path: plugins/aves_services
aves_services_platform:
- path: plugins/aves_services_none
+ path: plugins/aves_services_google
charts_flutter:
collection:
connectivity_plus: