diff --git a/mobile/lib/models/ffmpeg/ffprobe_keys.dart b/mobile/lib/models/ffmpeg/ffprobe_keys.dart index 081fe0ff7e..5eddee32c8 100644 --- a/mobile/lib/models/ffmpeg/ffprobe_keys.dart +++ b/mobile/lib/models/ffmpeg/ffprobe_keys.dart @@ -28,7 +28,7 @@ class FFProbeKeys { static const date = 'date'; static const disposition = 'disposition'; static const duration = 'duration'; - static const quickTimeLocation ="com.apple.quicktime.location.ISO6709"; + static const quickTimeLocation = "com.apple.quicktime.location.ISO6709"; static const durationMicros = 'duration_us'; static const encoder = 'encoder'; static const extraDataSize = 'extradata_size'; @@ -70,6 +70,8 @@ class FFProbeKeys { static const vendorId = 'vendor_id'; static const width = 'width'; static const xiaomiSlowMoment = 'com.xiaomi.slow_moment'; + static const sideDataList = 'side_data_list'; + static const rotation = 'rotation'; } class MediaStreamTypes { diff --git a/mobile/lib/models/ffmpeg/ffprobe_props.dart b/mobile/lib/models/ffmpeg/ffprobe_props.dart index 027d0377ee..b72c59f5ba 100644 --- a/mobile/lib/models/ffmpeg/ffprobe_props.dart +++ b/mobile/lib/models/ffmpeg/ffprobe_props.dart @@ -18,20 +18,56 @@ class FFProbeProps { String? bitrate; String? majorBrand; String? fps; - String? codecWidth; - String? codecHeight; + String? _codecWidth; + String? _codecHeight; + int? _rotation; // dot separated bitrate, fps, codecWidth, codecHeight. Ignore null value String get videoInfo { final List info = []; if (bitrate != null) info.add('$bitrate'); if (fps != null) info.add('ƒ/$fps'); - if (codecWidth != null && codecHeight != null) { - info.add('$codecWidth x $codecHeight'); + if (_codecWidth != null && _codecHeight != null) { + info.add('$_codecWidth x $_codecHeight'); } return info.join(' * '); } + int? get width { + if (_codecWidth == null || _codecHeight == null) return null; + final intCodecWidth = int.tryParse(_codecWidth!); + if (_rotation == null) { + return intCodecWidth; + } else { + if ((_rotation! ~/ 90).isEven) { + return intCodecWidth; + } else { + return int.tryParse(_codecHeight!); + } + } + } + + int? get height { + if (_codecWidth == null || _codecHeight == null) return null; + final intCodecHeight = int.tryParse(_codecHeight!); + if (_rotation == null) { + return intCodecHeight; + } else { + if ((_rotation! ~/ 90).isEven) { + return intCodecHeight; + } else { + return int.tryParse(_codecWidth!); + } + } + } + + double? get aspectRatio { + if (width == null || height == null || height == 0 || width == 0) { + return null; + } + return width! / height!; + } + // toString() method @override String toString() { @@ -132,11 +168,13 @@ class FFProbeProps { result.fps = _formatFPS(stream[key]); parsedData[key] = result.fps; } else if (key == FFProbeKeys.codedWidth) { - result.codecWidth = stream[key].toString(); - parsedData[key] = result.codecWidth; + result._codecWidth = stream[key].toString(); + parsedData[key] = result._codecWidth; } else if (key == FFProbeKeys.codedHeight) { - result.codecHeight = stream[key].toString(); - parsedData[key] = result.codecHeight; + result._codecHeight = stream[key].toString(); + parsedData[key] = result._codecHeight; + } else if (key == FFProbeKeys.sideDataList) { + result._rotation = stream[key][0][FFProbeKeys.rotation]; } } } diff --git a/mobile/lib/ui/viewer/file/zoomable_image.dart b/mobile/lib/ui/viewer/file/zoomable_image.dart index c6c7ba003d..4df004b1a2 100644 --- a/mobile/lib/ui/viewer/file/zoomable_image.dart +++ b/mobile/lib/ui/viewer/file/zoomable_image.dart @@ -14,8 +14,6 @@ import 'package:photos/events/files_updated_event.dart'; import 'package:photos/events/local_photos_updated_event.dart'; import "package:photos/models/file/extensions/file_props.dart"; import 'package:photos/models/file/file.dart'; -import "package:photos/models/metadata/file_magic.dart"; -import "package:photos/services/file_magic_service.dart"; import "package:photos/ui/actions/file/file_actions.dart"; import 'package:photos/ui/common/loading_widget.dart'; import 'package:photos/utils/file_util.dart'; @@ -31,12 +29,12 @@ class ZoomableImage extends StatefulWidget { const ZoomableImage( this.photo, { - Key? key, + super.key, this.shouldDisableScroll, required this.tagPrefix, this.backgroundDecoration, this.shouldCover = false, - }) : super(key: key); + }); @override State createState() => _ZoomableImageState(); @@ -359,29 +357,6 @@ class _ZoomableImageState extends State { if (finalImageInfo == null && canUpdateMetadata && !_photo.hasDimensions) { finalImageInfo = await getImageInfo(finalImageProvider); } - if (finalImageInfo != null && canUpdateMetadata) { - _updateAspectRatioIfNeeded(_photo, finalImageInfo).ignore(); - } - } - - // Fallback logic to finish back fill and update aspect - // ratio if needed. - Future _updateAspectRatioIfNeeded( - EnteFile enteFile, - ImageInfo imageInfo, - ) async { - final int h = imageInfo.image.height, w = imageInfo.image.width; - if (h != enteFile.height || w != enteFile.width) { - final logMessage = - 'Updating aspect ratio for from ${enteFile.height}x${enteFile.width} to ${h}x$w'; - _logger.info(logMessage); - await FileMagicService.instance.updatePublicMagicMetadata([ - enteFile, - ], { - heightKey: h, - widthKey: w, - }); - } } bool _isGIF() => _photo.displayName.toLowerCase().endsWith(".gif");