uni-app 关于 uni.createInnerAudioContext() 在 ios 和安卓上的两种情况

uni-app 关于 uni.createInnerAudioContext() 在 ios 和安卓上的两种情况

开发环境 版本号 项目创建方式
Windows 10 HBuilderX
产品分类:uniapp/App

PC开发环境操作系统:Windows

PC开发环境操作系统版本号:10

HBuilderX类型:正式

HBuilderX版本号:3.3.11

手机系统:iOS

手机系统版本号:iOS 15

手机厂商:苹果

手机机型:iPhoneX

页面类型:vue

vue版本:vue2

打包方式:云端

项目创建方式:HBuilderX

### 示例代码:

```javascript
var innerAudioContext = this._audioContext = uni.createInnerAudioContext();
innerAudioContext.autoplay = false;
innerAudioContext.src = 'https://img-cdn-qiniu.dcloud.net.cn/uniapp/audio/music.mp3';

//..音频可以播放 取音频时长并计算  
innerAudioContext.onCanplay( res => {  
    this.duration = this.durationCompute(innerAudioContext.duration)  
    console.log('可以播放了', this.duration)  
})  
console.log(JSON.stringify(innerAudioContext))  
innerAudioContext.onPlay(() => {  
    console.log('开始播放');  
});

操作步骤:

创建音频,获取duration

预期结果:

ios可以在创建音频的时候监听到onCanplay方法

实际结果:

ios无法在创建音频的时候监听到onCanplay方法

bug描述:

主要想实现在渲染出播放控件的时候就获取到总时长
onCanplay事件在安卓上是渲染完播放就执行进入,能直接拿到duration
但是在ios上,创建uni.createInnerAudioContext()后,不会直接执行onCanplay,当点击播放的时候才会监听到onCanplay事件,就没办法第一时间获取到duration,为什么ios和安卓会有这种区别,那ios需要怎么拿到duration呢?


更多关于uni-app 关于 uni.createInnerAudioContext() 在 ios 和安卓上的两种情况的实战教程也可以访问 https://www.itying.com/category-93-b0.html

6 回复

已验证

更多关于uni-app 关于 uni.createInnerAudioContext() 在 ios 和安卓上的两种情况的实战教程也可以访问 https://www.itying.com/category-93-b0.html


啥时候能更新?

回复 z***@163.com: 你好,后续官方有解决吗,我现在也遇到这个问题了

这不是问题,iOS端只有触发开始播放的时候才会加载音频数据,平台差异问题,你们应该服务端返回音频的时长,而不是靠播放器的 duration 来实现

请问一下 我后端给我返回的src 安卓上可以拿到duration 换到ios上却拿不到,随后我从网上找了别的地址试验,ios也可以拿到。再将可以拿到duration的音频下载由我后端传回,又拿不到了。是否我后端传回的src不合法,请问怎么调整为合法的src

在iOS平台上,innerAudioContext.duration确实需要先播放音频才能获取到,这是iOS系统层面的限制。以下是解决方案:

  1. 针对iOS的特殊处理方案:
if(uni.getSystemInfoSync().platform === 'ios') {
    innerAudioContext.play();
    setTimeout(() => {
        innerAudioContext.pause();
        innerAudioContext.seek(0);
        this.duration = this.durationCompute(innerAudioContext.duration);
    }, 500);
}
  1. 或者使用更优雅的监听方式:
innerAudioContext.onCanplay(() => {
    if(!this.duration) {
        innerAudioContext.play();
        setTimeout(() => {
            innerAudioContext.pause();
            innerAudioContext.seek(0);
            this.duration = innerAudioContext.duration;
        }, 100);
    }
});
回到顶部