Motion Photo Support (#1058)

This commit is contained in:
Neeraj Gupta 2023-05-03 14:23:12 +05:30 committed by GitHub
commit 8894c61d98
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 46 additions and 9 deletions

View file

@ -285,7 +285,7 @@ class File extends EnteFile {
} }
// return 0 if the height is not available // return 0 if the height is not available
int get heigth { int get height {
return pubMagicMetadata?.h ?? 0; return pubMagicMetadata?.h ?? 0;
} }

View file

@ -21,6 +21,7 @@ const publicMagicKeyWidth = 'w';
const publicMagicKeyHeight = 'h'; const publicMagicKeyHeight = 'h';
const pubMagicKeyLat = "lat"; const pubMagicKeyLat = "lat";
const pubMagicKeyLong = "long"; const pubMagicKeyLong = "long";
const pubMotionVideoIndex = "mvi";
class MagicMetadata { class MagicMetadata {
// 0 -> visible // 0 -> visible
@ -52,6 +53,9 @@ class PubMagicMetadata {
int? h; int? h;
double? lat; double? lat;
double? long; double? long;
// Motion Video Index. Positive value indicates that the file is a motion
// photo
int? mvi;
PubMagicMetadata({ PubMagicMetadata({
this.editedTime, this.editedTime,
@ -62,6 +66,7 @@ class PubMagicMetadata {
this.h, this.h,
this.lat, this.lat,
this.long, this.long,
this.mvi,
}); });
factory PubMagicMetadata.fromEncodedJson(String encodedJson) => factory PubMagicMetadata.fromEncodedJson(String encodedJson) =>
@ -81,6 +86,7 @@ class PubMagicMetadata {
h: map[publicMagicKeyHeight], h: map[publicMagicKeyHeight],
lat: map[pubMagicKeyLat], lat: map[pubMagicKeyLat],
long: map[pubMagicKeyLong], long: map[pubMagicKeyLong],
mvi: map[pubMotionVideoIndex],
); );
} }
} }

View file

