Merge pull request #48 from ente-io/support_sharing_video_thumbnail
Android: Support sharing videos to ente
This commit is contained in:
commit
8553e96247
6 changed files with 82 additions and 23 deletions
|
@ -32,6 +32,18 @@
|
|||
<data android:mimeType="image/*" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="video/*" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="video/*" />
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
|
|
|
@ -43,6 +43,14 @@ class _VideoWidgetState extends State<VideoWidget> {
|
|||
super.initState();
|
||||
if (widget.file.isRemoteFile()) {
|
||||
_loadNetworkVideo();
|
||||
} else if (widget.file.isSharedMediaToAppSandbox()) {
|
||||
final localFile = io.File(getSharedMediaFilePath(widget.file));
|
||||
if (localFile.existsSync()) {
|
||||
_logger.fine("loading from app cache");
|
||||
_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,14 @@ class _VideoWidgetState extends State<VideoWidget> {
|
|||
getFileFromServer(
|
||||
widget.file,
|
||||
progressCallback: (count, total) {
|
||||
setState(() {
|
||||
_progress = count / total;
|
||||
if (_progress == 1) {
|
||||
showToast("decrypting video...", toastLength: Toast.LENGTH_SHORT);
|
||||
}
|
||||
});
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_progress = count / total;
|
||||
if (_progress == 1) {
|
||||
showToast("decrypting video...", toastLength: Toast.LENGTH_SHORT);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
).then((file) {
|
||||
if (file != null) {
|
||||
|
|
|
@ -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<MediaUploadData> _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 generation failed for fileType: ${file.fileType.toString()}");
|
||||
}
|
||||
}
|
||||
|
||||
Future<Uint8List> getThumbnailFromInAppCacheFile(ente.File file) async {
|
||||
|
@ -149,6 +157,16 @@ Future<Uint8List> 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: 80,
|
||||
);
|
||||
localFile = io.File(thumbnailFilePath);
|
||||
}
|
||||
var thumbnailData = await localFile.readAsBytes();
|
||||
int compressionAttempts = 0;
|
||||
while (thumbnailData.length > kThumbnailDataLimit &&
|
||||
|
|
|
@ -40,29 +40,40 @@ Future<List<File>> convertIncomingSharedMediaToFile(
|
|||
List<SharedMediaFile> sharedMedia, int collectionID) async {
|
||||
List<File> 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);
|
||||
|
||||
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 =
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue