2***@qq.com
2***@qq.com
  • 发布:2022-10-19 23:17
  • 更新:2022-10-20 12:08
  • 阅读:399

【报Bug】uni.createInnerAudioContext() ,loop属性设置为true导致onEnded事件失效

分类:uni-app

产品分类: uniapp/App

PC开发环境操作系统: Windows

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

HBuilderX类型: 正式

HBuilderX版本号: 3.6.7

手机系统: Android

手机系统版本号: Android 11

手机厂商: 坚果R2

手机机型: 坚果R2

页面类型: vue

vue版本: vue3

打包方式: 云端

项目创建方式: HBuilderX

示例代码:

<template>  
    <view class="container">  
        <!-- 进度条 -->  
        <view class="steps">  
            <tui-steps :type="2" :items="items" spacing="180rpx" :activeSteps="activeSteps"></tui-steps>  
        </view>  
        <!-- 条文正文 -->  
        <view class="main">  
            《伤寒论》原书曾经西晋王叔和整理编次,在五代十国时期已经处于一线单传、存亡继绝的危机状态。此书在北宋国家书府秘藏八九十年,嘉佑年间(1056-1063),北宋校正医书局成立,选高继冲进献本为底本,由孙奇、林亿等校定,于1065年由朝廷诏命国子监雕版刊行,名为定本《伤寒论》,结束了从汉末至宋凡八百余年传本歧出、条文错乱的局面。  
        </view>  
    </view>  

    <!-- 播放控制 -->  
    <view class="control">  
        <image src="/static/images/oui/speed1.png" mode="aspectFit" class="btnSpeed" @click="speed(1)" />  
        <image :src="`${playState == 0 ? '/static/images/oui/play.png':'/static/images/oui/pause.png'}`"  
            mode="aspectFit" class="btnPlay" @click="changePlayState" />  
        <image src="/static/images/oui/speed2.png" mode="aspectFit" class="btnSpeed" @click="speed(2)" />  
    </view>  

    <tui-button type="gray-primary" :size="34" bold width="372rpx" height="84rpx" margin="0 auto" @click="shown">  
        确认取消按钮  
    </tui-button>  

    <!-- 对话框 -->  
    <oui-dialog :buttons="buttons" :show="show" title="" titleColor="#fff" @close="close" @click="buttonTap">  
        <!-- <template v-slot:title></template> -->  
        <template v-slot:content>  
            <block v-for="i in 3">  
                <image src="/static/images/oui/badge.png" mode="widthFix" class="img" />  
            </block>  
            <view class="wd-font-semibold">三星才能通关,同学仍需努力</view>  
        </template>  
        <template v-slot:note>  
            <view class="note">  
                <navigator url="/pages/itemDetail/itemDetail?articleId={{acticleID}}">今日到此,分享背诵结果</navigator>  
            </view>  
        </template>  
    </oui-dialog>  
</template>  

<script>  
export default {  
    data() {  
        return {  
            acticleID: 0,  
            show: false, //是否显示oui-dialog对话框  
            buttons: [], //oui-dialog对话框按钮数组  
            items: [ //步骤条 步骤项数组  
                {  
                    title: "熟读",  
                },  
                {  
                    title: "试炼",  
                },  
                {  
                    title: "闯关",  
                },  
            ],  
            activeSteps: 0, //步骤条 当前步骤编号  
            playCount: 0, //播放计数  
            playState: 0, //播放状态 0-暂停中 1-播放中  
            playSpeed: 2, //播放速度  
            playbackRate: [0.5, 0.8, 1.0, 1.25, 1.5, 2.0], ////播放速度倍率  
            innerAudioContext: uni.createInnerAudioContext()  
        }  
    },  

    onShow(options) {  
        let innerAudioContext = this.innerAudioContext;  
        innerAudioContext.loop = true; //循环播放   

        innerAudioContext.onError((res) => {  
            console.log(res.errMsg);  
            console.log(res.errCode);  
        });  

        //监听自然播放结束事件  
        innerAudioContext.onEnded((res) => {  
            this.playCount++  
            uni.showToast({  
                title: `第${this.playCount}遍完成`,  
                position: 'bottom'  
            })  

            //循环播放,若自然播放n(n=3)遍完成,那么执行后续逻辑  
            if (this.playCount < 3) {  
                // innerAudioContext.play()  
                // this.playState = 1;  
            } else {  
                this.playState = 0;  
            }  
        });  
    },  

    methods: {  
        shown() {  
            this.buttons = [{  
                text: "重背",  
                color: "#999",  
            },  
            {  
                text: "背诵下一条",  
                color: "#fff",  
            },  
            ]  
            this.show = true  
        },  

        close() {  
            this.show = false  
        },  
        buttonTap(e) {  
            console.log(e)  
            this.close()  
        },  

        changePlayState() {  

            // let toastTitle = ['已暂停', '开始播放']  
            // uni.showToast({  
            //  title: toastTitle[this.playState],  
            //  position: 'bottom'  
            // })  
            let innerAudioContext = this.innerAudioContext;  

            innerAudioContext.src = 'https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-hello-uniapp/2cc220e0-c27a-11ea-9dfb-6da8e309e0d8.mp3';  

            //切换播放状态  
            switch (this.playState) {  
                case 0:  
                    innerAudioContext.play()  
                    break;  
                case 1:  
                    innerAudioContext.pause()  
                default:  
                    break;  
            }  

            this.playState = this.playState ? 0 : 1  
        },  

        speed(e) {  
            let innerAudioContext = this.innerAudioContext;  
            switch (e) {  
                case 1:  
                    if (this.playSpeed > 0)  
                        this.playSpeed--;  

                    uni.showToast({  
                        title: this.playbackRate[this.playSpeed],  
                        position: 'bottom'  
                    })  

                    innerAudioContext.playbackRate = this.playbackRate[this.playSpeed]  
                    break;  
                case 2:  
                    if (this.playSpeed < 5)  
                        this.playSpeed++;  

                    uni.showToast({  
                        title: this.playbackRate[this.playSpeed],  
                        position: 'bottom'  
                    })  

                    innerAudioContext.playbackRate = this.playbackRate[this.playSpeed]  
                    break;  

                default:  
                    break;  
            }  
        }  
    },  

    onLoad(option) {  
        this.acticleID = option.id  
    },  
}  
</script>  

