Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package com.simform.audiowave.audio_wave

import android.Manifest
import android.app.Activity
import android.content.pm.PackageManager
import android.media.MediaRecorder
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.PluginRegistry
import java.io.IOException
import java.lang.IllegalStateException
import kotlin.math.log10

private const val LOG_TAG = "AudioWave"
private const val RECORD_AUDIO_REQUEST_CODE = 1001

class AudioWaveMethodCall: PluginRegistry.RequestPermissionsResultListener {
private var permissions = arrayOf(Manifest.permission.RECORD_AUDIO)
fun getDecibel(result: MethodChannel.Result, recorder: MediaRecorder?) {
val db = 20 * log10((recorder?.maxAmplitude?.toDouble() ?: 0.0 / 32768.0))
result.success(db)
}

fun initRecorder(path: String, result: MethodChannel.Result, recorder: MediaRecorder?) {
recorder?.apply {
setAudioSource(MediaRecorder.AudioSource.MIC)
setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
setOutputFile(path)
try {
recorder.prepare()
result.success(true)
} catch (e: IOException) {
Log.e(LOG_TAG, "Failed to stop initialize recorder")
}
}
}

fun stopRecording(result: MethodChannel.Result, recorder: MediaRecorder?) {
try {
recorder?.apply {
stop()
release()
}
result.success(false)
} catch (e: IllegalStateException) {
Log.e(LOG_TAG, "Failed to stop recording")
}
}

fun startRecorder(result: MethodChannel.Result, recorder: MediaRecorder?) {
try {
recorder?.start()
result.success(true)
} catch (e: IllegalStateException) {
Log.e(LOG_TAG, "Failed to start recording")
}
}

@RequiresApi(Build.VERSION_CODES.N)
fun pauseRecording(result: MethodChannel.Result, recorder: MediaRecorder?) {
try {
recorder?.pause()
result.success(false)
} catch (e: IllegalStateException) {
Log.e(LOG_TAG, "Failed to pause recording")
}
}

@RequiresApi(Build.VERSION_CODES.N)
fun resumeRecording(result: MethodChannel.Result, recorder: MediaRecorder?) {
try {
recorder?.resume()
result.success(true)
} catch (e: IllegalStateException) {
Log.e(LOG_TAG, "Failed to resume recording")
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>?,
grantResults: IntArray
): Boolean {
return if (requestCode == RECORD_AUDIO_REQUEST_CODE) {
grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED
} else {
false
}
}

private fun isPermissionGranted(activity: Activity?): Boolean {
val result =
ActivityCompat.checkSelfPermission(activity!!, permissions[0])
return result == PackageManager.PERMISSION_GRANTED
}

fun checkPermission(result: MethodChannel.Result,activity: Activity?) {
if (!isPermissionGranted(activity)) {
activity?.let {
ActivityCompat.requestPermissions(
it, permissions,
RECORD_AUDIO_REQUEST_CODE
)
}
} else {
result.success(true)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,35 +1,112 @@
package com.simform.audiowave.audio_wave

import android.app.Activity
import android.media.MediaRecorder
import android.os.Build
import android.util.Log
import androidx.annotation.NonNull

import androidx.annotation.RequiresApi
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import java.io.File
import java.io.IOException


/** AudioWavePlugin */
class AudioWavePlugin: FlutterPlugin, MethodCallHandler {
/// The MethodChannel that will the communication between Flutter and native Android
///
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
/// when the Flutter Engine is detached from the Activity
private lateinit var channel : MethodChannel

override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "audio_wave")
channel.setMethodCallHandler(this)
}

override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
if (call.method == "getPlatformVersion") {
result.success("Android ${android.os.Build.VERSION.RELEASE}")
} else {
result.notImplemented()
}
}

override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
}


class AudioWavePlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
private lateinit var channel: MethodChannel
private var recorder: MediaRecorder? = null
private var activity: Activity? = null
private lateinit var audioWaveMethodCall: AudioWaveMethodCall
private var path: String? = null

object Constants {
const val initRecorder = "initRecorder"
const val startRecording = "startRecording"
const val stopRecording = "stopRecording"
const val pauseRecording = "pauseRecording"
const val resumeRecording = "resumeRecording"
const val getDecibel = "getDecibel"
const val checkPermission = "checkPermission"
const val path = "path"
const val LOG_TAG = "AudioWave"
const val methodChannelName = "simform_audio_wave_plugin/methods"
}

override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(flutterPluginBinding.binaryMessenger, Constants.methodChannelName)
channel.setMethodCallHandler(this)
audioWaveMethodCall = AudioWaveMethodCall()
}

@RequiresApi(Build.VERSION_CODES.N)
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
when (call.method) {
Constants.initRecorder -> {
path = call.argument(Constants.path) as String?
checkPathAndInitialiseRecorder(result)
}
Constants.startRecording -> audioWaveMethodCall.startRecorder(result, recorder)
Constants.stopRecording -> {
recorder = null
audioWaveMethodCall.stopRecording(result, recorder)
}
Constants.pauseRecording -> audioWaveMethodCall.pauseRecording(result, recorder)
Constants.resumeRecording -> audioWaveMethodCall.resumeRecording(result, recorder)
Constants.getDecibel -> audioWaveMethodCall.getDecibel(result, recorder)
Constants.checkPermission -> audioWaveMethodCall.checkPermission(result, activity)
else -> result.notImplemented()
}
}

private fun checkPathAndInitialiseRecorder(result: Result) {
if (path == null) {
val outputDir = activity?.cacheDir
val outputFile: File?
try {
outputFile = File.createTempFile("audio-wave", ".mp3", outputDir)
path = outputFile.path
try {
recorder = MediaRecorder()
} catch (e: Exception) {
Log.e(Constants.LOG_TAG, "Failed to initialise Recorder")
}

audioWaveMethodCall.initRecorder(path!!, result, recorder)
} catch (e: IOException) {
Log.e(Constants.LOG_TAG, "Failed to create file")
}
} else {
audioWaveMethodCall.initRecorder(path!!, result, recorder)
}
}

override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
}

override fun onAttachedToActivity(binding: ActivityPluginBinding) {
activity = binding.activity
}

override fun onDetachedFromActivityForConfigChanges() {
activity = null
}

override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
activity = binding.activity
}

override fun onDetachedFromActivity() {
recorder?.release()
recorder = null
activity = null
}
}
2 changes: 1 addition & 1 deletion example/ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,4 @@ post_install do |installer|
]
end
end
end
end
Loading