Giter VIP home page Giter VIP logo

video_trimmer's Introduction

Awesome Flutter Pub Version GitHub stars GitHub license

Video Trimmer

A Flutter package for trimming videos

Features

  • Customizable video trimmer.
  • Supports two types of trim viewer, fixed length and scrollable.
  • Video playback control.
  • Retrieving and storing video file.

Also, supports conversion to GIF.

NOTE: Versions 3.0.0 and above uses the "Full" version of Flutter FFmpeg. To install the "LTS" version, use the "x.x.x-LTS" version of this package.

Following image shows the structure of the TrimViewer. It consists of the Duration on top (displaying the start, end, and scrubber time), TrimArea consisting of the thumbnails, and TrimEditor which is an overlay that let's you select a portion from the video.

Example

The example app running on an iPhone 13 Pro device:

Trimmer

Usage

Add the dependency video_trimmer to your pubspec.yaml file:

For using main version of FFmpeg package:

dependencies:
  video_trimmer: ^3.0.0

For using LTS version of FFmpeg package:

dependencies:
  video_trimmer: ^3.0.0-LTS

Android configuration

No additional configuration is needed for using on Android platform. You are good to go!

iOS configuration

  • Add the following keys to your Info.plist file, located in <project root>/ios/Runner/Info.plist:
    <key>NSCameraUsageDescription</key>
    <string>Used to demonstrate image picker plugin</string>
    <key>NSMicrophoneUsageDescription</key>
    <string>Used to capture audio for image picker plugin</string>
    <key>NSPhotoLibraryUsageDescription</key>
    <string>Used to demonstrate image picker plugin</string>
    

FFmpeg Release

This package supports both Main and LTS version of the FFmpeg implementation.

Main Release LTS Release
Android API Level 24 16
Android Camera Access Yes -
Android Architectures arm-v7a-neon
arm64-v8a
x86
x86-64
arm-v7a
arm-v7a-neon
arm64-v8a
x86
x86-64
iOS Min SDK 12.1 10
iOS Architectures arm64
arm64-simulator
arm64-mac-catalyst
x86-64
x86-64-mac-catalyst
armv7
arm64
i386
x86-64

Functionalities

Loading input video file

final Trimmer _trimmer = Trimmer();
await _trimmer.loadVideo(videoFile: file);

Saving trimmed video

Returns a string to indicate whether the saving operation was successful.

await _trimmer
    .saveTrimmedVideo(startValue: _startValue, endValue: _endValue)
    .then((value) {
  setState(() {
    _value = value;
  });
});

Video playback state

Returns the video playback state. If true then the video is playing, otherwise it is paused.

await _trimmer.videoPlaybackControl(
  startValue: _startValue,
  endValue: _endValue,
);

Advanced Command

You can use an advanced FFmpeg command if you require more customization. Just define your FFmpeg command using the ffmpegCommand property and set an output video format using customVideoFormat.

Refer to the Official FFmpeg Documentation for more information.

NOTE: Passing a wrong video format to the customVideoFormat property may result in a crash.

// Example of defining a custom command

// This is already used for creating GIF by
// default, so you do not need to use this.

await _trimmer
    .saveTrimmedVideo(
        startValue: _startValue,
        endValue: _endValue,
        ffmpegCommand:
            '-vf "fps=10,scale=480:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0',
        customVideoFormat: '.gif')
    .then((value) {
  setState(() {
    _value = value;
  });
});

Widgets

Display a video playback area

VideoViewer(trimmer: _trimmer)

Display the video trimmer area

TrimViewer(
  trimmer: _trimmer,
  viewerHeight: 50.0,
  viewerWidth: MediaQuery.of(context).size.width,
  maxVideoLength: const Duration(seconds: 10),
  onChangeStart: (value) => _startValue = value,
  onChangeEnd: (value) => _endValue = value,
  onChangePlaybackState: (value) =>
      setState(() => _isPlaying = value),
)

Example

Before using this example directly in a Flutter app, don't forget to add the video_trimmer & file_picker packages to your pubspec.yaml file.

You can try out this example by replacing the entire content of main.dart file of a newly created Flutter project.

import 'dart:io';

import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:video_trimmer/video_trimmer.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Video Trimmer',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Video Trimmer"),
      ),
      body: Center(
        child: Container(
          child: ElevatedButton(
            child: Text("LOAD VIDEO"),
            onPressed: () async {
              FilePickerResult? result = await FilePicker.platform.pickFiles(
                type: FileType.video,
                allowCompression: false,
              );
              if (result != null) {
                File file = File(result.files.single.path!);
                Navigator.of(context).push(
                  MaterialPageRoute(builder: (context) {
                    return TrimmerView(file);
                  }),
                );
              }
            },
          ),
        ),
      ),
    );
  }
}

class TrimmerView extends StatefulWidget {
  final File file;

  TrimmerView(this.file);

  @override
  _TrimmerViewState createState() => _TrimmerViewState();
}

class _TrimmerViewState extends State<TrimmerView> {
  final Trimmer _trimmer = Trimmer();

  double _startValue = 0.0;
  double _endValue = 0.0;

  bool _isPlaying = false;
  bool _progressVisibility = false;

  Future<String?> _saveVideo() async {
    setState(() {
      _progressVisibility = true;
    });

    String? _value;

    await _trimmer
        .saveTrimmedVideo(startValue: _startValue, endValue: _endValue)
        .then((value) {
      setState(() {
        _progressVisibility = false;
        _value = value;
      });
    });

    return _value;
  }

  void _loadVideo() {
    _trimmer.loadVideo(videoFile: widget.file);
  }

  @override
  void initState() {
    super.initState();

    _loadVideo();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Video Trimmer"),
      ),
      body: Builder(
        builder: (context) => Center(
          child: Container(
            padding: EdgeInsets.only(bottom: 30.0),
            color: Colors.black,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              mainAxisSize: MainAxisSize.max,
              children: <Widget>[
                Visibility(
                  visible: _progressVisibility,
                  child: LinearProgressIndicator(
                    backgroundColor: Colors.red,
                  ),
                ),
                ElevatedButton(
                  onPressed: _progressVisibility
                      ? null
                      : () async {
                          _saveVideo().then((outputPath) {
                            print('OUTPUT PATH: $outputPath');
                            final snackBar = SnackBar(
                                content: Text('Video Saved successfully'));
                            ScaffoldMessenger.of(context).showSnackBar(
                              snackBar,
                            );
                          });
                        },
                  child: Text("SAVE"),
                ),
                Expanded(
                  child: VideoViewer(trimmer: _trimmer),
                ),
                Center(
                  child: TrimViewer(
                    trimmer: _trimmer,
                    viewerHeight: 50.0,
                    viewerWidth: MediaQuery.of(context).size.width,
                    maxVideoLength: const Duration(seconds: 10),
                    onChangeStart: (value) => _startValue = value,
                    onChangeEnd: (value) => _endValue = value,
                    onChangePlaybackState: (value) =>
                        setState(() => _isPlaying = value),
                  ),
                ),
                TextButton(
                  child: _isPlaying
                      ? Icon(
                          Icons.pause,
                          size: 80.0,
                          color: Colors.white,
                        )
                      : Icon(
                          Icons.play_arrow,
                          size: 80.0,
                          color: Colors.white,
                        ),
                  onPressed: () async {
                    bool playbackState = await _trimmer.videoPlaybackControl(
                      startValue: _startValue,
                      endValue: _endValue,
                    );
                    setState(() {
                      _isPlaying = playbackState;
                    });
                  },
                )
              ],
            ),
          ),
        ),
      ),
    );
  }
}

Troubleshooting LTS version

While running on the Android platform if it gives an error that the minSdkVersion needs to be 24, or on iOS platform that the Podfile platform version should be 11, first go to pubspec.lock file and see if the version of ffmpeg_kit_flutter has -LTS suffix. This should fix all issues for iOS platform.

On Android, if you still face the same issue, try adding the following to the <project_directory>/android/app/src/main/AndroidManifest.xml:

<manifest xmlns:tools="http://schemas.android.com/tools" ....... >
    <uses-sdk tools:overrideLibrary="com.arthenica.ffmpegkit.flutter, com.arthenica.ffmpegkit" />
</manifest>

License

Copyright (c) 2023 Souvik Biswas

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

video_trimmer's People

Contributors

arjanaswal avatar domliang avatar farmery avatar jonasn5 avatar phil9l avatar sbis04 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

video_trimmer's Issues

Working in debug mode but shows grey screen in profile and release mode

#37 The referenced issue had the same problem. I am running oreo on phone.
I suspect there is some codec issues with ExoPlayer, please look into as I really like the video_trimmer and need it in my app.
I am attaching output of the error that I am getting and of flutter doctor.

I/ExoPlayerImpl(23828): Init f6a6995 [ExoPlayerLib/2.9.6] [OnePlus5, ONEPLUS A5000, OnePlus, 27]
I/MediaCodec(23828): name: OMX.qcom.video.decoder.avc
I/OMXClient(23828): Treble IOmx obtained
I/MediaCodec(23828): configure format is :{csd-1=java.nio.HeapByteBuffer[pos=0 lim=9 cap=9], max-height=640, max-width=288, mime=video/avc, width=288, priority=0, rotation-degrees=0, max-input-size=17706, height=640, csd-0=java.nio.HeapByteBuffer[pos=0 lim=21 cap=21]}
D/SurfaceUtils(23828): connecting to surface 0x75a3042010, reason connectToSurface
I/MediaCodec(23828): [OMX.qcom.video.decoder.avc] setting surface generation to 24399875
D/SurfaceUtils(23828): disconnecting from surface 0x75a3042010, reason connectToSurface(reconnect)
D/SurfaceUtils(23828): connecting to surface 0x75a3042010, reason connectToSurface(reconnect)
I/ExtendedACodec(23828): setupVideoDecoder()
I/ExtendedACodec(23828): Decoder will be in frame by frame mode
I/MediaCodec(23828): start
D/SurfaceUtils(23828): set up nativeWindow 0x75a3042010 for 288x640, color 0x7fa30c06, rotation 0, usage 0x20002900

Flutter doctor

[✓] Flutter (Channel stable, 1.20.2, on Microsoft Windows [Version 10.0.19041.450], locale en-IN)
    • Flutter version 1.20.2 at C:\flutter
    • Framework revision bbfbf1770c (12 days ago), 2020-08-13 08:33:09 -0700
    • Engine revision 9d5b21729f
    • Dart version 2.9.1


[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
    • Android SDK at C:\Users\rithi\AppData\Local\Android\Sdk
    • Platform android-29, build-tools 29.0.3
    • ANDROID_HOME = C:\Users\rithi\AppData\Local\Android\Sdk
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
    • All Android licenses accepted.

[✓] Android Studio (version 4.0)
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin version 48.1.2
    • Dart plugin version 193.7361
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)

[✓] VS Code (version 1.48.1)
    • VS Code at C:\Users\rithi\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension version 3.13.2

[✓] Connected device (1 available)
    • ONEPLUS A5000 (mobile) • 26b5c3ff • android-arm64 • Android 8.1.0 (API 27)

• No issues found!

crashing app

i am not able to run this package in minsdklevel 16

Profile Mode Error

This plugin works perfectly for me when i am in debug mode, but in profile mode the is an error, widgets do not display, just a blank grey screen

### Debug Mode
WhatsApp Image 2020-07-23 at 12 46 17 PM

### Profile Mode
WhatsApp Image 2020-07-23 at 12 49 55 PM

Profile modes of an app depicts the release mode perfomance, just wondering if this issue will be in the app when released

Execution failed for task ':app:transformClassesWithMultidexlistForRelease

Description
i tried

ext.flutterFFmpegPackage = 'min-lts'.

defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "{///}"
minSdkVersion 16
targetSdkVersion 28
multiDexEnabled true
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so flutter run --release works.
signingConfig signingConfigs.release
minifyEnabled true
multiDexKeepProguard file('multidex-config.pro')
}

org.gradle.jvmargs=-{something}
android.enableJetifier=true
android.useAndroidX=true
android.enableR8=false
  also tried  android.enableR8=true

Error:

Users/mac/Documents/FlutterProjects/droopy/android/app/multidex-config.pro: D8: Failed to read file:
/Users/mac/Documents/FlutterProjects/droopy/android/app/multidex-config.pro
[ +1 ms] FAILURE: Build failed with an exception.
[ ] * What went wrong:
[ ] Execution failed for task ':app:transformClassesWithMultidexlistForRelease'.
[ ] > com.android.build.api.transform.TransformException: Error while generating the main dex list:
[ ] Error while merging dex archives:
[ ] * Try:
[ ] Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with
--scan to get full insights.
[ +2 ms] * Get more help at https://help.gradle.org
[ ] BUILD FAILED in 10m 51s
[ +707 ms] Running Gradle task 'assembleRelease'... (completed in 668.8s, longer than expected)
[ +14 ms] The built failed likely due to AndroidX incompatibilities in a plugin. The tool is about to try using Jetfier to solve
the
incompatibility.
[ +155 ms] Building plugin cloud_firestore...
[ +34 ms] Running Gradle task 'assembleAarRelease'...
[ +61 ms] "flutter apk" took 675,343ms.
[ +11 ms] The plugin cloud_firestore could not be built due to the issue above.
[ ]
#0 throwToolExit (package:flutter_tools/src/base/common.dart:14:3)
#1 buildPluginsAsAar (package:flutter_tools/src/android/gradle.dart:803:7)
#2 _asyncErrorWrapperHelper.errorCallback (dart:async-patch/async_patch.dart:91:64)
#3 _rootRunBinary (dart:async/zone.dart:1214:47)
#4 _CustomZone.runBinary (dart:async/zone.dart:1107:19)
#5 _FutureListener.handleError (dart:async/future_impl.dart:157:20)
#6 Future._propagateToListeners.handleError (dart:async/future_impl.dart:708:47)
#7 Future._propagateToListeners (dart:async/future_impl.dart:729:24)
#8 Future._completeError (dart:async/future_impl.dart:537:5)
#9 Future._asyncCompleteError. (dart:async/future_impl.dart:593:7)
#10 _rootRun (dart:async/zone.dart:1190:13)
#11 _CustomZone.run (dart:async/zone.dart:1093:19)
#12 _CustomZone.runGuarded (dart:async/zone.dart:997:7)
#13 _CustomZone.bindCallbackGuarded. (dart:async/zone.dart:1037:23)
#14 _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
#15 _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
#16 _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:118:13)
#17 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:169:5)

Could not resolve the package 'video_trimmer'

Installed the package, the run pub get then throws this error.

Error: Could not resolve the package 'video_trimmer' in 'package:video_trimmer/video_trimmer.dart'.
lib/editor/video_edit/video_editor.dart:6:8: Error: Not found: 'package:video_trimmer/video_trimmer.dart'
import 'package:video_trimmer/video_trimmer.dart';
^

Any suggestions on how to solve?

Having Issues On iOS Platform 10.0

Facing build issues on iOS platform 10.0, am using the 'full-lts' package.
I get the ff error:

Undefined symbols for architecture armv7:
      "_OBJC_CLASS_$_MobileFFprobe", referenced from:
          objc-class-ref in flutter_ffmpeg(FlutterFfmpegPlugin.o)
      "_OBJC_CLASS_$_MobileFFmpeg", referenced from:
          objc-class-ref in flutter_ffmpeg(FlutterFfmpegPlugin.o)
      "_OBJC_CLASS_$_MobileFFmpegConfig", referenced from:
          objc-class-ref in flutter_ffmpeg(FlutterFfmpegPlugin.o)
      "_OBJC_CLASS_$_ArchDetect", referenced from:
          objc-class-ref in flutter_ffmpeg(FlutterFfmpegPlugin.o)
    ld: symbol(s) not found for architecture armv7
    clang: error: linker command failed with exit code 1 (use -v to see
    invocation)

