#405 fixed editing metadata for some MP4 files
This commit is contained in:
parent
b268a5c117
commit
85ffd6843b
4 changed files with 142 additions and 24 deletions
|
@ -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
|
||||
|
||||
## <a id="v1.7.4"></a>[v1.7.4] - 2022-11-11
|
||||
|
||||
### Added
|
||||
|
|
|
@ -124,6 +124,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
|
|||
val metadataMap = HashMap<String, MutableMap<String, String>>()
|
||||
var foundExif = false
|
||||
var foundXmp = false
|
||||
var foundMp4Uuid = false
|
||||
|
||||
fun processXmp(xmpMeta: XMPMeta, dirMap: MutableMap<String, String>, 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)) {
|
||||
// `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<XmpDirectory>()) {
|
||||
fallbackProcessXmp(dir.xmpMeta)
|
||||
}
|
||||
if (!foundMp4Uuid) {
|
||||
for (dir in dirs.filterIsInstance<Mp4UuidBoxDirectory>()) {
|
||||
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)) {
|
||||
// `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<XmpDirectory>()) {
|
||||
processXmp(dir.xmpMeta)
|
||||
}
|
||||
if (!foundMp4Uuid) {
|
||||
for (dir in dirs.filterIsInstance<Mp4UuidBoxDirectory>()) {
|
||||
processMp4Uuid(dir)
|
||||
}
|
||||
|
@ -941,13 +950,13 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
|
|||
}
|
||||
|
||||
XMP.checkHeic(context, mimeType, uri, foundXmp, ::processXmp)
|
||||
if (isLargeMp4(mimeType, sizeBytes)) {
|
||||
// `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<XmpDirectory>()) {
|
||||
processXmp(dir.xmpMeta)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fields.isEmpty()) {
|
||||
result.error("getPanoramaInfo-empty", "failed to get info for mimeType=$mimeType uri=$uri", null)
|
||||
|
@ -1026,13 +1035,13 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
|
|||
}
|
||||
|
||||
XMP.checkHeic(context, mimeType, uri, foundXmp, ::processXmp)
|
||||
if (isLargeMp4(mimeType, sizeBytes)) {
|
||||
// `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<XmpDirectory>()) {
|
||||
processXmp(dir.xmpMeta)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result.success(xmpStrings)
|
||||
}
|
||||
|
|
109
pubspec.lock
109
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:
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue