380 lines
17 KiB
Diff
380 lines
17 KiB
Diff
diff --git a/node_modules/react-native-audio-recorder-player/android/src/main/java/com/dooboolab.audiorecorderplayer/RNAudioRecorderPlayerModule.kt b/node_modules/react-native-audio-recorder-player/android/src/main/java/com/dooboolab.audiorecorderplayer/RNAudioRecorderPlayerModule.kt
|
|
index 4570fc2..8db4b61 100644
|
|
--- a/node_modules/react-native-audio-recorder-player/android/src/main/java/com/dooboolab.audiorecorderplayer/RNAudioRecorderPlayerModule.kt
|
|
+++ b/node_modules/react-native-audio-recorder-player/android/src/main/java/com/dooboolab.audiorecorderplayer/RNAudioRecorderPlayerModule.kt
|
|
@@ -18,7 +18,7 @@ import java.io.IOException
|
|
import java.util.*
|
|
import kotlin.math.log10
|
|
|
|
-class RNAudioRecorderPlayerModule(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext), PermissionListener, LifecycleEventListener {
|
|
+class RNAudioRecorderPlayerModule(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext), PermissionListener {
|
|
private var audioFileURL = ""
|
|
private var subsDurationMillis = 500
|
|
private var _meteringEnabled = false
|
|
@@ -38,78 +38,72 @@ class RNAudioRecorderPlayerModule(private val reactContext: ReactApplicationCont
|
|
fun startRecorder(path: String, audioSet: ReadableMap?, meteringEnabled: Boolean, promise: Promise) {
|
|
try {
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
- // On devices that run Android 10 (API level 29) or higher
|
|
- // your app can contribute to well-defined media collections such as MediaStore.Downloads without requesting any storage-related permissions
|
|
- // https://developer.android.com/about/versions/11/privacy/storage#permissions-target-11
|
|
- if (Build.VERSION.SDK_INT < 29 &&
|
|
- (ActivityCompat.checkSelfPermission(reactContext, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED ||
|
|
- ActivityCompat.checkSelfPermission(reactContext, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
|
|
- ActivityCompat.requestPermissions((currentActivity)!!, arrayOf(
|
|
- Manifest.permission.RECORD_AUDIO,
|
|
- Manifest.permission.WRITE_EXTERNAL_STORAGE), 0)
|
|
- promise.reject("No permission granted.", "Try again after adding permission.")
|
|
- return
|
|
- } else if (ActivityCompat.checkSelfPermission(reactContext, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
|
|
- ActivityCompat.requestPermissions((currentActivity)!!, arrayOf(Manifest.permission.RECORD_AUDIO), 0)
|
|
- promise.reject("No permission granted.", "Try again after adding permission.")
|
|
- return
|
|
- }
|
|
- }
|
|
+ val activity = reactContext.currentActivity
|
|
+
|
|
+ // Agar activity null hai (rare case), to direct reject kar do
|
|
+ if (activity == null) {
|
|
+ promise.reject("No permission granted.", "Activity is null.")
|
|
+ return
|
|
+ }
|
|
+
|
|
+ if (Build.VERSION.SDK_INT < 33 &&
|
|
+ (ActivityCompat.checkSelfPermission(reactContext, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED ||
|
|
+ ActivityCompat.checkSelfPermission(reactContext, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
|
|
+
|
|
+ ActivityCompat.requestPermissions(
|
|
+ activity,
|
|
+ arrayOf(
|
|
+ Manifest.permission.RECORD_AUDIO,
|
|
+ Manifest.permission.WRITE_EXTERNAL_STORAGE
|
|
+ ),
|
|
+ 0
|
|
+ )
|
|
+ promise.reject("No permission granted.", "Try again after adding permission.")
|
|
+ return
|
|
+
|
|
+ } else if (ActivityCompat.checkSelfPermission(reactContext, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
|
|
+
|
|
+ ActivityCompat.requestPermissions(
|
|
+ activity,
|
|
+ arrayOf(Manifest.permission.RECORD_AUDIO),
|
|
+ 0
|
|
+ )
|
|
+ promise.reject("No permission granted.", "Try again after adding permission.")
|
|
+ return
|
|
+ }
|
|
+}
|
|
+
|
|
} catch (ne: NullPointerException) {
|
|
Log.w(tag, ne.toString())
|
|
promise.reject("No permission granted.", "Try again after adding permission.")
|
|
return
|
|
}
|
|
-
|
|
- var outputFormat = if (audioSet != null && audioSet.hasKey("OutputFormatAndroid"))
|
|
- audioSet.getInt("OutputFormatAndroid")
|
|
- else
|
|
- MediaRecorder.OutputFormat.MPEG_4
|
|
-
|
|
- audioFileURL = if (((path == "DEFAULT"))) "${reactContext.cacheDir}/sound.${defaultFileExtensions.get(outputFormat)}" else path
|
|
+ audioFileURL = if (((path == "DEFAULT"))) "${reactContext.cacheDir}/$defaultFileName" else path
|
|
_meteringEnabled = meteringEnabled
|
|
|
|
- if (mediaRecorder != null) {
|
|
- promise.reject("InvalidState", "startRecorder has already been called.")
|
|
- return
|
|
+ if (mediaRecorder == null) {
|
|
+ mediaRecorder = MediaRecorder()
|
|
}
|
|
|
|
- var newMediaRecorder: MediaRecorder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
- MediaRecorder(reactContext)
|
|
+ if (audioSet != null) {
|
|
+ mediaRecorder!!.setAudioSource(if (audioSet.hasKey("AudioSourceAndroid")) audioSet.getInt("AudioSourceAndroid") else MediaRecorder.AudioSource.MIC)
|
|
+ mediaRecorder!!.setOutputFormat(if (audioSet.hasKey("OutputFormatAndroid")) audioSet.getInt("OutputFormatAndroid") else MediaRecorder.OutputFormat.MPEG_4)
|
|
+ mediaRecorder!!.setAudioEncoder(if (audioSet.hasKey("AudioEncoderAndroid")) audioSet.getInt("AudioEncoderAndroid") else MediaRecorder.AudioEncoder.AAC)
|
|
+ mediaRecorder!!.setAudioSamplingRate(if (audioSet.hasKey("AudioSamplingRateAndroid")) audioSet.getInt("AudioSamplingRateAndroid") else 48000)
|
|
+ mediaRecorder!!.setAudioEncodingBitRate(if (audioSet.hasKey("AudioEncodingBitRateAndroid")) audioSet.getInt("AudioEncodingBitRateAndroid") else 128000)
|
|
} else {
|
|
- MediaRecorder()
|
|
+ mediaRecorder!!.setAudioSource(MediaRecorder.AudioSource.MIC)
|
|
+ mediaRecorder!!.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
|
|
+ mediaRecorder!!.setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
|
|
+ mediaRecorder!!.setAudioEncodingBitRate(128000)
|
|
+ mediaRecorder!!.setAudioSamplingRate(48000)
|
|
}
|
|
+ mediaRecorder!!.setOutputFile(audioFileURL)
|
|
|
|
try {
|
|
- if (audioSet == null) {
|
|
- newMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC)
|
|
- newMediaRecorder.setOutputFormat(outputFormat)
|
|
- newMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
|
|
- } else {
|
|
- newMediaRecorder.setAudioSource(if (audioSet.hasKey("AudioSourceAndroid")) audioSet.getInt("AudioSourceAndroid") else MediaRecorder.AudioSource.MIC)
|
|
- newMediaRecorder.setOutputFormat(outputFormat)
|
|
- newMediaRecorder.setAudioEncoder(if (audioSet.hasKey("AudioEncoderAndroid")) audioSet.getInt("AudioEncoderAndroid") else MediaRecorder.AudioEncoder.AAC)
|
|
-
|
|
- if (audioSet.hasKey("AudioSamplingRateAndroid")) {
|
|
- newMediaRecorder.setAudioSamplingRate(audioSet.getInt("AudioSamplingRateAndroid"))
|
|
- }
|
|
-
|
|
- if (audioSet.hasKey("AudioEncodingBitRateAndroid")) {
|
|
- newMediaRecorder.setAudioEncodingBitRate(audioSet.getInt("AudioEncodingBitRateAndroid"))
|
|
- }
|
|
-
|
|
- if (audioSet.hasKey("AudioChannelsAndroid")) {
|
|
- newMediaRecorder.setAudioChannels(audioSet.getInt("AudioChannelsAndroid"))
|
|
- }
|
|
- }
|
|
- newMediaRecorder.setOutputFile(audioFileURL)
|
|
-
|
|
- newMediaRecorder.prepare()
|
|
+ mediaRecorder!!.prepare()
|
|
totalPausedRecordTime = 0L
|
|
- newMediaRecorder.start()
|
|
-
|
|
- mediaRecorder = newMediaRecorder
|
|
-
|
|
+ mediaRecorder!!.start()
|
|
val systemTime = SystemClock.elapsedRealtime()
|
|
recorderRunnable = object : Runnable {
|
|
override fun run() {
|
|
@@ -135,9 +129,6 @@ class RNAudioRecorderPlayerModule(private val reactContext: ReactApplicationCont
|
|
(recorderRunnable as Runnable).run()
|
|
promise.resolve("file:///$audioFileURL")
|
|
} catch (e: Exception) {
|
|
- newMediaRecorder.release()
|
|
- mediaRecorder = null
|
|
-
|
|
Log.e(tag, "Exception: ", e)
|
|
promise.reject("startRecord", e.message)
|
|
}
|
|
@@ -146,7 +137,7 @@ class RNAudioRecorderPlayerModule(private val reactContext: ReactApplicationCont
|
|
@ReactMethod
|
|
fun resumeRecorder(promise: Promise) {
|
|
if (mediaRecorder == null) {
|
|
- promise.reject("resumeRecorder", "Recorder is null.")
|
|
+ promise.reject("resumeReocrder", "Recorder is null.")
|
|
return
|
|
}
|
|
|
|
@@ -192,13 +183,14 @@ class RNAudioRecorderPlayerModule(private val reactContext: ReactApplicationCont
|
|
|
|
try {
|
|
mediaRecorder!!.stop()
|
|
- mediaRecorder!!.release()
|
|
- mediaRecorder = null
|
|
- promise.resolve("file:///$audioFileURL")
|
|
} catch (stopException: RuntimeException) {
|
|
stopException.message?.let { Log.d(tag,"" + it) }
|
|
promise.reject("stopRecord", stopException.message)
|
|
}
|
|
+
|
|
+ mediaRecorder!!.release()
|
|
+ mediaRecorder = null
|
|
+ promise.resolve("file:///$audioFileURL")
|
|
}
|
|
|
|
@ReactMethod
|
|
@@ -213,16 +205,6 @@ class RNAudioRecorderPlayerModule(private val reactContext: ReactApplicationCont
|
|
promise.resolve("set volume")
|
|
}
|
|
|
|
- @ReactMethod
|
|
- fun setPlaybackSpeed(playbackSpeed: Float, promise: Promise) {
|
|
- if (mediaPlayer == null) {
|
|
- promise.reject("setPlaybackSpeed", "player is null.")
|
|
- return
|
|
- }
|
|
- mediaPlayer!!.playbackParams = mediaPlayer!!.playbackParams.setSpeed(playbackSpeed)
|
|
- promise.resolve("setPlaybackSpeed")
|
|
- }
|
|
-
|
|
@ReactMethod
|
|
fun startPlayer(path: String, httpHeaders: ReadableMap?, promise: Promise) {
|
|
if (mediaPlayer != null) {
|
|
@@ -245,37 +227,36 @@ class RNAudioRecorderPlayerModule(private val reactContext: ReactApplicationCont
|
|
if ((path == "DEFAULT")) {
|
|
mediaPlayer!!.setDataSource("${reactContext.cacheDir}/$defaultFileName")
|
|
} else {
|
|
- if (httpHeaders != null) {
|
|
- val headers: MutableMap<String, String?> = HashMap<String, String?>()
|
|
- val iterator = httpHeaders.keySetIterator()
|
|
- while (iterator.hasNextKey()) {
|
|
- val key = iterator.nextKey()
|
|
- headers.put(key, httpHeaders.getString(key))
|
|
- }
|
|
- mediaPlayer!!.setDataSource(currentActivity!!.applicationContext, Uri.parse(path), headers)
|
|
- } else {
|
|
- mediaPlayer!!.setDataSource(path)
|
|
- }
|
|
+ if (httpHeaders != null) {
|
|
+ val headers: MutableMap<String, String?> = HashMap()
|
|
+ val iterator = httpHeaders.keySetIterator()
|
|
+ while (iterator.hasNextKey()) {
|
|
+ val key = iterator.nextKey()
|
|
+ headers[key] = httpHeaders.getString(key)
|
|
+ }
|
|
+
|
|
+ val activity = reactContext.currentActivity
|
|
+ val context = activity?.applicationContext ?: reactContext.applicationContext
|
|
+
|
|
+ mediaPlayer!!.setDataSource(context, Uri.parse(path), headers)
|
|
+} else {
|
|
+ mediaPlayer!!.setDataSource(path)
|
|
+}
|
|
+
|
|
}
|
|
|
|
mediaPlayer!!.setOnPreparedListener { mp ->
|
|
- Log.d(tag, "Mediaplayer prepared and start")
|
|
+ Log.d(tag, "mediaplayer prepared and start")
|
|
mp.start()
|
|
/**
|
|
* Set timer task to send event to RN.
|
|
*/
|
|
mTask = object : TimerTask() {
|
|
override fun run() {
|
|
- try {
|
|
- val obj = Arguments.createMap()
|
|
- obj.putInt("duration", mp.duration)
|
|
- obj.putInt("currentPosition", mp.currentPosition)
|
|
- obj.putBoolean("isFinished", false);
|
|
- sendEvent(reactContext, "rn-playback", obj)
|
|
- } catch (e: IllegalStateException) {
|
|
- // IllegalStateException 처리
|
|
- Log.e(tag, "Mediaplayer error: ${e.message}")
|
|
- }
|
|
+ val obj = Arguments.createMap()
|
|
+ obj.putInt("duration", mp.duration)
|
|
+ obj.putInt("currentPosition", mp.currentPosition)
|
|
+ sendEvent(reactContext, "rn-playback", obj)
|
|
}
|
|
}
|
|
|
|
@@ -294,16 +275,14 @@ class RNAudioRecorderPlayerModule(private val reactContext: ReactApplicationCont
|
|
*/
|
|
val obj = Arguments.createMap()
|
|
obj.putInt("duration", mp.duration)
|
|
- obj.putInt("currentPosition", mp.currentPosition)
|
|
- obj.putBoolean("isFinished", true);
|
|
+ obj.putInt("currentPosition", mp.duration)
|
|
sendEvent(reactContext, "rn-playback", obj)
|
|
/**
|
|
* Reset player.
|
|
*/
|
|
Log.d(tag, "Plays completed.")
|
|
- mTimer?.cancel()
|
|
+ mTimer!!.cancel()
|
|
mp.stop()
|
|
- mp.reset()
|
|
mp.release()
|
|
mediaPlayer = null
|
|
}
|
|
@@ -320,12 +299,12 @@ class RNAudioRecorderPlayerModule(private val reactContext: ReactApplicationCont
|
|
@ReactMethod
|
|
fun resumePlayer(promise: Promise) {
|
|
if (mediaPlayer == null) {
|
|
- promise.reject("resume", "Mediaplayer is null on resume.")
|
|
+ promise.reject("resume", "mediaPlayer is null on resume.")
|
|
return
|
|
}
|
|
|
|
if (mediaPlayer!!.isPlaying) {
|
|
- promise.reject("resume", "Mediaplayer is already running.")
|
|
+ promise.reject("resume", "mediaPlayer is already running.")
|
|
return
|
|
}
|
|
|
|
@@ -334,7 +313,7 @@ class RNAudioRecorderPlayerModule(private val reactContext: ReactApplicationCont
|
|
mediaPlayer!!.start()
|
|
promise.resolve("resume player")
|
|
} catch (e: Exception) {
|
|
- Log.e(tag, "Mediaplayer resume: " + e.message)
|
|
+ Log.e(tag, "mediaPlayer resume: " + e.message)
|
|
promise.reject("resume", e.message)
|
|
}
|
|
}
|
|
@@ -342,7 +321,7 @@ class RNAudioRecorderPlayerModule(private val reactContext: ReactApplicationCont
|
|
@ReactMethod
|
|
fun pausePlayer(promise: Promise) {
|
|
if (mediaPlayer == null) {
|
|
- promise.reject("pausePlay", "Mediaplayer is null on pause.")
|
|
+ promise.reject("pausePlay", "mediaPlayer is null on pause.")
|
|
return
|
|
}
|
|
|
|
@@ -358,7 +337,7 @@ class RNAudioRecorderPlayerModule(private val reactContext: ReactApplicationCont
|
|
@ReactMethod
|
|
fun seekToPlayer(time: Double, promise: Promise) {
|
|
if (mediaPlayer == null) {
|
|
- promise.reject("seekTo", "Mediaplayer is null on seek.")
|
|
+ promise.reject("seekTo", "mediaPlayer is null on seek.")
|
|
return
|
|
}
|
|
|
|
@@ -386,8 +365,6 @@ class RNAudioRecorderPlayerModule(private val reactContext: ReactApplicationCont
|
|
}
|
|
|
|
try {
|
|
- mediaPlayer!!.stop()
|
|
- mediaPlayer!!.reset()
|
|
mediaPlayer!!.release()
|
|
mediaPlayer = null
|
|
promise.resolve("stopped player")
|
|
@@ -413,51 +390,8 @@ class RNAudioRecorderPlayerModule(private val reactContext: ReactApplicationCont
|
|
return false
|
|
}
|
|
|
|
- init {
|
|
- reactContext.addLifecycleEventListener(this)
|
|
- }
|
|
-
|
|
- override fun onHostDestroy() {
|
|
- autoSaveRecordingIfNeeded()
|
|
- }
|
|
-
|
|
- override fun onHostPause() {}
|
|
-
|
|
- override fun onHostResume() {}
|
|
-
|
|
- private fun autoSaveRecordingIfNeeded() {
|
|
- if (mediaRecorder != null) {
|
|
- try {
|
|
- mediaRecorder!!.stop()
|
|
- mediaRecorder!!.release()
|
|
- mediaRecorder = null
|
|
- Log.d(tag, "Recording auto-saved on app pause/destroy.")
|
|
- } catch (e: Exception) {
|
|
- Log.e(tag, "Error auto-saving recording: ${e.message}")
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
- protected fun finalize() {
|
|
- reactContext.removeLifecycleEventListener(this)
|
|
- }
|
|
-
|
|
companion object {
|
|
private var tag = "RNAudioRecorderPlayer"
|
|
private var defaultFileName = "sound.mp4"
|
|
- private var defaultFileExtensions = listOf(
|
|
- "mp4", // DEFAULT = 0
|
|
- "3gp", // THREE_GPP
|
|
- "mp4", // MPEG_4
|
|
- "amr", // AMR_NB
|
|
- "amr", // AMR_WB
|
|
- "aac", // AAC_ADIF
|
|
- "aac", // AAC_ADTS
|
|
- "rtp", // OUTPUT_FORMAT_RTP_AVP
|
|
- "ts", // MPEG_2_TSMPEG_2_TS
|
|
- "webm",// WEBM
|
|
- "xxx", // UNUSED
|
|
- "ogg", // OGG
|
|
- )
|
|
}
|
|
}
|