react-native-compressor 1.7.2 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/README.md +51 -8
  2. package/android/build.gradle +9 -0
  3. package/android/src/main/java/com/reactnativecompressor/Audio/AudioCompressor.kt +527 -0
  4. package/android/src/main/java/com/reactnativecompressor/Audio/AudioMain.kt +31 -0
  5. package/android/src/main/java/com/reactnativecompressor/CompressorModule.kt +169 -0
  6. package/android/src/main/java/com/reactnativecompressor/CompressorPackage.kt +34 -0
  7. package/android/src/main/java/com/reactnativecompressor/Image/ImageCompressor.kt +199 -0
  8. package/android/src/main/java/com/reactnativecompressor/Image/ImageCompressorOptions.kt +57 -0
  9. package/android/src/main/java/com/reactnativecompressor/Image/ImageMain.kt +31 -0
  10. package/android/src/main/java/com/reactnativecompressor/Image/ImageSize.kt +3 -0
  11. package/android/src/main/java/com/reactnativecompressor/Utils/Downloader.kt +119 -0
  12. package/android/src/main/java/com/reactnativecompressor/Utils/EventEmitterHandler.kt +66 -0
  13. package/android/src/main/java/com/reactnativecompressor/Utils/MediaCache.kt +61 -0
  14. package/android/src/main/java/com/reactnativecompressor/Utils/RealPathUtil.kt +177 -0
  15. package/android/src/main/java/com/reactnativecompressor/Utils/Uploader.kt +117 -0
  16. package/android/src/main/java/com/reactnativecompressor/Utils/Utils.kt +162 -0
  17. package/android/src/main/java/com/reactnativecompressor/Utils/createVideoThumbnail.kt +158 -0
  18. package/android/src/main/java/com/reactnativecompressor/Video/AutoVideoCompression.kt +63 -0
  19. package/android/src/main/java/com/reactnativecompressor/Video/VideoCompressorHelper.kt +125 -0
  20. package/android/src/main/java/com/reactnativecompressor/Video/VideoMain.kt +86 -0
  21. package/android/src/newarch/CompressorSpec.kt +5 -0
  22. package/android/src/oldarch/CompressorSpec.kt +34 -0
  23. package/ios/Audio/AudioMain.swift +115 -0
  24. package/ios/Compressor-Bridging-Header.h +1 -2
  25. package/ios/Compressor.h +0 -8
  26. package/ios/Compressor.mm +37 -389
  27. package/ios/CompressorManager.swift +107 -0
  28. package/ios/Image/ImageCompressor.swift +354 -0
  29. package/ios/Image/ImageCompressorOptions.swift +93 -0
  30. package/ios/Image/ImageMain.swift +27 -0
  31. package/ios/Utils/CreateVideoThumbnail.swift +111 -0
  32. package/ios/Utils/Downloader.swift +157 -0
  33. package/ios/Utils/EventEmitterHandler.swift +54 -0
  34. package/ios/Utils/MediaCache.swift +48 -0
  35. package/ios/Utils/Uploader.swift +99 -0
  36. package/ios/Utils/Utils.swift +110 -0
  37. package/ios/Video/{VideoCompressor.swift → VideoMain.swift} +167 -146
  38. package/lib/commonjs/Image/index.js +1 -1
  39. package/lib/commonjs/Image/index.js.map +1 -1
  40. package/lib/commonjs/Main.js +1 -8
  41. package/lib/commonjs/Main.js.map +1 -1
  42. package/lib/commonjs/Spec/NativeCompressor.js.map +1 -1
  43. package/lib/commonjs/Video/index.js +4 -33
  44. package/lib/commonjs/Video/index.js.map +1 -1
  45. package/lib/commonjs/expo-plugin/compressor.js.map +1 -1
  46. package/lib/commonjs/index.js +25 -6
  47. package/lib/commonjs/index.js.map +1 -1
  48. package/lib/commonjs/utils/Downloader.js +38 -0
  49. package/lib/commonjs/utils/Downloader.js.map +1 -0
  50. package/lib/commonjs/utils/Uploader.js +40 -0
  51. package/lib/commonjs/utils/Uploader.js.map +1 -0
  52. package/lib/commonjs/utils/index.js +47 -1
  53. package/lib/commonjs/utils/index.js.map +1 -1
  54. package/lib/module/Image/index.js +1 -1
  55. package/lib/module/Image/index.js.map +1 -1
  56. package/lib/module/Main.js +1 -7
  57. package/lib/module/Main.js.map +1 -1
  58. package/lib/module/Spec/NativeCompressor.js.map +1 -1
  59. package/lib/module/Video/index.js +5 -33
  60. package/lib/module/Video/index.js.map +1 -1
  61. package/lib/module/expo-plugin/compressor.js.map +1 -1
  62. package/lib/module/index.js +9 -7
  63. package/lib/module/index.js.map +1 -1
  64. package/lib/module/utils/Downloader.js +31 -0
  65. package/lib/module/utils/Downloader.js.map +1 -0
  66. package/lib/module/utils/Uploader.js +33 -0
  67. package/lib/module/utils/Uploader.js.map +1 -0
  68. package/lib/module/utils/index.js +9 -0
  69. package/lib/module/utils/index.js.map +1 -1
  70. package/lib/typescript/Image/index.d.ts +4 -0
  71. package/lib/typescript/Image/index.d.ts.map +1 -1
  72. package/lib/typescript/Main.d.ts +1 -2
  73. package/lib/typescript/Main.d.ts.map +1 -1
  74. package/lib/typescript/Spec/NativeCompressor.d.ts +16 -2
  75. package/lib/typescript/Spec/NativeCompressor.d.ts.map +1 -1
  76. package/lib/typescript/Video/index.d.ts +4 -28
  77. package/lib/typescript/Video/index.d.ts.map +1 -1
  78. package/lib/typescript/index.d.ts +7 -4
  79. package/lib/typescript/index.d.ts.map +1 -1
  80. package/lib/typescript/utils/Downloader.d.ts +2 -0
  81. package/lib/typescript/utils/Downloader.d.ts.map +1 -0
  82. package/lib/typescript/utils/Uploader.d.ts +28 -0
  83. package/lib/typescript/utils/Uploader.d.ts.map +1 -0
  84. package/lib/typescript/utils/index.d.ts +4 -1
  85. package/lib/typescript/utils/index.d.ts.map +1 -1
  86. package/package.json +6 -4
  87. package/src/Image/index.tsx +5 -1
  88. package/src/Main.tsx +1 -15
  89. package/src/Spec/NativeCompressor.ts +25 -2
  90. package/src/Video/index.tsx +11 -84
  91. package/src/expo-plugin/compressor.ts +1 -1
  92. package/src/index.tsx +12 -3
  93. package/src/utils/Downloader.tsx +38 -0
  94. package/src/utils/Uploader.tsx +78 -0
  95. package/src/utils/index.tsx +15 -0
  96. package/android/src/main/java/com/reactnativecompressor/Audio/AudioCompressor.java +0 -605
  97. package/android/src/main/java/com/reactnativecompressor/CompressorModule.java +0 -220
  98. package/android/src/main/java/com/reactnativecompressor/CompressorPackage.java +0 -58
  99. package/android/src/main/java/com/reactnativecompressor/Image/ImageCompressor.java +0 -257
  100. package/android/src/main/java/com/reactnativecompressor/Image/utils/ImageCompressorOptions.java +0 -69
  101. package/android/src/main/java/com/reactnativecompressor/Image/utils/ImageSize.java +0 -13
  102. package/android/src/main/java/com/reactnativecompressor/Utils/FileUplaoder/FileUploadHelper.java +0 -39
  103. package/android/src/main/java/com/reactnativecompressor/Utils/FileUplaoder/FileUploader.java +0 -129
  104. package/android/src/main/java/com/reactnativecompressor/Utils/MediaCache.java +0 -65
  105. package/android/src/main/java/com/reactnativecompressor/Utils/RealPathUtil.java +0 -210
  106. package/android/src/main/java/com/reactnativecompressor/Utils/Utils.java +0 -272
  107. package/android/src/main/java/com/reactnativecompressor/Video/AutoVideoCompression/AutoVideoCompression.java +0 -87
  108. package/android/src/main/java/com/reactnativecompressor/Video/VideoCompressorHelper.java +0 -182
  109. package/android/src/main/java/com/reactnativecompressor/Video/VideoModule.java +0 -112
  110. package/android/src/newarch/CompressorSpec.java +0 -9
  111. package/android/src/newarch/VideoCompressorSpec.java +0 -9
  112. package/android/src/oldarch/CompressorSpec.java +0 -34
  113. package/android/src/oldarch/VideoCompressorSpec.java +0 -26
  114. package/ios/Image/ImageCompressor.h +0 -22
  115. package/ios/Image/ImageCompressor.m +0 -540
  116. package/ios/Image/ImageCompressorOptions.h +0 -28
  117. package/ios/Image/ImageCompressorOptions.m +0 -97
  118. package/ios/Utils/Downloader.h +0 -16
  119. package/ios/Utils/Downloader.m +0 -150
  120. package/ios/Utils/MediaCache.h +0 -11
  121. package/ios/Utils/MediaCache.m +0 -51
  122. package/ios/Video/VideoCompressor.h +0 -5
  123. package/ios/Video/VideoCompressor.m +0 -1
  124. package/lib/commonjs/Spec/NativeVideoCompressor.js +0 -10
  125. package/lib/commonjs/Spec/NativeVideoCompressor.js.map +0 -1
  126. package/lib/module/Spec/NativeVideoCompressor.js +0 -3
  127. package/lib/module/Spec/NativeVideoCompressor.js.map +0 -1
  128. package/lib/typescript/Spec/NativeVideoCompressor.d.ts +0 -13
  129. package/lib/typescript/Spec/NativeVideoCompressor.d.ts.map +0 -1
  130. package/src/Spec/NativeVideoCompressor.ts +0 -14
