From 30cbebeada604ab5cd26cf63533d82d18c60997c Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Mon, 20 Sep 2021 07:27:54 +0530 Subject: [PATCH 1/8] add dependency on video_thumbnail --- pubspec.lock | 7 +++++++ pubspec.yaml | 1 + 2 files changed, 8 insertions(+) diff --git a/pubspec.lock b/pubspec.lock index 81190bbe3..5325d50d6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1091,6 +1091,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.0" + video_thumbnail: + dependency: "direct main" + description: + name: video_thumbnail + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.3" visibility_detector: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index b98ee16b2..b48b0d62d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -98,6 +98,7 @@ dependencies: url_launcher: ^6.0.3 uuid: ^3.0.4 video_player: ^2.0.0 + video_thumbnail: ^0.4.3 visibility_detector: ^0.2.0 wallpaper_manager_flutter: ^0.0.2 From fd95bcdfe80b687ca321bed67b5c6a88b716bedf Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Mon, 20 Sep 2021 11:48:09 +0530 Subject: [PATCH 2/8] [shared-media] ignore unsupported file types --- lib/utils/share_util.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/utils/share_util.dart b/lib/utils/share_util.dart index 33bfdd5bc..0a4813549 100644 --- a/lib/utils/share_util.dart +++ b/lib/utils/share_util.dart @@ -40,6 +40,12 @@ Future> convertIncomingSharedMediaToFile( List sharedMedia, int collectionID) async { List localFiles = []; for (var media in sharedMedia) { + if (!(media.type == SharedMediaType.IMAGE || + media.type == SharedMediaType.VIDEO)) { + _logger.warning( + "ignore unsupported file type ${media.type.toString()} path: ${media.path}"); + continue; + } var enteFile = File(); // fileName: img_x.jpg enteFile.title = basename(media.path); From ccbcef0b6d439b2e87a8c5900055c1c32961a7c2 Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Mon, 20 Sep 2021 17:22:08 +0530 Subject: [PATCH 3/8] Support for generating thumbnail for shared video file --- lib/utils/file_uploader_util.dart | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/utils/file_uploader_util.dart b/lib/utils/file_uploader_util.dart index 77b9c111c..841543896 100644 --- a/lib/utils/file_uploader_util.dart +++ b/lib/utils/file_uploader_util.dart @@ -6,6 +6,7 @@ import 'package:archive/archive_io.dart'; import 'package:logging/logging.dart'; import 'package:motionphoto/motionphoto.dart'; import 'package:path/path.dart'; +import 'package:path_provider/path_provider.dart'; import 'package:photo_manager/photo_manager.dart'; import 'package:photos/core/configuration.dart'; import 'package:photos/core/constants.dart'; @@ -13,6 +14,7 @@ import 'package:photos/core/errors.dart'; import 'package:photos/models/file.dart' as ente; import 'package:photos/models/file_type.dart'; import 'package:photos/models/location.dart'; +import 'package:video_thumbnail/video_thumbnail.dart'; import 'file_util.dart'; @@ -140,8 +142,14 @@ Future _getMediaUploadDataFromAppCache(ente.File file) async { _logger.warning("File doesn't exist in app sandbox"); throw InvalidFileError("File doesn't exist in app sandbox"); } - thumbnailData = await getThumbnailFromInAppCacheFile(file); - return MediaUploadData(sourceFile, thumbnailData, isDeleted); + try { + thumbnailData = await getThumbnailFromInAppCacheFile(file); + return MediaUploadData(sourceFile, thumbnailData, isDeleted); + } catch (e, s) { + _logger.severe("failed to generate thumbnail", e, s); + throw InvalidFileError( + "thumbnail generated failed for fileType: ${file.fileType.toString()}"); + } } Future getThumbnailFromInAppCacheFile(ente.File file) async { @@ -149,6 +157,16 @@ Future getThumbnailFromInAppCacheFile(ente.File file) async { if (!localFile.existsSync()) { return null; } + if (file.fileType == FileType.video) { + final thumbnailFilePath = await VideoThumbnail.thumbnailFile( + video: localFile.path, + imageFormat: ImageFormat.JPEG, + thumbnailPath: (await getTemporaryDirectory()).path, + maxWidth: kThumbnailLargeSize, + quality: 100, + ); + localFile = io.File(thumbnailFilePath); + } var thumbnailData = await localFile.readAsBytes(); int compressionAttempts = 0; while (thumbnailData.length > kThumbnailDataLimit && From be8019f33860b4f118169b5e8b444b88155cbcfa Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Mon, 20 Sep 2021 17:33:34 +0530 Subject: [PATCH 4/8] SharedMedia: Fix handling of video media type --- lib/utils/share_util.dart | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/lib/utils/share_util.dart b/lib/utils/share_util.dart index 0a4813549..2bef1c831 100644 --- a/lib/utils/share_util.dart +++ b/lib/utils/share_util.dart @@ -49,26 +49,31 @@ Future> convertIncomingSharedMediaToFile( var enteFile = File(); // fileName: img_x.jpg enteFile.title = basename(media.path); - var ioFile = dartio.File(media.path); - ioFile = ioFile.renameSync(Configuration.instance.getSharedMediaCacheDirectory() + - "/" + - enteFile.title); + ioFile = ioFile.renameSync( + Configuration.instance.getSharedMediaCacheDirectory() + + "/" + + enteFile.title); enteFile.localID = kSharedMediaIdentifier + enteFile.title; enteFile.collectionID = collectionID; - enteFile.fileType = FileType.image; + enteFile.fileType = + media.type == SharedMediaType.IMAGE ? FileType.image : FileType.video; - var exifMap = await readExifFromFile(ioFile); - if (exifMap != null && - exifMap["Image DateTime"] != null && - '0000:00:00 00:00:00' != exifMap["Image DateTime"].toString()) { - try { - final exifTime = - _exifDateFormat.parse(exifMap["Image DateTime"].toString()); - enteFile.creationTime = exifTime.microsecondsSinceEpoch; - } catch (e) { - //ignore + if (enteFile.fileType == FileType.image) { + final exifMap = await readExifFromFile(ioFile); + if (exifMap != null && + exifMap["Image DateTime"] != null && + '0000:00:00 00:00:00' != exifMap["Image DateTime"].toString()) { + try { + final exifTime = + _exifDateFormat.parse(exifMap["Image DateTime"].toString()); + enteFile.creationTime = exifTime.microsecondsSinceEpoch; + } catch (e) { + //ignore + } } + } else if (enteFile.fileType == FileType.video) { + enteFile.duration = media.duration ?? 0; } if (enteFile.creationTime == null || enteFile.creationTime == 0) { final parsedDateTime = From fcb51f9f71f194a43f22dcfeb2402669deb51571 Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Mon, 20 Sep 2021 17:34:51 +0530 Subject: [PATCH 5/8] Support for loading video from app cache --- lib/ui/video_widget.dart | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/ui/video_widget.dart b/lib/ui/video_widget.dart index 0970eec31..2b2b439ae 100644 --- a/lib/ui/video_widget.dart +++ b/lib/ui/video_widget.dart @@ -43,6 +43,14 @@ class _VideoWidgetState extends State { super.initState(); if (widget.file.isRemoteFile()) { _loadNetworkVideo(); + } else if (widget.file.isSharedMediaToAppSandbox()) { + final localFile = io.File(getSharedMediaFilePath(widget.file)); + if (localFile.existsSync()) { + _logger.info("loading from local source"); + _setVideoPlayerController(file: localFile); + } else if (widget.file.uploadedFileID != null) { + _loadNetworkVideo(); + } } else { widget.file.getAsset().then((asset) async { if (asset == null || !(await asset.exists)) { @@ -62,12 +70,15 @@ class _VideoWidgetState extends State { getFileFromServer( widget.file, progressCallback: (count, total) { - setState(() { - _progress = count / total; - if (_progress == 1) { - showToast("decrypting video...", toastLength: Toast.LENGTH_SHORT); - } - }); + if (mounted) { + setState(() { + _logger.info("calling set state"); + _progress = count / total; + if (_progress == 1) { + showToast("decrypting video...", toastLength: Toast.LENGTH_SHORT); + } + }); + } }, ).then((file) { if (file != null) { From 2474130147d52de30d45e6d48fb112f293d14775 Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Mon, 20 Sep 2021 17:57:12 +0530 Subject: [PATCH 6/8] fix logging --- lib/ui/video_widget.dart | 3 +-- lib/utils/file_uploader_util.dart | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/ui/video_widget.dart b/lib/ui/video_widget.dart index 2b2b439ae..c7dcaec17 100644 --- a/lib/ui/video_widget.dart +++ b/lib/ui/video_widget.dart @@ -46,7 +46,7 @@ class _VideoWidgetState extends State { } else if (widget.file.isSharedMediaToAppSandbox()) { final localFile = io.File(getSharedMediaFilePath(widget.file)); if (localFile.existsSync()) { - _logger.info("loading from local source"); + _logger.fine("loading from app cache"); _setVideoPlayerController(file: localFile); } else if (widget.file.uploadedFileID != null) { _loadNetworkVideo(); @@ -72,7 +72,6 @@ class _VideoWidgetState extends State { progressCallback: (count, total) { if (mounted) { setState(() { - _logger.info("calling set state"); _progress = count / total; if (_progress == 1) { showToast("decrypting video...", toastLength: Toast.LENGTH_SHORT); diff --git a/lib/utils/file_uploader_util.dart b/lib/utils/file_uploader_util.dart index 841543896..219ff7794 100644 --- a/lib/utils/file_uploader_util.dart +++ b/lib/utils/file_uploader_util.dart @@ -148,7 +148,7 @@ Future _getMediaUploadDataFromAppCache(ente.File file) async { } catch (e, s) { _logger.severe("failed to generate thumbnail", e, s); throw InvalidFileError( - "thumbnail generated failed for fileType: ${file.fileType.toString()}"); + "thumbnail generation failed for fileType: ${file.fileType.toString()}"); } } From c35bb66743685d0087f41da46237a492e3cfb7f9 Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Mon, 20 Sep 2021 18:06:36 +0530 Subject: [PATCH 7/8] Android: register intent to receive video files --- android/app/src/main/AndroidManifest.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index d915141a6..77ac42cf1 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -32,6 +32,18 @@ + + + + + + + + + + + + From 8f2d5bbd0532687b4b07912e53a707c20ccdd1c3 Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Mon, 20 Sep 2021 20:48:20 +0530 Subject: [PATCH 8/8] reduce initial thumbnail quality to 80 --- lib/utils/file_uploader_util.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/utils/file_uploader_util.dart b/lib/utils/file_uploader_util.dart index 219ff7794..8a5ed73da 100644 --- a/lib/utils/file_uploader_util.dart +++ b/lib/utils/file_uploader_util.dart @@ -163,7 +163,7 @@ Future getThumbnailFromInAppCacheFile(ente.File file) async { imageFormat: ImageFormat.JPEG, thumbnailPath: (await getTemporaryDirectory()).path, maxWidth: kThumbnailLargeSize, - quality: 100, + quality: 80, ); localFile = io.File(thumbnailFilePath); }