<style lang="scss" scoped>  
.container {  
    padding: 0 30rpx;  

    .steps {  
        margin: 40rpx auto;  
    }  

    .main {  
        font-size: 36rpx;  
        line-height: 60rpx;  
        color: #666;  
        font-family: SourceHanSerifSC-Regular, SourceHanSerifSC;  
        font-weight: 400;  
        padding: 20rpx 20rpx;  
        background: #ffffff;  
        box-shadow: 0px 2px 16px 0px rgba(0, 0, 0, 0.1);  
        border-radius: 10rpx;  
    }  
}  

.control {  
    width: 65%;  
    height: 160rpx;  
    padding: 0 80rpx;  
    background: #fafafa;  
    box-shadow: 0px 2px 16px 0px rgba(0, 0, 0, 0.1);  
    border-radius: 84rpx;  
    position: absolute;  
    left: 0;  
    right: 0;  
    margin: 0 auto;  
    bottom: 155rpx;  
    text-align: center;  

    display: flex;  
    flex: 1;  
    align-items: center;  
    justify-content: space-between;  

    .btnPlay {  
        width: 80rpx;  
        height: 80rpx;  
        border: 20rpx solid #f6f6f6;  
        border-radius: 80rpx;  
        box-shadow: 0px 2px 16px 0px rgba(0, 0, 0, 0.1);  
    }  

    .btnSpeed {  
        width: 80rpx;  
    }  
}  

.img {  
    width: 120rpx;  
    height: 120rpx;  
    margin: 20rpx 20rpx;  
}  

.note {  
    font-size: 15px;  
    color: #5aa9f4;  
}  
</style>  

操作步骤:

如正文描述

预期结果:

如正文描述

实际结果:

如正文描述

bug描述:

uni.createInnerAudioContext()

使用场景
1、我需要音乐循环播放。当播放遍数超过5次的时候 ,页面中心显示一个对话框,但并不停止播放,仍然让音乐继续循环播放。

当前现状:
当loop属性设置为true时 ,会导致监听事件 onEnded 失效。 所以我在onEnded()事件中无法监控到当前已经播放了多少遍。

应该修复为:
我的理解是 虽然我设置的循环,但onEnded定义为“音频自然播放结束事件” 那么就应该在自然播放结束时如实出发。 循环是不停的再播一遍,再播一遍的意思是前一遍播放已经自然完整的结束了。因此【纵然是loop循环中,也应该如实触发onEnded事件】

2022-10-19 23:17 负责人:无 分享
已邀请:
DCloud_UNI_WZF

DCloud_UNI_WZF

ended事件为音频自然播放结束事件,而循环播放过程中播放到音频末尾并没有播放结束,所以不会触发该事件,和你理解的并不一致,包括 浏览器中 audio 标签的 ended 事件设计也是如此

  • 2***@qq.com (作者)

    你的解释虽然没有有问题,但要实现我所需的场景 ,有什么好的策略吗? 既要循环,又要能够统计到自然播放结束次数 ?

    2022-10-23 15:50

  • DCloud_UNI_WZF

    回复 2***@qq.com: 自己统计播放的时长呢?

    2022-10-23 16:52

该问题目前已经被锁定, 无法添加新回复