5***@163.com
5***@163.com
  • 发布:2025-02-27 12:51
  • 更新:2025-03-11 22:41
  • 阅读:193

【报Bug】uni.createInnerAudioContext在小程序中不能正常运行

分类:uni-app

产品分类: uniapp/小程序/微信

PC开发环境操作系统: Windows

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

HBuilderX类型: 正式

HBuilderX版本号: 4.53

第三方开发者工具版本号: 最新

基础库版本号: 最新

项目创建方式: HBuilderX

示例代码:
<template>  
    <view class="audio-page">  
        <view class="box-left">  
            <image class="box-img" :src="props.image" mode="aspectFill"></image>  
            <view class="page-btn" @click="clickAudio">  
                <image :src="VF.music_play?VF.stop_img:VF.start_img" mode="widthFix"></image>  
            </view>  
        </view>  
        <view class="box-content">  
            <view class="content-name">{{props.title}}</view>  
            <view class="progress">  
                <text>{{getMinuteTime(VF.now_time)}}</text>  
                <slider :value="VF.now_time/VF.total_time*100" block-size="10" block-color="#FF3333"  
                                activeColor="#FF3333" @change="sliderChange"></slider>  
                <text>{{getMinuteTime(VF.total_time)}}</text>  
            </view>  
        </view>  
    </view>  
</template>  

<script setup lang="ts">  
import { onBeforeUnmount, onMounted, reactive } from 'vue';  
interface Props {  
    autoplay : boolean,  
    music : string,  
    image : string,  
    title : number | string,  
    audioContext?: any, // 接收外部传入的音频实例  
}  
let props = withDefaults(defineProps<Props>(), {  
    autoplay: false,  
    music: '',  
    image: '',  
    title: '',  
})  

interface reactiveRules {  
    music_play : boolean,  
    AUDIO : any,  
    total_time : any,  
    now_time : any,  
    timeupdata : any,  
    interval : any,  
    start_img : string  
    stop_img : string  
}  

let VF = reactive<reactiveRules>({  
    music_play: false,  
    AUDIO: '',  
    total_time: 0,  
    now_time: 0,  
    timeupdata: '',  
    interval: '',  
    start_img: "",  
    stop_img: ""  
})  

onMounted(()=>{  
    initAudio()  
})  

const getMinuteTime = (data : any) => {  
    let minute : any = parseInt((data / 60).toString())  
    let second : any = parseInt((data % 60).toString())  
    if (minute.toString().length == 1) minute = `0${minute}`  
    if (second.toString().length == 1) second = `0${second}`  
    return `${minute}:${second}`  
}  

const clickAudio = () => {  
    if (!VF.AUDIO) return  

    if (VF.music_play) {  
        VF.music_play = false  
        VF.AUDIO.pause()  
    } else {  
        VF.music_play = true  
        VF.AUDIO.play()  
    }  
}  

const sliderChange = (e : any) => {  
    if (!VF.AUDIO) return  

    let second = e.detail.value / 100 * VF.total_time  
    VF.AUDIO.seek(second)  
    VF.now_time = second  
}  

