文章目录
- 1、参考资料
- 2、业务背景
- 3、解决方案
1、参考资料
Media Player called in state 0, error (-38,0)
MediaPlayer的使用
2、业务背景
- 对时长超过 5s 的音频提供裁剪、试听功能,裁剪、试听最大时长均为 5s。当视频长度在 5s ~ 6s 之间,试听暂停时,可能整个音频播放完成了,此时会回调
onCompletion
方法,试听封装类会在播放完成后调用reset
方法。此时,再次点击播放试听,调用start
方法时,播放无声音。 - new MediaPlayer() 或者 任何状态调用了
reset
方法之后, 进入Idle
(闲置) 状态
private fun playPrepare(audioPath: String?) {
audioPath ?: return
MLog.d(TAG, "playAudio: audioPath = $audioPath")
if (mediaPlayer == null) {
mediaPlayer = ListenKit.instance
mediaPlayer?.play(audioPath, startNow = false, listener = object : ListenKit.Listener {
override fun onPrepared() {
MLog.d(TAG, "playAudio: onPrepared currentCutStartTime = $currentCutStartTime")
}
override fun onCompletion() {
MLog.d(TAG, "playAudio: onCompletion")
}
})
}
}
private fun playAudio(audioPath: String?) {
...
mediaPlayer?.start()
...
}
private fun stopAudioIfNeed() {
MLog.d(TAG, "stopAudioIfNeed: isPlaying = $isPlaying")
if (isPlaying) {
...
mediaPlayer?.pause()
...
}
}
3、解决方案
- 在试听结束后添加
seekTo
代码,避免播放完成,即可避免在reset
之后调用start
导致播放异常
private fun stopAudioIfNeed() {
MLog.d(TAG, "stopAudioIfNeed: isPlaying = $isPlaying")
if (isPlaying) {
...
mediaPlayer?.pause()
// 针对时长在 5s~6s 之间的音频,若播放完成,会回调 onCompletion 方法,此时再调用 start,播放无声音,出现下面的信息:
// Attempt to perform seekTo in wrong state: mPlayer=0x0, mCurrentState=1
// error (-38, 0)
mediaPlayer?.seekToPosition(0) // 注意!!!
...
}
}
PlaybackCompleted 状态转移 : 如果设置了循环模式SetLooping(), 那么播放完毕之后会重新进入Started状态;若没设置循环,则调用 OnCompletion.onCompletion() 回调方法, MediaPlayer 会进入 PlaybackCompleted 状态;
也可以在该状态直接调用start()进入Started状态