#838 cataloguing: detect HDR videos
This commit is contained in:
parent
df2d088ecf
commit
219bf1bf3f
7 changed files with 27 additions and 15 deletions
|
@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
## <a id="unreleased"></a>[Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- Cataloguing: detect/filter HDR videos
|
||||
|
||||
### Changed
|
||||
|
||||
- check Media Store changes when resuming app
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package deckers.thibault.aves.channel.calls
|
||||
|
||||
import android.content.Context
|
||||
import android.media.MediaFormat
|
||||
import android.media.MediaMetadataRetriever
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
|
@ -559,7 +560,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
|
|||
|
||||
// identification of embedded gain map
|
||||
if (xmpMeta.hasHdrGainMap()) {
|
||||
flags = flags or MASK_HAS_HDR_GAIN_MAP
|
||||
flags = flags or MASK_IS_HDR
|
||||
}
|
||||
} catch (e: XMPException) {
|
||||
Log.w(LOG_TAG, "failed to read XMP directory for uri=$uri", e)
|
||||
|
@ -797,6 +798,14 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
|
|||
}
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
retriever.getSafeInt(MediaMetadataRetriever.METADATA_KEY_COLOR_TRANSFER) {
|
||||
if (it == MediaFormat.COLOR_TRANSFER_ST2084 || it == MediaFormat.COLOR_TRANSFER_HLG) {
|
||||
flags = flags or MASK_IS_HDR
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
metadataMap[KEY_FLAGS] = flags
|
||||
} catch (e: Exception) {
|
||||
Log.w(LOG_TAG, "failed to get catalog metadata by MediaMetadataRetriever for uri=$uri", e)
|
||||
|
@ -1300,7 +1309,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
|
|||
private const val MASK_IS_360 = 1 shl 3
|
||||
private const val MASK_IS_MULTIPAGE = 1 shl 4
|
||||
private const val MASK_IS_MOTION_PHOTO = 1 shl 5
|
||||
private const val MASK_HAS_HDR_GAIN_MAP = 1 shl 6
|
||||
private const val MASK_IS_HDR = 1 shl 6 // for images: embedded HDR gainmap, for videos: HDR color transfer
|
||||
private const val XMP_SUBJECTS_SEPARATOR = ";"
|
||||
|
||||
// overlay metadata
|
||||
|
|
|
@ -242,6 +242,11 @@ class AvesEntry with AvesEntryBase {
|
|||
return _bestDate;
|
||||
}
|
||||
|
||||
@override
|
||||
bool get isAnimated => catalogMetadata?.isAnimated ?? false;
|
||||
|
||||
bool get isHdr => _catalogMetadata?.isHdr ?? false;
|
||||
|
||||
int get rating => _catalogMetadata?.rating ?? 0;
|
||||
|
||||
@override
|
||||
|
@ -303,9 +308,6 @@ class AvesEntry with AvesEntryBase {
|
|||
return d == null ? null : DateTime(d.year, d.month, d.day);
|
||||
}
|
||||
|
||||
@override
|
||||
bool get isAnimated => catalogMetadata?.isAnimated ?? false;
|
||||
|
||||
@override
|
||||
int? get durationMillis => _durationMillis;
|
||||
|
||||
|
|
|
@ -13,8 +13,6 @@ extension ExtraAvesEntryMultipage on AvesEntry {
|
|||
|
||||
bool get isMotionPhoto => catalogMetadata?.isMotionPhoto ?? false;
|
||||
|
||||
bool get isHdr => catalogMetadata?.hasHdrGainMap ?? false;
|
||||
|
||||
String? getBurstKey(List<String> patterns) {
|
||||
final key = BurstPatterns.getKeyForName(filenameWithoutExtension, patterns);
|
||||
return key != null ? '$directory/$key' : null;
|
||||
|
|
|
@ -4,7 +4,7 @@ import 'package:flutter/foundation.dart';
|
|||
class CatalogMetadata {
|
||||
final int id;
|
||||
final int? dateMillis;
|
||||
final bool isAnimated, isGeotiff, is360, isMultiPage, isMotionPhoto, hasHdrGainMap;
|
||||
final bool isAnimated, isGeotiff, is360, isMultiPage, isMotionPhoto, isHdr;
|
||||
bool isFlipped;
|
||||
int? rotationDegrees;
|
||||
final String? mimeType, xmpSubjects, xmpTitle;
|
||||
|
@ -21,7 +21,7 @@ class CatalogMetadata {
|
|||
static const _is360Mask = 1 << 3;
|
||||
static const _isMultiPageMask = 1 << 4;
|
||||
static const _isMotionPhotoMask = 1 << 5;
|
||||
static const _hasHdrGainMapMask = 1 << 6;
|
||||
static const _isHdr = 1 << 6; // for images: embedded HDR gainmap, for videos: HDR color transfer
|
||||
|
||||
CatalogMetadata({
|
||||
required this.id,
|
||||
|
@ -33,7 +33,7 @@ class CatalogMetadata {
|
|||
this.is360 = false,
|
||||
this.isMultiPage = false,
|
||||
this.isMotionPhoto = false,
|
||||
this.hasHdrGainMap = false,
|
||||
this.isHdr = false,
|
||||
this.rotationDegrees,
|
||||
this.xmpSubjects,
|
||||
this.xmpTitle,
|
||||
|
@ -75,7 +75,7 @@ class CatalogMetadata {
|
|||
is360: is360,
|
||||
isMultiPage: isMultiPage ?? this.isMultiPage,
|
||||
isMotionPhoto: isMotionPhoto,
|
||||
hasHdrGainMap: hasHdrGainMap,
|
||||
isHdr: isHdr,
|
||||
rotationDegrees: rotationDegrees ?? this.rotationDegrees,
|
||||
xmpSubjects: xmpSubjects,
|
||||
xmpTitle: xmpTitle,
|
||||
|
@ -97,7 +97,7 @@ class CatalogMetadata {
|
|||
is360: flags & _is360Mask != 0,
|
||||
isMultiPage: flags & _isMultiPageMask != 0,
|
||||
isMotionPhoto: flags & _isMotionPhotoMask != 0,
|
||||
hasHdrGainMap: flags & _hasHdrGainMapMask != 0,
|
||||
isHdr: flags & _isHdr != 0,
|
||||
// `rotationDegrees` should default to `sourceRotationDegrees`, not 0
|
||||
rotationDegrees: map['rotationDegrees'],
|
||||
xmpSubjects: map['xmpSubjects'] ?? '',
|
||||
|
@ -112,7 +112,7 @@ class CatalogMetadata {
|
|||
'id': id,
|
||||
'mimeType': mimeType,
|
||||
'dateMillis': dateMillis,
|
||||
'flags': (isAnimated ? _isAnimatedMask : 0) | (isFlipped ? _isFlippedMask : 0) | (isGeotiff ? _isGeotiffMask : 0) | (is360 ? _is360Mask : 0) | (isMultiPage ? _isMultiPageMask : 0) | (isMotionPhoto ? _isMotionPhotoMask : 0) | (hasHdrGainMap ? _hasHdrGainMapMask : 0),
|
||||
'flags': (isAnimated ? _isAnimatedMask : 0) | (isFlipped ? _isFlippedMask : 0) | (isGeotiff ? _isGeotiffMask : 0) | (is360 ? _is360Mask : 0) | (isMultiPage ? _isMultiPageMask : 0) | (isMotionPhoto ? _isMotionPhotoMask : 0) | (isHdr ? _isHdr : 0),
|
||||
'rotationDegrees': rotationDegrees,
|
||||
'xmpSubjects': xmpSubjects,
|
||||
'xmpTitle': xmpTitle,
|
||||
|
|
|
@ -91,12 +91,12 @@ class GridThemeData {
|
|||
if (located && showLocated) LocationIcon.located(),
|
||||
if (!located && showUnlocated) LocationIcon.unlocated(),
|
||||
if (entry.rating != 0 && showRating) RatingIcon(entry: entry),
|
||||
if (entry.isHdr && showHdr) const HdrIcon(),
|
||||
if (entry.isPureVideo)
|
||||
VideoIcon(entry: entry)
|
||||
else if (entry.isAnimated)
|
||||
const AnimatedImageIcon()
|
||||
else ...[
|
||||
if (entry.isHdr && showHdr) const HdrIcon(),
|
||||
if (entry.isRaw && showRaw) const RawIcon(),
|
||||
if (entry.is360) const PanoramaIcon(),
|
||||
],
|
||||
|
|
|
@ -2,7 +2,6 @@ import 'dart:async';
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:aves/model/entry/entry.dart';
|
||||
import 'package:aves/model/entry/extensions/multipage.dart';
|
||||
import 'package:aves/services/common/services.dart';
|
||||
import 'package:aves/theme/durations.dart';
|
||||
import 'package:aves/widgets/viewer/controls/cast.dart';
|
||||
|
|
Loading…
Reference in a new issue