Readme misleading

Can we remove these lines from readme and just add refer flutter_ffmpeg installation?

  • Replace with the following in the # Plugin Pods section of the ios/Podfile:
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
# referring to absolute paths on developers' machines.

system('rm -rf .symlinks')
system('mkdir -p .symlinks/plugins')
plugin_pods = parse_KV_file('../.flutter-plugins')
plugin_pods.each do |name, path|
  symlink = File.join('.symlinks', 'plugins', name)
  File.symlink(path, symlink)
  if name == 'flutter_ffmpeg'
      pod name+'/<package name>', :path => File.join(symlink, 'ios')
  else
      pod name, :path => File.join(symlink, 'ios')
  end
end

Error creating release iOS

Hi bro. i can use my app on simulator and my device ios and android. but ... i have this error when i try to create a release

flutter build ios --release

Undefined symbols for architecture armv7:
"OBJC_CLASS$_MobileFFprobe", referenced from:
objc-class-ref in flutter_ffmpeg(FlutterFfmpegPlugin.o)
"OBJC_CLASS$_MobileFFmpeg", referenced from:
objc-class-ref in flutter_ffmpeg(FlutterFfmpegPlugin.o)
"OBJC_CLASS$_MobileFFmpegConfig", referenced from:
objc-class-ref in flutter_ffmpeg(FlutterFfmpegPlugin.o)
"OBJC_CLASS$_ArchDetect", referenced from:
objc-class-ref in flutter_ffmpeg(FlutterFfmpegPlugin.o)
ld: symbol(s) not found for architecture armv7

Imagen:

errores

Mis configuraciones:

configurations

Xcode try run archive:

xcode

Thank you!!!!

Thumbnail images of video is not showing correctly?

Hi,When I open videos the thumbnail images that come bottom are not loading correctly?Once the thumbnail loaded and suddenlt they skipped?
Error:This an error shown below:
"getFrameAtTime: videoFrame is a NULL pointer"

App size increased heavily

This is a great plugin, but my app bundle size increased by about 40 mb after adding this package.

Is there a way to reduce this? Or is it something I can't avoid?

flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, v1.17.5, on Mac OS X 10.15.5 19F101, locale en-IN)

[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 11.5)
[✓] Android Studio (version 4.0)
[!] IntelliJ IDEA Community Edition (version 2020.1)
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
[✓] VS Code (version 1.36.1)
[✓] Connected device (1 available)

! Doctor found issues in 1 category.

FYI: Issues Upgrading Packages to ^0.3.4

Hi!

I just wanted to post this incase any other people have issues upgrading their package to the newest version (video_trimmer: ^0.3.4).

When building for Android, I got weird errors like this:
Task 'assembleAarRelease' not found in root project 'cached_video_player'.

Here's what you need to do:

  1. in android/app/build_gradle... make sure you have these versions:
    minSdkVersion 24
    targetSdkVersion 29
    and
    compileSdkVersion 29

  2. in android/build_gradle... upgrade your classpath to:
    classpath 'com.android.tools.build:gradle:4.0.2'

  3. in android/gradle/wrapper/gradle-wrapper.properties change your distribution url to:
    distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip

  4. run flutter clean

  5. delete all data on your android vm and wipe the cache (or make a new device)

  6. Upgrade Flutter
    I'm on:
    Flutter (Channel stable, 1.22.4, on Mac OS X 10.15.2 19C57 darwin-x64, locale en-US)

  7. you might still get some package import conflicts...
    In pubspec.yaml, I ended up having to update the following:
    sdk: ">=2.2.2 <3.0.0"
    and also update some packages like "get".

After doing all this, Android finally compiled.
Hope this helps others with the same issue :)

ffmpg error in your pods

[!] CocoaPods could not find compatible versions for pod "flutter_ffmpeg/https":
In Podfile:
flutter_ffmpeg (from .symlinks/plugins/flutter_ffmpeg/ios) was resolved to 0.3.0, which depends on
flutter_ffmpeg/https (= 0.3.0)

