Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Compress videos, remove audio, manipulate thumbnails, and make your video compat
In addition, google chrome uses VP8/VP9, safari uses h264, and most of the time, it is necessary to encode the video in two formats, but not with this library.
All video files are encoded in an MP4 container with AAC audio that allows 100% compatibility with safari, mozila, chrome, android and iOS.

Works on ANDROID and IOS.
Works on ANDROID and IOS, except for the '.gif' to '.mp4' transformation which currently only works on Android.



Expand Down Expand Up @@ -164,6 +164,7 @@ class _Compress extends State<Compress> {
### TODO
- Add the trim video function
- Add cancel function to Android
- Add gif to mp4 to iOS

## Methods
| Functions | Parameters | Description | Returns |
Expand All @@ -172,6 +173,7 @@ class _Compress extends State<Compress> {
| getFileThumbnail | String `path`[video path], int `quality`(1-100)[thumbnail quality], int `position`[Get a thumbnail from video position] | get thumbnail file from video `path` | `Future<File>` |
| getMediaInfo | String `path`[video path] | get media information from video `path` | `Future<MediaInfo>` |
| compressVideo | String `path`[video path], VideoQuality `quality`[compressed video quality], bool `deleteOrigin`[delete the origin video], int `startTime`[compression video start time], int `duration`[compression video duration from start time], bool `includeAudio`[is include audio in compressed video], int `frameRate`[compressed video frame rate] | compression video at origin video `path` | `Future<MediaInfo>` |
| compressGifToVideo| String `path`[video path], VideoQuality `quality`[compressed video quality], bool `deleteOrigin`[delete the origin video], int `frameRate`[compressed video frame rate] | compression video at origin video `path` | `Future<MediaInfo>` |
| cancelCompression | `none` | cancel compressing | `Future<void>` |
| deleteAllCache | `none` | Delete all files generated by 'video_compress' will delete all files located at 'video_compress' | `Future<bool>` |

Expand Down
1 change: 1 addition & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,5 @@ android {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.otaliastudios:transcoder:0.9.1'
implementation 'com.otaliastudios.gif:compressor:1.0.0'
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ import com.otaliastudios.transcoder.strategy.DefaultVideoStrategy
import com.otaliastudios.transcoder.strategy.RemoveTrackStrategy
import com.otaliastudios.transcoder.strategy.TrackStrategy
import com.otaliastudios.transcoder.strategy.size.*
import com.otaliastudios.gif.GIFCompressor
import com.otaliastudios.gif.GIFListener
import com.otaliastudios.gif.strategy.DefaultStrategy
import com.otaliastudios.gif.strategy.Strategy
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.BinaryMessenger
import com.otaliastudios.transcoder.internal.Logger
Expand Down Expand Up @@ -162,6 +166,67 @@ class VideoCompressPlugin : MethodCallHandler, FlutterPlugin {
}
}).transcode()
}
"compressGifToVideo" -> {
//https://natario1.github.io/GIFCompressor/home for more options
val path = call.argument<String>("path")!!
val quality = call.argument<Int>("quality")!!
val deleteOrigin = call.argument<Boolean>("deleteOrigin")!!
val frameRate = if (call.argument<Int>("frameRate")==null) 30 else call.argument<Int>("frameRate")
val tempDir: String = context.getExternalFilesDir("video_compress")!!.absolutePath
val out = SimpleDateFormat("yyyy-MM-dd hh-mm-ss").format(Date())
val destPath: String = tempDir + File.separator + "VID_" + out + ".mp4"

var trackStrategy: Strategy = DefaultStrategy.atMost(340).build();

when (quality) {

0 -> {
trackStrategy = DefaultStrategy.atMost(720).build()
}

1 -> {
trackStrategy = DefaultStrategy.atMost(360).build()
}
2 -> {
trackStrategy = DefaultStrategy.atMost(640).build()
}
3 -> {
trackStrategy = DefaultStrategy.Builder()
.keyFrameInterval(3f)
.bitRate(1280 * 720 * 4.toLong())
.frameRate(frameRate!!)
.build()
}
}

transcodeFuture = GIFCompressor.into(destPath)
.addDataSource(context, Uri.parse(path))
.setStrategy(trackStrategy)
.setListener(object : GIFListener {
override fun onGIFCompressionFailed(exception: Throwable) {
result.success(null)
}

override fun onGIFCompressionProgress(progress: Double) {
channel.invokeMethod("updateProgress", progress * 100.00)
}

override fun onGIFCompressionCompleted() {
channel.invokeMethod("updateProgress", 100.00)
val json = Utility(channelName).getMediaInfoJson(context, destPath)
json.put("isCancel", false)
result.success(json.toString())
if (deleteOrigin) {
File(path).delete()
}
}

override fun onGIFCompressionCanceled() {
result.success(null)
}

}).compress()
}
else -> {
result.notImplemented()
}
Expand Down
49 changes: 49 additions & 0 deletions lib/src/video_compress/video_compressor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,55 @@ extension Compress on IVideoCompress {
}
}


/// transform a '.gif' into a '.mp4' from [path]
/// returns [Future<MediaInfo>]
///
/// you can choose its quality by [quality],
/// determine whether to delete his source file by [deleteOrigin]
/// optional parameters [frameRate]
Future<MediaInfo> compressGifToVideo(
String path, {
VideoQuality quality = VideoQuality.DefaultQuality,
bool deleteOrigin = false,
int startTime,
int duration,
int frameRate = 30,
}) async {
assert(path != null);
assert(Platform.isAndroid == true, "compressGifToVideo is currently only supported on Android");
if (isCompressing) {
throw StateError('''VideoCompress Error:
Method: compressGifToVideo
Already have a compression process, you need to wait for the process to finish or stop it''');
}

if (compressProgress$.notSubscribed) {
debugPrint('''VideoCompress: You can try to subscribe to the
compressProgress\$ stream to know the compressing state.''');
}
// ignore: invalid_use_of_protected_member
setProcessingStatus(true);
final jsonStr = await _invoke<String>('compressGifToVideo', {
'path': path,
'quality': quality.index,
'deleteOrigin': deleteOrigin,
'startTime': startTime,
'duration': duration,
'frameRate': frameRate,
});

// ignore: invalid_use_of_protected_member
setProcessingStatus(false);

if (jsonStr != null) {
final jsonMap = json.decode(jsonStr);
return MediaInfo.fromJson(jsonMap);
} else {
return null;
}
}

/// stop compressing the file that is currently being compressed.
/// If there is no compression process, nothing will happen.
Future<void> cancelCompression() async {
Expand Down