forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1diff --git a/node_modules/react-native-compressor/android/build.gradle b/node_modules/react-native-compressor/android/build.gradle
2index 5071139..84bee34 100644
3--- a/node_modules/react-native-compressor/android/build.gradle
4+++ b/node_modules/react-native-compressor/android/build.gradle
5@@ -115,7 +115,6 @@ dependencies {
6 implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4"
7 implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"
8 implementation 'org.mp4parser:isoparser:1.9.56'
9- implementation 'com.github.banketree:AndroidLame-kotlin:v0.0.1'
10 implementation 'javazoom:jlayer:1.0.1'
11 }
12
13diff --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
14deleted file mode 100644
15index 9292d3e..0000000
16--- a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioCompressor.kt
17+++ /dev/null
18@@ -1,264 +0,0 @@
19-package com.reactnativecompressor.Audio
20-
21-
22-import android.annotation.SuppressLint
23-import com.facebook.react.bridge.Promise
24-import com.facebook.react.bridge.ReactApplicationContext
25-import com.facebook.react.bridge.ReadableMap
26-import com.naman14.androidlame.LameBuilder
27-import com.naman14.androidlame.WaveReader
28-import com.reactnativecompressor.Utils.MediaCache
29-import com.reactnativecompressor.Utils.Utils
30-import com.reactnativecompressor.Utils.Utils.addLog
31-import javazoom.jl.converter.Converter
32-import javazoom.jl.decoder.JavaLayerException
33-import java.io.BufferedOutputStream
34-import java.io.File
35-import java.io.FileNotFoundException
36-import java.io.FileOutputStream
37-import java.io.IOException
38-
39-class AudioCompressor {
40- companion object {
41- val TAG="AudioMain"
42- private const val OUTPUT_STREAM_BUFFER = 8192
43-
44- var outputStream: BufferedOutputStream? = null
45- var waveReader: WaveReader? = null
46- @JvmStatic
47- fun CompressAudio(
48- fileUrl: String,
49- optionMap: ReadableMap,
50- context: ReactApplicationContext,
51- promise: Promise,
52- ) {
53- val realPath = Utils.getRealPath(fileUrl, context)
54- var _fileUrl=realPath
55- val filePathWithoutFileUri = realPath!!.replace("file://", "")
56- try {
57- var wavPath=filePathWithoutFileUri;
58- var isNonWav:Boolean=false
59- if (fileUrl.endsWith(".mp4", ignoreCase = true))
60- {
61- addLog("mp4 file found")
62- val mp3Path= Utils.generateCacheFilePath("mp3", context)
63- AudioExtractor().genVideoUsingMuxer(fileUrl, mp3Path, -1, -1, true, false)
64- _fileUrl=Utils.slashifyFilePath(mp3Path)
65- wavPath= Utils.generateCacheFilePath("wav", context)
66- try {
67- val converter = Converter()
68- converter.convert(mp3Path, wavPath)
69- } catch (e: JavaLayerException) {
70- addLog("JavaLayerException error"+e.localizedMessage)
71- e.printStackTrace();
72- }
73- isNonWav=true
74- }
75- else if (!fileUrl.endsWith(".wav", ignoreCase = true))
76- {
77- addLog("non wav file found")
78- wavPath= Utils.generateCacheFilePath("wav", context)
79- try {
80- val converter = Converter()
81- converter.convert(filePathWithoutFileUri, wavPath)
82- } catch (e: JavaLayerException) {
83- addLog("JavaLayerException error"+e.localizedMessage)
84- e.printStackTrace();
85- }
86- isNonWav=true
87- }
88-
89-
90- autoCompressHelper(wavPath,filePathWithoutFileUri, optionMap,context) { mp3Path, finished ->
91- if (finished) {
92- val returnableFilePath:String="file://$mp3Path"
93- addLog("finished: " + returnableFilePath)
94- MediaCache.removeCompletedImagePath(fileUrl)
95- if(isNonWav)
96- {
97- File(wavPath).delete()
98- }
99- promise.resolve(returnableFilePath)
100- } else {
101- addLog("error: "+mp3Path)
102- promise.resolve(_fileUrl)
103- }
104- }
105- } catch (e: Exception) {
106- promise.resolve(_fileUrl)
107- }
108- }
109-
110- @SuppressLint("WrongConstant")
111- private fun autoCompressHelper(
112- fileUrl: String,
113- actualFileUrl: String,
114- optionMap: ReadableMap,
115- context: ReactApplicationContext,
116- completeCallback: (String, Boolean) -> Unit
117- ) {
118-
119- val options = AudioHelper.fromMap(optionMap)
120- val quality = options.quality
121-
122- var isCompletedCallbackTriggered:Boolean=false
123- try {
124- var mp3Path = Utils.generateCacheFilePath("mp3", context)
125- val input = File(fileUrl)
126- val output = File(mp3Path)
127-
128- val CHUNK_SIZE = 8192
129- addLog("Initialising wav reader")
130-
131- waveReader = WaveReader(input)
132-
133- try {
134- waveReader!!.openWave()
135- } catch (e: IOException) {
136- e.printStackTrace()
137- }
138-
139- addLog("Intitialising encoder")
140-
141-
142- // for bitrate
143- var audioBitrate:Int
144- if(options.bitrate != -1)
145- {
146- audioBitrate= options.bitrate/1000
147- }
148- else
149- {
150- audioBitrate=AudioHelper.getDestinationBitrateByQuality(actualFileUrl, quality!!)
151- Utils.addLog("dest bitrate: $audioBitrate")
152- }
153-
154- var androidLame = LameBuilder();
155- androidLame.setOutBitrate(audioBitrate)
156-
157- // for channels
158- var audioChannels:Int
159- if(options.channels != -1){
160- audioChannels= options.channels!!
161- }
162- else
163- {
164- audioChannels=waveReader!!.channels
165- }
166- androidLame.setOutChannels(audioChannels)
167-
168- // for sample rate
169- androidLame.setInSampleRate(waveReader!!.sampleRate)
170- var audioSampleRate:Int
171- if(options.samplerate != -1){
172- audioSampleRate= options.samplerate!!
173- }
174- else
175- {
176- audioSampleRate=waveReader!!.sampleRate
177- }
178- androidLame.setOutSampleRate(audioSampleRate)
179- val androidLameBuild=androidLame.build()
180-
181- try {
182- outputStream = BufferedOutputStream(FileOutputStream(output), OUTPUT_STREAM_BUFFER)
183- } catch (e: FileNotFoundException) {
184- e.printStackTrace()
185- }
186-
187- var bytesRead = 0
188-
189- val buffer_l = ShortArray(CHUNK_SIZE)
190- val buffer_r = ShortArray(CHUNK_SIZE)
191- val mp3Buf = ByteArray(CHUNK_SIZE)
192-
193- val channels = waveReader!!.channels
194-
195- addLog("started encoding")
196- while (true) {
197- try {
198- if (channels == 2) {
199-
200- bytesRead = waveReader!!.read(buffer_l, buffer_r, CHUNK_SIZE)
201- addLog("bytes read=$bytesRead")
202-
203- if (bytesRead > 0) {
204-
205- var bytesEncoded = 0
206- bytesEncoded = androidLameBuild.encode(buffer_l, buffer_r, bytesRead, mp3Buf)
207- addLog("bytes encoded=$bytesEncoded")
208-
209- if (bytesEncoded > 0) {
210- try {
211- addLog("writing mp3 buffer to outputstream with $bytesEncoded bytes")
212- outputStream!!.write(mp3Buf, 0, bytesEncoded)
213- } catch (e: IOException) {
214- e.printStackTrace()
215- }
216-
217- }
218-
219- } else
220- break
221- } else {
222-
223- bytesRead = waveReader!!.read(buffer_l, CHUNK_SIZE)
224- addLog("bytes read=$bytesRead")
225-
226- if (bytesRead > 0) {
227- var bytesEncoded = 0
228-
229- bytesEncoded = androidLameBuild.encode(buffer_l, buffer_l, bytesRead, mp3Buf)
230- addLog("bytes encoded=$bytesEncoded")
231-
232- if (bytesEncoded > 0) {
233- try {
234- addLog("writing mp3 buffer to outputstream with $bytesEncoded bytes")
235- outputStream!!.write(mp3Buf, 0, bytesEncoded)
236- } catch (e: IOException) {
237- e.printStackTrace()
238- }
239-
240- }
241-
242- } else
243- break
244- }
245-
246-
247- } catch (e: IOException) {
248- e.printStackTrace()
249- }
250-
251- }
252-
253- addLog("flushing final mp3buffer")
254- val outputMp3buf = androidLameBuild.flush(mp3Buf)
255- addLog("flushed $outputMp3buf bytes")
256- if (outputMp3buf > 0) {
257- try {
258- addLog("writing final mp3buffer to outputstream")
259- outputStream!!.write(mp3Buf, 0, outputMp3buf)
260- addLog("closing output stream")
261- outputStream!!.close()
262- completeCallback(output.absolutePath, true)
263- isCompletedCallbackTriggered=true
264- } catch (e: IOException) {
265- completeCallback(e.localizedMessage, false)
266- e.printStackTrace()
267- }
268- }
269-
270- } catch (e: IOException) {
271- completeCallback(e.localizedMessage, false)
272- }
273- if(!isCompletedCallbackTriggered)
274- {
275- completeCallback("something went wrong", false)
276- }
277- }
278-
279-
280-
281- }
282-}
283diff --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
284deleted file mode 100644
285index c655182..0000000
286--- a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioExtractor.kt
287+++ /dev/null
288@@ -1,112 +0,0 @@
289-package com.reactnativecompressor.Audio
290-
291-import android.annotation.SuppressLint
292-import android.media.MediaCodec
293-import android.media.MediaExtractor
294-import android.media.MediaFormat
295-import android.media.MediaMetadataRetriever
296-import android.media.MediaMuxer
297-import android.util.Log
298-import java.io.IOException
299-import java.nio.ByteBuffer
300-
301-
302-class AudioExtractor {
303- /**
304- * @param srcPath the path of source video file.
305- * @param dstPath the path of destination video file.
306- * @param startMs starting time in milliseconds for trimming. Set to
307- * negative if starting from beginning.
308- * @param endMs end time for trimming in milliseconds. Set to negative if
309- * no trimming at the end.
310- * @param useAudio true if keep the audio track from the source.
311- * @param useVideo true if keep the video track from the source.
312- * @throws IOException
313- */
314- @SuppressLint("NewApi", "WrongConstant")
315- @Throws(IOException::class)
316- fun genVideoUsingMuxer(srcPath: String?, dstPath: String?, startMs: Int, endMs: Int, useAudio: Boolean, useVideo: Boolean) {
317- // Set up MediaExtractor to read from the source.
318- val extractor = MediaExtractor()
319- extractor.setDataSource(srcPath!!)
320- val trackCount = extractor.trackCount
321- // Set up MediaMuxer for the destination.
322- val muxer: MediaMuxer
323- muxer = MediaMuxer(dstPath!!, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)
324- // Set up the tracks and retrieve the max buffer size for selected
325- // tracks.
326- val indexMap = HashMap<Int, Int>(trackCount)
327- var bufferSize = -1
328- for (i in 0 until trackCount) {
329- val format = extractor.getTrackFormat(i)
330- val mime = format.getString(MediaFormat.KEY_MIME)
331- var selectCurrentTrack = false
332- if (mime!!.startsWith("audio/") && useAudio) {
333- selectCurrentTrack = true
334- } else if (mime.startsWith("video/") && useVideo) {
335- selectCurrentTrack = true
336- }
337- if (selectCurrentTrack) {
338- extractor.selectTrack(i)
339- val dstIndex = muxer.addTrack(format)
340- indexMap[i] = dstIndex
341- if (format.containsKey(MediaFormat.KEY_MAX_INPUT_SIZE)) {
342- val newSize = format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE)
343- bufferSize = if (newSize > bufferSize) newSize else bufferSize
344- }
345- }
346- }
347- if (bufferSize < 0) {
348- bufferSize = DEFAULT_BUFFER_SIZE
349- }
350- // Set up the orientation and starting time for extractor.
351- val retrieverSrc = MediaMetadataRetriever()
352- retrieverSrc.setDataSource(srcPath)
353- val degreesString = retrieverSrc.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION)
354- if (degreesString != null) {
355- val degrees = degreesString.toInt()
356- if (degrees >= 0) {
357- muxer.setOrientationHint(degrees)
358- }
359- }
360- if (startMs > 0) {
361- extractor.seekTo((startMs * 1000).toLong(), MediaExtractor.SEEK_TO_CLOSEST_SYNC)
362- }
363- // Copy the samples from MediaExtractor to MediaMuxer. We will loop
364- // for copying each sample and stop when we get to the end of the source
365- // file or exceed the end time of the trimming.
366- val offset = 0
367- var trackIndex = -1
368- val dstBuf = ByteBuffer.allocate(bufferSize)
369- val bufferInfo = MediaCodec.BufferInfo()
370- muxer.start()
371- while (true) {
372- bufferInfo.offset = offset
373- bufferInfo.size = extractor.readSampleData(dstBuf, offset)
374- if (bufferInfo.size < 0) {
375- Log.d(TAG, "Saw input EOS.")
376- bufferInfo.size = 0
377- break
378- } else {
379- bufferInfo.presentationTimeUs = extractor.sampleTime
380- if (endMs > 0 && bufferInfo.presentationTimeUs > endMs * 1000) {
381- Log.d(TAG, "The current sample is over the trim end time.")
382- break
383- } else {
384- bufferInfo.flags = extractor.sampleFlags
385- trackIndex = extractor.sampleTrackIndex
386- muxer.writeSampleData(indexMap[trackIndex]!!, dstBuf, bufferInfo)
387- extractor.advance()
388- }
389- }
390- }
391- muxer.stop()
392- muxer.release()
393- return
394- }
395-
396- companion object {
397- private const val DEFAULT_BUFFER_SIZE = 1 * 1024 * 1024
398- private const val TAG = "AudioExtractorDecoder"
399- }
400-}
401diff --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
402deleted file mode 100644
403index 42040b4..0000000
404--- a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioHelper.kt
405+++ /dev/null
406@@ -1,72 +0,0 @@
407-package com.reactnativecompressor.Audio
408-
409-import android.media.MediaExtractor
410-import android.media.MediaFormat
411-import com.facebook.react.bridge.ReadableMap
412-import com.reactnativecompressor.Utils.Utils
413-import java.io.File
414-import java.io.IOException
415-
416-
417-class AudioHelper {
418-
419- var quality: String? = "medium"
420- var bitrate: Int = -1
421- var samplerate: Int = -1
422- var channels: Int = -1
423- var progressDivider: Int? = 0
424-
425- companion object {
426- fun fromMap(map: ReadableMap): AudioHelper {
427- val options = AudioHelper()
428- val iterator = map.keySetIterator()
429- while (iterator.hasNextKey()) {
430- val key = iterator.nextKey()
431- when (key) {
432- "quality" -> options.quality = map.getString(key)
433- "bitrate" -> {
434- val bitrate = map.getInt(key)
435- options.bitrate = if (bitrate > 320000 || bitrate < 64000) 64000 else bitrate
436- }
437- "samplerate" -> options.samplerate = map.getInt(key)
438- "channels" -> options.channels = map.getInt(key)
439- }
440- }
441- return options
442- }
443-
444-
445- fun getAudioBitrate(path: String): Int {
446- val file = File(path)
447- val fileSize = file.length() * 8 // size in bits
448-
449- val mex = MediaExtractor()
450- try {
451- mex.setDataSource(path)
452- } catch (e: IOException) {
453- e.printStackTrace()
454- }
455-
456- val mf = mex.getTrackFormat(0)
457- val durationUs = mf.getLong(MediaFormat.KEY_DURATION)
458- val durationSec = durationUs / 1_000_000.0 // convert duration to seconds
459-
460- return (fileSize / durationSec).toInt()/1000 // bitrate in bits per second
461- }
462- fun getDestinationBitrateByQuality(path: String, quality: String): Int {
463- val originalBitrate = getAudioBitrate(path)
464- var destinationBitrate = originalBitrate
465- Utils.addLog("source bitrate: $originalBitrate")
466-
467- when (quality.lowercase()) {
468- "low" -> destinationBitrate = maxOf(64, (originalBitrate * 0.3).toInt())
469- "medium" -> destinationBitrate = (originalBitrate * 0.5).toInt()
470- "high" -> destinationBitrate = minOf(320, (originalBitrate * 0.7).toInt())
471- else -> Utils.addLog("Invalid quality level. Please enter 'low', 'medium', or 'high'.")
472- }
473-
474- return destinationBitrate
475- }
476-
477- }
478-}
479diff --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
480index 446d4fb..f021909 100644
481--- a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioMain.kt
482+++ b/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioMain.kt
483@@ -11,7 +11,9 @@ class AudioMain(private val reactContext: ReactApplicationContext) {
484 promise: Promise) {
485 try {
486
487- AudioCompressor.CompressAudio(fileUrl,optionMap,reactContext,promise)
488+ // Skip compression on Android to avoid libandroidlame dependency
489+ // Return the original file URL without compression
490+ promise.resolve(fileUrl)
491 } catch (ex: Exception) {
492 promise.reject(ex)
493 }
494diff --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
495index c14b727..1198908 100644
496--- a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Utils/Utils.kt
497+++ b/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Utils/Utils.kt
498@@ -7,7 +7,6 @@ import android.provider.OpenableColumns
499 import android.util.Log
500 import com.facebook.react.bridge.Promise
501 import com.facebook.react.bridge.ReactApplicationContext
502-import com.reactnativecompressor.Audio.AudioCompressor
503 import com.reactnativecompressor.Video.VideoCompressor.CompressionListener
504 import com.reactnativecompressor.Video.VideoCompressor.VideoCompressorClass
505 import java.io.FileNotFoundException
506@@ -152,10 +151,6 @@ object Utils {
507 }
508 }
509
510- fun addLog(log: String) {
511- Log.d(AudioCompressor.TAG, log)
512- }
513-
514 val exifAttributes = arrayOf(
515 "FNumber",
516 "ApertureValue",