{"id":13551467,"url":"https://github.com/LeGoffMael/video_editor","last_synced_at":"2025-04-03T01:33:09.042Z","repository":{"id":39059584,"uuid":"322992343","full_name":"LeGoffMael/video_editor","owner":"LeGoffMael","description":"A flutter package for editing video written in pure Dart with fully customizable UI. Supports crop, trim, rotation and cover selection.","archived":false,"fork":false,"pushed_at":"2024-08-07T12:03:12.000Z","size":43568,"stargazers_count":397,"open_issues_count":35,"forks_count":236,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-10-27T09:04:14.012Z","etag":null,"topics":["crop","flutter","package","trimmer","video","video-editor"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/video_editor","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LeGoffMael.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-20T04:24:28.000Z","updated_at":"2024-10-26T01:59:14.000Z","dependencies_parsed_at":"2023-12-16T20:08:52.032Z","dependency_job_id":"37b0938b-d571-4903-b5e3-4e1e157592b5","html_url":"https://github.com/LeGoffMael/video_editor","commit_stats":{"total_commits":396,"total_committers":15,"mean_commits":26.4,"dds":0.5555555555555556,"last_synced_commit":"c25300f0fd2a461ab2555809d46f0dc6f5ac035b"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LeGoffMael%2Fvideo_editor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LeGoffMael%2Fvideo_editor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LeGoffMael%2Fvideo_editor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LeGoffMael%2Fvideo_editor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LeGoffMael","download_url":"https://codeload.github.com/LeGoffMael/video_editor/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222675047,"owners_count":17021191,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["crop","flutter","package","trimmer","video","video-editor"],"created_at":"2024-08-01T12:01:48.844Z","updated_at":"2025-04-03T01:33:09.018Z","avatar_url":"https://github.com/LeGoffMael.png","language":"Dart","funding_links":[],"categories":["Dart","Components"],"sub_categories":["Media"],"readme":"# Flutter video editor\n\n[![Pub](https://img.shields.io/pub/v/video_editor.svg)](https://pub.dev/packages/video_editor)\n[![GitHub stars](https://img.shields.io/github/stars/LeGoffMael/video_editor?style=social)](https://github.com/LeGoffMael/video_editor/stargazers)\n\nA video editor that allows to edit (trim, crop, rotate and scale) and choose a cover with a very flexible UI design.\n\nThe library provides some tools to execute the exportation but does not handle it.\n\nThis library is written in Dart only but uses external packages such as [video_thumbnail](https://pub.dev/packages/video_thumbnail), which makes it available only on iOS and Android plaforms for now ([web support is currently in progress](https://github.com/LeGoffMael/video_editor/pull/147)).\n\n\u003e **Note**\n\u003e If you use a version between (1.2.3 and 2.4.0) your project might be subject to a GPL license.\n\n|             | Android | iOS   |\n|-------------|---------|-------|\n| **Support** | SDK 16+ | 11.0+ |\n\n## 📖 Installation\n\nFollowing steps will help you add this library as a dependency in your flutter project.\n\n- Run `flutter pub add video_editor`, or add video_editor to `pubspec.yaml` file manually.\n\n```yaml\ndependencies:\n  video_editor: ^2.4.0\n```\n\n- Import the package in your code:\n\n```dart\nimport 'package:video_editor/video_editor.dart';\n```\n\n## 📸 Screenshots\n\n| Example app running on an Iphone 11 pro | Customization example, light mode |\n| --------------------------------------- | --------------------------------- |\n| ![](./assets/demo.gif)                  | ![](./assets/light_editor.png)    |\n\n## 👀 Usage\n\n```dart\nfinal VideoEditorController _controller = VideoEditorController.file(\n  File('/path/to/video.mp4'),\n  minDuration: const Duration(seconds: 1),\n  maxDuration: const Duration(seconds: 10),\n);\n\n@override\nvoid initState() {\n  super.initState();\n  _controller.initialize().then((_) =\u003e setState(() {}));\n}\n\n@override\nvoid dispose() {\n  _controller.dispose();\n  super.dispose();\n}\n\n/// Basic export video function\nFuture\u003cvoid\u003e exportVideo() async {\n  final config = VideoFFmpegVideoEditorConfig(_controller);\n  // Returns the generated command and the output path\n  final FFmpegVideoEditorExecute execute = await config.getExecuteConfig();\n\n  // ... handle the video exportation yourself, using ffmpeg_kit_flutter, your own video server, ...\n}\n\n/// Export the video as a GIF image\nFuture\u003cvoid\u003e exportGif() async {\n  final gifConfig = VideoFFmpegVideoEditorConfig(\n    _controller,\n    format: VideoExportFormat.gif,\n  );\n  // Returns the generated command and the output path\n  final FFmpegVideoEditorExecute gifExecute = await gifConfig.getExecuteConfig();\n\n  // ...\n}\n\n/// Export a video, with custom command (ultrafast preset + horizontal flip)\nFuture\u003cvoid\u003e exportMirroredVideo() async {\n  final mirrorConfig = VideoFFmpegVideoEditorConfig(\n      _controller,\n      name: 'mirror-video'\n      commandBuilder: (VideoFFmpegVideoEditorConfig config, String videoPath, String outputPath) {\n        final List\u003cString\u003e filters = config.getExportFilters();\n        filters.add('hflip'); // add horizontal flip\n\n        return '-i $videoPath ${config.filtersCmd(filters)} -preset ultrafast $outputPath';\n      },\n    );\n  // Returns the generated command and the output path\n  final FFmpegVideoEditorExecute mirrorExecute = await mirrorConfig.getExecuteConfig();\n\n  // ...\n}\n```\n\nFor more details check out the [example](https://github.com/LeGoffMael/video_editor/tree/master/example).\n\n### VideoEditorController\n\n| Function                         | Description                       |\n| -------------------------------- | --------------------------------- |\n| initialize(double? aspectRatio)  | Init the `controller` parameters, the video, the trim and the cover, call `cropAspectRatio` |\n| rotate90Degrees(RotateDirection) | Rotate the video by 90 degrees in the direction provided            |\n| setPreferredRatioFromCrop        | Update the aspect ratio to the current crop area ratio              |\n| cropAspectRatio(double?)         | Update the aspect ratio + update the crop area to the center of the video size |\n| updateCrop(Offset, Offset)       | Update the controller crop min and max values                       |\n| applyCacheCrop                   | Update the controller crop min and max values with cache values     |\n| updateTrim(double, double)       | Update the controller trim min and max values                       |\n\n| Getter                           | Description                       |\n| -------------------------------- | --------------------------------- |\n| Duration startTrim               | The start value of the trimmed area |\n| Duration endTrim                 | The end value of the trimmed area |\n| Duration trimmedDuration         | The duration of the selected trimmed area |\n| bool isTrimmed                   | Set to `true` when the trimmed values are not the default video duration |\n| bool isTrimming                  | Set to `true` when startTrim or endTrim is changing |\n| Duration maxDuration             | The maxDuration possible for the trimmed area |\n| Duration minDuration             | The minDuration possible for the trimmed area |\n| Offset minCrop                   | The top left position of the crop area (between `0.0` and `1.0`) |\n| Offset maxCrop                   | The bottom right position of the crop area (between `0.0` and `1.0`) |\n| Size croppedArea                 | The actual Size of the crop area |\n| double? preferredCropAspectRatio | The preferred crop aspect ratio selected |\n| bool isRotated                   | Set to `true` when the rotation is different to `0` |\n| int rotation                     | The rotation angle set `0`, `90`, `180` and `270` |\n| int cacheRotation                | The sum of all the rotation applied in the editor |\n| CoverData? selectedCoverVal      | The selected cover thumbnail that will be used to export the final cover |\n| int coverThumbnailsQuality = 10  | The `coverThumbnailsQuality` param specifies the quality of the generated cover thumbnails, from 0 to 100 ([more info](https://pub.dev/packages/video_thumbnail)) |\n| int trimThumbnailsQuality = 10   | The `trimThumbnailsQuality` param specifies the quality of the generated trim slider thumbnails, from 0 to 100 ([more info](https://pub.dev/packages/video_thumbnail)) |\n\n\n### Widgets\n\n\u003cdetails\u003e\n  \u003csummary\u003eClick to expand widgets documentation\u003c/summary\u003e\n\n####  Crop\n##### 1. CropGridViewer\n\nThis widget is used to enable the crop actions on top of the video (CropGridViewer.edit), or only to preview the cropped result (CropGridViewer.preview).\n\n| Param                            | Description                       |\n| -------------------------------- | --------------------------------- |\n| required VideoEditorController controller | The `controller` param is mandatory so every change in the controller settings will propagate in the crop view |\n| EdgeInsets margin | The amount of space by which to inset the crop view, not used in preview mode |\n| bool rotateCropArea | To preserve `preferredCropAspectRatio` when crop view is rotated |\n\n#### Trimmer\n\n##### 1. TrimSlider\n\nDisplay the trimmer containing video thumbnails with rotation and crop parameters.\n\n| Param                            | Description                       |\n| -------------------------------- | --------------------------------- |\n| required VideoEditorController controller | The `controller` param is mandatory so every change in the controller settings will propagate in the trim slider view |\n| double height = 0.0 | The `height` param specifies the height of the generated thumbnails |\n| double horizontalMargin = 0.0 | The `horizontalMargin` param specifies the horizontal space to set around the slider. It is important when the trim can be dragged (`controller.maxDuration` \u003c `controller.videoDuration`) |\n| Widget? child | The `child` param can be specify to display a widget below this one (e.g: TrimTimeline) |\n| bool hasHaptic = true | The `hasHaptic` param specifies if haptic feed back can be triggered when the trim touch an edge (left or right) |\n| double maxViewportRatioo = 2.5 | The `maxViewportRatio` param specifies the upper limit of the view ratio |\n| ScrollController? scrollController | The `scrollController` param specifies the scroll controller to use for the trim slider view |\n\n##### 2. TrimTimeline\n\nDisplay the video timeline.\n\n| Param                            | Description                       |\n| -------------------------------- | --------------------------------- |\n| required VideoEditorController controller | The `controller` param is mandatory so depending on the `controller.maxDuration`, the generated timeline will be different |\n| double quantity = 8 | Expected `quantity` of elements shown in the timeline |\n| EdgeInsets padding = EdgeInsets.zero | The `padding` param specifies the space surrounding the timeline |\n| String localSeconds = 's' | The String to represents the seconds to show next to each timeline element |\n| TextStyle? textStyle | The TextStyle to use to style the timeline text |\n\n#### Cover\n##### 1. CoverSelection\n\nDisplay a couple of generated covers with rotation and crop parameters to updated the selected cover.\n\n| Param                            | Description                       |\n| -------------------------------- | --------------------------------- |\n| required VideoEditorController controller | The `controller` param is mandatory so every change in the controller settings will propagate in the cover selection view |\n| double size = 0.0 | The `size` param specifies the max size of the generated thumbnails |\n| double horizontalMargin = 0.0 | The `horizontalMargin` param need to be specify when there is a margin outside the crop view, so in case of a change the new layout can be computed properly. |\n| int quantity = 5 | The `quantity` param specifies the quantity of thumbnails to generate |\n| Wrap? wrap | The `wrap` widget to use to customize the thumbnails wrapper |\n| Function? selectedCoverBuilder | To returns how the selected cover should be displayed |\n\n##### 2. CoverViewer\n\nDisplay the selected cover with rotation and crop parameters.\n\n| Param                            | Description                       |\n| -------------------------------- | --------------------------------- |\n| required VideoEditorController controller | The `controller` param is mandatory so every change in the controller settings will propagate the crop parameters in the cover view |\n| String noCoverText = 'No selection' | The `noCoverText` param specifies the text to display when selectedCover is `null` |\n\n\u003c/details\u003e\n\n### Style\n\n\u003cdetails\u003e\n  \u003csummary\u003eClick to expand style documentation\u003c/summary\u003e\n\n#### 1. CropStyle\n\nYou can create your own CropStyle class to customize the CropGridViewer appareance.\n\n| Param                            | Description                       |\n| -------------------------------- | --------------------------------- |\n| Color croppingBackground = Colors.black.withOpacity(0.48) | The `croppingBackground` param specifies the color of the paint area outside the crop area when copping |\n| Color background = Colors.black | The `background` param specifies the color of the paint area outside the crop area when not copping |\n| double gridLineWidth = 1 | The `gridLineWidth` param specifies the width of the crop lines |\n| Color gridLineColor = Colors.white | The `gridLineColor` param specifies the color of the crop lines |\n| int gridSize = 3 | The `gridSize` param specifies the quantity of columns and rows in the crop view |\n| Color boundariesColor = Colors.white | The `boundariesColor` param specifies the color of the crop area's corner |\n| Color selectedBoundariesColor = kDefaultSelectedColor | The `selectedBoundariesColor` param specifies the color of the selected crop area's corner |\n| double boundariesLength = 20 | The `boundariesLength` param specifies the length of the crop area's corner |\n| double boundariesWidth = 5 | The `boundariesWidth` param specifies the width of the crop area's corner |\n\n#### 2. TrimStyle\n\nYou can create your own TrimStyle class to customize the TrimSlider appareance.\n\n| Param                            | Description                       |\n| -------------------------------- | --------------------------------- |\n| Color background = Colors.black.withOpacity(0.6) | The `background` param specifies the color of the paint area outside the trimmed area |\n| Color positionLineColor = Colors.red | The `positionLineColor` param specifies the color of the line showing the video position |\n| double positionLineWidth = 2 | The `positionLineWidth` param specifies the width  of the line showing the video position |\n| Color lineColor = Colors.white | The `lineColor` param specifies the color of the borders around the trimmed area |\n| Color onTrimmingColor = kDefaultSelectedColor | The `onTrimmingColor` param specifies the color of the borders around the trimmed area while it is getting trimmed |\n| Color onTrimmedColor = kDefaultSelectedColor | The `onTrimmedColor` param specifies the color of the borders around the trimmed area when the trimmed parameters are not default values |\n| double lineWidth = 2 | The `lineWidth` param specifies the width of the borders around the trimmed area |\n| TrimSliderEdgesType borderRadius = 5 | The `borderRadius` param specifies the border radius around the trimmer |\n| double edgesType = TrimSliderEdgesType.bar | The `edgesType` param specifies the style to apply to the edges (left \u0026 right) of the trimmer |\n| double edgesSize | The `edgesSize` param specifies the size of the edges behind the icons |\n| Color iconColor = Colors.black | The `iconColor` param specifies the color of the icons on the trimmed area's edges |\n| double iconSize = 25 | The `iconSize` param specifies the size of the icon on the trimmed area's edges |\n| IconData? leftIcon = Icons.arrow_left | The `leftIcon` param specifies the icon to show on the left edge of the trimmed area |\n| IconData? rightIcon = Icons.arrow_right | The `rightIcon` param specifies the icon to show on the right edge of the trimmed area |\n\n### 3. CoverStyle\n\nYou can create your own CoverStyle class to customize the CoverSelection appareance.\n\n| Param                            | Description                       |\n| -------------------------------- | --------------------------------- |\n| Color selectedBorderColor = Colors.white | The `selectedBorderColor` param specifies the color of the border around the selected cover thumbnail |\n| double borderWidth = 2 | The `borderWidth` param specifies the width of the border around each cover thumbnails |\n| double borderRadius = 5.0 | The `borderRadius` param specifies the border radius of each cover thumbnail |\n\n\u003c/details\u003e\n\n#### Export\n\n#### 1. FFmpegVideoEditorConfig\n\n| Param                            | Description                       |\n| -------------------------------- | --------------------------------- |\n| String? name | The `name` param specifies the filename of the generated file |\n| String? outputDirectory | The `outputDirectory` param specifies where the file should be generated, default to temporary directory |\n| double scale = 1 | The `scale` param is used to increase or decrease the generated file dimensions |\n| bool isFiltersEnabled = true | The `isFiltersEnabled` param specifies if the editor parameters should be applied |\n\n#### 2. VideoFFmpegVideoEditorConfig\n\nContains all FFmpegVideoEditorConfig parameters.\n\n| Param                            | Description                       |\n| -------------------------------- | --------------------------------- |\n| VideoExportFormat format = VideoExportFormat.mp4 | The `format` param specifies the extension of the generated video |\n| String Function? commandBuilder | The `commandBuilder` param can be used to generate a command with custom options |\n\n#### 3. CoverFFmpegVideoEditorConfig\n\nContains all FFmpegVideoEditorConfig parameters.\n\n| Param                            | Description                       |\n| -------------------------------- | --------------------------------- |\n| CoverExportFormat format = CoverExportFormat.jpg | The `format` param specifies the extension of the generated cover |\n| int quality = 100 | The `quality` param specifies the quality of the generated thumbnails, from 0 to 100 ([more info](https://pub.dev/packages/video_thumbnail)) |\n| String Function? commandBuilder | The `commandBuilder` param can be used to generate a command with custom options |\n\n## 💭 FAQ\n\n### 1. Why was FFmpeg removed from this package ?\n\nStarting from version 3.0.0, the video_editor package no longer includes [ffmpeg_kit_flutter](https://pub.dev/packages/ffmpeg_kit_flutter).\n\n - The inclusion of ffmpeg_kit_flutter binary in this package caused numerous issues for users who intended to utilize a different instance of FFmpeg within the same project (#37, #129, #153).\n - Additionally, it came to my attention that the video_editor package may have been mis-licensed and subject to the GPL v3.0 license since version 1.2.3, when it began utilizing the ffmpeg_kit_flutter_min_kit binary.\n - Lastly, the FFmpeg package is quite large and significantly increases the app size, which is not ideal for developers seeking to handle exportation in a different way.\n\n## ✨ Credit\n\nMany thanks to [seel-channel](https://github.com/seel-channel) who is the original creator of this library.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLeGoffMael%2Fvideo_editor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FLeGoffMael%2Fvideo_editor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLeGoffMael%2Fvideo_editor/lists"}