From 35d5f8e225b1939207efaf8968defcd3ef922137 Mon Sep 17 00:00:00 2001 From: Roscoe Rubin-Rottenberg Date: Tue, 7 Apr 2026 21:35:03 -0400 Subject: [PATCH] fix: unfork pro_video_editor to stop android crashing on upload --- android/app/build.gradle.kts | 2 +- android/build.gradle.kts | 23 +++++++++ .../pro_video_editor_repository.dart | 6 +-- .../pro_video_editor_repository_impl.dart | 4 +- .../ui/video_editor_grounded_page.dart | 34 +++++++++---- pubspec.lock | 51 ++++++++++++------- pubspec.yaml | 7 +-- 7 files changed, 87 insertions(+), 40 deletions(-) diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 86151446..211c5701 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -26,7 +26,7 @@ android { namespace = "so.sprk.app" compileSdk = 36 buildToolsVersion = "34.0.0" - ndkVersion = "27.0.12077973" + ndkVersion = "28.2.13676358" compileOptions { sourceCompatibility = JavaVersion.VERSION_11 diff --git a/android/build.gradle.kts b/android/build.gradle.kts index e20a2a2b..9ee35d56 100644 --- a/android/build.gradle.kts +++ b/android/build.gradle.kts @@ -6,6 +6,8 @@ allprojects { } } +val androidCompileSdk = 36 + val newBuildDir: Directory = rootProject.layout.buildDirectory.dir("../../build").get() rootProject.layout.buildDirectory.value(newBuildDir) @@ -13,6 +15,27 @@ subprojects { val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name) project.layout.buildDirectory.value(newSubprojectBuildDir) } +subprojects { + // Some hosted Flutter plugins pin compileSdk lower than their AndroidX dependencies require. + afterEvaluate { + extensions.findByName("android")?.let { androidExtension -> + androidExtension.javaClass.methods + .firstOrNull { + val parameterType = it.parameterTypes.singleOrNull() + it.name == "setCompileSdk" && + (parameterType == Int::class.javaPrimitiveType || + parameterType == Int::class.javaObjectType) + }?.invoke(androidExtension, androidCompileSdk) + ?: androidExtension.javaClass.methods + .firstOrNull { + val parameterType = it.parameterTypes.singleOrNull() + it.name == "compileSdkVersion" && + (parameterType == Int::class.javaPrimitiveType || + parameterType == Int::class.javaObjectType) + }?.invoke(androidExtension, androidCompileSdk) + } + } +} subprojects { project.evaluationDependsOn(":app") } diff --git a/lib/src/core/pro_video_editor/pro_video_editor_repository.dart b/lib/src/core/pro_video_editor/pro_video_editor_repository.dart index cfcbb97d..5433b8b6 100644 --- a/lib/src/core/pro_video_editor/pro_video_editor_repository.dart +++ b/lib/src/core/pro_video_editor/pro_video_editor_repository.dart @@ -21,14 +21,14 @@ abstract class ProVideoEditorRepository { Future> getKeyFrames(KeyFramesConfigs configs); /// Render a video and return the bytes. Use for small/short videos. - Future renderVideo(RenderVideoModel model); + Future renderVideo(VideoRenderData model); /// Render a video directly to a file path to avoid RAM pressure. - Future renderVideoToFile(String outputPath, RenderVideoModel model); + Future renderVideoToFile(String outputPath, VideoRenderData model); /// Stream progress updates for a given render task id. /// - /// The caller is responsible to pass the same [RenderVideoModel.id] or + /// The caller is responsible to pass the same [VideoRenderData.id] or /// [ThumbnailConfigs.id]/[KeyFramesConfigs.id]. Stream progressStream(); diff --git a/lib/src/core/pro_video_editor/pro_video_editor_repository_impl.dart b/lib/src/core/pro_video_editor/pro_video_editor_repository_impl.dart index e764305a..5c2359a3 100644 --- a/lib/src/core/pro_video_editor/pro_video_editor_repository_impl.dart +++ b/lib/src/core/pro_video_editor/pro_video_editor_repository_impl.dart @@ -32,12 +32,12 @@ class ProVideoEditorRepositoryImpl implements ProVideoEditorRepository { } @override - Future renderVideo(RenderVideoModel model) { + Future renderVideo(VideoRenderData model) { return ProVideoEditor.instance.renderVideo(model); } @override - Future renderVideoToFile(String outputPath, RenderVideoModel model) { + Future renderVideoToFile(String outputPath, VideoRenderData model) { return ProVideoEditor.instance.renderVideoToFile(outputPath, model); } diff --git a/lib/src/core/pro_video_editor/ui/video_editor_grounded_page.dart b/lib/src/core/pro_video_editor/ui/video_editor_grounded_page.dart index 7fce247b..f8d8d0c0 100644 --- a/lib/src/core/pro_video_editor/ui/video_editor_grounded_page.dart +++ b/lib/src/core/pro_video_editor/ui/video_editor_grounded_page.dart @@ -6,7 +6,7 @@ import 'package:atproto/com_atproto_repo_strongref.dart'; import 'package:atproto/core.dart'; import 'package:auto_route/auto_route.dart'; import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' hide ColorFilter; import 'package:get_it/get_it.dart'; import 'package:image_picker/image_picker.dart'; import 'package:path_provider/path_provider.dart'; @@ -23,7 +23,7 @@ import 'package:spark/src/core/pro_video_editor/ui/widgets/common/video_initiali import 'package:spark/src/core/pro_video_editor/ui/widgets/player/video_fullscreen_preview_page.dart'; import 'package:spark/src/core/pro_video_editor/ui/widgets/player/video_player_widget.dart'; import 'package:spark/src/core/pro_video_editor/ui/widgets/timeline/video_timeline_state.dart'; -import 'package:video_player/video_player.dart'; +import 'package:video_player/video_player.dart' hide VideoAudioTrack; @RoutePage() class VideoEditorGroundedPage extends StatefulWidget { @@ -518,23 +518,35 @@ class _VideoEditorGroundedPageState extends State } } - final exportModel = RenderVideoModel( + final customAudioPath = await _audioService.safeCustomAudioPath( + customAudioTrack, + ); + + final exportModel = VideoRenderData( id: _taskId, - video: _video, + videoSegments: [VideoSegment(video: _video, volume: originalVolume)], outputFormat: _outputFormat, enableAudio: _proVideoController?.isAudioEnabled ?? true, - imageBytes: parameters.layers.isNotEmpty ? parameters.image : null, + imageLayers: parameters.layers.isNotEmpty + ? [ImageLayer(image: EditorLayerImage.memory(parameters.image))] + : null, blur: parameters.blur, - colorMatrixList: parameters.colorFilters, + colorFilters: parameters.colorFilters + .map((matrix) => ColorFilter(matrix: matrix)) + .toList(), startTime: parameters.startTime, endTime: parameters.endTime, transform: _buildExportTransform(parameters), bitrate: _videoMetadata.bitrate, - customAudioPath: await _audioService.safeCustomAudioPath( - customAudioTrack, - ), - originalAudioVolume: originalVolume, - customAudioVolume: overlayVolume, + audioTracks: customAudioPath != null + ? [ + VideoAudioTrack( + path: customAudioPath, + volume: overlayVolume, + loop: true, + ), + ] + : const [], ); final now = DateTime.now().millisecondsSinceEpoch; diff --git a/pubspec.lock b/pubspec.lock index fae5541e..91fe9e76 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -61,10 +61,10 @@ packages: dependency: "direct main" description: name: app_badge_plus - sha256: ce3d8fdfcf39a1552cc8dea499ee3b4a86273ccf04c8de29e7960c739b045ae6 + sha256: "81130fe6150ce2a1f12af4bb7d6f646496d284d5f87f2c121af8258a453bbb3f" url: "https://pub.dev" source: hosted - version: "1.2.7" + version: "1.2.8" archive: dependency: transitive description: @@ -779,10 +779,10 @@ packages: dependency: transitive description: name: flutter_widget_from_html_core - sha256: "1120ee6ed3509ceff2d55aa6c6cbc7b6b1291434422de2411b5a59364dd6ff03" + sha256: "7ff010b116f6abc16429923e616fbc727f3f65ef4cee12ffdb280aeecbc21e7f" url: "https://pub.dev" source: hosted - version: "0.17.0" + version: "0.17.2" freezed: dependency: "direct main" description: @@ -867,10 +867,10 @@ packages: dependency: transitive description: name: hotreloader - sha256: bc167a1163807b03bada490bfe2df25b0d744df359227880220a5cbd04e5734b + sha256: "66871df468fc24eee81f1a0a7cb98acc104716f9b7376d355437b48d633c4ebf" url: "https://pub.dev" source: hosted - version: "4.3.0" + version: "4.4.0" html: dependency: transitive description: @@ -923,10 +923,10 @@ packages: dependency: transitive description: name: image_picker_android - sha256: "9eae0cbd672549dacc18df855c2a23782afe4854ada5190b7d63b30ee0b0d3fd" + sha256: "66810af8e99b2657ee98e5c6f02064f69bb63f7a70e343937f70946c5f8c6622" url: "https://pub.dev" source: hosted - version: "0.8.13+15" + version: "0.8.13+16" image_picker_for_web: dependency: transitive description: @@ -999,6 +999,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.5" + jni: + dependency: transitive + description: + name: jni + sha256: c2230682d5bc2362c1c9e8d3c7f406d9cbba23ab3f2e203a025dd47e0fb2e68f + url: "https://pub.dev" + source: hosted + version: "1.0.0" + jni_flutter: + dependency: transitive + description: + name: jni_flutter + sha256: "8b59e590786050b1cd866677dddaf76b1ade5e7bc751abe04b86e84d379d3ba6" + url: "https://pub.dev" + source: hosted + version: "1.0.1" json_annotation: dependency: "direct main" description: @@ -1211,10 +1227,10 @@ packages: dependency: transitive description: name: path_provider_android - sha256: "149441ca6e4f38193b2e004c0ca6376a3d11f51fa5a77552d8bd4d2b0c0912ba" + sha256: "914a07484c4380e572998d30486e77e0d9cd2faec72fee268086d07bf7f302c9" url: "https://pub.dev" source: hosted - version: "2.2.23" + version: "2.3.0" path_provider_foundation: dependency: transitive description: @@ -1315,19 +1331,18 @@ packages: dependency: "direct main" description: name: pro_image_editor - sha256: d7d06e085edb1b97e17bd7a47ae9d1cb86bf12179a67480bbcc870642bd98824 + sha256: c10a89dfc14ead9cc53f70944d238100b129d40b10038ef7eddae98b1698a8c3 url: "https://pub.dev" source: hosted - version: "12.0.13" + version: "12.1.0" pro_video_editor: dependency: "direct main" description: - path: "." - ref: dev - resolved-ref: f8c4678fe76ad8984fc03eeb0e1a45f6359fdc5b - url: "https://github.com/sprksocial/pro_video_editor.git" - source: git - version: "0.3.0" + name: pro_video_editor + sha256: "7bf4148a9bd2c6383bea1a36a01ff5099087b964ebaeaa56278cc7a4decc0566" + url: "https://pub.dev" + source: hosted + version: "1.14.3" pub_semver: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 7e88b2b4..b0fc8d85 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: spark description: "Spark mobile app" publish_to: "none" # The number after + should stay fixed, the android workflow will change it on every build -version: 0.10.0+1 +version: 0.10.1+1 environment: sdk: ^3.11.0 workspace: @@ -57,10 +57,7 @@ dependencies: pool: ^1.5.2 posthog_flutter: ^5.23.0 pro_image_editor: ^12.0.13 - pro_video_editor: - git: - url: https://github.com/sprksocial/pro_video_editor.git - ref: dev + pro_video_editor: 1.14.3 riverpod_annotation: ^4.0.2 share_plus: ^12.0.2 shared_preferences: ^2.5.5 -- 2.51.2