diff --git a/android/src/main/kotlin/com/example/video_compress/VideoCompressPlugin.kt b/android/src/main/kotlin/com/example/video_compress/VideoCompressPlugin.kt index 032e0bf5..43498982 100644 --- a/android/src/main/kotlin/com/example/video_compress/VideoCompressPlugin.kt +++ b/android/src/main/kotlin/com/example/video_compress/VideoCompressPlugin.kt @@ -14,6 +14,8 @@ import com.otaliastudios.transcoder.strategy.TrackStrategy import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.plugin.common.BinaryMessenger import com.otaliastudios.transcoder.internal.utils.Logger +import com.otaliastudios.transcoder.resize.AtMostResizer +import com.otaliastudios.transcoder.resize.ExactResizer import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel.MethodCallHandler @@ -83,6 +85,9 @@ class VideoCompressPlugin : MethodCallHandler, FlutterPlugin { val duration = call.argument("duration") val includeAudio = call.argument("includeAudio") ?: true val frameRate = if (call.argument("frameRate")==null) 30 else call.argument("frameRate") + val bitRate = call.argument("bitRate") + val outputWidth = call.argument("outputWidth") + val outputHeight = call.argument("outputHeight") val tempDir: String = context.getExternalFilesDir("video_compress")!!.absolutePath val out = SimpleDateFormat("yyyy-MM-dd hh-mm-ss").format(Date()) @@ -94,14 +99,59 @@ class VideoCompressPlugin : MethodCallHandler, FlutterPlugin { when (quality) { 0 -> { - videoTrackStrategy = DefaultVideoStrategy.atMost(720).build() + + assert(value = frameRate != null) + videoTrackStrategy = if (bitRate==null){ + DefaultVideoStrategy.Builder() + .keyFrameInterval(3f) + .frameRate(frameRate!!) // will be capped to the input frameRate + .addResizer(AtMostResizer(720)) + .build() + }else{ + DefaultVideoStrategy.Builder() + .keyFrameInterval(3f) + .bitRate(bitRate.toLong()) + .frameRate(frameRate!!) // will be capped to the input frameRate + .addResizer(AtMostResizer(720)) + .build() + } } 1 -> { - videoTrackStrategy = DefaultVideoStrategy.atMost(360).build() + + assert(value = frameRate != null) + videoTrackStrategy = if (bitRate==null){ + DefaultVideoStrategy.Builder() + .keyFrameInterval(3f) + .frameRate(frameRate!!) // will be capped to the input frameRate + .addResizer(AtMostResizer(360)) + .build() + }else{ + DefaultVideoStrategy.Builder() + .keyFrameInterval(3f) + .bitRate(bitRate.toLong()) + .frameRate(frameRate!!) // will be capped to the input frameRate + .addResizer(AtMostResizer(360)) + .build() + } } 2 -> { - videoTrackStrategy = DefaultVideoStrategy.atMost(640).build() + + assert(value = frameRate != null) + videoTrackStrategy = if (bitRate==null){ + DefaultVideoStrategy.Builder() + .keyFrameInterval(3f) + .frameRate(frameRate!!) // will be capped to the input frameRate + .addResizer(AtMostResizer(640)) + .build() + }else{ + DefaultVideoStrategy.Builder() + .keyFrameInterval(3f) + .bitRate(bitRate.toLong()) + .frameRate(frameRate!!) // will be capped to the input frameRate + .addResizer(AtMostResizer(640)) + .build() + } } 3 -> { @@ -113,17 +163,112 @@ class VideoCompressPlugin : MethodCallHandler, FlutterPlugin { .build() } 4 -> { - videoTrackStrategy = DefaultVideoStrategy.atMost(480, 640).build() + + assert(value = frameRate != null) + videoTrackStrategy = if (bitRate==null){ + DefaultVideoStrategy.Builder() + .keyFrameInterval(3f) + .frameRate(frameRate!!) // will be capped to the input frameRate + .addResizer(AtMostResizer(480,640)) + .build() + }else{ + DefaultVideoStrategy.Builder() + .keyFrameInterval(3f) + .bitRate(bitRate.toLong()) + .frameRate(frameRate!!) // will be capped to the input frameRate + .addResizer(AtMostResizer(480,640)) + .build() + } } 5 -> { - videoTrackStrategy = DefaultVideoStrategy.atMost(540, 960).build() + + assert(value = frameRate != null) + videoTrackStrategy = if (bitRate==null){ + DefaultVideoStrategy.Builder() + .keyFrameInterval(3f) + .frameRate(frameRate!!) // will be capped to the input frameRate + .addResizer(AtMostResizer(540,960)) + .build() + }else{ + DefaultVideoStrategy.Builder() + .keyFrameInterval(3f) + .bitRate(bitRate.toLong()) + .frameRate(frameRate!!) // will be capped to the input frameRate + .addResizer(AtMostResizer(540,960)) + .build() + } } 6 -> { - videoTrackStrategy = DefaultVideoStrategy.atMost(720, 1280).build() + + assert(value = frameRate != null) + videoTrackStrategy = if (bitRate==null){ + DefaultVideoStrategy.Builder() + .keyFrameInterval(3f) + .frameRate(frameRate!!) // will be capped to the input frameRate + .addResizer(AtMostResizer(720, 1280)) + .build() + }else{ + DefaultVideoStrategy.Builder() + .keyFrameInterval(3f) + .bitRate(bitRate.toLong()) + .frameRate(frameRate!!) // will be capped to the input frameRate + .addResizer(AtMostResizer(720,1280)) + .build() + } } 7 -> { - videoTrackStrategy = DefaultVideoStrategy.atMost(1080, 1920).build() - } + + assert(value = frameRate != null) + videoTrackStrategy = if (bitRate==null){ + DefaultVideoStrategy.Builder() + .keyFrameInterval(3f) + .frameRate(frameRate!!) // will be capped to the input frameRate + .addResizer(AtMostResizer(1080,1920)) + .build() + }else{ + DefaultVideoStrategy.Builder() + .keyFrameInterval(3f) + .bitRate(bitRate.toLong()) + .frameRate(frameRate!!) // will be capped to the input frameRate + .addResizer(AtMostResizer(1080,1920)) + .build() + } + } + 8 -> { + + assert(value = frameRate != null) + if(outputWidth != null && outputHeight != null) { + videoTrackStrategy = if (bitRate == null) { + DefaultVideoStrategy.Builder() + .keyFrameInterval(3f) + .frameRate(frameRate!!) // will be capped to the input frameRate + .addResizer(ExactResizer(outputWidth, outputHeight)) + .build() + } else { + DefaultVideoStrategy.Builder() + .keyFrameInterval(3f) + .bitRate(bitRate.toLong()) + .frameRate(frameRate!!) // will be capped to the input frameRate + .addResizer(ExactResizer(outputWidth, outputHeight)) + .build() + } + }else{ + videoTrackStrategy = if (bitRate==null){ + DefaultVideoStrategy.Builder() + .keyFrameInterval(3f) + .frameRate(frameRate!!) // will be capped to the input frameRate + .addResizer(AtMostResizer(720, 1280)) + .build() + }else{ + DefaultVideoStrategy.Builder() + .keyFrameInterval(3f) + .bitRate(bitRate.toLong()) + .frameRate(frameRate!!) // will be capped to the input frameRate + .addResizer(AtMostResizer(720,1280)) + .build() + } + } + } } audioTrackStrategy = if (includeAudio) { diff --git a/lib/src/video_compress/video_compressor.dart b/lib/src/video_compress/video_compressor.dart index 3b7b38e3..ab332b5f 100644 --- a/lib/src/video_compress/video_compressor.dart +++ b/lib/src/video_compress/video_compressor.dart @@ -109,8 +109,16 @@ extension Compress on IVideoCompress { /// compress video from [path] return [Future] /// /// you can choose its quality by [quality], + /// + /// Note : VideoQuality.CustomQuality is available only in Android platform. + /// /// determine whether to delete his source file by [deleteOrigin] - /// optional parameters [startTime] [duration] [includeAudio] [frameRate] + /// + /// optional parameters : [startTime] , [duration] , [includeAudio] , [frameRate] + /// + /// Android specific parameters : [bitRate] , [outputWidth] , [outputHeight] + /// + /// Note : if you don't choose VideoQuality.CustomQuality , [outputWidth] and [outputHeight] will be ignored. /// /// ## example /// ```dart @@ -128,6 +136,9 @@ extension Compress on IVideoCompress { int? duration, bool? includeAudio, int frameRate = 30, + int? bitRate, + int? outputWidth, + int? outputHeight }) async { if (isCompressing) { throw StateError('''VideoCompress Error: @@ -150,6 +161,9 @@ extension Compress on IVideoCompress { 'duration': duration, 'includeAudio': includeAudio, 'frameRate': frameRate, + 'bitRate': bitRate, + 'outputWidth': outputWidth, + 'outputHeight': outputHeight, }); // ignore: invalid_use_of_protected_member diff --git a/lib/src/video_compress/video_quality.dart b/lib/src/video_compress/video_quality.dart index c24b6058..de723a16 100644 --- a/lib/src/video_compress/video_quality.dart +++ b/lib/src/video_compress/video_quality.dart @@ -6,5 +6,6 @@ enum VideoQuality { Res640x480Quality, Res960x540Quality, Res1280x720Quality, - Res1920x1080Quality + Res1920x1080Quality, + CustomQuality }