react-native-audio-concat 0.7.0 → 0.7.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.
@@ -25,6 +25,11 @@ import java.util.concurrent.ConcurrentHashMap
25
25
  class AudioConcatModule(reactContext: ReactApplicationContext) :
26
26
  NativeAudioConcatSpec(reactContext) {
27
27
 
28
+ // CONCURRENCY PROTECTION: Serial executor to handle concurrent calls safely
29
+ // This prevents MediaCodec resource conflicts and ensures operations don't interfere
30
+ private val serialExecutor = Executors.newSingleThreadExecutor()
31
+ private val activeOperations = AtomicInteger(0)
32
+
28
33
  private data class AudioConfig(
29
34
  val sampleRate: Int,
30
35
  val channelCount: Int,
@@ -1311,15 +1316,28 @@ class AudioConcatModule(reactContext: ReactApplicationContext) :
1311
1316
  return NAME
1312
1317
  }
1313
1318
 
1319
+ override fun onCatalystInstanceDestroy() {
1320
+ super.onCatalystInstanceDestroy()
1321
+ // Clean up executor when module is destroyed
1322
+ serialExecutor.shutdown()
1323
+ Log.d("AudioConcat", "AudioConcat module destroyed, executor shutdown")
1324
+ }
1325
+
1314
1326
  override fun concatAudioFiles(data: ReadableArray, outputPath: String, promise: Promise) {
1315
- val totalStartTime = System.currentTimeMillis()
1316
- Log.d("AudioConcat", "========== Audio Concat Started ==========")
1327
+ // CONCURRENCY PROTECTION: Queue all operations to run serially
1328
+ // This prevents MediaCodec resource conflicts when multiple calls happen simultaneously
1329
+ val operationId = activeOperations.incrementAndGet()
1330
+ Log.d("AudioConcat", "========== Audio Concat Queued (Operation #$operationId) ==========")
1317
1331
 
1318
- try {
1319
- if (data.size() == 0) {
1320
- promise.reject("EMPTY_DATA", "Data array is empty")
1321
- return
1322
- }
1332
+ serialExecutor.submit {
1333
+ val totalStartTime = System.currentTimeMillis()
1334
+ Log.d("AudioConcat", "========== Audio Concat Started (Operation #$operationId) ==========")
1335
+
1336
+ try {
1337
+ if (data.size() == 0) {
1338
+ promise.reject("EMPTY_DATA", "Data array is empty")
1339
+ return@submit
1340
+ }
1323
1341
 
1324
1342
  // Parse data
1325
1343
  val parseStartTime = System.currentTimeMillis()
@@ -1340,7 +1358,7 @@ class AudioConcatModule(reactContext: ReactApplicationContext) :
1340
1358
 
1341
1359
  if (audioConfig == null) {
1342
1360
  promise.reject("NO_AUDIO_FILES", "No audio files found in data array")
1343
- return
1361
+ return@submit
1344
1362
  }
1345
1363
 
1346
1364
  val configTime = System.currentTimeMillis() - configStartTime
@@ -1825,14 +1843,17 @@ class AudioConcatModule(reactContext: ReactApplicationContext) :
1825
1843
  Log.d("AudioConcat", "Successfully merged audio to $outputPath")
1826
1844
  promise.resolve(outputPath)
1827
1845
 
1846
+ } catch (e: Exception) {
1847
+ Log.e("AudioConcat", "Error during streaming merge: ${e.message}", e)
1848
+ promise.reject("MERGE_ERROR", e.message, e)
1849
+ }
1850
+
1828
1851
  } catch (e: Exception) {
1829
- Log.e("AudioConcat", "Error during streaming merge: ${e.message}", e)
1830
- promise.reject("MERGE_ERROR", e.message, e)
1852
+ Log.e("AudioConcat", "Error parsing data: ${e.message}", e)
1853
+ promise.reject("PARSE_ERROR", e.message, e)
1854
+ } finally {
1855
+ Log.d("AudioConcat", "========== Audio Concat Finished (Operation #$operationId) ==========")
1831
1856
  }
1832
-
1833
- } catch (e: Exception) {
1834
- Log.e("AudioConcat", "Error parsing data: ${e.message}", e)
1835
- promise.reject("PARSE_ERROR", e.message, e)
1836
1857
  }
1837
1858
  }
1838
1859
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-audio-concat",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "audio-concat for react-native",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -38,7 +38,7 @@
38
38
  "lint": "eslint \"**/*.{js,ts,tsx}\"",
39
39
  "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
40
40
  "prepare": "bob build",
41
- "release": "release-it --only-version"
41
+ "release": "release-it"
42
42
  },
43
43
  "keywords": [
44
44
  "react-native",