@@ -0,0 +1,63 @@
1
+ package com.reactnativecompressor.Video
2
+
3
+ import android.media.MediaMetadataRetriever
4
+ import android.net.Uri
5
+ import com.facebook.react.bridge.Promise
6
+ import com.facebook.react.bridge.ReactApplicationContext
7
+ import com.reactnativecompressor.Utils.Utils.compressVideo
8
+ import com.reactnativecompressor.Utils.Utils.generateCacheFilePath
9
+ import java.io.File
10
+
11
+ object AutoVideoCompression {
12
+ fun createCompressionSettings(fileUrl: String?, options: VideoCompressorHelper, promise: Promise, reactContext: ReactApplicationContext?) {
13
+ val maxSize = options.maxSize
14
+ val minimumFileSizeForCompress = options.minimumFileSizeForCompress
15
+ try {
16
+ val uri = Uri.parse(fileUrl)
17
+ val srcPath = uri.path
18
+ val metaRetriever = MediaMetadataRetriever()
19
+ metaRetriever.setDataSource(srcPath)
20
+ val file = File(srcPath)
21
+ val sizeInBytes = file.length().toFloat()
22
+ val sizeInMb = sizeInBytes / (1024 * 1024)
23
+ if (sizeInMb > minimumFileSizeForCompress) {
24
+ val destinationPath = generateCacheFilePath("mp4", reactContext!!)
25
+ val actualHeight = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)!!.toInt()
26
+ val actualWidth = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)!!.toInt()
27
+ val bitrate = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE)!!.toInt()
28
+ val scale = if (actualWidth > actualHeight) maxSize / actualWidth else maxSize / actualHeight
29
+ val resultWidth = Math.round(actualWidth * scale / 2) * 2
30
+ val resultHeight = Math.round(actualHeight * scale / 2) * 2
31
+ val videoBitRate = makeVideoBitrate(
32
+ actualHeight, actualWidth,
33
+ bitrate,
34
+ resultHeight, resultWidth
35
+ ).toFloat()
36
+ compressVideo(srcPath!!, destinationPath, resultWidth, resultHeight, videoBitRate, options.uuid!!,options.progressDivider!!, promise, reactContext)
37
+ } else {
38
+ promise.resolve(fileUrl)
39
+ }
40
+ } catch (ex: Exception) {
41
+ promise.reject(ex)
42
+ }
43
+ }
44
+
45
+ fun makeVideoBitrate(originalHeight: Int, originalWidth: Int, originalBitrate: Int, height: Int, width: Int): Int {
46
+ val compressFactor = 0.8f
47
+ val minCompressFactor = 0.8f
48
+ val maxBitrate = 1669000
49
+ var remeasuredBitrate = (originalBitrate / Math.min(originalHeight / height.toFloat(), originalWidth / width.toFloat())).toInt()
50
+ remeasuredBitrate = (remeasuredBitrate * compressFactor).toInt()
51
+ val minBitrate = (getVideoBitrateWithFactor(minCompressFactor) / (1280f * 720f / (width * height))).toInt()
52
+ if (originalBitrate < minBitrate) {
53
+ return remeasuredBitrate
54
+ }
55
+ return if (remeasuredBitrate > maxBitrate) {
56
+ maxBitrate
57
+ } else Math.max(remeasuredBitrate, minBitrate)
58
+ }
59
+
60
+ private fun getVideoBitrateWithFactor(f: Float): Int {
61
+ return (f * 2000f * 1000f * 1.13f).toInt()
62
+ }
63
+ }
@@ -0,0 +1,125 @@
1
+ package com.reactnativecompressor.Video
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.content.Context
5
+ import android.media.MediaMetadataRetriever
6
+ import android.net.Uri
7
+ import android.os.Handler
8
+ import android.os.PowerManager
9
+ import android.os.PowerManager.WakeLock
10
+ import com.facebook.react.bridge.LifecycleEventListener
11
+ import com.facebook.react.bridge.Promise
12
+ import com.facebook.react.bridge.ReactApplicationContext
13
+ import com.facebook.react.bridge.ReadableMap
14
+ import com.reactnativecompressor.Utils.EventEmitterHandler
15
+ import com.reactnativecompressor.Utils.Utils
16
+ import java.util.UUID
17
+
18
+ class VideoCompressorHelper {
19
+ enum class CompressionMethod {
20
+ auto,
21
+ manual
22
+ }
23
+
24
+ var compressionMethod = CompressionMethod.auto
25
+ var bitrate = 0f
26
+ var uuid: String? = ""
27
+ var maxSize = 640.0f
28
+ var progressDivider: Int? = 0
29
+ var minimumFileSizeForCompress = 0.0f
30
+
31
+ companion object {
32
+ private var _reactContext: ReactApplicationContext? = null
33
+ private var backgroundId: String? = null
34
+ private var handler: Handler? = null
35
+ private var runnable: Runnable? = null
36
+ private var powerManager: PowerManager? = null
37
+ private var wakeLock: WakeLock? = null
38
+ private val listener: LifecycleEventListener = object : LifecycleEventListener {
39
+ override fun onHostResume() {}
40
+ override fun onHostPause() {}
41
+ override fun onHostDestroy() {
42
+ if (wakeLock!!.isHeld) {
43
+ wakeLock!!.release()
44
+ EventEmitterHandler.emitBackgroundTaskExpired(backgroundId)
45
+
46
+ }
47
+ }
48
+ }
49
+
50
+ @SuppressLint("InvalidWakeLockTag")
51
+ fun video_activateBackgroundTask_helper(options: ReadableMap?, reactContext: ReactApplicationContext): String {
52
+ _reactContext = reactContext
53
+ backgroundId = UUID.randomUUID().toString()
54
+ powerManager = reactContext.getSystemService(Context.POWER_SERVICE) as PowerManager
55
+ wakeLock = powerManager!!.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "bg_wakelock")
56
+ reactContext.addLifecycleEventListener(listener)
57
+ if (!wakeLock!!.isHeld()) {
58
+ wakeLock!!.acquire()
59
+ }
60
+ handler = Handler()
61
+ runnable = Runnable { }
62
+ handler!!.post(runnable!!)
63
+ return ""
64
+ }
65
+
66
+ fun video_deactivateBackgroundTask_helper(options: ReadableMap?, reactContext: ReactApplicationContext?): String {
67
+ if (wakeLock!!.isHeld) wakeLock!!.release()
68
+
69
+ // avoid null pointer exceptio when stop is called without start
70
+ if (handler != null) handler!!.removeCallbacks(runnable!!)
71
+ backgroundId = ""
72
+ return ""
73
+ }
74
+
75
+ fun fromMap(map: ReadableMap): VideoCompressorHelper {
76
+ val options = VideoCompressorHelper()
77
+ val iterator = map.keySetIterator()
78
+ while (iterator.hasNextKey()) {
79
+ val key = iterator.nextKey()
80
+ when (key) {
81
+ "compressionMethod" -> options.compressionMethod = CompressionMethod.valueOf(map.getString(key)!!)
82
+ "maxSize" -> options.maxSize = map.getDouble(key).toFloat()
83
+ "uuid" -> options.uuid = map.getString(key)
84
+ "minimumFileSizeForCompress" -> options.minimumFileSizeForCompress = map.getDouble(key).toFloat()
85
+ "bitrate" -> options.bitrate = map.getDouble(key).toFloat()
86
+ "progressDivider" -> options.progressDivider = map.getInt(key)
87
+ }
88
+ }
89
+ return options
90
+ }
91
+ fun VideoCompressManual(fileUrl: String?, options: VideoCompressorHelper, promise: Promise, reactContext: ReactApplicationContext?) {
92
+ try {
93
+ val uri = Uri.parse(fileUrl)
94
+ val srcPath = uri.path
95
+ val destinationPath = Utils.generateCacheFilePath("mp4", reactContext!!)
96
+ val metaRetriever = MediaMetadataRetriever()
97
+ metaRetriever.setDataSource(srcPath)
98
+ var height = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)!!.toInt()
99
+ var width = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)!!.toInt()
100
+ val bitrate = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE)!!.toInt()
101
+ val isPortrait = height > width
102
+ val maxSize = options.maxSize.toInt()
103
+ if (isPortrait && height > maxSize) {
104
+ width = (maxSize.toFloat() / height * width).toInt()
105
+ height = maxSize
106
+ } else if (width > maxSize) {
107
+ height = (maxSize.toFloat() / width * height).toInt()
108
+ width = maxSize
109
+ } else {
110
+ if (options.bitrate == 0f) {
111
+ options.bitrate = (bitrate * 0.8).toInt().toFloat()
112
+ }
113
+ }
114
+ val videoBitRate = if (options.bitrate > 0) options.bitrate else (height * width * 1.5).toFloat()
115
+ Utils.compressVideo(srcPath!!, destinationPath, width, height, videoBitRate, options.uuid!!,options.progressDivider!!, promise, reactContext)
116
+ } catch (ex: Exception) {
117
+ promise.reject(ex)
118
+ }
119
+ }
120
+
121
+ fun VideoCompressAuto(fileUrl: String?, options: VideoCompressorHelper?, promise: Promise?, reactContext: ReactApplicationContext?) {
122
+ AutoVideoCompression.createCompressionSettings(fileUrl, options!!, promise!!, reactContext)
123
+ }
124
+ }
125
+ }
@@ -0,0 +1,86 @@
1
+ package com.reactnativecompressor.Video
2
+
3
+ import android.media.MediaMetadataRetriever
4
+ import android.net.Uri
5
+ import android.util.Log
6
+ import com.facebook.react.bridge.Arguments
7
+ import com.facebook.react.bridge.Promise
8
+ import com.facebook.react.bridge.ReactApplicationContext
9
+ import com.facebook.react.bridge.ReadableMap
10
+ import com.reactnativecompressor.Utils.Utils
11
+ import com.reactnativecompressor.Video.VideoCompressorHelper.Companion.video_activateBackgroundTask_helper
12
+ import com.reactnativecompressor.Video.VideoCompressorHelper.Companion.video_deactivateBackgroundTask_helper
13
+ import java.io.File
14
+
15
+ class VideoMain(private val reactContext: ReactApplicationContext) {
16
+ //Video
17
+ fun compress(
18
+ fileUrl: String,
19
+ optionMap: ReadableMap,
20
+ promise: Promise) {
21
+ var fileUrl: String? = fileUrl
22
+ val options = VideoCompressorHelper.fromMap(optionMap)
23
+ fileUrl = Utils.getRealPath(fileUrl, reactContext, options.uuid,options.progressDivider)
24
+ if (options.compressionMethod === VideoCompressorHelper.CompressionMethod.auto) {
25
+ VideoCompressorHelper.VideoCompressAuto(fileUrl, options, promise, reactContext)
26
+ } else {
27
+ VideoCompressorHelper.VideoCompressManual(fileUrl, options, promise, reactContext)
28
+ }
29
+ }
30
+
31
+ fun cancelCompression(
32
+ uuid: String) {
33
+ Utils.cancelCompressionHelper(uuid)
34
+ Log.d("cancelCompression", uuid)
35
+ }
36
+
37
+ fun activateBackgroundTask(
38
+ options: ReadableMap,
39
+ promise: Promise) {
40
+ try {
41
+ val response: String = video_activateBackgroundTask_helper(options, reactContext)
42
+ promise.resolve(response)
43
+ } catch (ex: Exception) {
44
+ promise.reject(ex)
45
+ }
46
+ }
47
+
48
+ fun deactivateBackgroundTask(
49
+ options: ReadableMap,
50
+ promise: Promise) {
51
+ try {
52
+ val response: String = video_deactivateBackgroundTask_helper(options, reactContext)
53
+ promise.resolve(response)
54
+ } catch (ex: Exception) {
55
+ promise.reject(ex)
56
+ }
57
+ }
58
+
59
+ fun getVideoMetaData(filePath: String, promise: Promise) {
60
+ var filePath: String? = filePath
61
+ try {
62
+ filePath = Utils.getRealPath(filePath, reactContext)
63
+ val uri = Uri.parse(filePath)
64
+ val srcPath = uri.path
65
+ val metaRetriever = MediaMetadataRetriever()
66
+ metaRetriever.setDataSource(srcPath)
67
+ val file = File(srcPath)
68
+ val sizeInKBs = (file.length() / 1024).toFloat()
69
+ val actualHeight = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)!!.toInt()
70
+ val actualWidth = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)!!.toInt()
71
+ val duration = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)!!.toLong()
72
+ val creationTime = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DATE)
73
+ val extension = filePath!!.substring(filePath.lastIndexOf(".") + 1)
74
+ val params = Arguments.createMap()
75
+ params.putString("size", sizeInKBs.toString())
76
+ params.putString("width", actualWidth.toString())
77
+ params.putString("height", actualHeight.toString())
78
+ params.putString("duration", (duration / 1000).toString())
79
+ params.putString("extension", extension)
80
+ params.putString("creationTime", creationTime.toString())
81
+ promise.resolve(params)
82
+ } catch (e: Exception) {
83
+ promise.reject(e)
84
+ }
85
+ }
86
+ }
@@ -0,0 +1,5 @@
1
+ package com.reactnativecompressor
2
+
3
+ import com.facebook.react.bridge.ReactApplicationContext
4
+
5
+ abstract class CompressorSpec(context: ReactApplicationContext?) : NativeCompressorSpec(context)
@@ -0,0 +1,34 @@
1
+ package com.reactnativecompressor
2
+
3
+ import com.facebook.react.bridge.Promise
4
+ import com.facebook.react.bridge.ReactApplicationContext
5
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
6
+ import com.facebook.react.bridge.ReadableMap
7
+
8
+ abstract class CompressorSpec(context: ReactApplicationContext?) : ReactContextBaseJavaModule(context) {
9
+ abstract fun image_compress(
10
+ imagePath: String,
11
+ optionMap: ReadableMap,
12
+ promise: Promise)
13
+
14
+ abstract fun compress_audio(
15
+ fileUrl: String,
16
+ optionMap: ReadableMap,
17
+ promise: Promise)
18
+
19
+ abstract fun generateFilePath(_extension: String, promise: Promise)
20
+ abstract fun getRealPath(path: String, type: String, promise: Promise)
21
+ abstract fun getVideoMetaData(filePath: String, promise: Promise)
22
+ abstract fun getFileSize(filePath: String, promise: Promise)
23
+ abstract fun compress(fileUrl: String, optionMap: ReadableMap, promise: Promise)
24
+ abstract fun cancelCompression(uuid: String)
25
+ abstract fun upload(fileUrl: String, options: ReadableMap, promise: Promise)
26
+
27
+ abstract fun download(fileUrl: String, options: ReadableMap, promise: Promise)
28
+ abstract fun activateBackgroundTask(options: ReadableMap, promise: Promise)
29
+ abstract fun deactivateBackgroundTask(options: ReadableMap, promise: Promise)
30
+ abstract fun createVideoThumbnail(fileUrl: String?, options: ReadableMap?, promise: Promise)
31
+ abstract fun clearCache(cacheDir: String?, promise: com.facebook.react.bridge.Promise?)
32
+ abstract fun addListener(eventName: String)
33
+ abstract fun removeListeners(count: Double)
34
+ }
@@ -0,0 +1,115 @@
1
+ //
2
+ // AudioMain.swift
3
+ // react-native-compressor
4
+ //
5
+ // Created by Numan on 10/09/2023.
6
+ //
7
+
8
+ import Foundation
9
+ import AVFoundation
10
+ let AlAsset_Library_Scheme = "assets-library"
11
+ class AudioMain{
12
+ static func compress_audio(_ fileUrl: String, optionMap: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
13
+ do {
14
+ var fileUrl = fileUrl
15
+ if fileUrl.hasPrefix("file://") {
16
+ fileUrl = fileUrl.replacingOccurrences(of: "file://", with: "")
17
+ }
18
+ let fileManager = FileManager.default
19
+ var isDir: ObjCBool = false
20
+ if !fileManager.fileExists(atPath: fileUrl, isDirectory: &isDir) || isDir.boolValue {
21
+ let err = NSError(domain: "file not found", code: -15, userInfo: nil)
22
+ reject(String(err.code), err.localizedDescription, err)
23
+ return
24
+ }
25
+
26
+ let assetOptions: [String: Any] = [AVURLAssetPreferPreciseDurationAndTimingKey: true]
27
+ let asset = AVURLAsset(url: URL(fileURLWithPath: fileUrl), options: assetOptions)
28
+ let quality = optionMap["quality"] as? String ?? ""
29
+ let qualityConstant = getAudioQualityConstant(quality)
30
+ auto_compress_helper(asset, qualityConstant: qualityConstant) { mp3Path, finished in
31
+ if finished {
32
+ resolve("file://\(mp3Path ?? "")")
33
+ } else {
34
+ reject("Error", "Something went wrong", nil)
35
+ }
36
+ }
37
+ } catch {
38
+ reject(error.localizedDescription, error.localizedDescription, nil)
39
+ }
40
+ }
41
+
42
+ static func getAudioQualityConstant(_ quality: String) -> String {
43
+ let audioQualityArray = ["low", "medium", "high"]
44
+ if let index = audioQualityArray.firstIndex(of: quality) {
45
+ switch index {
46
+ case 0:
47
+ return AVAssetExportPresetLowQuality
48
+ case 1:
49
+ return AVAssetExportPresetMediumQuality
50
+ case 2:
51
+ return AVAssetExportPresetHighestQuality
52
+ default:
53
+ return AVAssetExportPresetMediumQuality
54
+ }
55
+ }
56
+ return AVAssetExportPresetMediumQuality
57
+ }
58
+
59
+ static func auto_compress_helper(_ avAsset: AVURLAsset, qualityConstant: String, complete completeCallback: @escaping (_ mp3Path: String?, _ finished: Bool) -> Void) {
60
+ var path: String
61
+ if avAsset.url.scheme == AlAsset_Library_Scheme {
62
+ path = avAsset.url.query ?? ""
63
+ if path.isEmpty {
64
+ completeCallback(nil, false)
65
+ return
66
+ }
67
+ } else {
68
+ path = avAsset.url.path
69
+ if path.isEmpty || !FileManager.default.fileExists(atPath: path) {
70
+ completeCallback(nil, false)
71
+ return
72
+ }
73
+ }
74
+
75
+ let mp3Path = Utils.generateCacheFilePath("m4a")
76
+
77
+ if FileManager.default.fileExists(atPath: mp3Path) {
78
+ completeCallback(mp3Path, true)
79
+ return
80
+ }
81
+
82
+ let compatiblePresets = AVAssetExportSession.exportPresets(compatibleWith: avAsset)
83
+
84
+ if compatiblePresets.contains(qualityConstant) {
85
+ let exportSession = AVAssetExportSession(asset: avAsset, presetName: AVAssetExportPresetAppleM4A)
86
+
87
+ let mp3Url = URL(fileURLWithPath: mp3Path)
88
+ exportSession?.outputURL = mp3Url
89
+ exportSession?.shouldOptimizeForNetworkUse = true
90
+ exportSession?.outputFileType = .m4a
91
+
92
+ exportSession?.exportAsynchronously(completionHandler: {
93
+ var finished = false
94
+ switch exportSession?.status {
95
+ case .failed:
96
+ print("AVAssetExportSessionStatusFailed, error: \(exportSession?.error?.localizedDescription ?? "").")
97
+ case .cancelled:
98
+ print("AVAssetExportSessionStatusCancelled.")
99
+ case .completed:
100
+ print("AVAssetExportSessionStatusCompleted.")
101
+ finished = true
102
+ case .unknown:
103
+ print("AVAssetExportSessionStatusUnknown")
104
+ case .waiting:
105
+ print("AVAssetExportSessionStatusWaiting")
106
+ case .exporting:
107
+ print("AVAssetExportSessionStatusExporting")
108
+ default:
109
+ break
110
+ }
111
+ completeCallback(mp3Path, finished)
112
+ })
113
+ }
114
+ }
115
+ }
@@ -3,5 +3,4 @@
3
3
  //
4
4
  #import <React/RCTBridgeModule.h>
5
5
  #import <React/RCTEventEmitter.h>
6
- #import "ImageCompressor.h"
7
- #import "MediaCache.h"
6
+ #import <Foundation/Foundation.h>
package/ios/Compressor.h CHANGED
@@ -2,12 +2,4 @@
2
2
 
3
3
  #ifdef RCT_NEW_ARCH_ENABLED
4
4
  #import "RNCompressorSpec.h"
5
-
6
- @interface Compressor : RCTEventEmitter <NativeCompressorSpec>
7
- #else
8
- #import <React/RCTBridgeModule.h>
9
-
10
- @interface Compressor : RCTEventEmitter <RCTBridgeModule>
11
5
  #endif
12
-
13
- @end