@@ -4,6 +4,7 @@ import android.content.Context
44import android.graphics.Bitmap
55import android.media.MediaMetadataRetriever
66import android.net.Uri
7+ import android.os.Build
78import java.io.File
89import java.io.FileOutputStream
910import java.util.concurrent.Executors
@@ -14,8 +15,8 @@ data class StreamVideoThumbnailResult(
1415)
1516
1617object StreamVideoThumbnailGenerator {
17- private const val DEFAULT_COMPRESSION_QUALITY = 70
18- private const val DEFAULT_MAX_DIMENSION = 256
18+ private const val DEFAULT_COMPRESSION_QUALITY = 80
19+ private const val DEFAULT_MAX_DIMENSION = 512
1920 private const val CACHE_VERSION = " v1"
2021 private const val CACHE_DIRECTORY_NAME = " @stream-io-stream-video-thumbnails"
2122 private const val MAX_CONCURRENT_GENERATIONS = 5
@@ -63,19 +64,13 @@ object StreamVideoThumbnailGenerator {
6364
6465 return try {
6566 setDataSource(retriever, context, url)
66- val frame =
67- retriever.getFrameAtTime(100000 , MediaMetadataRetriever .OPTION_CLOSEST_SYNC )
68- ? : throw IllegalStateException (" Failed to extract video frame for $url " )
69- val scaledFrame = scaleBitmap(frame)
67+ val thumbnail = extractThumbnailFrame(retriever, url)
7068
7169 FileOutputStream (outputFile).use { stream ->
72- scaledFrame .compress(Bitmap .CompressFormat .JPEG , DEFAULT_COMPRESSION_QUALITY , stream)
70+ thumbnail .compress(Bitmap .CompressFormat .JPEG , DEFAULT_COMPRESSION_QUALITY , stream)
7371 }
7472
75- if (scaledFrame != frame) {
76- scaledFrame.recycle()
77- }
78- frame.recycle()
73+ thumbnail.recycle()
7974
8075 Uri .fromFile(outputFile).toString()
8176 } catch (error: Throwable ) {
@@ -89,6 +84,28 @@ object StreamVideoThumbnailGenerator {
8984 }
9085 }
9186
87+ private fun extractThumbnailFrame (retriever : MediaMetadataRetriever , url : String ): Bitmap {
88+ if (Build .VERSION .SDK_INT >= 27 ) {
89+ return retriever.getScaledFrameAtTime(
90+ 100000 ,
91+ MediaMetadataRetriever .OPTION_CLOSEST_SYNC ,
92+ DEFAULT_MAX_DIMENSION ,
93+ DEFAULT_MAX_DIMENSION ,
94+ ) ? : throw IllegalStateException (" Failed to extract video frame for $url " )
95+ }
96+
97+ val frame =
98+ retriever.getFrameAtTime(100000 , MediaMetadataRetriever .OPTION_CLOSEST_SYNC )
99+ ? : throw IllegalStateException (" Failed to extract video frame for $url " )
100+ val scaledFrame = scaleBitmap(frame)
101+
102+ if (scaledFrame != frame) {
103+ frame.recycle()
104+ }
105+
106+ return scaledFrame
107+ }
108+
92109 private fun buildCacheFileName (url : String ): String {
93110 val cacheKey =
94111 fnv1a64(" $CACHE_VERSION |$DEFAULT_MAX_DIMENSION |$DEFAULT_COMPRESSION_QUALITY |$url " )
0 commit comments