Fix bitrate value used for video transcoding (#5183)
* Fix bitrate value used for video transcoding: It should be 1000 times what it is now. The video size estimation was wrong since the retrieved duration value was in milliseconds, not seconds. * Use `Duration` as the result type for `getDuration`
This commit is contained in:
committed by
GitHub
parent
aac9642159
commit
5feb7a99a9
@@ -101,8 +101,9 @@ class DefaultMediaOptimizationSelectorPresenter @AssistedInject constructor(
|
||||
|
||||
val sizeEstimations = VideoCompressionPreset.entries
|
||||
.map { preset ->
|
||||
val bitRate = preset.compressorHelper().calculateOptimalBitrate(videoDimensions, 30)
|
||||
val calculatedSize = (bitRate * duration / 8 * 1.1).roundToLong() // Adding 10% overhead for safety
|
||||
val bitRateAsBytes = preset.compressorHelper().calculateOptimalBitrate(videoDimensions, 30) / 8f
|
||||
val durationInSeconds = duration.inWholeSeconds.toFloat()
|
||||
val calculatedSize = (bitRateAsBytes * durationInSeconds * 1.1f).roundToLong() // Adding 10% overhead for safety
|
||||
VideoUploadEstimation(
|
||||
preset = preset,
|
||||
sizeInBytes = calculatedSize,
|
||||
|
||||
@@ -18,10 +18,12 @@ import dagger.assisted.AssistedInject
|
||||
import io.element.android.libraries.core.extensions.runCatchingExceptions
|
||||
import io.element.android.libraries.di.AppScope
|
||||
import io.element.android.libraries.di.ApplicationContext
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
interface VideoMetadataExtractor : AutoCloseable {
|
||||
fun getSize(): Result<Size>
|
||||
fun getDuration(): Result<Long>
|
||||
fun getDuration(): Result<Duration>
|
||||
interface Factory {
|
||||
fun create(uri: Uri): VideoMetadataExtractor
|
||||
}
|
||||
@@ -57,9 +59,10 @@ class DefaultVideoMetadataExtractor @AssistedInject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getDuration(): Result<Long> = runCatchingExceptions {
|
||||
override fun getDuration(): Result<Duration> = runCatchingExceptions {
|
||||
mediaMetadataRetriever.value.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.toLong()
|
||||
?.takeIf { it > 0L }
|
||||
?.milliseconds
|
||||
?: error("Could not retrieve video duration from metadata")
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import kotlin.time.Duration.Companion.minutes
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class DefaultMediaOptimizationSelectorPresenterTest {
|
||||
@@ -158,7 +159,7 @@ class DefaultMediaOptimizationSelectorPresenterTest {
|
||||
mediaExtractorFactory = FakeVideoMetadataExtractorFactory(
|
||||
FakeVideoMetadataExtractor(
|
||||
sizeResult = Result.success(Size(10_000, 10_000)),
|
||||
duration = Result.success(600L)
|
||||
duration = Result.success(10.minutes)
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
@@ -10,14 +10,16 @@ package io.element.android.features.messages.test.attachments.video
|
||||
import android.net.Uri
|
||||
import android.util.Size
|
||||
import io.element.android.features.messages.impl.attachments.video.VideoMetadataExtractor
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
class FakeVideoMetadataExtractor(
|
||||
private val sizeResult: Result<Size> = Result.success(Size(1, 1)),
|
||||
private val duration: Result<Long> = Result.success(1L),
|
||||
private val duration: Result<Duration> = Result.success(1.milliseconds),
|
||||
) : VideoMetadataExtractor {
|
||||
override fun getSize(): Result<Size> = sizeResult
|
||||
|
||||
override fun getDuration(): Result<Long> = duration
|
||||
override fun getDuration(): Result<Duration> = duration
|
||||
|
||||
override fun close() = Unit
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ class VideoCompressorHelper(
|
||||
val pixelsPerFrame = outputSize.width * outputSize.height
|
||||
// Apparently, 0.1 bits per pixel is a sweet spot for video compression
|
||||
val bitsPerPixel = 0.1f
|
||||
return (pixelsPerFrame * bitsPerPixel * frameRate).toLong() / 1000
|
||||
return (pixelsPerFrame * bitsPerPixel * frameRate).toLong()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user