video: improved date detection

This commit is contained in:
Thibault Deckers 2021-08-24 09:54:27 +09:00
parent c0e11a68fa
commit fc10f97bfa
4 changed files with 36 additions and 4 deletions

View file

@ -429,10 +429,14 @@ class AvesEntry {
} else { } else {
if (isVideo && (!isSized || durationMillis == 0)) { if (isVideo && (!isSized || durationMillis == 0)) {
// exotic video that is not sized during loading // exotic video that is not sized during loading
final fields = await VideoMetadataFormatter.getCatalogMetadata(this); final fields = await VideoMetadataFormatter.getLoadingMetadata(this);
await _applyNewFields(fields, persist: persist); await _applyNewFields(fields, persist: persist);
} }
catalogMetadata = await metadataService.getCatalogMetadata(this, background: background); catalogMetadata = await metadataService.getCatalogMetadata(this, background: background);
if (isVideo && (catalogMetadata?.dateMillis ?? 0) == 0) {
catalogMetadata = await VideoMetadataFormatter.getCatalogMetadata(this);
}
} }
} }

View file

@ -75,13 +75,14 @@ class CatalogMetadata {
CatalogMetadata copyWith({ CatalogMetadata copyWith({
int? contentId, int? contentId,
String? mimeType, String? mimeType,
int? dateMillis,
bool? isMultiPage, bool? isMultiPage,
int? rotationDegrees, int? rotationDegrees,
}) { }) {
return CatalogMetadata( return CatalogMetadata(
contentId: contentId ?? this.contentId, contentId: contentId ?? this.contentId,
mimeType: mimeType ?? this.mimeType, mimeType: mimeType ?? this.mimeType,
dateMillis: dateMillis, dateMillis: dateMillis ?? this.dateMillis,
isAnimated: isAnimated, isAnimated: isAnimated,
isFlipped: isFlipped, isFlipped: isFlipped,
isGeotiff: isGeotiff, isGeotiff: isGeotiff,

View file

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:aves/model/entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/metadata.dart';
import 'package:aves/model/video/channel_layouts.dart'; import 'package:aves/model/video/channel_layouts.dart';
import 'package:aves/model/video/codecs.dart'; import 'package:aves/model/video/codecs.dart';
import 'package:aves/model/video/keys.dart'; import 'package:aves/model/video/keys.dart';
@ -9,6 +10,7 @@ import 'package:aves/model/video/profiles/h264.dart';
import 'package:aves/model/video/profiles/hevc.dart'; import 'package:aves/model/video/profiles/hevc.dart';
import 'package:aves/ref/languages.dart'; import 'package:aves/ref/languages.dart';
import 'package:aves/ref/mp4.dart'; import 'package:aves/ref/mp4.dart';
import 'package:aves/services/services.dart';
import 'package:aves/utils/file_utils.dart'; import 'package:aves/utils/file_utils.dart';
import 'package:aves/utils/math_utils.dart'; import 'package:aves/utils/math_utils.dart';
import 'package:aves/utils/string_utils.dart'; import 'package:aves/utils/string_utils.dart';
@ -50,7 +52,7 @@ class VideoMetadataFormatter {
return info; return info;
} }
static Future<Map<String, int>> getCatalogMetadata(AvesEntry entry) async { static Future<Map<String, int>> getLoadingMetadata(AvesEntry entry) async {
final mediaInfo = await getVideoMetadata(entry); final mediaInfo = await getVideoMetadata(entry);
final fields = <String, int>{}; final fields = <String, int>{};
@ -75,6 +77,30 @@ class VideoMetadataFormatter {
return fields; return fields;
} }
static Future<CatalogMetadata?> getCatalogMetadata(AvesEntry entry) async {
final mediaInfo = await getVideoMetadata(entry);
int? dateMillis;
final dateString = mediaInfo[Keys.date];
if (dateString is String && dateString != '0') {
final date = DateTime.tryParse(dateString);
if (date != null) {
dateMillis = date.millisecondsSinceEpoch;
} else {
await reportService.recordError('getCatalogMetadata failed to parse date=$dateString for mimeType=${entry.mimeType} entry=$entry', null);
}
}
if (dateMillis != null) {
return (entry.catalogMetadata ?? CatalogMetadata(contentId: entry.contentId)).copyWith(
dateMillis: dateMillis,
);
}
return entry.catalogMetadata;
}
// pattern to extract optional language code suffix, e.g. 'location-eng' // pattern to extract optional language code suffix, e.g. 'location-eng'
static final keyWithLanguagePattern = RegExp(r'^(.*)-([a-z]{3})$'); static final keyWithLanguagePattern = RegExp(r'^(.*)-([a-z]{3})$');

View file

@ -41,6 +41,7 @@ class MimeTypes {
static const anyVideo = 'video/*'; static const anyVideo = 'video/*';
static const avi = 'video/avi'; static const avi = 'video/avi';
static const aviVnd = 'video/vnd.avi';
static const mkv = 'video/x-matroska'; static const mkv = 'video/x-matroska';
static const mov = 'video/quicktime'; static const mov = 'video/quicktime';
static const mp2t = 'video/mp2t'; // .m2ts static const mp2t = 'video/mp2t'; // .m2ts
@ -61,7 +62,7 @@ class MimeTypes {
static const Set<String> _knownOpaqueImages = {heic, heif, jpeg}; static const Set<String> _knownOpaqueImages = {heic, heif, jpeg};
static const Set<String> _knownVideos = {avi, mkv, mov, mp2t, mp4, ogg}; static const Set<String> _knownVideos = {avi, aviVnd, mkv, mov, mp2t, mp4, ogg};
static final Set<String> knownMediaTypes = {..._knownOpaqueImages, ...alphaImages, ...rawImages, ...undecodableImages, ..._knownVideos}; static final Set<String> knownMediaTypes = {..._knownOpaqueImages, ...alphaImages, ...rawImages, ...undecodableImages, ..._knownVideos};