const initAudio = () => {  
    // 销毁之前的实例  
    if (VF.AUDIO) {  
        VF.AUDIO.destroy()  
    }  

    // 使用传入的音频实例  
    if (props.audioContext) {  
        VF.AUDIO = props.audioContext;  
        console.log('使用外部传入的音频实例');  
    } else {  
        // 如果没有传入实例,则创建新的实例(兼容旧代码)  
        // #ifdef MP-WEIXIN  
        try {  
            VF.AUDIO = wx.createInnerAudioContext()  
            // 微信小程序特殊处理  
            wx.setInnerAudioOption({  
                obeyMuteSwitch: false,  // 不遵循静音开关  
                speakerOn: true,       // 开启扬声器播放  
                mixWithOther: true,    // 与其他音频混播  
                success: function() {  
                    console.log('音频选项设置成功');  
                },  
                fail: function(err) {  
                    console.error('音频选项设置失败:', err);  
                }  
            });  
        } catch (error) {  
            console.error('创建音频实例失败:', error);  
        }  
        // #endif  

        // #ifndef !MP-WEIXIN  
        VF.AUDIO = uni.createInnerAudioContext()  
        // #endif  
    }  

    if (!VF.AUDIO) return  

    // 基本设置  
    VF.AUDIO.obeyMuteSwitch = false  // 不遵循系统静音开关  
    VF.AUDIO.volume = 1              // 设置音量为最大  

    // #ifdef MP-WEIXIN  
    // 微信小程序下额外设置  
    VF.AUDIO.volume = 1;             // 再次确保音量最大  
    // #endif  

    VF.AUDIO.src = props.music  

    // 事件监听  
    VF.AUDIO.onPlay(() => {  
        console.log('音频开始播放')  
        VF.music_play = true  

        // #ifdef MP-WEIXIN  
        // 播放时再次确认音量设置  
        VF.AUDIO.volume = 1;  
        // #endif  
    })  

    VF.AUDIO.onPause(() => {  
        console.log('音频暂停播放')  
        VF.music_play = false  
    })  

    VF.AUDIO.onStop(() => {  
        console.log('音频停止播放')  
        VF.music_play = false  
        VF.now_time = 0  
    })  

    VF.AUDIO.onEnded(() => {  
        console.log('音频播放结束')  
        VF.music_play = false  
        VF.now_time = 0  
        clearInterval(VF.timeupdata)  
    })  

    VF.AUDIO.onError((res) => {  
        console.error('音频播放错误:', res.errMsg, res.errCode)  
        VF.music_play = false  
    })  

    VF.AUDIO.onCanplay(() => {  
        console.log('音频准备就绪')  
        if (props.autoplay) {  
            VF.AUDIO.play()  
            VF.music_play = true  
        }  
    })  

    // 获取音频时长  
    VF.interval = setInterval(() => {  
        if (VF.AUDIO.duration != 0 && !isNaN(VF.AUDIO.duration)) {  
            VF.total_time = Math.round(VF.AUDIO.duration)  
            console.log("音频时长", VF.total_time)  
            clearInterval(VF.interval)  
            VF.AUDIO.play()  
        }  
    }, 100)  

    // 添加音量变化监听  
    // #ifdef MP-WEIXIN  
    // VF.AUDIO.onVolumeChange(() => {  
    //  console.log('音量变化:', VF.AUDIO.volume)  
    //  // 如果音量被设置为0,尝试恢复  
    //  if (VF.AUDIO.volume === 0) {  
    //      VF.AUDIO.volume = 1  
    //  }  
    // })  
    VF.AUDIO.volume = 1  
    // #endif  

    // 更新播放进度的代码改为使用currentTime  
    VF.timeupdata = setInterval(() => {  
        if (VF.music_play) {  
            VF.now_time++  
            if (VF.now_time >= VF.total_time) {  
                VF.music_play = false  
                VF.now_time = 0  
                VF.AUDIO.stop()  
                clearInterval(VF.timeupdata)  
            }  
        }  
    }, 1000)  
}  

onBeforeUnmount(()=>{  
    if (VF.AUDIO) {  
        VF.music_play = false  
        VF.AUDIO.stop()  
        VF.AUDIO.destroy()  
        VF.AUDIO = null  
    }  
    clearInterval(VF.timeupdata)  
    clearInterval(VF.interval)  
})  
</script>  

