uni-app uni.createInnerAudioContext() seek方法在安卓下播放音频与currentTime对不上
uni-app uni.createInnerAudioContext() seek方法在安卓下播放音频与currentTime对不上
开发环境 | 版本号 | 项目创建方式 |
---|---|---|
Windows | Windows 11 家庭版 23H2 | HBuilderX |
产品分类:uniapp/App
PC开发环境操作系统:Windows
手机系统:Android
手机系统版本号:Android 14
手机厂商:小米
手机机型:redmi note 14 5G
页面类型:vue
vue版本:vue3
打包方式:云端
示例代码:
<template>
<view class="app">
<view>当前时间{{currentTime}}</view>
<view @click="seek">从48s开始播放</view>
<view @click="play">直接播放</view>
</view>
</template>
<script setup>
import {ref} from 'vue';
import {onReady} from "@dcloudio/uni-app";
let innerAudioContext = ref();
const currentTime = ref(0);
let timer = null;
onReady(() => {
innerAudioContext = uni.createInnerAudioContext();
innerAudioContext.src = "/storage/emulated/0/Android/data/com.luanmiyun.pluad/apps/__UNI__18354DE/doc/audio/1733362495043_IMPORT_2F153FA31F50E418E0A5E5465D37DFC9_1h-29m-48s_965065ab-1e85-47d0-ba9d-e9758d110dd3_12-02_周例会_项目进展与问题解决_项目管理与技术实现_项目开发与集成.mp3";
innerAudioContext.onPlay(() => {
timer && clearInterval(timer);
timer = setInterval(() => {
currentTime.value = innerAudioContext.currentTime
}, 100)
});
});
const seek = () => {
innerAudioContext.seek(48);
play();
}
const play = () => {
innerAudioContext.play();
}
</script>
<style scoped lang="scss">
.app{
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
view{
margin-top: 40rpx;
}
}
</style>
操作步骤:
操作流程:
- 点击“直接播放”,让音频正常播放到48-49s的时候,音频片段播放“那个本质…”的话语,这个是正常的
- 点击“从48s开始播放”,用seek方法跳转到48s再播,音频和时间就对不上了,“那个本质”的话语需要到57s左右才能播出来,也就是音频延迟了大约10s。用onTimeUpdate监听的currentTime却正常,只是音频和时间对不上。
预期结果:
seek之后播放的音频和正常播放的音频片段一致。
实际结果:
seek之后播放的音频慢了大概10s
bug描述:
uni.createInnerAudioContext()的seek方法在安卓端的实际播放音频内容慢了10s左右。ios正常。
在处理 uni-app
中使用 uni.createInnerAudioContext()
播放音频时,如果发现在安卓设备上 seek
方法设置的位置与 currentTime
属性显示的位置不一致,这可能是由于音频缓冲或同步问题导致的。以下是一个简化的代码示例,展示如何使用 seek
方法并监听 timeupdate
事件来观察 currentTime
的变化,以便进行调试和进一步处理。
// 创建一个音频上下文
const innerAudioContext = uni.createInnerAudioContext();
// 设置音频源
innerAudioContext.src = 'https://example.com/audio.mp3';
// 监听音频自然播放到结束事件
innerAudioContext.onEnded(() => {
console.log('Audio ended');
});
// 监听时间更新事件,用于观察currentTime的变化
innerAudioContext.ontimeupdate(() => {
console.log('Current time:', innerAudioContext.currentTime);
});
// 播放音频
innerAudioContext.play();
// 假设在某个时间点,我们需要跳转到音频的某个位置
setTimeout(() => {
const targetTime = 60; // 目标跳转时间,单位为秒
console.log(`Seeking to ${targetTime}s`);
innerAudioContext.seek(targetTime);
}, 5000); // 5秒后执行seek操作
// 为了进一步调试,我们可以在seek后定期检查currentTime
const checkCurrentTime = () => {
if (innerAudioContext.currentTime !== targetTime) {
console.log(`Expected time: ${targetTime}s, Actual time: ${innerAudioContext.currentTime}s`);
setTimeout(checkCurrentTime, 1000); // 每秒检查一次
} else {
console.log('Seek completed successfully');
}
};
// 在seek操作后立即开始检查currentTime
setTimeout(checkCurrentTime, 1000); // 稍微延迟开始检查,给seek操作一些缓冲时间
// 注意:这里的checkCurrentTime函数是一个简单的调试辅助,
// 在实际应用中,可能需要根据具体需求调整检查频率或逻辑,
// 比如增加超时机制以避免无限循环。
// 停止播放(用于测试结束或其他目的)
// innerAudioContext.stop();
在上述代码中,我们通过 setTimeout
模拟了在播放一段时间后跳转到指定时间点的操作,并通过 ontimeupdate
事件监听器来实时输出当前的播放时间。此外,还定义了一个 checkCurrentTime
函数来定期检查 currentTime
是否达到了预期的位置,这有助于诊断 seek
方法与 currentTime
不一致的问题。
请注意,由于音频缓冲和设备性能的差异,seek
操作后的 currentTime
可能会有短暂的延迟才能达到目标值。在实际应用中,应根据用户体验需求合理处理这种延迟。