[mob][photos] run ffmpeg in isolate (#5743)

## Description

- [x] Create a new service to use for FFmpeg in an isolate'ed
environment
- [x] Apply this service wherever we use FFmpeg Kit
- [x] Make FFMpeg accessible in an isolate (background)

## Tests

- [x] Test FFmpeg intergrations
This commit is contained in:
Prateek Sunal
2025-08-12 13:44:45 +05:30
committed by GitHub
9 changed files with 235 additions and 215 deletions

View File

@@ -1,11 +1,5 @@
package io.ente.photos
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity : FlutterFragmentActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine)
}
}
class MainActivity : FlutterFragmentActivity() {}

View File

@@ -18,37 +18,37 @@ PODS:
- Flutter
- file_saver (0.0.1):
- Flutter
- Firebase/CoreOnly (11.10.0):
- FirebaseCore (~> 11.10.0)
- Firebase/Messaging (11.10.0):
- Firebase/CoreOnly (11.15.0):
- FirebaseCore (~> 11.15.0)
- Firebase/Messaging (11.15.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 11.10.0)
- firebase_core (3.13.1):
- Firebase/CoreOnly (= 11.10.0)
- FirebaseMessaging (~> 11.15.0)
- firebase_core (3.15.1):
- Firebase/CoreOnly (= 11.15.0)
- Flutter
- firebase_messaging (15.2.6):
- Firebase/Messaging (= 11.10.0)
- firebase_messaging (15.2.9):
- Firebase/Messaging (= 11.15.0)
- firebase_core
- Flutter
- FirebaseCore (11.10.0):
- FirebaseCoreInternal (~> 11.10.0)
- GoogleUtilities/Environment (~> 8.0)
- GoogleUtilities/Logger (~> 8.0)
- FirebaseCoreInternal (11.10.0):
- "GoogleUtilities/NSData+zlib (~> 8.0)"
- FirebaseInstallations (11.10.0):
- FirebaseCore (~> 11.10.0)
- GoogleUtilities/Environment (~> 8.0)
- GoogleUtilities/UserDefaults (~> 8.0)
- FirebaseCore (11.15.0):
- FirebaseCoreInternal (~> 11.15.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Logger (~> 8.1)
- FirebaseCoreInternal (11.15.0):
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- FirebaseInstallations (11.15.0):
- FirebaseCore (~> 11.15.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- PromisesObjC (~> 2.4)
- FirebaseMessaging (11.10.0):
- FirebaseCore (~> 11.10.0)
- FirebaseMessaging (11.15.0):
- FirebaseCore (~> 11.15.0)
- FirebaseInstallations (~> 11.0)
- GoogleDataTransport (~> 10.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
- GoogleUtilities/Environment (~> 8.0)
- GoogleUtilities/Reachability (~> 8.0)
- GoogleUtilities/UserDefaults (~> 8.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Reachability (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- nanopb (~> 3.30910.0)
- Flutter (1.0.0)
- flutter_email_sender (0.0.1):
@@ -198,23 +198,23 @@ PODS:
- sqflite_darwin (0.0.4):
- Flutter
- FlutterMacOS
- sqlite3 (3.49.2):
- sqlite3/common (= 3.49.2)
- sqlite3/common (3.49.2)
- sqlite3/dbstatvtab (3.49.2):
- sqlite3 (3.50.1):
- sqlite3/common (= 3.50.1)
- sqlite3/common (3.50.1)
- sqlite3/dbstatvtab (3.50.1):
- sqlite3/common
- sqlite3/fts5 (3.49.2):
- sqlite3/fts5 (3.50.1):
- sqlite3/common
- sqlite3/math (3.49.2):
- sqlite3/math (3.50.1):
- sqlite3/common
- sqlite3/perf-threadsafe (3.49.2):
- sqlite3/perf-threadsafe (3.50.1):
- sqlite3/common
- sqlite3/rtree (3.49.2):
- sqlite3/rtree (3.50.1):
- sqlite3/common
- sqlite3_flutter_libs (0.0.1):
- Flutter
- FlutterMacOS
- sqlite3 (~> 3.49.2)
- sqlite3 (~> 3.50.1)
- sqlite3/dbstatvtab
- sqlite3/fts5
- sqlite3/math
@@ -446,19 +446,19 @@ SPEC CHECKSUMS:
ffmpeg_kit_custom: 682b4f2f1ff1f8abae5a92f6c3540f2441d5be99
ffmpeg_kit_flutter: 915b345acc97d4142e8a9a8549d177ff10f043f5
file_saver: 6cdbcddd690cb02b0c1a0c225b37cd805c2bf8b6
Firebase: 1fe1c0a7d9aaea32efe01fbea5f0ebd8d70e53a2
firebase_core: ba71b44041571da878cb624ce0d80250bcbe58ad
firebase_messaging: 13129fe2ca166d1ed2d095062d76cee88943d067
FirebaseCore: 8344daef5e2661eb004b177488d6f9f0f24251b7
FirebaseCoreInternal: ef4505d2afb1d0ebbc33162cb3795382904b5679
FirebaseInstallations: 9980995bdd06ec8081dfb6ab364162bdd64245c3
FirebaseMessaging: 2b9f56aa4ed286e1f0ce2ee1d413aabb8f9f5cb9
Firebase: d99ac19b909cd2c548339c2241ecd0d1599ab02e
firebase_core: ece862f94b2bc72ee0edbeec7ab5c7cb09fe1ab5
firebase_messaging: e1a5fae495603115be1d0183bc849da748734e2b
FirebaseCore: efb3893e5b94f32b86e331e3bd6dadf18b66568e
FirebaseCoreInternal: 9afa45b1159304c963da48addb78275ef701c6b4
FirebaseInstallations: 317270fec08a5d418fdbc8429282238cab3ac843
FirebaseMessaging: 3b26e2cee503815e01c3701236b020aa9b576f09
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_email_sender: aa1e9772696691d02cd91fea829856c11efb8e58
flutter_image_compress_common: 1697a328fd72bfb335507c6bca1a65fa5ad87df1
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
flutter_local_notifications: a5a732f069baa862e728d839dd2ebb904737effb
flutter_native_splash: 6cad9122ea0fad137d23137dd14b937f3e90b145
flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf
flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13
flutter_sodium: 7e4621538491834eba53bd524547854bcbbd6987
flutter_timezone: 7c838e17ffd4645d261e87037e5bebf6d38fe544
@@ -501,14 +501,14 @@ SPEC CHECKSUMS:
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
sqlite3: 3c950dc86011117c307eb0b28c4a7bb449dce9f1
sqlite3_flutter_libs: 74334e3ef2dbdb7d37e50859bb45da43935779c4
sqlite3: 1d85290c3321153511f6e900ede7a1608718bbd5
sqlite3_flutter_libs: e7fc8c9ea2200ff3271f08f127842131746b70e2
system_info_plus: 555ce7047fbbf29154726db942ae785c29211740
thermal: d4c48be750d1ddbab36b0e2dcb2471531bc8df41
ua_client_hints: 92fe0d139619b73ec9fcb46cc7e079a26178f586
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
video_player_avfoundation: 2cef49524dd1f16c5300b9cd6efd9611ce03639b
video_thumbnail: 584ccfa55d8fd2f3d5507218b0a18d84c839c620
video_thumbnail: b637e0ad5f588ca9945f6e2c927f73a69a661140
volume_controller: 3657a1f65bedb98fa41ff7dc5793537919f31b12
wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
workmanager: b89e4e4445d8b57ee2fdbf1c3925696ebe5b8990

View File

@@ -2,7 +2,7 @@ import AVFoundation
import Flutter
import UIKit
import app_links
import workmanager_apple
import workmanager
@main
@objc class AppDelegate: FlutterAppDelegate {

View File

@@ -0,0 +1,49 @@
import "dart:async";
import "dart:isolate";
import "package:ffmpeg_kit_flutter/ffmpeg_kit.dart";
import "package:ffmpeg_kit_flutter/ffprobe_kit.dart";
import "package:flutter/services.dart";
import "package:photos/utils/ffprobe_util.dart";
class IsolatedFfmpegService {
static Future<Map> runFfmpeg(String command) async {
final rootIsolateToken = RootIsolateToken.instance!;
return await Isolate.run<Map>(() => _ffmpegRun(command, rootIsolateToken));
}
static Future<Map> getVideoInfo(String file) async {
final rootIsolateToken = RootIsolateToken.instance!;
return await Isolate.run<Map>(() => _getVideoProps(file, rootIsolateToken));
}
}
@pragma('vm:entry-point')
Future<Map> _getVideoProps(
String filePath,
RootIsolateToken rootIsolateToken,
) async {
BackgroundIsolateBinaryMessenger.ensureInitialized(rootIsolateToken);
final session = await FFprobeKit.getMediaInformation(filePath);
final mediaInfo = session.getMediaInformation();
if (mediaInfo == null) {
return {};
}
final metadata = await FFProbeUtil.getMetadata(mediaInfo);
return metadata;
}
@pragma('vm:entry-point')
Future<Map> _ffmpegRun(String value, RootIsolateToken rootIsolateToken) async {
BackgroundIsolateBinaryMessenger.ensureInitialized(rootIsolateToken);
final session = await FFmpegKit.execute(value, true);
final returnCode = await session.getReturnCode();
final output = await session.getOutput();
return {
"returnCode": returnCode?.getValue(),
"output": output,
};
}

View File

@@ -6,8 +6,6 @@ import "dart:io";
import "package:collection/collection.dart";
import "package:dio/dio.dart";
import "package:encrypt/encrypt.dart" as enc;
import "package:ffmpeg_kit_flutter/ffmpeg_kit.dart";
import "package:ffmpeg_kit_flutter/ffmpeg_session.dart";
import "package:ffmpeg_kit_flutter/return_code.dart";
import "package:flutter/foundation.dart";
import "package:flutter/widgets.dart";
@@ -31,6 +29,7 @@ import "package:photos/models/preview/preview_item_status.dart";
import "package:photos/service_locator.dart";
import "package:photos/services/collections_service.dart";
import "package:photos/services/filedata/model/file_data.dart";
import "package:photos/services/isolated_ffmpeg_service.dart";
import "package:photos/ui/notification/toast.dart";
import "package:photos/utils/exif_util.dart";
import "package:photos/utils/file_key.dart";
@@ -219,11 +218,9 @@ class VideoPreviewService {
"${keyfile.path}\n");
_logger.info(
'Generating HLS Playlist ${enteFile.displayName} at $prefix/output.m3u8}',
'Generating HLS Playlist ${enteFile.displayName} at $prefix/output.m3u8',
);
FFmpegSession? session;
final reencodeVideo =
!(isH264 && bitrate != null && bitrate <= 4000 * 1000);
final rescaleVideo = !(bitrate != null && bitrate <= 2000 * 1000);
@@ -270,21 +267,26 @@ class VideoPreviewService {
_logger.info(command);
session = await FFmpegKit.execute(
final playlistGenResult = await IsolatedFfmpegService.runFfmpeg(
// input file path
'-i "${file.path}" ' +
// main params for streaming
command +
// output file path
'$prefix/output.m3u8',
).onError(
(error, stackTrace) {
_logger.warning("FFmpeg command failed", error, stackTrace);
return {};
},
);
final returnCode = await session.getReturnCode();
final playlistGenReturnCode = playlistGenResult["returnCode"] as int?;
String? objectId;
int? objectSize;
if (ReturnCode.isSuccess(returnCode)) {
if (ReturnCode.success == playlistGenReturnCode) {
try {
_items[enteFile.uploadedFileID!] = PreviewItem(
status: PreviewItemStatus.uploading,
@@ -303,19 +305,29 @@ class VideoPreviewService {
objectSize = result.$2;
// Fetch resolution of generated stream by decrypting a single frame
final FFmpegSession session2 = await FFmpegKit.execute(
final playlistFrameResult = await IsolatedFfmpegService.runFfmpeg(
'-allowed_extensions ALL -i "$prefix/output.m3u8" -frames:v 1 -c copy "$prefix/frame.ts"',
).onError(
(error, stackTrace) {
_logger.warning(
"FFmpeg command failed for frame",
error,
stackTrace,
);
return {};
},
);
final returnCode2 = await session2.getReturnCode();
final playlistFrameReturnCode =
playlistFrameResult["returnCode"] as int?;
int? width, height;
try {
if (ReturnCode.isSuccess(returnCode2)) {
FFProbeProps? props2;
if (ReturnCode.success == playlistFrameReturnCode) {
FFProbeProps? playlistFrameProps;
final file2 = File("$prefix/frame.ts");
props2 = await getVideoPropsAsync(file2);
width = props2?.width;
height = props2?.height;
playlistFrameProps = await getVideoPropsAsync(file2);
width = playlistFrameProps?.width;
height = playlistFrameProps?.height;
}
} catch (err, sT) {
_logger.warning("Failed to fetch resolution of stream", err, sT);
@@ -335,13 +347,13 @@ class VideoPreviewService {
error = "Failed to upload video preview\nError: $err";
_logger.shout("Something went wrong with preview upload", err, sT);
}
} else if (ReturnCode.isCancel(returnCode)) {
} else if (ReturnCode.cancel == playlistGenReturnCode) {
_logger.warning("FFmpeg command cancelled");
error = "FFmpeg command cancelled";
} else {
final output = await session.getOutput();
final output = playlistGenResult["output"] as String?;
_logger.shout(
"FFmpeg command failed with return code $returnCode",
"FFmpeg command failed with return code $playlistGenReturnCode",
output ?? "Error not found",
);
error = "Failed to generate video preview\nError: $output";
@@ -376,7 +388,9 @@ class VideoPreviewService {
if (uploadingFileId == enteFile.uploadedFileID!) {
uploadingFileId = -1;
}
_logger.info("[chunk] Processing ${_items.length} items for streaming");
_logger.info(
"[chunk] Processing ${_items.length} items for streaming, $error",
);
// process next file
if (fileQueue.isNotEmpty) {
final entry = fileQueue.entries.first;

View File

@@ -1,13 +1,8 @@
import "dart:async";
import "dart:developer";
import "dart:io";
import "package:computer/computer.dart";
import 'package:exif_reader/exif_reader.dart';
import "package:ffmpeg_kit_flutter/ffprobe_kit.dart";
import "package:ffmpeg_kit_flutter/media_information.dart";
import "package:ffmpeg_kit_flutter/media_information_session.dart";
import "package:flutter/foundation.dart";
import 'package:intl/intl.dart';
import 'package:logging/logging.dart';
// ignore: implementation_imports
@@ -15,8 +10,8 @@ import "package:motion_photos/src/xmp_extractor.dart";
import "package:photos/models/ffmpeg/ffprobe_props.dart";
import 'package:photos/models/file/file.dart';
import "package:photos/models/location/location.dart";
import "package:photos/services/isolated_ffmpeg_service.dart";
import "package:photos/services/location_service.dart";
import "package:photos/utils/ffprobe_util.dart";
import 'package:photos/utils/file_util.dart';
const kDateTimeOriginal = "EXIF DateTimeOriginal";
@@ -74,45 +69,16 @@ Map<String, dynamic> _getXMPComputer(Map<String, dynamic> args) {
Future<FFProbeProps?> getVideoPropsAsync(File originalFile) async {
try {
final stopwatch = Stopwatch()..start();
final Map<int, StringBuffer> logs = {};
final completer = Completer<MediaInformation?>();
final session = await FFprobeKit.getMediaInformationAsync(
originalFile.path,
(MediaInformationSession session) async {
// This callback is called when the session is complete
final mediaInfo = session.getMediaInformation();
if (mediaInfo == null) {
_logger.warning("Failed to get video metadata");
final failStackTrace = await session.getFailStackTrace();
final output = await session.getOutput();
_logger.warning(
'Failed to get video metadata. failStackTrace=$failStackTrace, output=$output',
);
}
completer.complete(mediaInfo);
},
(log) {
// put log messages into a map
logs.putIfAbsent(log.getSessionId(), () => StringBuffer());
logs[log.getSessionId()]!.write(log.getMessage());
},
);
// Wait for the session to complete
await session.getReturnCode();
final mediaInfo = await completer.future;
if (kDebugMode) {
log("uncomment below line to see ffprobe logs");
// logs.forEach((key, value) {
// log("log for session $key: $value", name: "FFprobeKit");
// });
}
if (mediaInfo == null) {
final mediaInfo =
await IsolatedFfmpegService.getVideoInfo(originalFile.path);
if (mediaInfo.isEmpty) {
return null;
}
final properties = await FFProbeUtil.getProperties(mediaInfo);
final properties = await FFProbeProps.parseData(mediaInfo);
_logger.info("getVideoPropsAsync took ${stopwatch.elapsedMilliseconds}ms");
stopwatch.stop();
return properties;
} catch (e, s) {

View File

@@ -13,10 +13,10 @@ packages:
dependency: transitive
description:
name: _flutterfire_internals
sha256: "214e6f07e2a44f45972e0365c7b537eaeaddb4598db0778dd4ac64b4acd3f5b1"
sha256: a5788040810bd84400bc209913fbc40f388cded7cdf95ee2f5d2bff7e38d5241
url: "https://pub.dev"
source: hosted
version: "1.3.55"
version: "1.3.58"
adaptive_theme:
dependency: "direct main"
description:
@@ -29,10 +29,10 @@ packages:
dependency: transitive
description:
name: analyzer
sha256: de617bfdc64f3d8b00835ec2957441ceca0a29cdf7881f7ab231bc14f71159c0
sha256: "01949bf52ad33f0e0f74f881fbaac4f348c556531951d92c8d16f1262aa19ff8"
url: "https://pub.dev"
source: hosted
version: "7.5.6"
version: "7.5.4"
android_intent_plus:
dependency: "direct main"
description:
@@ -117,10 +117,10 @@ packages:
dependency: transitive
description:
name: asn1lib
sha256: "1c296cd268f486cabcc3930e9b93a8133169305f18d722916e675959a88f6d2c"
sha256: "9a8f69025044eb466b9b60ef3bc3ac99b4dc6c158ae9c56d25eeccf5bc56d024"
url: "https://pub.dev"
source: hosted
version: "1.5.9"
version: "1.6.5"
async:
dependency: "direct main"
description:
@@ -166,10 +166,10 @@ packages:
dependency: transitive
description:
name: build
sha256: cef23f1eda9b57566c81e2133d196f8e3df48f244b317368d65c5943d91148f0
sha256: "51dc711996cbf609b90cbe5b335bbce83143875a9d58e4b5c6d3c4f684d3dda7"
url: "https://pub.dev"
source: hosted
version: "2.4.2"
version: "2.5.4"
build_config:
dependency: transitive
description:
@@ -190,26 +190,26 @@ packages:
dependency: transitive
description:
name: build_resolvers
sha256: b9e4fda21d846e192628e7a4f6deda6888c36b5b69ba02ff291a01fd529140f0
sha256: ee4257b3f20c0c90e72ed2b57ad637f694ccba48839a821e87db762548c22a62
url: "https://pub.dev"
source: hosted
version: "2.4.4"
version: "2.5.4"
build_runner:
dependency: "direct dev"
description:
name: build_runner
sha256: "058fe9dce1de7d69c4b84fada934df3e0153dd000758c4d65964d0166779aa99"
sha256: "382a4d649addbfb7ba71a3631df0ec6a45d5ab9b098638144faf27f02778eb53"
url: "https://pub.dev"
source: hosted
version: "2.4.15"
version: "2.5.4"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
sha256: "22e3aa1c80e0ada3722fe5b63fd43d9c8990759d0a2cf489c8c5d7b2bdebc021"
sha256: "85fbbb1036d576d966332a3f5ce83f2ce66a40bea1a94ad2d5fc29a19a0d3792"
url: "https://pub.dev"
source: hosted
version: "8.0.0"
version: "9.1.2"
built_collection:
dependency: transitive
description:
@@ -425,10 +425,10 @@ packages:
dependency: transitive
description:
name: dart_style
sha256: "27eb0ae77836989a3bc541ce55595e8ceee0992807f14511552a898ddd0d88ac"
sha256: "5b236382b47ee411741447c1f1e111459c941ea1b3f2b540dde54c210a3662af"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
version: "3.1.0"
dart_ui_isolate:
dependency: "direct main"
description:
@@ -465,10 +465,10 @@ packages:
dependency: transitive
description:
name: device_info_plus_platform_interface
sha256: "0b04e02b30791224b31969eb1b50d723498f402971bff3630bca2ba839bd1ed2"
sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f
url: "https://pub.dev"
source: hosted
version: "7.0.2"
version: "7.0.3"
dio:
dependency: "direct main"
description:
@@ -663,7 +663,7 @@ packages:
description:
path: "flutter/flutter"
ref: remove-event-sub
resolved-ref: b7aac7903f70dce6d71506e221066af1a53ec7fc
resolved-ref: "2c0f34797df830ef61e6ed479583b368c342cb37"
url: "https://github.com/ente-io/ffmpeg-kit"
source: git
version: "6.0.3"
@@ -672,7 +672,7 @@ packages:
description:
path: "flutter/flutter_platform_interface"
ref: remove-event-sub
resolved-ref: b7aac7903f70dce6d71506e221066af1a53ec7fc
resolved-ref: "2c0f34797df830ef61e6ed479583b368c342cb37"
url: "https://github.com/ente-io/ffmpeg-kit"
source: git
version: "0.2.1"
@@ -704,50 +704,50 @@ packages:
dependency: "direct main"
description:
name: firebase_core
sha256: "8cfe3c900512399ce8d50fcc817e5758ff8615eeb6fa5c846a4cc47bbf6353b6"
sha256: c6e8a6bf883d8ddd0dec39be90872daca65beaa6f4cff0051ed3b16c56b82e9f
url: "https://pub.dev"
source: hosted
version: "3.13.1"
version: "3.15.1"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
sha256: d7253d255ff10f85cfd2adaba9ac17bae878fa3ba577462451163bd9f1d1f0bf
sha256: "5dbc900677dcbe5873d22ad7fbd64b047750124f1f9b7ebe2a33b9ddccc838eb"
url: "https://pub.dev"
source: hosted
version: "5.4.0"
version: "6.0.0"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
sha256: ddd72baa6f727e5b23f32d9af23d7d453d67946f380bd9c21daf474ee0f7326e
sha256: "0ed0dc292e8f9ac50992e2394e9d336a0275b6ae400d64163fdf0a8a8b556c37"
url: "https://pub.dev"
source: hosted
version: "2.23.0"
version: "2.24.1"
firebase_messaging:
dependency: "direct main"
description:
name: firebase_messaging
sha256: "38111089e511f03daa2c66b4c3614c16421b7d78c84ee04331a0a65b47df4542"
sha256: "0f3363f97672eb9f65609fa00ed2f62cc8ec93e7e2d4def99726f9165d3d8a73"
url: "https://pub.dev"
source: hosted
version: "15.2.6"
version: "15.2.9"
firebase_messaging_platform_interface:
dependency: transitive
description:
name: firebase_messaging_platform_interface
sha256: ba254769982e5f439e534eed68856181c74e2b3f417c8188afad2bb440807cc7
sha256: "7a05ef119a14c5f6a9440d1e0223bcba20c8daf555450e119c4c477bf2c3baa9"
url: "https://pub.dev"
source: hosted
version: "4.6.6"
version: "4.6.9"
firebase_messaging_web:
dependency: transitive
description:
name: firebase_messaging_web
sha256: dba89137272aac39e95f71408ba25c33fb8ed903cd5fa8d1e49b5cd0d96069e0
sha256: a4547f76da2a905190f899eb4d0150e1d0fd52206fce469d9f05ae15bb68b2c5
url: "https://pub.dev"
source: hosted
version: "3.10.6"
version: "3.10.9"
fixnum:
dependency: "direct main"
description:
@@ -930,10 +930,10 @@ packages:
dependency: "direct dev"
description:
name: flutter_launcher_icons
sha256: bfa04787c85d80ecb3f8777bde5fc10c3de809240c48fa061a2c2bf15ea5211c
sha256: "10f13781741a2e3972126fae08393d3c4e01fa4cd7473326b94b72cf594195e7"
url: "https://pub.dev"
source: hosted
version: "0.14.3"
version: "0.14.4"
flutter_lints:
dependency: "direct dev"
description:
@@ -946,10 +946,10 @@ packages:
dependency: "direct main"
description:
name: flutter_local_notifications
sha256: b94a50aabbe56ef254f95f3be75640f99120429f0a153b2dc30143cffc9bfdf3
sha256: edae0c34573233ab03f5ba1f07465e55c384743893042cb19e010b4ee8541c12
url: "https://pub.dev"
source: hosted
version: "19.2.1"
version: "19.3.0"
flutter_local_notifications_linux:
dependency: transitive
description:
@@ -962,10 +962,10 @@ packages:
dependency: transitive
description:
name: flutter_local_notifications_platform_interface
sha256: "2569b973fc9d1f63a37410a9f7c1c552081226c597190cb359ef5d5762d1631c"
sha256: "277d25d960c15674ce78ca97f57d0bae2ee401c844b6ac80fcd972a9c99d09fe"
url: "https://pub.dev"
source: hosted
version: "9.0.0"
version: "9.1.0"
flutter_local_notifications_windows:
dependency: transitive
description:
@@ -1007,10 +1007,10 @@ packages:
dependency: "direct dev"
description:
name: flutter_native_splash
sha256: "7062602e0dbd29141fb8eb19220b5871ca650be5197ab9c1f193a28b17537bc7"
sha256: "8321a6d11a8d13977fa780c89de8d257cce3d841eecfb7a4cadffcc4f12d82dc"
url: "https://pub.dev"
source: hosted
version: "2.4.4"
version: "2.4.6"
flutter_password_strength:
dependency: "direct main"
description:
@@ -1112,10 +1112,10 @@ packages:
dependency: "direct main"
description:
name: flutter_svg
sha256: d44bf546b13025ec7353091516f6881f1d4c633993cb109c3916c3a0159dadf1
sha256: cd57f7969b4679317c17af6fd16ee233c1e60a82ed209d8a475c54fd6fd6f845
url: "https://pub.dev"
source: hosted
version: "2.1.0"
version: "2.2.0"
flutter_test:
dependency: "direct dev"
description: flutter
@@ -1146,26 +1146,26 @@ packages:
dependency: "direct main"
description:
name: fraction
sha256: "7804c9a73d26bd3d5ccf52b7225eecd0af4e33b310729726dc8f8bb14c217716"
sha256: dd487c01c0bfdcccc44d15250b24b4bee94b6981e01e8c41007a1b02f395ea01
url: "https://pub.dev"
source: hosted
version: "5.0.4"
version: "5.0.5"
freezed:
dependency: "direct dev"
description:
name: freezed
sha256: "6022db4c7bfa626841b2a10f34dd1e1b68e8f8f9650db6112dcdeeca45ca793c"
sha256: "2d399f823b8849663744d2a9ddcce01c49268fb4170d0442a655bf6a2f47be22"
url: "https://pub.dev"
source: hosted
version: "3.0.6"
version: "3.1.0"
freezed_annotation:
dependency: "direct main"
description:
name: freezed_annotation
sha256: c87ff004c8aa6af2d531668b46a4ea379f7191dc6dfa066acd53d506da6e044b
sha256: "7294967ff0a6d98638e7acb774aac3af2550777accd8149c90af5b014e6d44d8"
url: "https://pub.dev"
source: hosted
version: "3.0.0"
version: "3.1.0"
frontend_server_client:
dependency: transitive
description:
@@ -1311,10 +1311,10 @@ packages:
dependency: transitive
description:
name: in_app_purchase_storekit
sha256: "9c2b438aa8ef95ac1c1f5ab1aaace8d6edd0ba3745b8b8df832f7baa2e7492f7"
sha256: ceddd5a70d268f762d29993ed470054bc2baf8793e41800bc82cde05110260d0
url: "https://pub.dev"
source: hosted
version: "0.4.1"
version: "0.4.2"
integration_test:
dependency: "direct dev"
description: flutter
@@ -1348,10 +1348,10 @@ packages:
dependency: transitive
description:
name: iso_base_media
sha256: "0f5594feef1fba98179a2df95d1afbdda952de0c7a2e35e6815093f7c00aaf06"
sha256: "0a94fa4ff4ce7e6894d7afc96c1eee6911c12827f8cf184ca752ce3437a818a1"
url: "https://pub.dev"
source: hosted
version: "4.5.2"
version: "4.6.1"
jni:
dependency: transitive
description:
@@ -1468,10 +1468,10 @@ packages:
dependency: transitive
description:
name: local_auth_darwin
sha256: "630996cd7b7f28f5ab92432c4b35d055dd03a747bc319e5ffbb3c4806a3e50d2"
sha256: "25163ce60a5a6c468cf7a0e3dc8a165f824cabc2aa9e39a5e9fc5c2311b7686f"
url: "https://pub.dev"
source: hosted
version: "1.4.3"
version: "1.5.0"
local_auth_ios:
dependency: "direct main"
description:
@@ -1500,10 +1500,10 @@ packages:
dependency: transitive
description:
name: logger
sha256: be4b23575aac7ebf01f225a241eb7f6b5641eeaf43c6a8613510fc2f8cf187d1
sha256: "2621da01aabaf223f8f961e751f2c943dbb374dc3559b982f200ccedadaa6999"
url: "https://pub.dev"
source: hosted
version: "2.5.0"
version: "2.6.0"
logging:
dependency: "direct main"
description:
@@ -1919,10 +1919,10 @@ packages:
dependency: "direct main"
description:
name: permission_handler
sha256: "2d070d8684b68efb580a5997eb62f675e8a885ef0be6e754fb9ef489c177470f"
sha256: bc917da36261b00137bbc8896bf1482169cd76f866282368948f032c8c1caae1
url: "https://pub.dev"
source: hosted
version: "12.0.0+1"
version: "12.0.1"
permission_handler_android:
dependency: transitive
description:
@@ -1967,10 +1967,10 @@ packages:
dependency: transitive
description:
name: petitparser
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646"
url: "https://pub.dev"
source: hosted
version: "6.0.2"
version: "6.1.0"
photo_manager:
dependency: "direct main"
description:
@@ -2047,10 +2047,10 @@ packages:
dependency: transitive
description:
name: posix
sha256: f0d7856b6ca1887cfa6d1d394056a296ae33489db914e365e2044fdada449e62
sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61"
url: "https://pub.dev"
source: hosted
version: "6.0.2"
version: "6.0.3"
privacy_screen:
dependency: "direct main"
description:
@@ -2128,10 +2128,10 @@ packages:
dependency: transitive
description:
name: random_access_source
sha256: dc86934da2cc4777334f43916234410f232032738c519c0c3452147c5d4fec89
sha256: "26d1509a9fd935ab9c77102ab4c94b343d36216387d985975c380efe450b81b8"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
version: "3.0.0"
receive_sharing_intent:
dependency: "direct main"
description:
@@ -2161,10 +2161,10 @@ packages:
dependency: transitive
description:
name: screen_brightness_android
sha256: "6ba1b5812f66c64e9e4892be2d36ecd34210f4e0da8bdec6a2ea34f1aa42683e"
sha256: fb5fa43cb89d0c9b8534556c427db1e97e46594ac5d66ebdcf16063b773d54ed
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.1.2"
screen_brightness_platform_interface:
dependency: transitive
description:
@@ -2305,10 +2305,10 @@ packages:
dependency: transitive
description:
name: shelf_web_socket
sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67
sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
version: "3.0.0"
sky_engine:
dependency: transitive
description: flutter
@@ -2374,26 +2374,26 @@ packages:
dependency: transitive
description:
name: sqflite_android
sha256: "78f489aab276260cdd26676d2169446c7ecd3484bbd5fead4ca14f3ed4dd9ee3"
sha256: "2b3070c5fa881839f8b402ee4a39c1b4d561704d4ebbbcfb808a119bc2a1701b"
url: "https://pub.dev"
source: hosted
version: "2.4.0"
version: "2.4.1"
sqflite_common:
dependency: transitive
description:
name: sqflite_common
sha256: "761b9740ecbd4d3e66b8916d784e581861fd3c3553eda85e167bc49fdb68f709"
sha256: "84731e8bfd8303a3389903e01fb2141b6e59b5973cacbb0929021df08dddbe8b"
url: "https://pub.dev"
source: hosted
version: "2.5.4+6"
version: "2.5.5"
sqflite_darwin:
dependency: transitive
description:
name: sqflite_darwin
sha256: "22adfd9a2c7d634041e96d6241e6e1c8138ca6817018afc5d443fef91dcefa9c"
sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3"
url: "https://pub.dev"
source: hosted
version: "2.4.1+1"
version: "2.4.2"
sqflite_migration:
dependency: "direct main"
description:
@@ -2422,10 +2422,10 @@ packages:
dependency: "direct main"
description:
name: sqlite3_flutter_libs
sha256: "7986c26234c0a5cf4fd83ff4ee39d4195b1f47cdb50a949ec7987ede4dcbdc2a"
sha256: e07232b998755fe795655c56d1f5426e0190c9c435e1752d39e7b1cd33699c71
url: "https://pub.dev"
source: hosted
version: "0.5.33"
version: "0.5.34"
sqlite3_web:
dependency: transitive
description:
@@ -2502,26 +2502,26 @@ packages:
dependency: "direct main"
description:
name: syncfusion_flutter_core
sha256: "98580db6186b46aae965d3f480f7830b0ee6f58c4e1bbbb3fb3de6a121f61836"
sha256: bee87cdfe527b31705190162e3bd27bf468d591ae7c68182244bdfd94e21f737
url: "https://pub.dev"
source: hosted
version: "29.1.38"
version: "29.2.11"
syncfusion_flutter_sliders:
dependency: "direct main"
description:
name: syncfusion_flutter_sliders
sha256: a0d479786701f505b3c29f48c1c7934e2e0ffe682adb72ed95b39918914eeea7
sha256: "84ba05823f00e30cb0fdb98ad300a204617db4a6407de7c184f9836276f386b9"
url: "https://pub.dev"
source: hosted
version: "29.1.38"
version: "29.2.11"
synchronized:
dependency: "direct main"
description:
name: synchronized
sha256: "69fe30f3a8b04a0be0c15ae6490fc859a78ef4c43ae2dd5e8a623d45bfcf9225"
sha256: "0669c70faae6270521ee4f05bffd2919892d42d1276e6c495be80174b6bc0ef6"
url: "https://pub.dev"
source: hosted
version: "3.3.0+3"
version: "3.3.1"
system_info_plus:
dependency: "direct main"
description:
@@ -2726,10 +2726,10 @@ packages:
dependency: transitive
description:
name: vector_graphics
sha256: "44cc7104ff32563122a929e4620cf3efd584194eec6d1d913eb5ba593dbcf6de"
sha256: a4f059dc26fc8295b5921376600a194c4ec7d55e72f2fe4c7d2831e103d461e6
url: "https://pub.dev"
source: hosted
version: "1.1.18"
version: "1.1.19"
vector_graphics_codec:
dependency: transitive
description:
@@ -2792,26 +2792,26 @@ packages:
dependency: transitive
description:
name: video_player_android
sha256: "28dcc4122079f40f93a0965b3679aff1a5f4251cf79611bd8011f937eb6b69de"
sha256: "4a5135754a62dbc827a64a42ef1f8ed72c962e191c97e2d48744225c2b9ebb73"
url: "https://pub.dev"
source: hosted
version: "2.8.4"
version: "2.8.7"
video_player_avfoundation:
dependency: transitive
description:
name: video_player_avfoundation
sha256: "9ee764e5cd2fc1e10911ae8ad588e1a19db3b6aa9a6eb53c127c42d3a3c3f22f"
sha256: "0d47db6cbf72db61d86369219efd35c7f9d93515e1319da941ece81b1f21c49c"
url: "https://pub.dev"
source: hosted
version: "2.7.1"
version: "2.7.2"
video_player_platform_interface:
dependency: transitive
description:
name: video_player_platform_interface
sha256: df534476c341ab2c6a835078066fc681b8265048addd853a1e3c78740316a844
sha256: cf2a1d29a284db648fd66cbd18aacc157f9862d77d2cc790f6f9678a46c1db5a
url: "https://pub.dev"
source: hosted
version: "6.3.0"
version: "6.4.0"
video_player_web:
dependency: transitive
description:
@@ -2823,12 +2823,11 @@ packages:
video_thumbnail:
dependency: "direct main"
description:
path: "."
ref: HEAD
resolved-ref: ba086b927621434d1bbd73eeffbe7504d7abebfa
url: "https://github.com/ente-io/video_thumbnail_fork.git"
source: git
version: "0.5.3"
name: video_thumbnail
sha256: "181a0c205b353918954a881f53a3441476b9e301641688a581e0c13f00dc588b"
url: "https://pub.dev"
source: hosted
version: "0.5.6"
visibility_detector:
dependency: "direct main"
description:
@@ -2873,10 +2872,10 @@ packages:
dependency: "direct overridden"
description:
name: watcher
sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104"
sha256: "0b7fd4a0bbc4b92641dbf20adfd7e3fd1398fe17102d94b674234563e110088a"
url: "https://pub.dev"
source: hosted
version: "1.1.1"
version: "1.1.2"
web:
dependency: transitive
description:
@@ -3006,5 +3005,5 @@ packages:
source: hosted
version: "3.1.3"
sdks:
dart: ">=3.7.0 <4.0.0"
flutter: ">=3.27.0"
dart: ">=3.7.2 <4.0.0"
flutter: ">=3.29.0"

View File

@@ -248,9 +248,6 @@ dependency_overrides:
url: https://github.com/ente-io/packages.git
ref: android_video_roation_fix
path: packages/video_player/video_player/
video_thumbnail: # update source if there is any update
git:
url: https://github.com/ente-io/video_thumbnail_fork.git
watcher: ^1.1.0
win32: "5.10.1"

View File

@@ -1,2 +1,3 @@
- Isolate FFMpeg
- Aman: Fixed bottom nav bar color in light theme, resolved paint editor's initial color, and added tap-to-reset with haptics for tune adjustments (brightness/exposure)
- Gracefully handle heic rendering on Android