[READ ONLY MIRROR] Open Source TikTok alternative built on AT Protocol github.com/sprksocial/client
flutter atproto video dart
10
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: unfork pro_video_editor to stop android crashing on upload

+87 -40
+1 -1
android/app/build.gradle.kts
··· 26 26 namespace = "so.sprk.app" 27 27 compileSdk = 36 28 28 buildToolsVersion = "34.0.0" 29 - ndkVersion = "27.0.12077973" 29 + ndkVersion = "28.2.13676358" 30 30 31 31 compileOptions { 32 32 sourceCompatibility = JavaVersion.VERSION_11
+23
android/build.gradle.kts
··· 6 6 } 7 7 } 8 8 9 + val androidCompileSdk = 36 10 + 9 11 val newBuildDir: Directory = rootProject.layout.buildDirectory.dir("../../build").get() 10 12 rootProject.layout.buildDirectory.value(newBuildDir) 11 13 12 14 subprojects { 13 15 val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name) 14 16 project.layout.buildDirectory.value(newSubprojectBuildDir) 17 + } 18 + subprojects { 19 + // Some hosted Flutter plugins pin compileSdk lower than their AndroidX dependencies require. 20 + afterEvaluate { 21 + extensions.findByName("android")?.let { androidExtension -> 22 + androidExtension.javaClass.methods 23 + .firstOrNull { 24 + val parameterType = it.parameterTypes.singleOrNull() 25 + it.name == "setCompileSdk" && 26 + (parameterType == Int::class.javaPrimitiveType || 27 + parameterType == Int::class.javaObjectType) 28 + }?.invoke(androidExtension, androidCompileSdk) 29 + ?: androidExtension.javaClass.methods 30 + .firstOrNull { 31 + val parameterType = it.parameterTypes.singleOrNull() 32 + it.name == "compileSdkVersion" && 33 + (parameterType == Int::class.javaPrimitiveType || 34 + parameterType == Int::class.javaObjectType) 35 + }?.invoke(androidExtension, androidCompileSdk) 36 + } 37 + } 15 38 } 16 39 subprojects { 17 40 project.evaluationDependsOn(":app")
+3 -3
lib/src/core/pro_video_editor/pro_video_editor_repository.dart
··· 21 21 Future<List<Uint8List>> getKeyFrames(KeyFramesConfigs configs); 22 22 23 23 /// Render a video and return the bytes. Use for small/short videos. 24 - Future<Uint8List> renderVideo(RenderVideoModel model); 24 + Future<Uint8List> renderVideo(VideoRenderData model); 25 25 26 26 /// Render a video directly to a file path to avoid RAM pressure. 27 - Future<String> renderVideoToFile(String outputPath, RenderVideoModel model); 27 + Future<String> renderVideoToFile(String outputPath, VideoRenderData model); 28 28 29 29 /// Stream progress updates for a given render task id. 30 30 /// 31 - /// The caller is responsible to pass the same [RenderVideoModel.id] or 31 + /// The caller is responsible to pass the same [VideoRenderData.id] or 32 32 /// [ThumbnailConfigs.id]/[KeyFramesConfigs.id]. 33 33 Stream<ProgressModel> progressStream(); 34 34
+2 -2
lib/src/core/pro_video_editor/pro_video_editor_repository_impl.dart
··· 32 32 } 33 33 34 34 @override 35 - Future<Uint8List> renderVideo(RenderVideoModel model) { 35 + Future<Uint8List> renderVideo(VideoRenderData model) { 36 36 return ProVideoEditor.instance.renderVideo(model); 37 37 } 38 38 39 39 @override 40 - Future<String> renderVideoToFile(String outputPath, RenderVideoModel model) { 40 + Future<String> renderVideoToFile(String outputPath, VideoRenderData model) { 41 41 return ProVideoEditor.instance.renderVideoToFile(outputPath, model); 42 42 } 43 43
+23 -11
lib/src/core/pro_video_editor/ui/video_editor_grounded_page.dart
··· 6 6 import 'package:atproto/core.dart'; 7 7 import 'package:auto_route/auto_route.dart'; 8 8 import 'package:flutter/foundation.dart'; 9 - import 'package:flutter/material.dart'; 9 + import 'package:flutter/material.dart' hide ColorFilter; 10 10 import 'package:get_it/get_it.dart'; 11 11 import 'package:image_picker/image_picker.dart'; 12 12 import 'package:path_provider/path_provider.dart'; ··· 23 23 import 'package:spark/src/core/pro_video_editor/ui/widgets/player/video_fullscreen_preview_page.dart'; 24 24 import 'package:spark/src/core/pro_video_editor/ui/widgets/player/video_player_widget.dart'; 25 25 import 'package:spark/src/core/pro_video_editor/ui/widgets/timeline/video_timeline_state.dart'; 26 - import 'package:video_player/video_player.dart'; 26 + import 'package:video_player/video_player.dart' hide VideoAudioTrack; 27 27 28 28 @RoutePage() 29 29 class VideoEditorGroundedPage extends StatefulWidget { ··· 518 518 } 519 519 } 520 520 521 - final exportModel = RenderVideoModel( 521 + final customAudioPath = await _audioService.safeCustomAudioPath( 522 + customAudioTrack, 523 + ); 524 + 525 + final exportModel = VideoRenderData( 522 526 id: _taskId, 523 - video: _video, 527 + videoSegments: [VideoSegment(video: _video, volume: originalVolume)], 524 528 outputFormat: _outputFormat, 525 529 enableAudio: _proVideoController?.isAudioEnabled ?? true, 526 - imageBytes: parameters.layers.isNotEmpty ? parameters.image : null, 530 + imageLayers: parameters.layers.isNotEmpty 531 + ? [ImageLayer(image: EditorLayerImage.memory(parameters.image))] 532 + : null, 527 533 blur: parameters.blur, 528 - colorMatrixList: parameters.colorFilters, 534 + colorFilters: parameters.colorFilters 535 + .map((matrix) => ColorFilter(matrix: matrix)) 536 + .toList(), 529 537 startTime: parameters.startTime, 530 538 endTime: parameters.endTime, 531 539 transform: _buildExportTransform(parameters), 532 540 bitrate: _videoMetadata.bitrate, 533 - customAudioPath: await _audioService.safeCustomAudioPath( 534 - customAudioTrack, 535 - ), 536 - originalAudioVolume: originalVolume, 537 - customAudioVolume: overlayVolume, 541 + audioTracks: customAudioPath != null 542 + ? [ 543 + VideoAudioTrack( 544 + path: customAudioPath, 545 + volume: overlayVolume, 546 + loop: true, 547 + ), 548 + ] 549 + : const [], 538 550 ); 539 551 540 552 final now = DateTime.now().millisecondsSinceEpoch;
+33 -18
pubspec.lock
··· 61 61 dependency: "direct main" 62 62 description: 63 63 name: app_badge_plus 64 - sha256: ce3d8fdfcf39a1552cc8dea499ee3b4a86273ccf04c8de29e7960c739b045ae6 64 + sha256: "81130fe6150ce2a1f12af4bb7d6f646496d284d5f87f2c121af8258a453bbb3f" 65 65 url: "https://pub.dev" 66 66 source: hosted 67 - version: "1.2.7" 67 + version: "1.2.8" 68 68 archive: 69 69 dependency: transitive 70 70 description: ··· 779 779 dependency: transitive 780 780 description: 781 781 name: flutter_widget_from_html_core 782 - sha256: "1120ee6ed3509ceff2d55aa6c6cbc7b6b1291434422de2411b5a59364dd6ff03" 782 + sha256: "7ff010b116f6abc16429923e616fbc727f3f65ef4cee12ffdb280aeecbc21e7f" 783 783 url: "https://pub.dev" 784 784 source: hosted 785 - version: "0.17.0" 785 + version: "0.17.2" 786 786 freezed: 787 787 dependency: "direct main" 788 788 description: ··· 867 867 dependency: transitive 868 868 description: 869 869 name: hotreloader 870 - sha256: bc167a1163807b03bada490bfe2df25b0d744df359227880220a5cbd04e5734b 870 + sha256: "66871df468fc24eee81f1a0a7cb98acc104716f9b7376d355437b48d633c4ebf" 871 871 url: "https://pub.dev" 872 872 source: hosted 873 - version: "4.3.0" 873 + version: "4.4.0" 874 874 html: 875 875 dependency: transitive 876 876 description: ··· 923 923 dependency: transitive 924 924 description: 925 925 name: image_picker_android 926 - sha256: "9eae0cbd672549dacc18df855c2a23782afe4854ada5190b7d63b30ee0b0d3fd" 926 + sha256: "66810af8e99b2657ee98e5c6f02064f69bb63f7a70e343937f70946c5f8c6622" 927 927 url: "https://pub.dev" 928 928 source: hosted 929 - version: "0.8.13+15" 929 + version: "0.8.13+16" 930 930 image_picker_for_web: 931 931 dependency: transitive 932 932 description: ··· 999 999 url: "https://pub.dev" 1000 1000 source: hosted 1001 1001 version: "1.0.5" 1002 + jni: 1003 + dependency: transitive 1004 + description: 1005 + name: jni 1006 + sha256: c2230682d5bc2362c1c9e8d3c7f406d9cbba23ab3f2e203a025dd47e0fb2e68f 1007 + url: "https://pub.dev" 1008 + source: hosted 1009 + version: "1.0.0" 1010 + jni_flutter: 1011 + dependency: transitive 1012 + description: 1013 + name: jni_flutter 1014 + sha256: "8b59e590786050b1cd866677dddaf76b1ade5e7bc751abe04b86e84d379d3ba6" 1015 + url: "https://pub.dev" 1016 + source: hosted 1017 + version: "1.0.1" 1002 1018 json_annotation: 1003 1019 dependency: "direct main" 1004 1020 description: ··· 1211 1227 dependency: transitive 1212 1228 description: 1213 1229 name: path_provider_android 1214 - sha256: "149441ca6e4f38193b2e004c0ca6376a3d11f51fa5a77552d8bd4d2b0c0912ba" 1230 + sha256: "914a07484c4380e572998d30486e77e0d9cd2faec72fee268086d07bf7f302c9" 1215 1231 url: "https://pub.dev" 1216 1232 source: hosted 1217 - version: "2.2.23" 1233 + version: "2.3.0" 1218 1234 path_provider_foundation: 1219 1235 dependency: transitive 1220 1236 description: ··· 1315 1331 dependency: "direct main" 1316 1332 description: 1317 1333 name: pro_image_editor 1318 - sha256: d7d06e085edb1b97e17bd7a47ae9d1cb86bf12179a67480bbcc870642bd98824 1334 + sha256: c10a89dfc14ead9cc53f70944d238100b129d40b10038ef7eddae98b1698a8c3 1319 1335 url: "https://pub.dev" 1320 1336 source: hosted 1321 - version: "12.0.13" 1337 + version: "12.1.0" 1322 1338 pro_video_editor: 1323 1339 dependency: "direct main" 1324 1340 description: 1325 - path: "." 1326 - ref: dev 1327 - resolved-ref: f8c4678fe76ad8984fc03eeb0e1a45f6359fdc5b 1328 - url: "https://github.com/sprksocial/pro_video_editor.git" 1329 - source: git 1330 - version: "0.3.0" 1341 + name: pro_video_editor 1342 + sha256: "7bf4148a9bd2c6383bea1a36a01ff5099087b964ebaeaa56278cc7a4decc0566" 1343 + url: "https://pub.dev" 1344 + source: hosted 1345 + version: "1.14.3" 1331 1346 pub_semver: 1332 1347 dependency: transitive 1333 1348 description:
+2 -5
pubspec.yaml
··· 2 2 description: "Spark mobile app" 3 3 publish_to: "none" 4 4 # The number after + should stay fixed, the android workflow will change it on every build 5 - version: 0.10.0+1 5 + version: 0.10.1+1 6 6 environment: 7 7 sdk: ^3.11.0 8 8 workspace: ··· 57 57 pool: ^1.5.2 58 58 posthog_flutter: ^5.23.0 59 59 pro_image_editor: ^12.0.13 60 - pro_video_editor: 61 - git: 62 - url: https://github.com/sprksocial/pro_video_editor.git 63 - ref: dev 60 + pro_video_editor: 1.14.3 64 61 riverpod_annotation: ^4.0.2 65 62 share_plus: ^12.0.2 66 63 shared_preferences: ^2.5.5