@ -111,8 +111,9 @@ class _ThumbnailWidgetState extends State<ThumbnailWidget> {
} }
if (widget.file!.fileType == FileType.video) { if (widget.file!.fileType == FileType.video) {
contentChildren.add(const VideoOverlayIcon()); contentChildren.add(const VideoOverlayIcon());
} else if (widget.file!.fileType == FileType.livePhoto && } else if (widget.shouldShowLivePhotoOverlay &&
widget.shouldShowLivePhotoOverlay) { (widget.file!.fileType == FileType.livePhoto ||
((widget.file!.pubMagicMetadata?.mvi ?? 0) > 0))) {
contentChildren.add(const LivePhotoOverlayIcon()); contentChildren.add(const LivePhotoOverlayIcon());
} }
if (widget.shouldShowOwnerAvatar) { if (widget.shouldShowOwnerAvatar) {

View file

@ -276,7 +276,7 @@ class _ZoomableImageState extends State<ZoomableImage>
final int h = imageInfo.image.height, w = imageInfo.image.width; final int h = imageInfo.image.height, w = imageInfo.image.width;
if (h != 0 && if (h != 0 &&
w != 0 && w != 0 &&
(h != widget.photo.heigth || w != widget.photo.width)) { (h != widget.photo.height || w != widget.photo.width)) {
_logger.info('Updating aspect ratio for ${widget.photo} to $h:$w'); _logger.info('Updating aspect ratio for ${widget.photo} to $h:$w');
await FileMagicService.instance.updatePublicMagicMetadata( await FileMagicService.instance.updatePublicMagicMetadata(
[widget.photo], {publicMagicKeyHeight: h, publicMagicKeyWidth: w}); [widget.photo], {publicMagicKeyHeight: h, publicMagicKeyWidth: w});

View file

@ -5,10 +5,13 @@ import 'package:chewie/chewie.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:motion_photos/motion_photos.dart'; import 'package:motion_photos/motion_photos.dart';
import "package:photos/core/configuration.dart";
import 'package:photos/core/constants.dart'; import 'package:photos/core/constants.dart';
import "package:photos/generated/l10n.dart"; import "package:photos/generated/l10n.dart";
import 'package:photos/models/file.dart'; import 'package:photos/models/file.dart';
import "package:photos/models/file_type.dart"; import "package:photos/models/file_type.dart";
import "package:photos/models/magic_metadata.dart";
import "package:photos/services/file_magic_service.dart";
import 'package:photos/ui/viewer/file/zoomable_image.dart'; import 'package:photos/ui/viewer/file/zoomable_image.dart';
import 'package:photos/utils/file_util.dart'; import 'package:photos/utils/file_util.dart';
import 'package:photos/utils/toast_util.dart'; import 'package:photos/utils/toast_util.dart';
@ -177,6 +180,13 @@ class _ZoomableLiveImageState extends State<ZoomableLiveImage>
final motionPhoto = MotionPhotos(imageFile.path); final motionPhoto = MotionPhotos(imageFile.path);
final index = motionPhoto.getMotionVideoIndex(); final index = motionPhoto.getMotionVideoIndex();
if (index != null) { if (index != null) {
if (widget.file.pubMagicMetadata?.mvi == null &&
(widget.file.ownerID ?? 0) == Configuration.instance.getUserID()!) {
FileMagicService.instance.updatePublicMagicMetadata(
[widget.file],
{pubMotionVideoIndex: index.start},
).ignore();
}
return motionPhoto.getMotionVideoFile( return motionPhoto.getMotionVideoFile(
index: index, index: index,
); );

View file

@ -458,12 +458,17 @@ class FileUploader {
MetadataRequest? pubMetadataRequest; MetadataRequest? pubMetadataRequest;
if ((mediaUploadData.height ?? 0) != 0 && if ((mediaUploadData.height ?? 0) != 0 &&
(mediaUploadData.width ?? 0) != 0) { (mediaUploadData.width ?? 0) != 0) {
final pubMetadata = {
publicMagicKeyHeight: mediaUploadData.height,
publicMagicKeyWidth: mediaUploadData.width
};
if (mediaUploadData.motionPhotoStartIndex != null) {
pubMetadata[pubMotionVideoIndex] =
mediaUploadData.motionPhotoStartIndex;
}
pubMetadataRequest = await getPubMetadataRequest( pubMetadataRequest = await getPubMetadataRequest(
file, file,
{ pubMetadata,
publicMagicKeyHeight: mediaUploadData.height,
publicMagicKeyWidth: mediaUploadData.width
},
fileAttributes.key!, fileAttributes.key!,
); );
} }

View file

@ -6,6 +6,7 @@ import 'dart:ui' as ui;
import 'package:archive/archive_io.dart'; import 'package:archive/archive_io.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import "package:motion_photos/motion_photos.dart";
import 'package:motionphoto/motionphoto.dart'; import 'package:motionphoto/motionphoto.dart';
import 'package:path/path.dart'; import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
@ -33,6 +34,9 @@ class MediaUploadData {
final FileHashData? hashData; final FileHashData? hashData;
final int? height; final int? height;
final int? width; final int? width;
// For android motion photos, the startIndex is the index of the first frame
// For iOS, this value will be always null.
final int? motionPhotoStartIndex;
MediaUploadData( MediaUploadData(
this.sourceFile, this.sourceFile,
@ -41,6 +45,7 @@ class MediaUploadData {
this.hashData, { this.hashData, {
this.height, this.height,
this.width, this.width,
this.motionPhotoStartIndex,
}); });
} }
@ -154,6 +159,15 @@ Future<MediaUploadData> _getMediaUploadDataFromAssetFile(ente.File file) async {
h = asset.height; h = asset.height;
w = asset.width; w = asset.width;
} }
int? motionPhotoStartingIndex;
if (io.Platform.isAndroid && asset.type == AssetType.image) {
try {
motionPhotoStartingIndex =
MotionPhotos(sourceFile.path).getMotionVideoIndex()?.start;
} catch (e) {
_logger.severe('error while detecthing motion photo start index', e);
}
}
return MediaUploadData( return MediaUploadData(
sourceFile, sourceFile,
thumbnailData, thumbnailData,
@ -161,6 +175,7 @@ Future<MediaUploadData> _getMediaUploadDataFromAssetFile(ente.File file) async {
FileHashData(fileHash, zipHash: zipHash), FileHashData(fileHash, zipHash: zipHash),
height: h, height: h,
width: w, width: w,
motionPhotoStartIndex: motionPhotoStartingIndex,
); );
} }

View file

@ -12,7 +12,7 @@ description: ente photos application
# Read more about iOS versioning at # Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 0.7.45+445 version: 0.7.47+447
environment: environment:
sdk: '>=2.17.0 <3.0.0' sdk: '>=2.17.0 <3.0.0'