Skip to content

Commit

Permalink
Merge pull request AbedElazizShe#7 from AbedElazizShe/dev
Browse files Browse the repository at this point in the history
- Enable setting a video quality
- Enable/disable checking for a minimum bitrate value
  • Loading branch information
AbedElazizShe authored May 29, 2020
2 parents 8e92951 + 7b32747 commit b14e4bf
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 147 deletions.
38 changes: 22 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,15 @@ The general idea of how the library works is that, extreme high bitrate is reduc
I would like to mention that the set attributes for size and quality worked just great in my projects and met the expectations. It may or may not meet yours. I’d appreciate your feedback so I can enhance the compression process.

## How it works
When the video file is called to be compressed, the library checks for minimum size and bitrate to determines whether the video needs to be compressed or not. This becomes handy if you don’t want the video to be compressed every time it is to be processed to avoid having very bad quality after multiple rounds of compression. The minimum values set here are;
When the video file is called to be compressed, the library checks if the user wants to set a min bitrate to avoid compressing low resolution videos. This becomes handy if you don’t want the video to be compressed every time it is to be processed to avoid having very bad quality after multiple rounds of compression. The minimum is;
* Bitrate: 2MB
* Height: 640
* Width: 360

If the file has higher values than that, the library generates new size and bitrate for the output file as follows;
You can pass one of a 3 video qualities; High, Medium, or Low and the library will handle generating the right bitrate value for the output video
```kotlin
when {
bitrate >= 15000000 -> 2000000 // > 15Mbps becomes 2Mbps
bitrate >= 8000000 -> 1500000 // > 8Mbps becomes 1.5Mbps
bitrate >= 4000000 -> 1000000 // > 4Mbps becomes 1Mbps
else -> 750000 // other values become 750KB
return when (quality) {
VideoQuality.LOW -> (bitrate * 0.1).roundToInt()
VideoQuality.MEDIUM -> (bitrate * 0.2).roundToInt()
VideoQuality.HIGH -> (bitrate * 0.3).roundToInt()
}

when {
Expand Down Expand Up @@ -62,19 +59,24 @@ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:${Version.coroutin
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:${Version.coroutines}"
```

Then just call [doVideoCompression] and pass both source and destination file paths. The method has a callback for 4 functions;
Then just call [doVideoCompression] and pass both source and destination file paths. The method has a callback for 5 functions;
1) OnStart - called when compression started
2) OnSuccess - called when compression completed with no errors/exceptions
3) OnFailure - called when an exception occured or video bitrate and size are below the minimum required for compression.
3) OnFailure - called when an exception occurred or video bitrate and size are below the minimum required for compression.
4) OnProgress - called with progress new value
5) OnCancelled - called when the job is cancelled

You can pass the optional video quality (default is medium) and if to enable checking for min bitrate (default is true)

To cancel the compression job, just call [VideoCompressor.cancel()]

```kotlin
VideoCompressor.doVideoCompression(
path,
desFile.path,
object : CompressionListener {
override fun onProgress(percent: Float) {
// Update UI with progress value
// Update UI with progress value
}

override fun onStart() {
Expand All @@ -86,18 +88,22 @@ VideoCompressor.doVideoCompression(
}

override fun onFailure() {
// On Failure
// On Failure
}

override fun onCancelled() {
// On Cancelled
}

})
}, VideoQuality.MEDIUM, isMinBitRateEnabled = false)
```

## Compatibility
Minimum Android SDK: LightCompressor requires a minimum API level of 21.

## Performance
This method was tested on Pixel, Huawei, Xiaomi, Samsung and Nokia phones and more than 150 videos.
Here’s some results from pixel 2 XL;
Here’s some results from pixel 2 XL (medium quality);
* 94.3MB compressed to 9.2MB in 11 seconds
* 151.2MB compressed to 14.7MB in 18 seconds
* 65.7MB compressed to 6.4MB in 8 seconds
Expand All @@ -120,7 +126,7 @@ allprojects {
Include this in your Module-level build.gradle file:

```groovy
implementation 'com.github.AbedElazizShe:LightCompressor:0.2.0'
implementation 'com.github.AbedElazizShe:LightCompressor:0.3.0'
```

## Getting help
Expand Down
98 changes: 51 additions & 47 deletions app/src/main/java/com/abedelazizshe/lightcompressor/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.abedelazizshe.lightcompressorlibrary.CompressionListener
import com.abedelazizshe.lightcompressorlibrary.VideoCompressor
import com.abedelazizshe.lightcompressorlibrary.VideoQuality
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.content_main.*
import java.io.File
Expand Down Expand Up @@ -79,7 +80,7 @@ class MainActivity : AppCompatActivity() {
GlideApp.with(this).load(uri).into(videoImage)

val downloadsPath =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
val desFile = File(downloadsPath, "${System.currentTimeMillis()}_${file.name}")
if (desFile.exists()) {
desFile.delete()
Expand All @@ -94,43 +95,46 @@ class MainActivity : AppCompatActivity() {
var time = 0L

VideoCompressor.start(
path,
desFile.path,
object : CompressionListener {
override fun onProgress(percent: Float) {
//Update UI
progress.text = "${percent.toLong()}%"
}
override fun onStart() {
time = System.currentTimeMillis()
progress.visibility = View.VISIBLE
originalSize.text = "Original size: ${getFileSize(file.length())}"
}
override fun onSuccess() {
val newSizeValue = desFile.length()

newSize.text =
"Size after compression: ${getFileSize(newSizeValue)}"

time = System.currentTimeMillis() - time
timeTaken.text =
"Duration: ${DateUtils.formatElapsedTime(time / 1000)}"

path = desFile.path

Handler().postDelayed({
progress.visibility = View.GONE
}, 50)
}
override fun onFailure() {
progress.text = "This video cannot be compressed!"
}

override fun onCancelled() {
Log.wtf("TAG", "compression has been canclled")
// make UI changes, cleanup, etc
}
})
path,
desFile.path,
object : CompressionListener {
override fun onProgress(percent: Float) {
//Update UI
progress.text = "${percent.toLong()}%"
}

override fun onStart() {
time = System.currentTimeMillis()
progress.visibility = View.VISIBLE
originalSize.text = "Original size: ${getFileSize(file.length())}"
}

override fun onSuccess() {
val newSizeValue = desFile.length()

newSize.text =
"Size after compression: ${getFileSize(newSizeValue)}"

time = System.currentTimeMillis() - time
timeTaken.text =
"Duration: ${DateUtils.formatElapsedTime(time / 1000)}"

path = desFile.path

Handler().postDelayed({
progress.visibility = View.GONE
}, 50)
}

override fun onFailure() {
progress.text = "This video cannot be compressed!"
}

override fun onCancelled() {
Log.wtf("TAG", "compression has been cancelled")
// make UI changes, cleanup, etc
}
}, VideoQuality.MEDIUM, isMinBitRateEnabled = false)
}
}

Expand All @@ -139,21 +143,21 @@ class MainActivity : AppCompatActivity() {

private fun setReadStoragePermission() {
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.WRITE_EXTERNAL_STORAGE
) != PackageManager.PERMISSION_GRANTED
this,
Manifest.permission.WRITE_EXTERNAL_STORAGE
) != PackageManager.PERMISSION_GRANTED
) {

if (ActivityCompat.shouldShowRequestPermissionRationale(
this,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
this,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
) {
} else {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
1
this,
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
1
)
}
}
Expand Down
Loading

0 comments on commit b14e4bf

Please sign in to comment.