Merge branch 'vitorpamplona:main' into follows-and-followsets-unified

This commit is contained in:
KotlinGeekDev
2025-09-26 12:12:28 +00:00
committed by GitHub
3 changed files with 25 additions and 35 deletions

View File

@@ -332,9 +332,9 @@ dependencies {
implementation libs.audiowaveform implementation libs.audiowaveform
// Video compression lib // Video compression lib
implementation libs.abedElazizShe.image.compressor implementation libs.abedElazizShe.video.compressor.fork
// Image compression lib // Image compression lib
implementation libs.zelory.video.compressor implementation libs.zelory.image.compressor
// Cbor for cashuB format // Cbor for cashuB format
implementation libs.kotlinx.serialization.cbor implementation libs.kotlinx.serialization.cbor

View File

@@ -38,8 +38,8 @@ import kotlinx.coroutines.withTimeoutOrNull
import java.io.File import java.io.File
import java.util.UUID import java.util.UUID
import kotlin.coroutines.resume import kotlin.coroutines.resume
import kotlin.math.roundToInt
// TODO: add Auto setting. Focus on small fast streams. 4->1080p, 1080p->720p, 720p and below stay the same resolution. Use existing matrix to determine bitrate.
data class VideoInfo( data class VideoInfo(
val resolution: VideoResolution, val resolution: VideoResolution,
val framerate: Float, val framerate: Float,
@@ -80,18 +80,19 @@ enum class VideoStandard(
override fun toString(): String = label override fun toString(): String = label
} }
private const val MBPS_TO_BPS_MULTIPLIER = 1_000_000
data class CompressionRule( data class CompressionRule(
val width: Int, val width: Int,
val height: Int, val height: Int,
val bitrateMbps: Float, val bitrateMbps: Float,
val description: String, val description: String,
) { ) {
fun getBitrateMbpsInt(framerate: Float): Int { fun getBitrateBps(framerate: Float): Int {
// Apply 1.5x multiplier for 60fps+ videos // Apply 1.5x multiplier for 60fps+ videos
val multiplier = if (framerate >= 60f) 1.5f else 1.0f val multiplier = if (framerate >= 60f) 1.5f else 1.0f
// Library doesn't support float so we have to convert it to int and use 1 as minimum return (bitrateMbps * multiplier * MBPS_TO_BPS_MULTIPLIER).toInt()
return (bitrateMbps * multiplier).roundToInt().coerceAtLeast(1)
} }
} }
@@ -144,39 +145,28 @@ object VideoCompressionHelper {
): MediaCompressorResult { ): MediaCompressorResult {
val videoInfo = getVideoInfo(uri, applicationContext) val videoInfo = getVideoInfo(uri, applicationContext)
val videoBitrateInMbps = val (videoBitrateInBps, resizer) =
if (videoInfo != null) { videoInfo?.let { info ->
val bitrateMbpsInt = val rule =
compressionRules compressionRules
.getValue(mediaQuality) .getValue(mediaQuality)
.getValue(videoInfo.resolution.getStandard()) .getValue(info.resolution.getStandard())
.getBitrateMbpsInt(videoInfo.framerate)
val bitrateBps = rule.getBitrateBps(info.framerate)
Log.d(LOG_TAG, "Bitrate: ${bitrateBps}bps for ${info.resolution.getStandard()} quality=$mediaQuality framerate=${info.framerate}fps.")
Log.d( Log.d(
LOG_TAG, LOG_TAG,
"Bitrate: ${bitrateMbpsInt}Mbps for ${videoInfo.resolution.getStandard()} " + "Resizer: ${info.resolution.width}x${info.resolution.height} -> " +
"quality=$mediaQuality framerate=${videoInfo.framerate}fps.", "${rule.width}x${rule.height} (${rule.description})",
) )
} else { val resizer = VideoResizer.limitSize(rule.width.toDouble(), rule.height.toDouble())
Pair(bitrateBps, resizer)
} ?: run {
Log.w(LOG_TAG, "Video bitrate fallback: 2Mbps (videoInfo unavailable)") Log.w(LOG_TAG, "Video bitrate fallback: 2Mbps (videoInfo unavailable)")
2
}
val resizer =
if (videoInfo != null) {
val rules =
compressionRules
.getValue(mediaQuality)
.getValue(videoInfo.resolution.getStandard())
Log.d(
LOG_TAG,
"Resizer: ${videoInfo.resolution.width}x${videoInfo.resolution.height} -> " +
"${rules.width}x${rules.height} (${rules.description})",
)
VideoResizer.limitSize(rules.width.toDouble(), rules.height.toDouble())
} else {
Log.d(LOG_TAG, "Resizer: null (original resolution preserved)") Log.d(LOG_TAG, "Resizer: null (original resolution preserved)")
null Pair(2 * MBPS_TO_BPS_MULTIPLIER, null)
} }
// Get original file size safely // Get original file size safely
@@ -192,7 +182,7 @@ object VideoCompressionHelper {
storageConfiguration = AppSpecificStorageConfiguration(), storageConfiguration = AppSpecificStorageConfiguration(),
configureWith = configureWith =
Configuration( Configuration(
videoBitrateInMbps = videoBitrateInMbps, videoBitrateInBps = videoBitrateInBps.toLong(),
resizer = resizer, resizer = resizer,
videoNames = listOf(UUID.randomUUID().toString()), videoNames = listOf(UUID.randomUUID().toString()),
isMinBitrateCheckEnabled = false, isMinBitrateCheckEnabled = false,

View File

@@ -33,7 +33,7 @@ languageId = "17.0.6"
lazysodiumAndroid = "5.2.0" lazysodiumAndroid = "5.2.0"
lazysodiumJava = "5.2.0" lazysodiumJava = "5.2.0"
lifecycleRuntimeKtx = "2.9.4" lifecycleRuntimeKtx = "2.9.4"
lightcompressor = "1.3.3" lightcompressor = "1.4.0"
markdown = "e1151c8" markdown = "e1151c8"
media3 = "1.8.0" media3 = "1.8.0"
mockk = "1.14.5" mockk = "1.14.5"
@@ -63,7 +63,7 @@ core = "1.7.0"
mavenPublish = "0.34.0" mavenPublish = "0.34.0"
[libraries] [libraries]
abedElazizShe-image-compressor = { group = "com.github.AbedElazizShe", name = "LightCompressor", version.ref = "lightcompressor" } abedElazizShe-video-compressor-fork = { group = "com.github.davotoula", name = "LightCompressor-enhanced", version.ref = "lightcompressor" }
accompanist-adaptive = { group = "com.google.accompanist", name = "accompanist-adaptive", version.ref = "accompanistAdaptive" } accompanist-adaptive = { group = "com.google.accompanist", name = "accompanist-adaptive", version.ref = "accompanistAdaptive" }
accompanist-permissions = { group = "com.google.accompanist", name = "accompanist-permissions", version.ref = "accompanistAdaptive" } accompanist-permissions = { group = "com.google.accompanist", name = "accompanist-permissions", version.ref = "accompanistAdaptive" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
@@ -145,7 +145,7 @@ vico-charts-compose = { group = "com.patrykandpatrick.vico", name = "compose", v
vico-charts-core = { group = "com.patrykandpatrick.vico", name = "core", version.ref = "vico-charts" } vico-charts-core = { group = "com.patrykandpatrick.vico", name = "core", version.ref = "vico-charts" }
vico-charts-m3 = { group = "com.patrykandpatrick.vico", name = "compose-m3", version.ref = "vico-charts" } vico-charts-m3 = { group = "com.patrykandpatrick.vico", name = "compose-m3", version.ref = "vico-charts" }
vico-charts-views = { group = "com.patrykandpatrick.vico", name = "views", version.ref = "vico-charts" } vico-charts-views = { group = "com.patrykandpatrick.vico", name = "views", version.ref = "vico-charts" }
zelory-video-compressor = { group = "id.zelory", name = "compressor", version.ref = "zelory" } zelory-image-compressor = { group = "id.zelory", name = "compressor", version.ref = "zelory" }
zoomable = { group = "net.engawapg.lib", name = "zoomable", version.ref = "zoomable" } zoomable = { group = "net.engawapg.lib", name = "zoomable", version.ref = "zoomable" }
zxing = { group = "com.google.zxing", name = "core", version.ref = "zxing" } zxing = { group = "com.google.zxing", name = "core", version.ref = "zxing" }
zxing-embedded = { group = "com.journeyapps", name = "zxing-android-embedded", version.ref = "zxingAndroidEmbedded" } zxing-embedded = { group = "com.journeyapps", name = "zxing-android-embedded", version.ref = "zxingAndroidEmbedded" }