Specs satisfying the flutter_ffmpeg/https (= 0.3.0) dependency were found, but they required a higher minimum deployment target.

Trimmed video first seconds sometimes stuck

Hi!
First of all, I love this new package,
While I was using it, I realized that sometimes the video is stuck in the first few seconds after it was trimmed (but the audio is still playing).
I think that it is because of the FFmpeg command, but I'm not sure and couldn't find the exact reason.

Move whole slider

Hello sir, Please add the functionality to move the whole slider, when the maximum duration is reached.

Set max duration of the video

I am using the video_trimmer for my project. I want to trim the video to maximum 15 secs. By default whenever I select any video it is selected as whole, for example if I select a video of 60 secs the default selected video covers all 60 secs. But I want that even if the source video is a length greater than 15 secs it should select only 15 seconds from the start like the video trimmer in whatsapp which only selects 30 seconds of the video while uploading a video status.
Thanks in advance if you can provide some argument for max length to be selected in TrimEditor class

Not able to set max video duration

Steps to reproduce -

  1. Use imagepicker.pickVideo to select video from file manager
  2. video_player plays the video successfully
  3. Use trimmer to trim the picked video
  4. Save the trimmed video
  5. imagepicker.pickVideo the trimmed video to select the trimmed video now

Observation -

  1. Trimmed video is not initialisating and is not playable in the video_player.

Code to save the video -

await widget._trimmer
        .saveTrimmedVideo(
            startValue: _startValue,
            endValue: _endValue,
            outputFormat: FileFormat.mp4,
            videoFileName: 'Trimmed_${new DateTime.now()}',
            videoFolderName: "Videos/Trimmed",
            storageDir: StorageDir.externalStorageDirectory)
        .then((value) {
      setState(() {
        _progressVisibility = false;
        _value = value;
      });
    });

Please let me know if you need more details on reproducing this issue?
Thanks!

incompatible with flutter_localizations

I get this message when using this library with flutter_localizations.

"Because every version of flutter_localizations from sdk depends on intl 0.16.0 and every version of video_trimmer depends on intl ^0.16.1, flutter_localizations from sdk is incompatible with video_trimmer."

I tried downgrading but didn't work.

iOS force to compress video

Hi there,
In iOS, once a video is selected, the video is compressed before going to trim interface, while this step is skipped in Android.

Any hint to remove this behaviour in iOS? It causes the video being proccessed (compressed) twice resulting bad quality.

TrimEditor Unable to zoom

