Browse Source

上传 音效播放 优化

newdev_shunjiawei
liwei1dao 1 year ago
parent
commit
4a3be3f65b
  1. 195
      local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt

195
local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt

@ -26,6 +26,7 @@ import com.deep_voice.speech.tts.TtsEventListener
import com.deep_voice.speech.tts.TtsEventType
import com.deep_voice.bytedance_speech.BytedanceTTS
import java.util.UUID
import com.yunqiinnovation.agent_service.Utils
/**
* 代理服务事件监听接口
@ -1164,6 +1165,22 @@ object AgentService : CoroutineScope {
class AudioPlayer(private val context: Context) {
private var mediaPlayer: MediaPlayer? = null
private var isInitialized = false
private val playbackLock = Object() // 添加同步锁
/**
* 安全检查 MediaPlayer 是否正在播放
*/
private fun isMediaPlayerPlaying(): Boolean {
return try {
mediaPlayer?.isPlaying == true
} catch (e: IllegalStateException) {
Log.w(TAG, "MediaPlayer 状态异常,假定未播放: ${e.message}")
false
} catch (e: Exception) {
Log.w(TAG, "检查播放状态时发生异常: ${e.message}")
false
}
}
/**
* 播放音频资源
@ -1172,75 +1189,167 @@ object AgentService : CoroutineScope {
* @param volume 音量大小,范围0.0-1.0,默认1.0
*/
fun playAudio(resId: Int, isLooping: Boolean = false, volume: Float = 1.0f) {
try {
// 释放之前的资源
release()
synchronized(playbackLock) {
try {
// 强制停止并释放之前的资源
forceStop()
// 创建播放器并设置资源
mediaPlayer = MediaPlayer().apply {
// 设置资源
context.resources.openRawResourceFd(resId)?.use { fd ->
setDataSource(fd.fileDescriptor, fd.startOffset, fd.length)
}
// 创建播放器并设置资源
mediaPlayer = MediaPlayer().apply {
// 设置资源
context.resources.openRawResourceFd(resId)?.use { fd ->
setDataSource(fd.fileDescriptor, fd.startOffset, fd.length)
}
this.isLooping = isLooping // 设置循环属性
setVolume(volume, volume) // 设置音量(左声道,右声道)
this.isLooping = isLooping // 设置循环属性
setVolume(volume, volume) // 设置音量(左声道,右声道)
setOnCompletionListener {
if (!isLooping) {
release()
setOnCompletionListener {
if (!isLooping) {
release()
}
}
}
prepare()
start()
setOnErrorListener { _, what, extra ->
Log.e(TAG, "MediaPlayer 错误: what=$what, extra=$extra")
forceRelease()
true // 返回true表示错误已处理
}
prepare()
start()
Log.d(TAG, "开始播放音频资源: $resId, 循环: $isLooping")
}
isInitialized = true
} catch (e: Exception) {
Log.e(TAG, "播放音频资源异常: ${e.message}", e)
forceRelease()
}
} catch (e: Exception) {
Log.e(TAG, "播放音频资源异常: ${e.message}", e)
release()
}
}
/**
* 停止音频播放
*/
fun stopAudio() {
try {
mediaPlayer?.apply {
when {
isPlaying -> {
synchronized(playbackLock) {
try {
mediaPlayer?.apply {
if (isMediaPlayerPlaying()) {
stop()
Log.d(TAG, "音频已停止")
}
else -> {
} else {
Log.d(TAG, "音频未在播放状态,无需停止")
}
}
} catch (e: IllegalStateException) {
Log.e(TAG, "MediaPlayer 状态异常,无法停止: ${e.message}", e)
forceRelease()
} catch (e: Exception) {
Log.e(TAG, "停止音频播放异常: ${e.message}", e)
forceRelease()
}
} catch (e: IllegalStateException) {
Log.e(TAG, "MediaPlayer 状态异常,无法停止: ${e.message}", e)
// 重置 MediaPlayer
release()
} catch (e: Exception) {
Log.e(TAG, "停止音频播放异常: ${e.message}", e)
}
}
/**
* 释放资源
* 强制停止播放(不释放资源)
*/
fun release() {
private fun forceStop() {
try {
mediaPlayer?.apply {
if (isPlaying) {
stop()
if (isMediaPlayerPlaying()) {
try {
stop()
Log.d(TAG, "强制停止音频播放")
} catch (e: Exception) {
Log.w(TAG, "强制停止时异常: ${e.message}")
}
}
try {
reset()
} catch (e: Exception) {
Log.w(TAG, "重置时异常: ${e.message}")
}
reset()
release()
}
mediaPlayer = null
isInitialized = false
} catch (e: Exception) {
Log.e(TAG, "释放音频资源异常: ${e.message}", e)
mediaPlayer = null
isInitialized = false
Log.w(TAG, "强制停止过程中异常: ${e.message}")
}
}
/**
* 释放资源
*/
fun release() {
synchronized(playbackLock) {
try {
mediaPlayer?.apply {
// 安全停止播放
if (isMediaPlayerPlaying()) {
try {
stop()
} catch (e: IllegalStateException) {
Log.w(TAG, "停止播放时状态异常: ${e.message}")
}
}
// 安全重置
try {
reset()
} catch (e: IllegalStateException) {
Log.w(TAG, "重置 MediaPlayer 时状态异常: ${e.message}")
}
// 安全释放 - 修复递归调用问题
try {
release() // 这里调用的是 MediaPlayer.release(),不是递归
} catch (e: Exception) {
Log.w(TAG, "释放 MediaPlayer 时异常: ${e.message}")
}
}
} catch (e: Exception) {
Log.e(TAG, "释放音频资源异常: ${e.message}", e)
} finally {
// 确保变量被清理
mediaPlayer = null
isInitialized = false
}
}
}
/**
* 强制释放资源,不进行状态检查
*/
private fun forceRelease() {
synchronized(playbackLock) {
try {
mediaPlayer?.apply {
try {
reset()
} catch (e: Exception) {
Log.w(TAG, "重置 MediaPlayer 失败: ${e.message}")
}
try {
release()
} catch (e: Exception) {
Log.w(TAG, "释放 MediaPlayer 失败: ${e.message}")
}
}
} catch (e: Exception) {
Log.w(TAG, "强制释放资源时发生异常: ${e.message}")
} finally {
mediaPlayer = null
isInitialized = false
}
}
}
/**
* 检查是否正在播放
*/
fun isPlaying(): Boolean {
synchronized(playbackLock) {
return isMediaPlayerPlaying()
}
}
}

Loading…
Cancel
Save