<style lang="scss">  
.audio-page{  
    width: 100%;  
    height: 150upx;  
    display: flex;  
    align-items: center;  
    justify-content: space-between;  
    box-shadow: 3upx 3upx 6upx #ccc;  
    .box-left{  
        width: 150upx;  
        height: 150upx;  
        position: relative;  
        display: flex;  
        .box-img{  
            width: 100%;  
            height: 100%;  
            position: absolute;  
            left: 0;  
            top: 0;  
            z-index: 2;  
        }  
        .page-btn{  
            width: 100%;  
            height: 100%;  
            display: flex;  
            align-items: center;  
            justify-content: center;  
            position: absolute;  
            left: 0;  
            top: 0;  
            z-index: 3;  
            image{  
                width: 50upx;  
                height: 50upx;  
                background-color: rgba($color: #000000, $alpha: 0.3);  
                border-radius: 50%;  
            }  
        }  
    }  
    .box-content{  
        flex: 1;  
        height: 100%;  
        display: flex;  
        flex-direction: column;  
        justify-content: center;  
        padding: 0 30upx;  
        box-sizing: border-box;  
        font-size: 24upx;  
        .content-name{  
            width: 100%;  
            display: -webkit-box;/* 弹性盒模型 */  
            -webkit-box-orient: vertical;/* 元素垂直居中*/  
            -webkit-line-clamp: 1;/*  文字显示的行数*/  
            overflow:hidden;/* 超出隐藏 */  
        }  
        .progress{  
            width: 100%;  
            display: flex;  
            align-items: center;  
            justify-content: space-between;  
            slider{  
                width: 80%;  
            }  
        }  
    }  
}  
</style>

操作步骤:

调用组件,然后播放。

预期结果:
正常播放,有声音。 <kk-audio audioContext="globalAudioContext" music="https://web-ext-storage.dcloud.net.cn/uni-app/ForElise.mp3"
title="音频标题"
/>

实际结果:

不能正常播放。

bug描述:

有没有大佬可以指导下uni.createInnerAudioContext?
现在的情况是:
1、web上正常播放
2、小程序上设置autoplay,正常播放
3、点击按钮播放,没有声音。

再细一点解释下:

1、使用uni.createInnerAudioContext构建了一个播放器,在web上正常运行。
2、使用uni.createInnerAudioContext的方法,在页面onload后进行创建,关联src,autoplay,正常播放。
3、同2的使用,但是绑定button,手动触发play()方法,无效,不能播放。
4、查看实例,里面正常拥有src数据。且可以读出音频时长。但是点播放没有声音,也不知道是没有正常播放,还是没有声音。
以上情况都是小程序上不能正常使用。

2025-02-27 12:51 负责人:DCloud_UNI_OttoJi 分享
已邀请:
DCloud_UNI_OttoJi

DCloud_UNI_OttoJi - 日常回复 uni-app/x 问题,如果艾特我没看到,请主动私信

可能是你在开发阶段没有开启忽略网络白名单校验。我使用下面简单代码可以正常 play 和 autoplay

我测试 vue3 + 最新的 HBuilderX Alpha 可以正常运行到微信小程序模拟器,你可以结合我的代码修改并反馈

<template>  
  <view @click="start">start</view>  
  <view @click="play">play</view>  
</template>  

<script>  
  export default {  

    data() {  
      return {  
        ctx: null,  
        isPlaying: false  
      }  
    },  
    methods: {  
      play() {  
        if (this.ctx) {  
          if (this.isPlaying) {  
            this.ctx.pause()  
            this.isPlaying = false  
          } else {  
            this.ctx.play()  
            this.isPlaying = true  
          }  
        }  
      },  
      start() {  
        const innerAudioContext = uni.createInnerAudioContext();  
        this.ctx = innerAudioContext  
        innerAudioContext.autoplay = true;  
        innerAudioContext.src = 'https://web-ext-storage.dcloud.net.cn/uni-app/ForElise.mp3';  
        innerAudioContext.onPlay(() => {  
          console.log('开始播放');  
        });  
        innerAudioContext.onError((res) => {  
          console.log(res.errMsg);  
          console.log(res.errCode);  
        });  
      }  
    }  
  }  
</script>  
  • 5***@163.com (作者)

    我用你的源码试了下,这美妙的钢琴曲变成了噪音(太多实例)。而且我说的问题,其实被你复现了。自动播放正常,但暂停和播放功能无效。我的代码和你的代码,问题一样。

    2025-03-11 12:10

  • 5***@163.com (作者)

    我试试更新下 hx,,,不能删IDE的锅吧???

    2025-03-11 12:11

  • DCloud_UNI_OttoJi

    回复 5***@163.com: 你升级下最新版 alpha,我复测是正常可以正常播放和暂停的,你再试一下?如果还有问题私聊我吧

    2025-03-11 21:52

  • 5***@163.com (作者)

    回复 DCloud_UNI_OttoJi: 无语了,还真就是Hbuilder 的问题。。。

    我的排查步骤:


    1、更新微信小程序基础库——bug依旧

    2、更新微信开发者工具到最新——bug依旧

    3、更新Hbuilder到最新——解决。。。

    2025-03-11 22:41

5***@163.com

5***@163.com (作者)

无语了,还真就是Hbuilder 的问题。。。
我的排查步骤:

1、更新微信小程序基础库——bug依旧
2、更新微信开发者工具到最新——bug依旧
3、更新Hbuilder到最新——解决。。。

  • DCloud_UNI_OttoJi

    ok 解决了就好,HBuilderX 可能修复了某些问题。如果还有问题新开帖子艾特我吧

    2025-03-12 11:03

要回复问题请先登录注册