All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
main.com.sceyt.chatuikit.shared.media_encoder.VideoTranscodeHelper.kt Maven / Gradle / Ivy
package com.sceyt.chatuikit.shared.media_encoder
import android.app.Application
import android.net.Uri
import com.abedelazizshe.lightcompressorlibrary.CompressionListener
import com.abedelazizshe.lightcompressorlibrary.VideoQuality
import com.sceyt.chatuikit.koin.SceytKoinComponent
import com.sceyt.chatuikit.logger.SceytLog
import com.sceyt.chatuikit.shared.media_encoder.TranscodeResultEnum.Cancelled
import com.sceyt.chatuikit.shared.media_encoder.TranscodeResultEnum.Failure
import com.sceyt.chatuikit.shared.media_encoder.TranscodeResultEnum.Progress
import com.sceyt.chatuikit.shared.media_encoder.TranscodeResultEnum.Start
import com.sceyt.chatuikit.shared.media_encoder.TranscodeResultEnum.Success
import kotlinx.coroutines.suspendCancellableCoroutine
import org.koin.core.component.inject
import java.io.File
import java.util.concurrent.ConcurrentLinkedQueue
import kotlin.coroutines.resume
object VideoTranscodeHelper : SceytKoinComponent {
private val application by inject()
private var pendingTranscodeQue: ConcurrentLinkedQueue = ConcurrentLinkedQueue()
@Volatile
private var currentTranscodePath: String? = null
suspend fun transcodeAsResult(destination: File, path: String, quality: VideoQuality = VideoQuality.MEDIUM): VideoTranscodeData {
return suspendCancellableCoroutine {
checkAndTranscode(destination, path, quality) { data ->
when (data.resultType) {
Cancelled -> it.resume(VideoTranscodeData(Cancelled))
Failure -> {
SceytLog.i("transcodeVideoFailure", data.errorMessage)
it.resume(VideoTranscodeData(Failure, data.errorMessage))
}
Success -> it.resume(VideoTranscodeData(Success))
Progress, Start -> Unit
}
}
}
}
fun transcodeAsResultWithCallback(destination: File, path: String, quality: VideoQuality = VideoQuality.MEDIUM,
callback: (VideoTranscodeData) -> Unit) {
checkAndTranscode(destination, path, quality, callback)
}
private fun checkAndTranscode(destination: File, filePath: String, quality: VideoQuality = VideoQuality.MEDIUM,
callback: (VideoTranscodeData) -> Unit) {
if (currentTranscodePath == null) {
currentTranscodePath = filePath
CustomVideoCompressor.start(
context = application,
srcUri = Uri.parse(filePath),
destPath = destination.absolutePath,
configureWith = CustomConfiguration(
quality = quality,
isMinBitrateCheckEnabled = true,
disableAudio = false,
videoBitrateCoefficient = 0.09f,
),
listener = object : CompressionListener {
override fun onCancelled() {
callback(VideoTranscodeData(Cancelled))
uploadNext()
}
override fun onFailure(failureMessage: String) {
callback(VideoTranscodeData(Failure, failureMessage))
uploadNext()
}
override fun onProgress(percent: Float) {
callback(VideoTranscodeData(Progress, progressPercent = 0f))
}
override fun onStart() {
callback(VideoTranscodeData(Start))
}
override fun onSuccess() {
callback(VideoTranscodeData(Success))
uploadNext()
}
},
)
} else {
val alreadyExist = currentTranscodePath == filePath || pendingTranscodeQue.any { it.filePath == filePath }
if (!alreadyExist)
pendingTranscodeQue.add(PendingTranscodeData(destination, filePath, quality, callback))
}
}
private fun uploadNext() {
currentTranscodePath = null
if (pendingTranscodeQue.isEmpty()) return
pendingTranscodeQue.poll()?.let {
checkAndTranscode(it.destination, it.filePath, it.quality, it.callback)
}
}
fun cancel(filePath: String?) {
filePath ?: return
if (currentTranscodePath == filePath) {
CustomVideoCompressor.cancel()
} else {
pendingTranscodeQue.find { it.filePath == filePath }?.let {
pendingTranscodeQue.remove(it)
}
}
}
}
private data class PendingTranscodeData(
val destination: File,
val filePath: String,
val quality: VideoQuality,
val callback: (VideoTranscodeData) -> Unit
)
data class VideoTranscodeData(
val resultType: TranscodeResultEnum,
val errorMessage: String? = null,
val progressPercent: Float = 0f
)
enum class TranscodeResultEnum {
Cancelled, Failure, Progress, Start, Success
}