From 467c0ea8b5d3ba59353d7963c3cad132a1ba344d Mon Sep 17 00:00:00 2001 From: RyuJongJin <266630912+RyuJongJin@users.noreply.github.com> Date: Fri, 2 Oct 2026 20:16:58 +0900 Subject: [PATCH] =?UTF-8?q?v2026.10.02=5F001:=20Android=20MKV=20=EB=A7=8C?= =?UTF-8?q?=EB=93=A4=EA=B8=B0=EA=B0=80=20=EB=81=9D=EB=82=98=EB=8F=84=20?= =?UTF-8?q?=EB=AA=87=20=EB=B6=84=EC=94=A9=20"=EC=9E=91=EC=97=85=20?= =?UTF-8?q?=EC=A4=91"=20=EC=9C=BC=EB=A1=9C=20=EB=A9=88=EC=B6=94=EB=8D=98?= =?UTF-8?q?=20=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ffmpeg-kit 플러그인 사본: 통계(진행률) 이벤트를 세션마다 0.25초에 한 번만 Dart 로 보냄 (프레임마다 보내 메인 스레드 줄이 밀리고 완료 이벤트가 늦게 도착, 그동안 다른 작업 버튼이 모두 잠김) - FfmpegKitMediaTool: 진행률이 0.5% 이상 바뀔 때만 화면 갱신 Co-Authored-By: Claude Opus 5.5 --- .../android/ffmpeg_kit_media_tool.dart | 10 ++++++--- .../JJ_PATCH.md | 5 +++++ .../ffmpegkit/FFmpegKitFlutterPlugin.java | 21 +++++++++++++++++++ pubspec.yaml | 2 +- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/lib/platform/android/ffmpeg_kit_media_tool.dart b/lib/platform/android/ffmpeg_kit_media_tool.dart index 3ecc5ec..9c43491 100644 --- a/lib/platform/android/ffmpeg_kit_media_tool.dart +++ b/lib/platform/android/ffmpeg_kit_media_tool.dart @@ -71,6 +71,7 @@ class FfmpegKitMediaTool implements MediaTool { final totalMs = duration?.inMilliseconds ?? 0; final done = Completer(); final errTail = []; + var lastProgress = 0.0; final session = await FFmpegKit.executeWithArgumentsAsync( a, (s) async { @@ -93,9 +94,12 @@ class FfmpegKitMediaTool implements MediaTool { } }, (st) { - if (onProgress != null && totalMs > 0 && st.getTime() > 0) { - onProgress((st.getTime() / totalMs).clamp(0.0, 1.0)); - } + if (onProgress == null || totalMs <= 0 || st.getTime() <= 0) return; + // 화면을 다시 그리는 일이 많지 않도록 0.5% 이상 바뀔 때만 알린다 + final x = (st.getTime() / totalMs).clamp(0.0, 1.0); + if (x - lastProgress < 0.005) return; + lastProgress = x; + onProgress(x); }, ); final id = session.getSessionId(); diff --git a/packages/ffmpeg_kit_flutter_new_min_gpl/JJ_PATCH.md b/packages/ffmpeg_kit_flutter_new_min_gpl/JJ_PATCH.md index d5f043b..48f8c1d 100644 --- a/packages/ffmpeg_kit_flutter_new_min_gpl/JJ_PATCH.md +++ b/packages/ffmpeg_kit_flutter_new_min_gpl/JJ_PATCH.md @@ -9,3 +9,8 @@ JJ_MKVMaker 의 Windows 판은 동봉한 ffmpeg.exe 를 쓰므로 필요 없다. ## 수정 - pubspec.yaml: 플러그인 플랫폼을 android 만 남김 (ios · macos · windows · linux 제거) - windows · linux · macos · ios · example 폴더 제거 + +## 통계 이벤트 줄이기 (2026-10-02) +FFmpeg 는 프레임마다 통계(진행률)를 보낸다. 17분 영상 하나에 수만 개가 Dart 로 넘어가 메인 스레드 줄이 밀리고, +완료 이벤트가 그 뒤에 서 있어 FFmpeg 가 4초 만에 끝나도 앱은 2분 넘게 "작업 중" 으로 남았다. +- android/.../FFmpegKitFlutterPlugin.java: 통계는 세션마다 0.25초에 한 번만 보낸다 (`shouldEmitStatistics`) diff --git a/packages/ffmpeg_kit_flutter_new_min_gpl/android/src/main/java/com/antonkarpenko/ffmpegkit/FFmpegKitFlutterPlugin.java b/packages/ffmpeg_kit_flutter_new_min_gpl/android/src/main/java/com/antonkarpenko/ffmpegkit/FFmpegKitFlutterPlugin.java index 6a6b472..3d6500b 100644 --- a/packages/ffmpeg_kit_flutter_new_min_gpl/android/src/main/java/com/antonkarpenko/ffmpegkit/FFmpegKitFlutterPlugin.java +++ b/packages/ffmpeg_kit_flutter_new_min_gpl/android/src/main/java/com/antonkarpenko/ffmpegkit/FFmpegKitFlutterPlugin.java @@ -161,6 +161,11 @@ public class FFmpegKitFlutterPlugin implements FlutterPlugin, ActivityAware, Met }); FFmpegKitConfig.enableStatisticsCallback(statistics -> { + // JJ_PATCH: FFmpeg 는 프레임마다 통계를 보낸다 (긴 영상이면 수만 개). + // 모두 Dart 로 보내면 메인 스레드 줄이 밀려 완료 이벤트가 몇 분씩 늦게 도착한다 → 세션마다 0.25초에 한 번만 + if (!shouldEmitStatistics(statistics)) { + return; + } for (FFmpegKitFlutterPlugin plugin : attachedPlugins) { if (plugin.statisticsEnabled.get() && plugin.eventSink != null) { plugin.emitStatistics(statistics); @@ -169,7 +174,23 @@ public class FFmpegKitFlutterPlugin implements FlutterPlugin, ActivityAware, Met }); } + // JJ_PATCH: 세션별 마지막 통계 전송 시각 (완료되면 지운다) + private static final long STATISTICS_INTERVAL_MS = 250; + private static final java.util.concurrent.ConcurrentHashMap lastStatisticsAt = + new java.util.concurrent.ConcurrentHashMap<>(); + + private static boolean shouldEmitStatistics(final Statistics statistics) { + final long now = android.os.SystemClock.uptimeMillis(); + final Long last = lastStatisticsAt.get(statistics.getSessionId()); + if (last != null && now - last < STATISTICS_INTERVAL_MS) { + return false; + } + lastStatisticsAt.put(statistics.getSessionId(), now); + return true; + } + private static void broadcastSession(final Session session) { + lastStatisticsAt.remove(session.getSessionId()); boolean delivered = false; for (FFmpegKitFlutterPlugin plugin : attachedPlugins) { if (plugin.eventSink != null) { diff --git a/pubspec.yaml b/pubspec.yaml index d97ac67..0122a04 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 2026.10.1+3 +version: 2026.10.2+1 environment: sdk: ^3.13.4