Skip to content

Commit 85b0f11

Browse files
authored
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`
1 parent 90ad961 commit 85b0f11

File tree

5 files changed

+15
-8
lines changed

5 files changed

+15
-8
lines changed

features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/video/DefaultMediaOptimizationSelectorPresenter.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,9 @@ class DefaultMediaOptimizationSelectorPresenter @AssistedInject constructor(
101101

102102
val sizeEstimations = VideoCompressionPreset.entries
103103
.map { preset ->
104-
val bitRate = preset.compressorHelper().calculateOptimalBitrate(videoDimensions, 30)
105-
val calculatedSize = (bitRate * duration / 8 * 1.1).roundToLong() // Adding 10% overhead for safety
104+
val bitRateAsBytes = preset.compressorHelper().calculateOptimalBitrate(videoDimensions, 30) / 8f
105+
val durationInSeconds = duration.inWholeSeconds.toFloat()
106+
val calculatedSize = (bitRateAsBytes * durationInSeconds * 1.1f).roundToLong() // Adding 10% overhead for safety
106107
VideoUploadEstimation(
107108
preset = preset,
108109
sizeInBytes = calculatedSize,

features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/video/VideoMetadataExtractor.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ import dagger.assisted.AssistedInject
1818
import io.element.android.libraries.core.extensions.runCatchingExceptions
1919
import io.element.android.libraries.di.AppScope
2020
import io.element.android.libraries.di.ApplicationContext
21+
import kotlin.time.Duration
22+
import kotlin.time.Duration.Companion.milliseconds
2123

2224
interface VideoMetadataExtractor : AutoCloseable {
2325
fun getSize(): Result<Size>
24-
fun getDuration(): Result<Long>
26+
fun getDuration(): Result<Duration>
2527
interface Factory {
2628
fun create(uri: Uri): VideoMetadataExtractor
2729
}
@@ -57,9 +59,10 @@ class DefaultVideoMetadataExtractor @AssistedInject constructor(
5759
}
5860
}
5961

60-
override fun getDuration(): Result<Long> = runCatchingExceptions {
62+
override fun getDuration(): Result<Duration> = runCatchingExceptions {
6163
mediaMetadataRetriever.value.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.toLong()
6264
?.takeIf { it > 0L }
65+
?.milliseconds
6366
?: error("Could not retrieve video duration from metadata")
6467
}
6568

features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/video/DefaultMediaOptimizationSelectorPresenterTest.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import kotlinx.coroutines.test.runTest
3434
import org.junit.Rule
3535
import org.junit.Test
3636
import org.junit.runner.RunWith
37+
import kotlin.time.Duration.Companion.minutes
3738

3839
@RunWith(AndroidJUnit4::class)
3940
class DefaultMediaOptimizationSelectorPresenterTest {
@@ -158,7 +159,7 @@ class DefaultMediaOptimizationSelectorPresenterTest {
158159
mediaExtractorFactory = FakeVideoMetadataExtractorFactory(
159160
FakeVideoMetadataExtractor(
160161
sizeResult = Result.success(Size(10_000, 10_000)),
161-
duration = Result.success(600L)
162+
duration = Result.success(10.minutes)
162163
)
163164
),
164165
)

features/messages/test/src/main/kotlin/io/element/android/features/messages/test/attachments/video/FakeVideoMetadataExtractor.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,16 @@ package io.element.android.features.messages.test.attachments.video
1010
import android.net.Uri
1111
import android.util.Size
1212
import io.element.android.features.messages.impl.attachments.video.VideoMetadataExtractor
13+
import kotlin.time.Duration
14+
import kotlin.time.Duration.Companion.milliseconds
1315

1416
class FakeVideoMetadataExtractor(
1517
private val sizeResult: Result<Size> = Result.success(Size(1, 1)),
16-
private val duration: Result<Long> = Result.success(1L),
18+
private val duration: Result<Duration> = Result.success(1.milliseconds),
1719
) : VideoMetadataExtractor {
1820
override fun getSize(): Result<Size> = sizeResult
1921

20-
override fun getDuration(): Result<Long> = duration
22+
override fun getDuration(): Result<Duration> = duration
2123

2224
override fun close() = Unit
2325
}

libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/media/VideoCompressorHelper.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class VideoCompressorHelper(
3838
val pixelsPerFrame = outputSize.width * outputSize.height
3939
// Apparently, 0.1 bits per pixel is a sweet spot for video compression
4040
val bitsPerPixel = 0.1f
41-
return (pixelsPerFrame * bitsPerPixel * frameRate).toLong() / 1000
41+
return (pixelsPerFrame * bitsPerPixel * frameRate).toLong()
4242
}
4343
}
4444

0 commit comments

Comments
 (0)