···11+diff --git a/node_modules/react-native-compressor/android/build.gradle b/node_modules/react-native-compressor/android/build.gradle
22+index 5071139..84bee34 100644
33+--- a/node_modules/react-native-compressor/android/build.gradle
44++++ b/node_modules/react-native-compressor/android/build.gradle
55+@@ -115,7 +115,6 @@ dependencies {
66+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4"
77+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"
88+ implementation 'org.mp4parser:isoparser:1.9.56'
99+- implementation 'com.github.banketree:AndroidLame-kotlin:v0.0.1'
1010+ implementation 'javazoom:jlayer:1.0.1'
1111+ }
1212+1313+diff --git a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioCompressor.kt b/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioCompressor.kt
1414+deleted file mode 100644
1515+index 9292d3e..0000000
1616+--- a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioCompressor.kt
1717++++ /dev/null
1818+@@ -1,264 +0,0 @@
1919+-package com.reactnativecompressor.Audio
2020+-
2121+-
2222+-import android.annotation.SuppressLint
2323+-import com.facebook.react.bridge.Promise
2424+-import com.facebook.react.bridge.ReactApplicationContext
2525+-import com.facebook.react.bridge.ReadableMap
2626+-import com.naman14.androidlame.LameBuilder
2727+-import com.naman14.androidlame.WaveReader
2828+-import com.reactnativecompressor.Utils.MediaCache
2929+-import com.reactnativecompressor.Utils.Utils
3030+-import com.reactnativecompressor.Utils.Utils.addLog
3131+-import javazoom.jl.converter.Converter
3232+-import javazoom.jl.decoder.JavaLayerException
3333+-import java.io.BufferedOutputStream
3434+-import java.io.File
3535+-import java.io.FileNotFoundException
3636+-import java.io.FileOutputStream
3737+-import java.io.IOException
3838+-
3939+-class AudioCompressor {
4040+- companion object {
4141+- val TAG="AudioMain"
4242+- private const val OUTPUT_STREAM_BUFFER = 8192
4343+-
4444+- var outputStream: BufferedOutputStream? = null
4545+- var waveReader: WaveReader? = null
4646+- @JvmStatic
4747+- fun CompressAudio(
4848+- fileUrl: String,
4949+- optionMap: ReadableMap,
5050+- context: ReactApplicationContext,
5151+- promise: Promise,
5252+- ) {
5353+- val realPath = Utils.getRealPath(fileUrl, context)
5454+- var _fileUrl=realPath
5555+- val filePathWithoutFileUri = realPath!!.replace("file://", "")
5656+- try {
5757+- var wavPath=filePathWithoutFileUri;
5858+- var isNonWav:Boolean=false
5959+- if (fileUrl.endsWith(".mp4", ignoreCase = true))
6060+- {
6161+- addLog("mp4 file found")
6262+- val mp3Path= Utils.generateCacheFilePath("mp3", context)
6363+- AudioExtractor().genVideoUsingMuxer(fileUrl, mp3Path, -1, -1, true, false)
6464+- _fileUrl=Utils.slashifyFilePath(mp3Path)
6565+- wavPath= Utils.generateCacheFilePath("wav", context)
6666+- try {
6767+- val converter = Converter()
6868+- converter.convert(mp3Path, wavPath)
6969+- } catch (e: JavaLayerException) {
7070+- addLog("JavaLayerException error"+e.localizedMessage)
7171+- e.printStackTrace();
7272+- }
7373+- isNonWav=true
7474+- }
7575+- else if (!fileUrl.endsWith(".wav", ignoreCase = true))
7676+- {
7777+- addLog("non wav file found")
7878+- wavPath= Utils.generateCacheFilePath("wav", context)
7979+- try {
8080+- val converter = Converter()
8181+- converter.convert(filePathWithoutFileUri, wavPath)
8282+- } catch (e: JavaLayerException) {
8383+- addLog("JavaLayerException error"+e.localizedMessage)
8484+- e.printStackTrace();
8585+- }
8686+- isNonWav=true
8787+- }
8888+-
8989+-
9090+- autoCompressHelper(wavPath,filePathWithoutFileUri, optionMap,context) { mp3Path, finished ->
9191+- if (finished) {
9292+- val returnableFilePath:String="file://$mp3Path"
9393+- addLog("finished: " + returnableFilePath)
9494+- MediaCache.removeCompletedImagePath(fileUrl)
9595+- if(isNonWav)
9696+- {
9797+- File(wavPath).delete()
9898+- }
9999+- promise.resolve(returnableFilePath)
100100+- } else {
101101+- addLog("error: "+mp3Path)
102102+- promise.resolve(_fileUrl)
103103+- }
104104+- }
105105+- } catch (e: Exception) {
106106+- promise.resolve(_fileUrl)
107107+- }
108108+- }
109109+-
110110+- @SuppressLint("WrongConstant")
111111+- private fun autoCompressHelper(
112112+- fileUrl: String,
113113+- actualFileUrl: String,
114114+- optionMap: ReadableMap,
115115+- context: ReactApplicationContext,
116116+- completeCallback: (String, Boolean) -> Unit
117117+- ) {
118118+-
119119+- val options = AudioHelper.fromMap(optionMap)
120120+- val quality = options.quality
121121+-
122122+- var isCompletedCallbackTriggered:Boolean=false
123123+- try {
124124+- var mp3Path = Utils.generateCacheFilePath("mp3", context)
125125+- val input = File(fileUrl)
126126+- val output = File(mp3Path)
127127+-
128128+- val CHUNK_SIZE = 8192
129129+- addLog("Initialising wav reader")
130130+-
131131+- waveReader = WaveReader(input)
132132+-
133133+- try {
134134+- waveReader!!.openWave()
135135+- } catch (e: IOException) {
136136+- e.printStackTrace()
137137+- }
138138+-
139139+- addLog("Intitialising encoder")
140140+-
141141+-
142142+- // for bitrate
143143+- var audioBitrate:Int
144144+- if(options.bitrate != -1)
145145+- {
146146+- audioBitrate= options.bitrate/1000
147147+- }
148148+- else
149149+- {
150150+- audioBitrate=AudioHelper.getDestinationBitrateByQuality(actualFileUrl, quality!!)
151151+- Utils.addLog("dest bitrate: $audioBitrate")
152152+- }
153153+-
154154+- var androidLame = LameBuilder();
155155+- androidLame.setOutBitrate(audioBitrate)
156156+-
157157+- // for channels
158158+- var audioChannels:Int
159159+- if(options.channels != -1){
160160+- audioChannels= options.channels!!
161161+- }
162162+- else
163163+- {
164164+- audioChannels=waveReader!!.channels
165165+- }
166166+- androidLame.setOutChannels(audioChannels)
167167+-
168168+- // for sample rate
169169+- androidLame.setInSampleRate(waveReader!!.sampleRate)
170170+- var audioSampleRate:Int
171171+- if(options.samplerate != -1){
172172+- audioSampleRate= options.samplerate!!
173173+- }
174174+- else
175175+- {
176176+- audioSampleRate=waveReader!!.sampleRate
177177+- }
178178+- androidLame.setOutSampleRate(audioSampleRate)
179179+- val androidLameBuild=androidLame.build()
180180+-
181181+- try {
182182+- outputStream = BufferedOutputStream(FileOutputStream(output), OUTPUT_STREAM_BUFFER)
183183+- } catch (e: FileNotFoundException) {
184184+- e.printStackTrace()
185185+- }
186186+-
187187+- var bytesRead = 0
188188+-
189189+- val buffer_l = ShortArray(CHUNK_SIZE)
190190+- val buffer_r = ShortArray(CHUNK_SIZE)
191191+- val mp3Buf = ByteArray(CHUNK_SIZE)
192192+-
193193+- val channels = waveReader!!.channels
194194+-
195195+- addLog("started encoding")
196196+- while (true) {
197197+- try {
198198+- if (channels == 2) {
199199+-
200200+- bytesRead = waveReader!!.read(buffer_l, buffer_r, CHUNK_SIZE)
201201+- addLog("bytes read=$bytesRead")
202202+-
203203+- if (bytesRead > 0) {
204204+-
205205+- var bytesEncoded = 0
206206+- bytesEncoded = androidLameBuild.encode(buffer_l, buffer_r, bytesRead, mp3Buf)
207207+- addLog("bytes encoded=$bytesEncoded")
208208+-
209209+- if (bytesEncoded > 0) {
210210+- try {
211211+- addLog("writing mp3 buffer to outputstream with $bytesEncoded bytes")
212212+- outputStream!!.write(mp3Buf, 0, bytesEncoded)
213213+- } catch (e: IOException) {
214214+- e.printStackTrace()
215215+- }
216216+-
217217+- }
218218+-
219219+- } else
220220+- break
221221+- } else {
222222+-
223223+- bytesRead = waveReader!!.read(buffer_l, CHUNK_SIZE)
224224+- addLog("bytes read=$bytesRead")
225225+-
226226+- if (bytesRead > 0) {
227227+- var bytesEncoded = 0
228228+-
229229+- bytesEncoded = androidLameBuild.encode(buffer_l, buffer_l, bytesRead, mp3Buf)
230230+- addLog("bytes encoded=$bytesEncoded")
231231+-
232232+- if (bytesEncoded > 0) {
233233+- try {
234234+- addLog("writing mp3 buffer to outputstream with $bytesEncoded bytes")
235235+- outputStream!!.write(mp3Buf, 0, bytesEncoded)
236236+- } catch (e: IOException) {
237237+- e.printStackTrace()
238238+- }
239239+-
240240+- }
241241+-
242242+- } else
243243+- break
244244+- }
245245+-
246246+-
247247+- } catch (e: IOException) {
248248+- e.printStackTrace()
249249+- }
250250+-
251251+- }
252252+-
253253+- addLog("flushing final mp3buffer")
254254+- val outputMp3buf = androidLameBuild.flush(mp3Buf)
255255+- addLog("flushed $outputMp3buf bytes")
256256+- if (outputMp3buf > 0) {
257257+- try {
258258+- addLog("writing final mp3buffer to outputstream")
259259+- outputStream!!.write(mp3Buf, 0, outputMp3buf)
260260+- addLog("closing output stream")
261261+- outputStream!!.close()
262262+- completeCallback(output.absolutePath, true)
263263+- isCompletedCallbackTriggered=true
264264+- } catch (e: IOException) {
265265+- completeCallback(e.localizedMessage, false)
266266+- e.printStackTrace()
267267+- }
268268+- }
269269+-
270270+- } catch (e: IOException) {
271271+- completeCallback(e.localizedMessage, false)
272272+- }
273273+- if(!isCompletedCallbackTriggered)
274274+- {
275275+- completeCallback("something went wrong", false)
276276+- }
277277+- }
278278+-
279279+-
280280+-
281281+- }
282282+-}
283283+diff --git a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioExtractor.kt b/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioExtractor.kt
284284+deleted file mode 100644
285285+index c655182..0000000
286286+--- a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioExtractor.kt
287287++++ /dev/null
288288+@@ -1,112 +0,0 @@
289289+-package com.reactnativecompressor.Audio
290290+-
291291+-import android.annotation.SuppressLint
292292+-import android.media.MediaCodec
293293+-import android.media.MediaExtractor
294294+-import android.media.MediaFormat
295295+-import android.media.MediaMetadataRetriever
296296+-import android.media.MediaMuxer
297297+-import android.util.Log
298298+-import java.io.IOException
299299+-import java.nio.ByteBuffer
300300+-
301301+-
302302+-class AudioExtractor {
303303+- /**
304304+- * @param srcPath the path of source video file.
305305+- * @param dstPath the path of destination video file.
306306+- * @param startMs starting time in milliseconds for trimming. Set to
307307+- * negative if starting from beginning.
308308+- * @param endMs end time for trimming in milliseconds. Set to negative if
309309+- * no trimming at the end.
310310+- * @param useAudio true if keep the audio track from the source.
311311+- * @param useVideo true if keep the video track from the source.
312312+- * @throws IOException
313313+- */
314314+- @SuppressLint("NewApi", "WrongConstant")
315315+- @Throws(IOException::class)
316316+- fun genVideoUsingMuxer(srcPath: String?, dstPath: String?, startMs: Int, endMs: Int, useAudio: Boolean, useVideo: Boolean) {
317317+- // Set up MediaExtractor to read from the source.
318318+- val extractor = MediaExtractor()
319319+- extractor.setDataSource(srcPath!!)
320320+- val trackCount = extractor.trackCount
321321+- // Set up MediaMuxer for the destination.
322322+- val muxer: MediaMuxer
323323+- muxer = MediaMuxer(dstPath!!, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)
324324+- // Set up the tracks and retrieve the max buffer size for selected
325325+- // tracks.
326326+- val indexMap = HashMap<Int, Int>(trackCount)
327327+- var bufferSize = -1
328328+- for (i in 0 until trackCount) {
329329+- val format = extractor.getTrackFormat(i)
330330+- val mime = format.getString(MediaFormat.KEY_MIME)
331331+- var selectCurrentTrack = false
332332+- if (mime!!.startsWith("audio/") && useAudio) {
333333+- selectCurrentTrack = true
334334+- } else if (mime.startsWith("video/") && useVideo) {
335335+- selectCurrentTrack = true
336336+- }
337337+- if (selectCurrentTrack) {
338338+- extractor.selectTrack(i)
339339+- val dstIndex = muxer.addTrack(format)
340340+- indexMap[i] = dstIndex
341341+- if (format.containsKey(MediaFormat.KEY_MAX_INPUT_SIZE)) {
342342+- val newSize = format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE)
343343+- bufferSize = if (newSize > bufferSize) newSize else bufferSize
344344+- }
345345+- }
346346+- }
347347+- if (bufferSize < 0) {
348348+- bufferSize = DEFAULT_BUFFER_SIZE
349349+- }
350350+- // Set up the orientation and starting time for extractor.
351351+- val retrieverSrc = MediaMetadataRetriever()
352352+- retrieverSrc.setDataSource(srcPath)
353353+- val degreesString = retrieverSrc.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION)
354354+- if (degreesString != null) {
355355+- val degrees = degreesString.toInt()
356356+- if (degrees >= 0) {
357357+- muxer.setOrientationHint(degrees)
358358+- }
359359+- }
360360+- if (startMs > 0) {
361361+- extractor.seekTo((startMs * 1000).toLong(), MediaExtractor.SEEK_TO_CLOSEST_SYNC)
362362+- }
363363+- // Copy the samples from MediaExtractor to MediaMuxer. We will loop
364364+- // for copying each sample and stop when we get to the end of the source
365365+- // file or exceed the end time of the trimming.
366366+- val offset = 0
367367+- var trackIndex = -1
368368+- val dstBuf = ByteBuffer.allocate(bufferSize)
369369+- val bufferInfo = MediaCodec.BufferInfo()
370370+- muxer.start()
371371+- while (true) {
372372+- bufferInfo.offset = offset
373373+- bufferInfo.size = extractor.readSampleData(dstBuf, offset)
374374+- if (bufferInfo.size < 0) {
375375+- Log.d(TAG, "Saw input EOS.")
376376+- bufferInfo.size = 0
377377+- break
378378+- } else {
379379+- bufferInfo.presentationTimeUs = extractor.sampleTime
380380+- if (endMs > 0 && bufferInfo.presentationTimeUs > endMs * 1000) {
381381+- Log.d(TAG, "The current sample is over the trim end time.")
382382+- break
383383+- } else {
384384+- bufferInfo.flags = extractor.sampleFlags
385385+- trackIndex = extractor.sampleTrackIndex
386386+- muxer.writeSampleData(indexMap[trackIndex]!!, dstBuf, bufferInfo)
387387+- extractor.advance()
388388+- }
389389+- }
390390+- }
391391+- muxer.stop()
392392+- muxer.release()
393393+- return
394394+- }
395395+-
396396+- companion object {
397397+- private const val DEFAULT_BUFFER_SIZE = 1 * 1024 * 1024
398398+- private const val TAG = "AudioExtractorDecoder"
399399+- }
400400+-}
401401+diff --git a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioHelper.kt b/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioHelper.kt
402402+deleted file mode 100644
403403+index 42040b4..0000000
404404+--- a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioHelper.kt
405405++++ /dev/null
406406+@@ -1,72 +0,0 @@
407407+-package com.reactnativecompressor.Audio
408408+-
409409+-import android.media.MediaExtractor
410410+-import android.media.MediaFormat
411411+-import com.facebook.react.bridge.ReadableMap
412412+-import com.reactnativecompressor.Utils.Utils
413413+-import java.io.File
414414+-import java.io.IOException
415415+-
416416+-
417417+-class AudioHelper {
418418+-
419419+- var quality: String? = "medium"
420420+- var bitrate: Int = -1
421421+- var samplerate: Int = -1
422422+- var channels: Int = -1
423423+- var progressDivider: Int? = 0
424424+-
425425+- companion object {
426426+- fun fromMap(map: ReadableMap): AudioHelper {
427427+- val options = AudioHelper()
428428+- val iterator = map.keySetIterator()
429429+- while (iterator.hasNextKey()) {
430430+- val key = iterator.nextKey()
431431+- when (key) {
432432+- "quality" -> options.quality = map.getString(key)
433433+- "bitrate" -> {
434434+- val bitrate = map.getInt(key)
435435+- options.bitrate = if (bitrate > 320000 || bitrate < 64000) 64000 else bitrate
436436+- }
437437+- "samplerate" -> options.samplerate = map.getInt(key)
438438+- "channels" -> options.channels = map.getInt(key)
439439+- }
440440+- }
441441+- return options
442442+- }
443443+-
444444+-
445445+- fun getAudioBitrate(path: String): Int {
446446+- val file = File(path)
447447+- val fileSize = file.length() * 8 // size in bits
448448+-
449449+- val mex = MediaExtractor()
450450+- try {
451451+- mex.setDataSource(path)
452452+- } catch (e: IOException) {
453453+- e.printStackTrace()
454454+- }
455455+-
456456+- val mf = mex.getTrackFormat(0)
457457+- val durationUs = mf.getLong(MediaFormat.KEY_DURATION)
458458+- val durationSec = durationUs / 1_000_000.0 // convert duration to seconds
459459+-
460460+- return (fileSize / durationSec).toInt()/1000 // bitrate in bits per second
461461+- }
462462+- fun getDestinationBitrateByQuality(path: String, quality: String): Int {
463463+- val originalBitrate = getAudioBitrate(path)
464464+- var destinationBitrate = originalBitrate
465465+- Utils.addLog("source bitrate: $originalBitrate")
466466+-
467467+- when (quality.lowercase()) {
468468+- "low" -> destinationBitrate = maxOf(64, (originalBitrate * 0.3).toInt())
469469+- "medium" -> destinationBitrate = (originalBitrate * 0.5).toInt()
470470+- "high" -> destinationBitrate = minOf(320, (originalBitrate * 0.7).toInt())
471471+- else -> Utils.addLog("Invalid quality level. Please enter 'low', 'medium', or 'high'.")
472472+- }
473473+-
474474+- return destinationBitrate
475475+- }
476476+-
477477+- }
478478+-}
479479+diff --git a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioMain.kt b/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioMain.kt
480480+index 446d4fb..f021909 100644
481481+--- a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioMain.kt
482482++++ b/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioMain.kt
483483+@@ -11,7 +11,9 @@ class AudioMain(private val reactContext: ReactApplicationContext) {
484484+ promise: Promise) {
485485+ try {
486486+487487+- AudioCompressor.CompressAudio(fileUrl,optionMap,reactContext,promise)
488488++ // Skip compression on Android to avoid libandroidlame dependency
489489++ // Return the original file URL without compression
490490++ promise.resolve(fileUrl)
491491+ } catch (ex: Exception) {
492492+ promise.reject(ex)
493493+ }
494494+diff --git a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Utils/Utils.kt b/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Utils/Utils.kt
495495+index c14b727..1198908 100644
496496+--- a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Utils/Utils.kt
497497++++ b/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Utils/Utils.kt
498498+@@ -7,7 +7,6 @@ import android.provider.OpenableColumns
499499+ import android.util.Log
500500+ import com.facebook.react.bridge.Promise
501501+ import com.facebook.react.bridge.ReactApplicationContext
502502+-import com.reactnativecompressor.Audio.AudioCompressor
503503+ import com.reactnativecompressor.Video.VideoCompressor.CompressionListener
504504+ import com.reactnativecompressor.Video.VideoCompressor.VideoCompressorClass
505505+ import java.io.FileNotFoundException
506506+@@ -152,10 +151,6 @@ object Utils {
507507+ }
508508+ }
509509+510510+- fun addLog(log: String) {
511511+- Log.d(AudioCompressor.TAG, log)
512512+- }
513513+-
514514+ val exifAttributes = arrayOf(
515515+ "FNumber",
516516+ "ApertureValue",
+5
patches/react-native-compressor+1.13.0.patch.md
···11+# react-native-compressor
22+33+Patch file taken from https://github.com/numandev1/react-native-compressor/pull/355#issuecomment-3180870738
44+55+This patch removes the audio compression feature on Android from the library. This is because `libandroidlame.so`, the native dependency, does not support 16kb page sizes, and the Play Store has made this mandatory as of 1st Nov 2025.