mirror of
https://github.com/ente-io/ente.git
synced 2025-08-09 07:48:52 +00:00
fix: processing and display logic
This commit is contained in:
parent
330a3b4dea
commit
a72ae560c9
@ -1737,7 +1737,7 @@ class FilesDB {
|
|||||||
final db = await instance.sqliteAsyncDB;
|
final db = await instance.sqliteAsyncDB;
|
||||||
final results = await db.getAll(
|
final results = await db.getAll(
|
||||||
'''
|
'''
|
||||||
SELECT * FROM $filesTable WHERE $columnFileType = ? AND $columnCreationTime > ?
|
SELECT * FROM $filesTable WHERE $columnFileType = ? AND $columnCreationTime > ? AND $columnUploadedFileID != -1
|
||||||
''',
|
''',
|
||||||
[getInt(fileType), beginDate.millisecondsSinceEpoch],
|
[getInt(fileType), beginDate.millisecondsSinceEpoch],
|
||||||
);
|
);
|
||||||
|
@ -97,209 +97,211 @@ class PreviewVideoStore {
|
|||||||
if (file == null) return;
|
if (file == null) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// check if playlist already exist
|
|
||||||
await getPlaylist(enteFile);
|
|
||||||
final resultUrl = await getPreviewUrl(enteFile);
|
|
||||||
if (ctx != null && ctx.mounted) {
|
|
||||||
showShortToast(ctx, 'Video preview already exists');
|
|
||||||
}
|
|
||||||
debugPrint("previewUrl $resultUrl");
|
|
||||||
return;
|
|
||||||
} catch (e, s) {
|
|
||||||
if (e is DioError && e.response?.statusCode == 404) {
|
|
||||||
_logger.info("No preview found for $enteFile");
|
|
||||||
} else {
|
|
||||||
_logger.warning("Failed to get playlist for $enteFile", e, s);
|
|
||||||
rethrow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final fileSize = file.lengthSync();
|
|
||||||
FFProbeProps? props;
|
|
||||||
|
|
||||||
if (fileSize <= 10 * 1024 * 1024) {
|
|
||||||
props = await getVideoPropsAsync(file);
|
|
||||||
final videoData = List.from(props?.propData?["streams"] ?? [])
|
|
||||||
.firstWhereOrNull((e) => e["type"] == "video");
|
|
||||||
|
|
||||||
final codec = videoData["codec_name"]?.toString().toLowerCase();
|
|
||||||
final codecIsH264 = codec?.contains("h264") ?? false;
|
|
||||||
if (codecIsH264) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isUploading) {
|
|
||||||
_items[enteFile.uploadedFileID!] = PreviewItem(
|
|
||||||
status: PreviewItemStatus.inQueue,
|
|
||||||
file: enteFile,
|
|
||||||
collectionID: enteFile.collectionID ?? 0,
|
|
||||||
);
|
|
||||||
Bus.instance.fire(PreviewUpdatedEvent(_items));
|
|
||||||
files.add(enteFile);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_items[enteFile.uploadedFileID!] = PreviewItem(
|
|
||||||
status: PreviewItemStatus.compressing,
|
|
||||||
file: enteFile,
|
|
||||||
collectionID: enteFile.collectionID ?? 0,
|
|
||||||
);
|
|
||||||
Bus.instance.fire(PreviewUpdatedEvent(_items));
|
|
||||||
|
|
||||||
props ??= await getVideoPropsAsync(file);
|
|
||||||
|
|
||||||
final videoData = List.from(props?.propData?["streams"] ?? [])
|
|
||||||
.firstWhereOrNull((e) => e["type"] == "video");
|
|
||||||
|
|
||||||
final codec = videoData["codec_name"]?.toString().toLowerCase();
|
|
||||||
final bitrate = props?.duration?.inSeconds != null
|
|
||||||
? (fileSize * 8) / props!.duration!.inSeconds
|
|
||||||
: null;
|
|
||||||
|
|
||||||
final String tempDir = Configuration.instance.getTempDirectory();
|
|
||||||
final String prefix =
|
|
||||||
"${tempDir}_${enteFile.uploadedFileID}_${newID("pv")}";
|
|
||||||
Directory(prefix).createSync();
|
|
||||||
_logger.info('Compressing video ${enteFile.displayName}');
|
|
||||||
final key = enc.Key.fromLength(16);
|
|
||||||
|
|
||||||
final keyfile = File('$prefix/keyfile.key');
|
|
||||||
keyfile.writeAsBytesSync(key.bytes);
|
|
||||||
|
|
||||||
final keyinfo = File('$prefix/mykey.keyinfo');
|
|
||||||
keyinfo.writeAsStringSync("data:text/plain;base64,${key.base64}\n"
|
|
||||||
"${keyfile.path}\n");
|
|
||||||
_logger.info(
|
|
||||||
'Generating HLS Playlist ${enteFile.displayName} at $prefix/output.m3u8}',
|
|
||||||
);
|
|
||||||
|
|
||||||
FFmpegSession? session;
|
|
||||||
final codecIsH264 = codec?.contains("h264") ?? false;
|
|
||||||
if (bitrate != null && bitrate <= 4000 * 1000 && codecIsH264) {
|
|
||||||
// create playlist without compression, as is
|
|
||||||
session = await FFmpegKit.execute(
|
|
||||||
'-i "${file.path}" '
|
|
||||||
'-metadata:s:v:0 rotate=0 ' // Adjust metadata if needed
|
|
||||||
'-c:v copy ' // Copy the original video codec
|
|
||||||
'-c:a copy ' // Copy the original audio codec
|
|
||||||
'-f hls -hls_time 10 -hls_flags single_file '
|
|
||||||
'-hls_list_size 0 -hls_key_info_file ${keyinfo.path} '
|
|
||||||
'$prefix/output.m3u8',
|
|
||||||
);
|
|
||||||
} else if (bitrate != null &&
|
|
||||||
codec != null &&
|
|
||||||
bitrate <= 2000 * 1000 &&
|
|
||||||
!codecIsH264) {
|
|
||||||
// compress video with crf=21, h264 no change in resolution or frame rate,
|
|
||||||
// just change color scheme
|
|
||||||
session = await FFmpegKit.execute(
|
|
||||||
'-i "${file.path}" '
|
|
||||||
'-metadata:s:v:0 rotate=0 ' // Keep rotation metadata
|
|
||||||
'-vf "format=yuv420p10le,zscale=transfer=linear,tonemap=tonemap=hable:desat=0:peak=10,zscale=transfer=bt709:matrix=bt709:primaries=bt709,format=yuv420p" ' // Adjust color scheme
|
|
||||||
'-color_primaries bt709 -color_trc bt709 -colorspace bt709 ' // Set color profile to BT.709
|
|
||||||
'-c:v libx264 -crf 21 -preset medium ' // Compress with CRF=21 using H.264
|
|
||||||
'-c:a copy ' // Keep original audio
|
|
||||||
'-f hls -hls_time 10 -hls_flags single_file '
|
|
||||||
'-hls_list_size 0 -hls_key_info_file ${keyinfo.path} '
|
|
||||||
'$prefix/output.m3u8',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
session ??= await FFmpegKit.execute(
|
|
||||||
'-i "${file.path}" '
|
|
||||||
'-metadata:s:v:0 rotate=0 '
|
|
||||||
'-vf "scale=-2:720,fps=30,format=yuv420p10le,zscale=transfer=linear,tonemap=tonemap=hable:desat=0:peak=10,zscale=transfer=bt709:matrix=bt709:primaries=bt709,format=yuv420p" '
|
|
||||||
'-color_primaries bt709 -color_trc bt709 -colorspace bt709 '
|
|
||||||
'-x264-params "colorprim=bt709:transfer=bt709:colormatrix=bt709" '
|
|
||||||
'-c:v libx264 -b:v 2000k -preset medium '
|
|
||||||
'-c:a aac -b:a 128k -f hls -hls_time 10 -hls_flags single_file '
|
|
||||||
'-hls_list_size 0 -hls_key_info_file ${keyinfo.path} '
|
|
||||||
'$prefix/output.m3u8',
|
|
||||||
);
|
|
||||||
|
|
||||||
final returnCode = await session.getReturnCode();
|
|
||||||
|
|
||||||
String? error;
|
|
||||||
|
|
||||||
if (ReturnCode.isSuccess(returnCode)) {
|
|
||||||
try {
|
try {
|
||||||
|
// check if playlist already exist
|
||||||
|
await getPlaylist(enteFile);
|
||||||
|
final resultUrl = await getPreviewUrl(enteFile);
|
||||||
|
if (ctx != null && ctx.mounted) {
|
||||||
|
showShortToast(ctx, 'Video preview already exists');
|
||||||
|
}
|
||||||
|
debugPrint("previewUrl $resultUrl");
|
||||||
|
return;
|
||||||
|
} catch (e, s) {
|
||||||
|
if (e is DioError && e.response?.statusCode == 404) {
|
||||||
|
_logger.info("No preview found for $enteFile");
|
||||||
|
} else {
|
||||||
|
_logger.warning("Failed to get playlist for $enteFile", e, s);
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final fileSize = file.lengthSync();
|
||||||
|
FFProbeProps? props;
|
||||||
|
|
||||||
|
if (fileSize <= 10 * 1024 * 1024) {
|
||||||
|
props = await getVideoPropsAsync(file);
|
||||||
|
final videoData = List.from(props?.propData?["streams"] ?? [])
|
||||||
|
.firstWhereOrNull((e) => e["type"] == "video");
|
||||||
|
|
||||||
|
final codec = videoData["codec_name"]?.toString().toLowerCase();
|
||||||
|
final codecIsH264 = codec?.contains("h264") ?? false;
|
||||||
|
if (codecIsH264) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isUploading) {
|
||||||
_items[enteFile.uploadedFileID!] = PreviewItem(
|
_items[enteFile.uploadedFileID!] = PreviewItem(
|
||||||
status: PreviewItemStatus.uploading,
|
status: PreviewItemStatus.inQueue,
|
||||||
file: enteFile,
|
file: enteFile,
|
||||||
collectionID: enteFile.collectionID ?? 0,
|
collectionID: enteFile.collectionID ?? 0,
|
||||||
);
|
);
|
||||||
Bus.instance.fire(PreviewUpdatedEvent(_items));
|
Bus.instance.fire(PreviewUpdatedEvent(_items));
|
||||||
|
files.add(enteFile);
|
||||||
_logger.info('Playlist Generated ${enteFile.displayName}');
|
return;
|
||||||
final playlistFile = File("$prefix/output.m3u8");
|
|
||||||
final previewFile = File("$prefix/output.ts");
|
|
||||||
final result = await _uploadPreviewVideo(enteFile, previewFile);
|
|
||||||
final String objectID = result.$1;
|
|
||||||
final objectSize = result.$2;
|
|
||||||
await _reportVideoPreview(
|
|
||||||
enteFile,
|
|
||||||
playlistFile,
|
|
||||||
objectID: objectID,
|
|
||||||
objectSize: objectSize,
|
|
||||||
);
|
|
||||||
|
|
||||||
FFProbeProps? props2;
|
|
||||||
props2 = await getVideoPropsAsync(playlistFile);
|
|
||||||
FileMagicService.instance.updatePublicMagicMetadata(
|
|
||||||
[enteFile],
|
|
||||||
{
|
|
||||||
previewHeightKey: props2?.height,
|
|
||||||
previewWidthKey: props2?.width,
|
|
||||||
previewSizeKey: objectSize,
|
|
||||||
},
|
|
||||||
).ignore();
|
|
||||||
_logger.info("Video preview uploaded for $enteFile");
|
|
||||||
} catch (_) {
|
|
||||||
error = "Failed to upload video preview";
|
|
||||||
}
|
}
|
||||||
} else if (ReturnCode.isCancel(returnCode)) {
|
|
||||||
_logger.warning("FFmpeg command cancelled");
|
|
||||||
error = "FFmpeg command cancelled";
|
|
||||||
} else {
|
|
||||||
_logger.severe("FFmpeg command failed with return code $returnCode");
|
|
||||||
if (kDebugMode) {
|
|
||||||
final output = await session.getOutput();
|
|
||||||
_logger.severe(output);
|
|
||||||
}
|
|
||||||
error = "Failed to generate video preview";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error == null) {
|
|
||||||
_items[enteFile.uploadedFileID!] = PreviewItem(
|
_items[enteFile.uploadedFileID!] = PreviewItem(
|
||||||
status: PreviewItemStatus.uploaded,
|
status: PreviewItemStatus.compressing,
|
||||||
file: enteFile,
|
file: enteFile,
|
||||||
retryCount: _items[enteFile.uploadedFileID!]!.retryCount,
|
|
||||||
collectionID: enteFile.collectionID ?? 0,
|
collectionID: enteFile.collectionID ?? 0,
|
||||||
);
|
);
|
||||||
} else {
|
Bus.instance.fire(PreviewUpdatedEvent(_items));
|
||||||
if (_items[enteFile.uploadedFileID!]!.retryCount < 3) {
|
|
||||||
_items[enteFile.uploadedFileID!] = PreviewItem(
|
props ??= await getVideoPropsAsync(file);
|
||||||
status: PreviewItemStatus.retry,
|
|
||||||
file: enteFile,
|
final videoData = List.from(props?.propData?["streams"] ?? [])
|
||||||
retryCount: _items[enteFile.uploadedFileID!]!.retryCount + 1,
|
.firstWhereOrNull((e) => e["type"] == "video");
|
||||||
collectionID: enteFile.collectionID ?? 0,
|
|
||||||
|
final codec = videoData["codec_name"]?.toString().toLowerCase();
|
||||||
|
final bitrate = props?.duration?.inSeconds != null
|
||||||
|
? (fileSize * 8) / props!.duration!.inSeconds
|
||||||
|
: null;
|
||||||
|
|
||||||
|
final String tempDir = Configuration.instance.getTempDirectory();
|
||||||
|
final String prefix =
|
||||||
|
"${tempDir}_${enteFile.uploadedFileID}_${newID("pv")}";
|
||||||
|
Directory(prefix).createSync();
|
||||||
|
_logger.info('Compressing video ${enteFile.displayName}');
|
||||||
|
final key = enc.Key.fromLength(16);
|
||||||
|
|
||||||
|
final keyfile = File('$prefix/keyfile.key');
|
||||||
|
keyfile.writeAsBytesSync(key.bytes);
|
||||||
|
|
||||||
|
final keyinfo = File('$prefix/mykey.keyinfo');
|
||||||
|
keyinfo.writeAsStringSync("data:text/plain;base64,${key.base64}\n"
|
||||||
|
"${keyfile.path}\n");
|
||||||
|
_logger.info(
|
||||||
|
'Generating HLS Playlist ${enteFile.displayName} at $prefix/output.m3u8}',
|
||||||
|
);
|
||||||
|
|
||||||
|
FFmpegSession? session;
|
||||||
|
final codecIsH264 = codec?.contains("h264") ?? false;
|
||||||
|
if (bitrate != null && bitrate <= 4000 * 1000 && codecIsH264) {
|
||||||
|
// create playlist without compression, as is
|
||||||
|
session = await FFmpegKit.execute(
|
||||||
|
'-i "${file.path}" '
|
||||||
|
'-metadata:s:v:0 rotate=0 ' // Adjust metadata if needed
|
||||||
|
'-c:v copy ' // Copy the original video codec
|
||||||
|
'-c:a copy ' // Copy the original audio codec
|
||||||
|
'-f hls -hls_time 10 -hls_flags single_file '
|
||||||
|
'-hls_list_size 0 -hls_key_info_file ${keyinfo.path} '
|
||||||
|
'$prefix/output.m3u8',
|
||||||
);
|
);
|
||||||
files.add(enteFile);
|
} else if (bitrate != null &&
|
||||||
|
codec != null &&
|
||||||
|
bitrate <= 2000 * 1000 &&
|
||||||
|
!codecIsH264) {
|
||||||
|
// compress video with crf=21, h264 no change in resolution or frame rate,
|
||||||
|
// just change color scheme
|
||||||
|
session = await FFmpegKit.execute(
|
||||||
|
'-i "${file.path}" '
|
||||||
|
'-metadata:s:v:0 rotate=0 ' // Keep rotation metadata
|
||||||
|
'-vf "format=yuv420p10le,zscale=transfer=linear,tonemap=tonemap=hable:desat=0:peak=10,zscale=transfer=bt709:matrix=bt709:primaries=bt709,format=yuv420p" ' // Adjust color scheme
|
||||||
|
'-color_primaries bt709 -color_trc bt709 -colorspace bt709 ' // Set color profile to BT.709
|
||||||
|
'-c:v libx264 -crf 21 -preset medium ' // Compress with CRF=21 using H.264
|
||||||
|
'-c:a copy ' // Keep original audio
|
||||||
|
'-f hls -hls_time 10 -hls_flags single_file '
|
||||||
|
'-hls_list_size 0 -hls_key_info_file ${keyinfo.path} '
|
||||||
|
'$prefix/output.m3u8',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
session ??= await FFmpegKit.execute(
|
||||||
|
'-i "${file.path}" '
|
||||||
|
'-metadata:s:v:0 rotate=0 '
|
||||||
|
'-vf "scale=-2:720,fps=30,format=yuv420p10le,zscale=transfer=linear,tonemap=tonemap=hable:desat=0:peak=10,zscale=transfer=bt709:matrix=bt709:primaries=bt709,format=yuv420p" '
|
||||||
|
'-color_primaries bt709 -color_trc bt709 -colorspace bt709 '
|
||||||
|
'-x264-params "colorprim=bt709:transfer=bt709:colormatrix=bt709" '
|
||||||
|
'-c:v libx264 -b:v 2000k -preset medium '
|
||||||
|
'-c:a aac -b:a 128k -f hls -hls_time 10 -hls_flags single_file '
|
||||||
|
'-hls_list_size 0 -hls_key_info_file ${keyinfo.path} '
|
||||||
|
'$prefix/output.m3u8',
|
||||||
|
);
|
||||||
|
|
||||||
|
final returnCode = await session.getReturnCode();
|
||||||
|
|
||||||
|
String? error;
|
||||||
|
|
||||||
|
if (ReturnCode.isSuccess(returnCode)) {
|
||||||
|
try {
|
||||||
|
_items[enteFile.uploadedFileID!] = PreviewItem(
|
||||||
|
status: PreviewItemStatus.uploading,
|
||||||
|
file: enteFile,
|
||||||
|
collectionID: enteFile.collectionID ?? 0,
|
||||||
|
);
|
||||||
|
Bus.instance.fire(PreviewUpdatedEvent(_items));
|
||||||
|
|
||||||
|
_logger.info('Playlist Generated ${enteFile.displayName}');
|
||||||
|
final playlistFile = File("$prefix/output.m3u8");
|
||||||
|
final previewFile = File("$prefix/output.ts");
|
||||||
|
final result = await _uploadPreviewVideo(enteFile, previewFile);
|
||||||
|
final String objectID = result.$1;
|
||||||
|
final objectSize = result.$2;
|
||||||
|
await _reportVideoPreview(
|
||||||
|
enteFile,
|
||||||
|
playlistFile,
|
||||||
|
objectID: objectID,
|
||||||
|
objectSize: objectSize,
|
||||||
|
);
|
||||||
|
|
||||||
|
FFProbeProps? props2;
|
||||||
|
props2 = await getVideoPropsAsync(playlistFile);
|
||||||
|
FileMagicService.instance.updatePublicMagicMetadata(
|
||||||
|
[enteFile],
|
||||||
|
{
|
||||||
|
previewHeightKey: props2?.height,
|
||||||
|
previewWidthKey: props2?.width,
|
||||||
|
previewSizeKey: objectSize,
|
||||||
|
},
|
||||||
|
).ignore();
|
||||||
|
_logger.info("Video preview uploaded for $enteFile");
|
||||||
|
} catch (_) {
|
||||||
|
error = "Failed to upload video preview";
|
||||||
|
}
|
||||||
|
} else if (ReturnCode.isCancel(returnCode)) {
|
||||||
|
_logger.warning("FFmpeg command cancelled");
|
||||||
|
error = "FFmpeg command cancelled";
|
||||||
} else {
|
} else {
|
||||||
|
_logger.severe("FFmpeg command failed with return code $returnCode");
|
||||||
|
if (kDebugMode) {
|
||||||
|
final output = await session.getOutput();
|
||||||
|
_logger.severe(output);
|
||||||
|
}
|
||||||
|
error = "Failed to generate video preview";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error == null) {
|
||||||
_items[enteFile.uploadedFileID!] = PreviewItem(
|
_items[enteFile.uploadedFileID!] = PreviewItem(
|
||||||
status: PreviewItemStatus.failed,
|
status: PreviewItemStatus.uploaded,
|
||||||
file: enteFile,
|
file: enteFile,
|
||||||
retryCount: _items[enteFile.uploadedFileID!]!.retryCount,
|
retryCount: _items[enteFile.uploadedFileID!]!.retryCount,
|
||||||
collectionID: enteFile.collectionID ?? 0,
|
collectionID: enteFile.collectionID ?? 0,
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
if (_items[enteFile.uploadedFileID!]!.retryCount < 3) {
|
||||||
|
_items[enteFile.uploadedFileID!] = PreviewItem(
|
||||||
|
status: PreviewItemStatus.retry,
|
||||||
|
file: enteFile,
|
||||||
|
retryCount: _items[enteFile.uploadedFileID!]!.retryCount + 1,
|
||||||
|
collectionID: enteFile.collectionID ?? 0,
|
||||||
|
);
|
||||||
|
files.add(enteFile);
|
||||||
|
} else {
|
||||||
|
_items[enteFile.uploadedFileID!] = PreviewItem(
|
||||||
|
status: PreviewItemStatus.failed,
|
||||||
|
file: enteFile,
|
||||||
|
retryCount: _items[enteFile.uploadedFileID!]!.retryCount,
|
||||||
|
collectionID: enteFile.collectionID ?? 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Bus.instance.fire(PreviewUpdatedEvent(_items));
|
||||||
|
} finally {
|
||||||
|
isUploading = false;
|
||||||
|
if (files.isNotEmpty) {
|
||||||
|
final file = files.first;
|
||||||
|
files.remove(file);
|
||||||
|
await chunkAndUploadVideo(ctx, file);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Bus.instance.fire(PreviewUpdatedEvent(_items));
|
|
||||||
|
|
||||||
isUploading = false;
|
|
||||||
if (files.isNotEmpty) {
|
|
||||||
final file = files.first;
|
|
||||||
files.remove(file);
|
|
||||||
await chunkAndUploadVideo(ctx, file);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,18 +500,8 @@ class PreviewVideoStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final allFiles = files
|
final allFiles = files
|
||||||
.where(
|
.where((file) => previewIds?[file.uploadedFileID] == null)
|
||||||
(file) =>
|
|
||||||
file.uploadedFileID != null &&
|
|
||||||
previewIds?[file.uploadedFileID] == null &&
|
|
||||||
file.fileType == FileType.video,
|
|
||||||
)
|
|
||||||
.toList();
|
.toList();
|
||||||
final file = allFiles.first;
|
|
||||||
allFiles.remove(file);
|
|
||||||
|
|
||||||
this.files.addAll(allFiles);
|
|
||||||
await chunkAndUploadVideo(null, file);
|
|
||||||
|
|
||||||
// set all video status to be in queue
|
// set all video status to be in queue
|
||||||
for (final file in allFiles) {
|
for (final file in allFiles) {
|
||||||
@ -519,5 +511,13 @@ class PreviewVideoStore {
|
|||||||
collectionID: file.collectionID ?? 0,
|
collectionID: file.collectionID ?? 0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Bus.instance.fire(PreviewUpdatedEvent(_items));
|
||||||
|
|
||||||
|
final file = allFiles.first;
|
||||||
|
allFiles.remove(file);
|
||||||
|
|
||||||
|
this.files.addAll(allFiles);
|
||||||
|
|
||||||
|
await chunkAndUploadVideo(null, file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ class StatusBarWidget extends StatefulWidget {
|
|||||||
|
|
||||||
class _StatusBarWidgetState extends State<StatusBarWidget> {
|
class _StatusBarWidgetState extends State<StatusBarWidget> {
|
||||||
static final _logger = Logger("StatusBarWidget");
|
static final _logger = Logger("StatusBarWidget");
|
||||||
int previewCount = 0;
|
late int previewCount = 0;
|
||||||
|
|
||||||
late StreamSubscription<SyncStatusUpdate> _subscription;
|
late StreamSubscription<SyncStatusUpdate> _subscription;
|
||||||
late StreamSubscription<NotificationEvent> _notificationSubscription;
|
late StreamSubscription<NotificationEvent> _notificationSubscription;
|
||||||
@ -88,12 +88,11 @@ class _StatusBarWidgetState extends State<StatusBarWidget> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// visit LinkedHashMap and calculat previewCount
|
|
||||||
previewCount = PreviewVideoStore.instance.previews.values
|
previewCount = PreviewVideoStore.instance.previews.values
|
||||||
.where(
|
.where(
|
||||||
(element) =>
|
(element) =>
|
||||||
element.status == PreviewItemStatus.compressing ||
|
element.status != PreviewItemStatus.uploaded &&
|
||||||
element.status == PreviewItemStatus.uploading,
|
element.status != PreviewItemStatus.failed,
|
||||||
)
|
)
|
||||||
.length;
|
.length;
|
||||||
|
|
||||||
@ -102,10 +101,11 @@ class _StatusBarWidgetState extends State<StatusBarWidget> {
|
|||||||
previewCount = event.items.values
|
previewCount = event.items.values
|
||||||
.where(
|
.where(
|
||||||
(element) =>
|
(element) =>
|
||||||
element.status == PreviewItemStatus.compressing ||
|
element.status != PreviewItemStatus.uploaded &&
|
||||||
element.status == PreviewItemStatus.uploading,
|
element.status != PreviewItemStatus.failed,
|
||||||
)
|
)
|
||||||
.length;
|
.length;
|
||||||
|
setState(() {});
|
||||||
});
|
});
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
@ -79,9 +79,9 @@ class _PreviewStatusWidgetState extends State<PreviewStatusWidget> {
|
|||||||
preview?.status == PreviewItemStatus.retry;
|
preview?.status == PreviewItemStatus.retry;
|
||||||
final isFailed = preview?.status == PreviewItemStatus.failed;
|
final isFailed = preview?.status == PreviewItemStatus.failed;
|
||||||
|
|
||||||
final isBeforeCutoffDate = widget.file.updationTime != null &&
|
final isBeforeCutoffDate = widget.file.creationTime != null &&
|
||||||
PreviewVideoStore.instance.videoStreamingCutoff != null
|
PreviewVideoStore.instance.videoStreamingCutoff != null
|
||||||
? DateTime.fromMillisecondsSinceEpoch(widget.file.updationTime!)
|
? DateTime.fromMillisecondsSinceEpoch(widget.file.creationTime!)
|
||||||
.isBefore(
|
.isBefore(
|
||||||
PreviewVideoStore.instance.videoStreamingCutoff!,
|
PreviewVideoStore.instance.videoStreamingCutoff!,
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user