GestureDetector(
onScaleUpdate: (ScaleUpdateDetails details) {
print("scale ");
setState(() {

                    if( details.scale.clamp(.8, 10.0) == 1) 
                      {
                        return;
                      }
                    _width = 200 * details.scale.clamp(.8, 10.0);
                  });
                  print("scale width "+ _width.toString());
                },
                onScaleEnd: (ScaleEndDetails details) {
                  setState(() {
                  
                  });
                },
                child:  
                  TrimEditor(

TrimEditor initialized with custom start and end value

Hi, great trimmer - I like it.

I'm having a problem. I want to set the default start and end value in the TrimEditor in the constructor so that it is initialized with custom play startValue and endValue of the video. So that it does not play the whole video when loading the video again. I'm saving the trimmed startValue and endValue in database and reading it every time video loads so I can show trimmed sliders according to startValue and endValue. But your TrimEditor does not allow to do that.

Right now it is only possible to change start and end value with the slider, but I would like to have the TrimEditor start with fx. 4000 milisecons to 9000 milliseconds...

So fx. I would like TrimEditor(viewerHeight: 70.0, startDuration: 4000, endDuration 9000, ect.....)

I would really appreciate if you would implement that.

Best regards, Jan

Minimum Android version

Thanks for this great package, it will be very useful for the new trends related to Videos.

I would like to know why the minimum version of Android is 24?

I suppose it has to do with the FFmpeg package that requires a minimum version of android.

Do you have a future plan to cover more versions until at least 23?

I see that at level 23 is 16.9% of the devices with this version.

I leave here the reference.

distribution android version

Video not saving

some times video save at android/data/com.trimmer.videotrimmer/files/Picture/(video saved here)

but some times it did not save at that place

and where can i find this location
/data/user/0/com.trimmer.videotrimmer/app_flutter/Trimmer/image_picker6447870776611015947_trimmed:Aug14,2020-08:25:17.mp4
i did not get it any where in my phone

video pass

when ever i try to pass a video to other class it says

The getter 'path' was called on null.
Receiver: null
Tried calling: path

i tried this code:

   RaisedButton(
                 onPressed: _progressVisibility
                     ? null
                     : () async {
                   _saveVideo().then((outputPath) async{
                     Navigator.push(
                         context, MaterialPageRoute(
                         builder: (context) => Edit(
                           videoPath: outputPath,
                         )));
                     print('OUTPUT PATH: $outputPath');
                     final snackBar = SnackBar(
                       content: Text('Video Saved successfully $outputPath'),
                     );
                     Scaffold.of(context).showSnackBar(snackBar);
                   });
//                    checkTime();
                 },
                 child: Text("SAVE"),
               ),

is there any way i can save video in my dir something like this:

 final Directory extDir = await getApplicationDocumentsDirectory();

    final String dirPath = '${extDir.path}/videos';
    await Directory(dirPath).create(recursive: true);
    String videoFileName = '${timestamp()}.mp4';

    String videoFile = '$dirPath/${timestamp()}.mp4';

Trim Swipe Exceeds

Video_1589689730

When swipe continues to start to end or end to start it exceeds the view and also the value.

empty file

After trimming the video, when I create a file object from the returned path, I get an empty file.

Future _saveVideo() async {

setState(() {
  _progressVisibility = true;
});

String path = await widget._trimmer.saveTrimmedVideo(
  startValue: _startValue,
  endValue: _endValue,
  storageDir: StorageDir.temporaryDirectory,
);

File file = File(path);
print('File length: ${await file.length()}');  // the result is 0.

return path;

}

Extract single frame from video

Is it possible to extract a single frame from a video using this trimmer? If not, is that an enhancement you would consider adding? Regardless, thanks for your excellent package!

Trimming videos less than 1sec

The is an issue with trimming videos less than 1 second (any time less than 0:00:00 which can be 0:00:00.30), the trimmed video cannot be played

/data/user/0/MyProject/files/ffmpeg": error=13, Permission denied

Hi,

I changed targetSdk 29 for upload google playstore. ( google targetSdk policy )

Now I got this error

when I click (button), phone die immediately
these code
await _trimmer .saveTrimmedVideo(startValue: _startValue, endValue: _endValue) .then((value) { setState(() { _value = value; }); })

and error message like this
E/FFmpeg ( 9618): java.io.IOException: Cannot run program "/data/user/0/myProject/files/ffmpeg": error=13, Permission denied

is there a way to solve this problem?
( targetSdk 28 was no problem )

How to get access to the video controller ?

hi I want to use the video controller but i m not able to find the currently using controller in the VideoViewer()
and if i m creating a new videocontroller then how to dispose both at same time ?
Please help!

Multiple VideoViewer is same page

Can I use multiple VideoViewer and Trimmer in same page?
I have more than one video loaded with PageView.builder
I tried couple ways to develop but failed.

Looking forward to your advice.

Support for latest video_player plugin

I can't update video_player plugin to 1.0.0 due that video_trimmer doesn't support it, will be great to add support :D Thanks for your amazing work mate!

Pub error when i try to install video_trimmer

Because every version of video_trimmer depends on image_picker ^0.6.5+2 and betabili depends on image_picker 0.6.0+2, video_trimmer is forbidden.
So, because betabili depends on video_trimmer ^0.1.2, version solving failed.
pub get failed (1; So, because betabili depends on video_trimmer ^0.1.2, version solving failed.)

Saved video output return

Hi!
In the new 0.22 release the saved output path is returned, but it starts and ends with quotes.
The result is that when I try to see if the file exists, it returns false and I have to subtract the first and last characters.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.