@@ -9,7 +9,6 @@ import android.os.Build
99import android.text.TextUtils
1010import android.webkit.URLUtil
1111import com.facebook.react.bridge.Arguments
12- import com.facebook.react.bridge.GuardedResultAsyncTask
1312import com.facebook.react.bridge.Promise
1413import com.facebook.react.bridge.ReactApplicationContext
1514import com.facebook.react.bridge.ReactContext
@@ -23,69 +22,76 @@ import java.io.UnsupportedEncodingException
2322import java.lang.ref.WeakReference
2423import java.net.URLDecoder
2524import java.util.UUID
26-
25+ import kotlinx.coroutines.CoroutineScope
26+ import kotlinx.coroutines.Dispatchers
27+ import kotlinx.coroutines.launch
28+ import kotlinx.coroutines.withContext
2729
2830class CreateVideoThumbnailClass (private val reactContext : ReactApplicationContext ) {
2931 @ReactMethod
30- fun create (fileUrl : String ,options : ReadableMap , promise : Promise ) {
31- ProcessDataTask (reactContext,fileUrl, promise, options).execute()
32- }
33-
34- private class ProcessDataTask (reactContext : ReactContext ,private val filePath : String , private val promise : Promise , private val options : ReadableMap ) : GuardedResultAsyncTask<ReadableMap?>(reactContext.exceptionHandler) {
35- private val weakContext: WeakReference <Context >
36-
37- init {
38- weakContext = WeakReference (reactContext.applicationContext)
39- }
40-
41- override fun doInBackgroundGuarded (): ReadableMap ? {
42- val format = " jpeg"
43- val cacheName = if (options.hasKey(" cacheName" )) options.getString(" cacheName" ) else " "
44- val thumbnailDir = weakContext.get()!! .applicationContext.cacheDir.absolutePath + " /thumbnails"
45- val cacheDir = createDirIfNotExists(thumbnailDir)
46- if (! TextUtils .isEmpty(cacheName)) {
47- val file = File (thumbnailDir, " $cacheName .$format " )
48- if (file.exists()) {
49- val map = Arguments .createMap()
50- map.putString(" path" , " file://" + file.absolutePath)
51- val image = BitmapFactory .decodeFile(file.absolutePath)
52- map.putDouble(" size" , image.byteCount.toDouble())
53- map.putString(" mime" , " image/$format " )
54- map.putDouble(" width" , image.width.toDouble())
55- map.putDouble(" height" , image.height.toDouble())
56- return map
57- }
58- }
59- val headers: Map <String , String > = if (options.hasKey(" headers" )) options.getMap(" headers" )!! .toHashMap() as Map <String , String > else HashMap <String , String >()
60- val fileName = if (TextUtils .isEmpty(cacheName)) " thumb-" + UUID .randomUUID().toString() else " $cacheName .$format "
61- var fOut: OutputStream ? = null
32+ fun create (fileUrl : String , options : ReadableMap , promise : Promise ) {
33+ CoroutineScope (Dispatchers .Main ).launch {
6234 try {
63- val file = File (cacheDir, fileName)
64- val context = weakContext.get()
65- val image = getBitmapAtTime(context, filePath, 0 , headers)
66- file.createNewFile()
67- fOut = FileOutputStream (file)
35+ val result = processDataInBackground(reactContext, fileUrl, options)
36+ promise.resolve(result)
37+ } catch (e: Exception ) {
38+ promise.reject(" CreateVideoThumbnail_ERROR" , e)
39+ }
40+ }
41+ }
6842
69- // 100 means no compression, the lower you go, the stronger the compression
70- image.compress(Bitmap .CompressFormat .JPEG , 90 , fOut)
71- fOut.flush()
72- fOut.close()
43+ private suspend fun processDataInBackground (reactContext : ReactContext , filePath : String , options : ReadableMap ): ReadableMap ? = withContext(Dispatchers .IO ) {
44+ val weakContext = WeakReference (reactContext.applicationContext)
45+ val format = " jpeg"
46+ val cacheName = if (options.hasKey(" cacheName" )) options.getString(" cacheName" ) else " "
47+ val thumbnailDir = weakContext.get()!! .applicationContext.cacheDir.absolutePath + " /thumbnails"
48+ val cacheDir = createDirIfNotExists(thumbnailDir)
7349
50+ if (! TextUtils .isEmpty(cacheName)) {
51+ val file = File (thumbnailDir, " $cacheName .$format " )
52+ if (file.exists()) {
7453 val map = Arguments .createMap()
7554 map.putString(" path" , " file://" + file.absolutePath)
55+ val image = BitmapFactory .decodeFile(file.absolutePath)
7656 map.putDouble(" size" , image.byteCount.toDouble())
7757 map.putString(" mime" , " image/$format " )
7858 map.putDouble(" width" , image.width.toDouble())
7959 map.putDouble(" height" , image.height.toDouble())
80- return map
81- } catch (e: Exception ) {
82- promise.reject(" CreateVideoThumbnail_ERROR" , e)
60+ return @withContext map
8361 }
84- return null
8562 }
8663
87- override fun onPostExecuteGuarded (readableArray : ReadableMap ? ) {
88- promise.resolve(readableArray)
64+ val headers: Map <String , String > = if (options.hasKey(" headers" )) options.getMap(" headers" )!! .toHashMap() as Map <String , String > else HashMap <String , String >()
65+ val fileName = if (TextUtils .isEmpty(cacheName)) " thumb-" + UUID .randomUUID().toString() else " $cacheName .$format "
66+ var fOut: OutputStream ? = null
67+
68+ try {
69+ val file = File (cacheDir, fileName)
70+ val context = weakContext.get()
71+ val image = getBitmapAtTime(context, filePath, 0 , headers)
72+ file.createNewFile()
73+ fOut = FileOutputStream (file)
74+
75+ // 100 means no compression, the lower you go, the stronger the compression
76+ image.compress(Bitmap .CompressFormat .JPEG , 90 , fOut)
77+ fOut.flush()
78+ fOut.close()
79+
80+ val map = Arguments .createMap()
81+ map.putString(" path" , " file://" + file.absolutePath)
82+ map.putDouble(" size" , image.byteCount.toDouble())
83+ map.putString(" mime" , " image/$format " )
84+ map.putDouble(" width" , image.width.toDouble())
85+ map.putDouble(" height" , image.height.toDouble())
86+ return @withContext map
87+ } catch (e: Exception ) {
88+ throw e
89+ } finally {
90+ try {
91+ fOut?.close()
92+ } catch (e: IOException ) {
93+ // Ignore
94+ }
8995 }
9096 }
9197
0 commit comments