10 changed files with 448 additions and 732 deletions
@ -1,572 +0,0 @@ |
|||||
package com.example.deep_voice |
|
||||
|
|
||||
import android.content.Context |
|
||||
import android.media.audiofx.AcousticEchoCanceler |
|
||||
import android.media.audiofx.NoiseSuppressor |
|
||||
import android.media.audiofx.AutomaticGainControl |
|
||||
import android.media.AudioManager |
|
||||
import android.os.Build |
|
||||
import android.util.Log |
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin |
|
||||
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 io.flutter.embedding.engine.plugins.activity.ActivityAware |
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding |
|
||||
import android.app.Application |
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin.FlutterPluginBinding |
|
||||
import io.flutter.embedding.engine.FlutterEngine |
|
||||
import io.flutter.FlutterInjector |
|
||||
|
|
||||
/** |
|
||||
* 音频处理插件 |
|
||||
* |
|
||||
* 提供回音消除、降噪和自动增益控制等功能 |
|
||||
*/ |
|
||||
class AudioProcessingPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { |
|
||||
private lateinit var channel: MethodChannel |
|
||||
private lateinit var context: Context |
|
||||
private lateinit var audioManager: AudioManager |
|
||||
|
|
||||
// 音频处理组件 |
|
||||
private var echoCanceler: AcousticEchoCanceler? = null |
|
||||
private var noiseSuppressor: NoiseSuppressor? = null |
|
||||
private var automaticGainControl: AutomaticGainControl? = null |
|
||||
|
|
||||
// 当前音频会话ID |
|
||||
private var currentAudioSessionId: Int = -1 |
|
||||
|
|
||||
companion object { |
|
||||
private const val TAG = "AudioProcessingPlugin" |
|
||||
private const val CHANNEL_NAME = "com.deep_voice.audio_processing" |
|
||||
|
|
||||
// 保存静态实例,确保在任何地方都能访问 |
|
||||
@JvmStatic |
|
||||
private var instance: AudioProcessingPlugin? = null |
|
||||
|
|
||||
// 保存应用Context |
|
||||
@JvmStatic |
|
||||
private var applicationContext: Context? = null |
|
||||
|
|
||||
// 静态初始化块,尝试在类加载时就获取applicationContext |
|
||||
init { |
|
||||
try { |
|
||||
Log.i(TAG, "AudioProcessingPlugin静态初始化块被执行") |
|
||||
// 尝试通过FlutterInjector获取applicationContext |
|
||||
val flutterLoader = FlutterInjector.instance().flutterLoader() |
|
||||
if (flutterLoader.initialized()) { |
|
||||
Log.i(TAG, "FlutterLoader已初始化") |
|
||||
} else { |
|
||||
Log.i(TAG, "FlutterLoader尚未初始化") |
|
||||
} |
|
||||
} catch (e: Exception) { |
|
||||
Log.e(TAG, "静态初始化块执行失败: ${e.message}") |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 获取实例的方法 |
|
||||
@JvmStatic |
|
||||
fun getInstance(): AudioProcessingPlugin? { |
|
||||
return instance |
|
||||
} |
|
||||
|
|
||||
// 获取应用Context的方法 |
|
||||
@JvmStatic |
|
||||
fun getApplicationContext(): Context? { |
|
||||
return applicationContext |
|
||||
} |
|
||||
|
|
||||
// 设置应用Context的方法,可以从外部调用 |
|
||||
@JvmStatic |
|
||||
fun setApplicationContext(ctx: Context) { |
|
||||
if (applicationContext == null) { |
|
||||
applicationContext = ctx.applicationContext |
|
||||
Log.i(TAG, "通过setApplicationContext方法设置了applicationContext") |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 构造函数,尝试获取applicationContext |
|
||||
init { |
|
||||
Log.i(TAG, "AudioProcessingPlugin实例初始化块被执行") |
|
||||
} |
|
||||
|
|
||||
override fun onAttachedToEngine(binding: FlutterPluginBinding) { |
|
||||
Log.i(TAG, "onAttachedToEngine被调用") |
|
||||
context = binding.applicationContext |
|
||||
applicationContext = context |
|
||||
audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager |
|
||||
channel = MethodChannel(binding.binaryMessenger, CHANNEL_NAME) |
|
||||
channel.setMethodCallHandler(this) |
|
||||
instance = this |
|
||||
Log.i(TAG, "音频处理插件已初始化,context: $context, applicationContext: $applicationContext") |
|
||||
} |
|
||||
|
|
||||
override fun onDetachedFromEngine(binding: FlutterPluginBinding) { |
|
||||
channel.setMethodCallHandler(null) |
|
||||
releaseAudioEffects() |
|
||||
if (instance == this) { |
|
||||
instance = null |
|
||||
} |
|
||||
Log.i(TAG, "音频处理插件已释放") |
|
||||
} |
|
||||
|
|
||||
// 实现ActivityAware接口,获取Activity上下文 |
|
||||
override fun onAttachedToActivity(binding: ActivityPluginBinding) { |
|
||||
Log.i(TAG, "onAttachedToActivity被调用") |
|
||||
// 如果context尚未初始化,使用Activity上下文 |
|
||||
if (!::context.isInitialized) { |
|
||||
context = binding.activity |
|
||||
Log.i(TAG, "使用Activity上下文初始化context") |
|
||||
|
|
||||
// 如果audioManager尚未初始化,初始化它 |
|
||||
if (!::audioManager.isInitialized) { |
|
||||
audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager |
|
||||
Log.i(TAG, "使用Activity上下文初始化audioManager") |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
override fun onDetachedFromActivity() { |
|
||||
Log.i(TAG, "onDetachedFromActivity被调用") |
|
||||
} |
|
||||
|
|
||||
override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) { |
|
||||
onAttachedToActivity(binding) |
|
||||
} |
|
||||
|
|
||||
override fun onDetachedFromActivityForConfigChanges() { |
|
||||
onDetachedFromActivity() |
|
||||
} |
|
||||
|
|
||||
override fun onMethodCall(call: MethodCall, result: Result) { |
|
||||
when (call.method) { |
|
||||
"isEchoCancellationAvailable" -> { |
|
||||
result.success(AcousticEchoCanceler.isAvailable()) |
|
||||
} |
|
||||
"isNoiseSuppressionAvailable" -> { |
|
||||
result.success(NoiseSuppressor.isAvailable()) |
|
||||
} |
|
||||
"enableEchoCancellation" -> { |
|
||||
val audioSessionId = call.argument<Int>("audioSessionId") |
|
||||
if (audioSessionId == null) { |
|
||||
result.error("INVALID_ARGUMENT", "音频会话ID不能为空", null) |
|
||||
return |
|
||||
} |
|
||||
result.success(enableEchoCancellation(audioSessionId)) |
|
||||
} |
|
||||
"disableEchoCancellation" -> { |
|
||||
result.success(disableEchoCancellation()) |
|
||||
} |
|
||||
"enableNoiseSuppression" -> { |
|
||||
val audioSessionId = call.argument<Int>("audioSessionId") |
|
||||
if (audioSessionId == null) { |
|
||||
result.error("INVALID_ARGUMENT", "音频会话ID不能为空", null) |
|
||||
return |
|
||||
} |
|
||||
result.success(enableNoiseSuppression(audioSessionId)) |
|
||||
} |
|
||||
"disableNoiseSuppression" -> { |
|
||||
result.success(disableNoiseSuppression()) |
|
||||
} |
|
||||
"getAudioSessionId" -> { |
|
||||
// 尝试获取当前活动的音频会话ID |
|
||||
try { |
|
||||
Log.i(TAG, "getAudioSessionId方法被调用") |
|
||||
|
|
||||
// 检查applicationContext是否已初始化 |
|
||||
if (applicationContext != null) { |
|
||||
Log.i(TAG, "静态applicationContext已初始化") |
|
||||
|
|
||||
// 如果context尚未初始化,使用applicationContext |
|
||||
if (!::context.isInitialized) { |
|
||||
context = applicationContext!! |
|
||||
Log.i(TAG, "使用静态applicationContext初始化context") |
|
||||
} |
|
||||
} else { |
|
||||
Log.w(TAG, "静态applicationContext尚未初始化") |
|
||||
} |
|
||||
|
|
||||
// 检查context是否初始化 |
|
||||
if (!::context.isInitialized) { |
|
||||
Log.e(TAG, "context尚未初始化,尝试从静态实例获取") |
|
||||
|
|
||||
// 尝试从静态实例获取context |
|
||||
val staticInstance = getInstance() |
|
||||
if (staticInstance != null) { |
|
||||
try { |
|
||||
// 尝试访问context,如果未初始化会抛出异常 |
|
||||
val testContext = staticInstance.context |
|
||||
context = testContext |
|
||||
Log.i(TAG, "从静态实例获取context成功") |
|
||||
} catch (e: UninitializedPropertyAccessException) { |
|
||||
Log.e(TAG, "静态实例的context也未初始化: ${e.message}") |
|
||||
|
|
||||
// 尝试使用应用级别的Context |
|
||||
val appContext = getApplicationContext() |
|
||||
if (appContext != null) { |
|
||||
context = appContext |
|
||||
Log.i(TAG, "使用应用级别的Context初始化成功") |
|
||||
} else { |
|
||||
Log.e(TAG, "无法获取任何有效的Context,无法获取音频会话ID") |
|
||||
result.success(-1) |
|
||||
return |
|
||||
} |
|
||||
} |
|
||||
} else { |
|
||||
// 尝试使用应用级别的Context |
|
||||
val appContext = getApplicationContext() |
|
||||
if (appContext != null) { |
|
||||
context = appContext |
|
||||
Log.i(TAG, "使用应用级别的Context初始化成功") |
|
||||
} else { |
|
||||
Log.e(TAG, "无法获取context,无法获取音频会话ID") |
|
||||
result.success(-1) |
|
||||
return |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 检查audioManager是否初始化,如果没有则初始化 |
|
||||
if (!::audioManager.isInitialized) { |
|
||||
Log.w(TAG, "audioManager尚未初始化,正在初始化") |
|
||||
try { |
|
||||
audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager |
|
||||
Log.i(TAG, "audioManager初始化成功") |
|
||||
} catch (e: Exception) { |
|
||||
Log.e(TAG, "初始化audioManager失败: ${e.message}") |
|
||||
result.success(-1) |
|
||||
return |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 使用ensureValidAudioSessionId方法获取有效的音频会话ID |
|
||||
val sessionId = ensureValidAudioSessionId() |
|
||||
Log.i(TAG, "返回音频会话ID: $sessionId") |
|
||||
result.success(sessionId) |
|
||||
} catch (e: Exception) { |
|
||||
Log.e(TAG, "获取音频会话ID失败: ${e.message}") |
|
||||
result.success(-1) |
|
||||
} |
|
||||
} |
|
||||
else -> { |
|
||||
result.notImplemented() |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 启用回音消除 |
|
||||
* |
|
||||
* @param audioSessionId 音频会话ID |
|
||||
* @return 是否成功启用 |
|
||||
*/ |
|
||||
private fun enableEchoCancellation(audioSessionId: Int): Boolean { |
|
||||
if (!AcousticEchoCanceler.isAvailable()) { |
|
||||
Log.w(TAG, "设备不支持回音消除") |
|
||||
return false |
|
||||
} |
|
||||
|
|
||||
try { |
|
||||
Log.i(TAG, "尝试启用回音消除,音频会话ID: $audioSessionId") |
|
||||
|
|
||||
// 确保context已初始化 |
|
||||
if (!::context.isInitialized) { |
|
||||
Log.w(TAG, "context尚未初始化,尝试获取") |
|
||||
|
|
||||
// 尝试从静态实例或应用级别获取context |
|
||||
val staticInstance = getInstance() |
|
||||
if (staticInstance != null && try { staticInstance.context; true } catch (e: Exception) { false }) { |
|
||||
context = staticInstance.context |
|
||||
} else { |
|
||||
val appContext = getApplicationContext() |
|
||||
if (appContext != null) { |
|
||||
context = appContext |
|
||||
} else { |
|
||||
Log.e(TAG, "无法获取context,无法启用回音消除") |
|
||||
return false |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 确保audioManager已初始化 |
|
||||
if (!::audioManager.isInitialized) { |
|
||||
try { |
|
||||
audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager |
|
||||
Log.i(TAG, "audioManager初始化成功") |
|
||||
} catch (e: Exception) { |
|
||||
Log.e(TAG, "初始化audioManager失败: ${e.message}") |
|
||||
return false |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 如果已经创建了回音消除器,先释放 |
|
||||
if (echoCanceler != null) { |
|
||||
echoCanceler?.release() |
|
||||
echoCanceler = null |
|
||||
} |
|
||||
|
|
||||
// 创建新的回音消除器 |
|
||||
echoCanceler = AcousticEchoCanceler.create(audioSessionId) |
|
||||
if (echoCanceler == null) { |
|
||||
Log.e(TAG, "创建回音消除器失败") |
|
||||
return false |
|
||||
} |
|
||||
|
|
||||
// 启用回音消除 |
|
||||
echoCanceler?.enabled = true |
|
||||
currentAudioSessionId = audioSessionId |
|
||||
|
|
||||
Log.i(TAG, "回音消除已启用,音频会话ID: $audioSessionId") |
|
||||
return echoCanceler?.enabled == true |
|
||||
} catch (e: Exception) { |
|
||||
Log.e(TAG, "启用回音消除失败: ${e.message}") |
|
||||
return false |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 禁用回音消除 |
|
||||
* |
|
||||
* @return 是否成功禁用 |
|
||||
*/ |
|
||||
private fun disableEchoCancellation(): Boolean { |
|
||||
if (echoCanceler == null) { |
|
||||
return true |
|
||||
} |
|
||||
|
|
||||
try { |
|
||||
echoCanceler?.enabled = false |
|
||||
echoCanceler?.release() |
|
||||
echoCanceler = null |
|
||||
Log.i(TAG, "回音消除已禁用") |
|
||||
return true |
|
||||
} catch (e: Exception) { |
|
||||
Log.e(TAG, "禁用回音消除失败: ${e.message}") |
|
||||
return false |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 启用噪声抑制 |
|
||||
* |
|
||||
* @param audioSessionId 音频会话ID |
|
||||
* @return 是否成功启用 |
|
||||
*/ |
|
||||
private fun enableNoiseSuppression(audioSessionId: Int): Boolean { |
|
||||
if (!NoiseSuppressor.isAvailable()) { |
|
||||
Log.w(TAG, "设备不支持噪声抑制") |
|
||||
return false |
|
||||
} |
|
||||
|
|
||||
try { |
|
||||
Log.i(TAG, "尝试启用噪声抑制,音频会话ID: $audioSessionId") |
|
||||
|
|
||||
// 确保context已初始化 |
|
||||
if (!::context.isInitialized) { |
|
||||
Log.w(TAG, "context尚未初始化,尝试获取") |
|
||||
|
|
||||
// 尝试从静态实例或应用级别获取context |
|
||||
val staticInstance = getInstance() |
|
||||
if (staticInstance != null && try { staticInstance.context; true } catch (e: Exception) { false }) { |
|
||||
context = staticInstance.context |
|
||||
} else { |
|
||||
val appContext = getApplicationContext() |
|
||||
if (appContext != null) { |
|
||||
context = appContext |
|
||||
} else { |
|
||||
Log.e(TAG, "无法获取context,无法启用噪声抑制") |
|
||||
return false |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 确保audioManager已初始化 |
|
||||
if (!::audioManager.isInitialized) { |
|
||||
try { |
|
||||
audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager |
|
||||
Log.i(TAG, "audioManager初始化成功") |
|
||||
} catch (e: Exception) { |
|
||||
Log.e(TAG, "初始化audioManager失败: ${e.message}") |
|
||||
return false |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 如果已经创建了噪声抑制器,先释放 |
|
||||
if (noiseSuppressor != null) { |
|
||||
noiseSuppressor?.release() |
|
||||
noiseSuppressor = null |
|
||||
} |
|
||||
|
|
||||
// 创建新的噪声抑制器 |
|
||||
noiseSuppressor = NoiseSuppressor.create(audioSessionId) |
|
||||
if (noiseSuppressor == null) { |
|
||||
Log.e(TAG, "创建噪声抑制器失败") |
|
||||
return false |
|
||||
} |
|
||||
|
|
||||
// 启用噪声抑制 |
|
||||
noiseSuppressor?.enabled = true |
|
||||
currentAudioSessionId = audioSessionId |
|
||||
|
|
||||
Log.i(TAG, "噪声抑制已启用,音频会话ID: $audioSessionId") |
|
||||
return noiseSuppressor?.enabled == true |
|
||||
} catch (e: Exception) { |
|
||||
Log.e(TAG, "启用噪声抑制失败: ${e.message}") |
|
||||
return false |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 禁用噪声抑制 |
|
||||
* |
|
||||
* @return 是否成功禁用 |
|
||||
*/ |
|
||||
private fun disableNoiseSuppression(): Boolean { |
|
||||
if (noiseSuppressor == null) { |
|
||||
return true |
|
||||
} |
|
||||
|
|
||||
try { |
|
||||
noiseSuppressor?.enabled = false |
|
||||
noiseSuppressor?.release() |
|
||||
noiseSuppressor = null |
|
||||
Log.i(TAG, "噪声抑制已禁用") |
|
||||
return true |
|
||||
} catch (e: Exception) { |
|
||||
Log.e(TAG, "禁用噪声抑制失败: ${e.message}") |
|
||||
return false |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 释放所有音频效果 |
|
||||
*/ |
|
||||
private fun releaseAudioEffects() { |
|
||||
try { |
|
||||
echoCanceler?.release() |
|
||||
echoCanceler = null |
|
||||
|
|
||||
noiseSuppressor?.release() |
|
||||
noiseSuppressor = null |
|
||||
|
|
||||
automaticGainControl?.release() |
|
||||
automaticGainControl = null |
|
||||
|
|
||||
currentAudioSessionId = -1 |
|
||||
Log.i(TAG, "所有音频效果已释放") |
|
||||
} catch (e: Exception) { |
|
||||
Log.e(TAG, "释放音频效果失败: ${e.message}") |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 检查音频会话ID是否有效,如果无效则创建一个新的 |
|
||||
* |
|
||||
* @return 有效的音频会话ID |
|
||||
*/ |
|
||||
private fun ensureValidAudioSessionId(): Int { |
|
||||
// 如果已经有有效的音频会话ID,直接返回 |
|
||||
if (currentAudioSessionId > 0) { |
|
||||
Log.i(TAG, "使用已存在的音频会话ID: $currentAudioSessionId") |
|
||||
return currentAudioSessionId |
|
||||
} |
|
||||
|
|
||||
Log.i(TAG, "尝试创建有效的音频会话ID") |
|
||||
|
|
||||
// 尝试从AudioManager获取音频会话ID |
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && ::audioManager.isInitialized) { |
|
||||
try { |
|
||||
val audioAttributes = audioManager.getActivePlaybackConfigurations() |
|
||||
if (audioAttributes.isNotEmpty()) { |
|
||||
val sessionId = audioAttributes[0].audioAttributes.usage |
|
||||
if (sessionId > 0) { |
|
||||
currentAudioSessionId = sessionId |
|
||||
Log.i(TAG, "从AudioManager获取到音频会话ID: $sessionId") |
|
||||
return sessionId |
|
||||
} |
|
||||
} |
|
||||
} catch (e: Exception) { |
|
||||
Log.e(TAG, "从AudioManager获取音频会话ID失败: ${e.message}") |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 尝试创建一个临时的AudioTrack来获取会话ID |
|
||||
try { |
|
||||
val audioTrack = android.media.AudioTrack( |
|
||||
android.media.AudioAttributes.Builder() |
|
||||
.setUsage(android.media.AudioAttributes.USAGE_MEDIA) |
|
||||
.setContentType(android.media.AudioAttributes.CONTENT_TYPE_SPEECH) |
|
||||
.build(), |
|
||||
android.media.AudioFormat.Builder() |
|
||||
.setSampleRate(16000) |
|
||||
.setChannelMask(android.media.AudioFormat.CHANNEL_OUT_MONO) |
|
||||
.setEncoding(android.media.AudioFormat.ENCODING_PCM_16BIT) |
|
||||
.build(), |
|
||||
1024, // 最小缓冲区大小 |
|
||||
android.media.AudioTrack.MODE_STREAM, |
|
||||
android.media.AudioManager.AUDIO_SESSION_ID_GENERATE |
|
||||
) |
|
||||
|
|
||||
val generatedSessionId = audioTrack.audioSessionId |
|
||||
if (generatedSessionId > 0) { |
|
||||
currentAudioSessionId = generatedSessionId |
|
||||
Log.i(TAG, "成功创建临时AudioTrack并获取音频会话ID: $generatedSessionId") |
|
||||
|
|
||||
// 释放AudioTrack资源 |
|
||||
audioTrack.release() |
|
||||
|
|
||||
return generatedSessionId |
|
||||
} else { |
|
||||
Log.w(TAG, "创建的AudioTrack未返回有效的音频会话ID") |
|
||||
audioTrack.release() |
|
||||
} |
|
||||
} catch (e: Exception) { |
|
||||
Log.e(TAG, "创建临时AudioTrack失败: ${e.message}") |
|
||||
} |
|
||||
|
|
||||
// 尝试创建一个临时的AudioRecord来获取会话ID |
|
||||
try { |
|
||||
val minBufferSize = android.media.AudioRecord.getMinBufferSize( |
|
||||
16000, |
|
||||
android.media.AudioFormat.CHANNEL_IN_MONO, |
|
||||
android.media.AudioFormat.ENCODING_PCM_16BIT |
|
||||
) |
|
||||
|
|
||||
if (minBufferSize > 0) { |
|
||||
val audioRecord = android.media.AudioRecord( |
|
||||
android.media.MediaRecorder.AudioSource.MIC, |
|
||||
16000, |
|
||||
android.media.AudioFormat.CHANNEL_IN_MONO, |
|
||||
android.media.AudioFormat.ENCODING_PCM_16BIT, |
|
||||
minBufferSize |
|
||||
) |
|
||||
|
|
||||
val recordSessionId = audioRecord.audioSessionId |
|
||||
if (recordSessionId > 0) { |
|
||||
currentAudioSessionId = recordSessionId |
|
||||
Log.i(TAG, "成功创建临时AudioRecord并获取音频会话ID: $recordSessionId") |
|
||||
|
|
||||
// 释放AudioRecord资源 |
|
||||
audioRecord.release() |
|
||||
|
|
||||
return recordSessionId |
|
||||
} else { |
|
||||
Log.w(TAG, "创建的AudioRecord未返回有效的音频会话ID") |
|
||||
audioRecord.release() |
|
||||
} |
|
||||
} else { |
|
||||
Log.w(TAG, "无法获取有效的AudioRecord最小缓冲区大小") |
|
||||
} |
|
||||
} catch (e: Exception) { |
|
||||
Log.e(TAG, "创建临时AudioRecord失败: ${e.message}") |
|
||||
} |
|
||||
|
|
||||
// 如果以上方法都失败,使用一个固定的默认值 |
|
||||
val defaultSessionId = 1 |
|
||||
Log.w(TAG, "使用默认音频会话ID: $defaultSessionId") |
|
||||
currentAudioSessionId = defaultSessionId |
|
||||
return defaultSessionId |
|
||||
} |
|
||||
} |
|
||||
Loading…
Reference in new issue