微信小程序-audio功能实现

前提:

参考:(真机这样写还是有问题)
《1》构造npm:

  • https://blog.youkuaiyun.com/zxh7770/article/details/105108779

《2》小程序:

  • https://developers.weixin.qq.com/community/develop/doc/000ac4d78f41503fe059037b656400

1、场景:初始化跳转到上次播放的位置,可前进后退各15s的时间
2、出现问题:

  • seek后出现onTimeUpdate监听失效,无法更新当前的进度条(进度条设置在监听中了)

3、问题原因:

  • seek 跳转需要先puse暂停后再play才可以监控到

4、解决问题

  • 点击seek时再onSeek监听中去暂停puse,在onCanplay中去开启播放play,就可以解决了
  • 关键代码如下:
  this.innerAudioContext.onSeeking(()=>{
       this.innerAudioContext.pause()
  })
  this.innerAudioContext.onCanplay(() => {           
        this.innerAudioContext.play()
   })

在这里插入图片描述

  • 功能实现(详情如下)
   // pages/knowladgedetailinfo/knowladgedetailinfo.js
const  moment = require('moment') //这个插件需要下载

Page({

    /**
     * 页面的初始数据
     */
    data: {
            isPlay:false,//是否播放 true:播放
            currentTime:0,
            currentWidth:0,
            url:'https://XXXXXX.mp3',
            duration:0,//总时间长度
            
    },
    //获取文章详情-就是后端返回音频的url和当前时间的一些业务信息
    getArticleDetail(){
    	//例如 this.setData({//currentTime、url})
    },
    //点击播放
    handleMusicPlay(){
        let isPlay = !this.data.isPlay;
        // 修改是否播放的状态
        this.setData({
          isPlay,
        })
        this.musicControl(isPlay,  this.data.audio);
    },
    // 控制音乐播放/暂停的功能函数
    musicControl(isPlay, musicLink){
        const {currentTime} = this.data
        if(isPlay && musicLink){ // 音乐播放
             this.innerAudioContext.autoplay = isPlay //是否自动播放
             this.innerAudioContext.src = musicLink 
             this.innerAudioContext.seek(currentTime)
        }else{
            this.innerAudioContext.pause();
        }
    },
    // 修改播放状态的功能函数
    changePlayState(isPlay){
        // 修改音乐是否的状态
        this.setData({
            isPlay
        })
    },
    //播放前进后退
    handleTime(item){           
        if(item.currentTarget.dataset.type==='left'){
            this.innerAudioContext.currentTime>15?this.innerAudioContext.seek((this.innerAudioContext.currentTime-15)):this.innerAudioContext.seek(0)
        }else{
            this.innerAudioContext.currentTime>totalTime?this.innerAudioContext.seek(totalTime):this.innerAudioContext.seek((this.innerAudioContext.currentTime+15)) 
        }
    },
    //提交-保存当前记录播放截止记录(后端接口提供创建记录保存最后播发的时间)
    handleSubmitTime(){
        console.log('时间提交',this.data.cognitionId)
    },
    //创建audio
    handleCreateAudio(){
        this.innerAudioContext = wx.createInnerAudioContext()
        this.innerAudioContext.onPlay(() => {
            this.changePlayState(true);
        })
        this.innerAudioContext.onPause(()=>{
            this.changePlayState(false);
        })
        this.innerAudioContext.onCanplay(() => {
            this.innerAudioContext.play()
        })
        this.innerAudioContext.onTimeUpdate(()=>{
                let currentTime = moment(this.innerAudioContext.currentTime * 1000).format('mm:ss')
                let currentWidth = this.innerAudioContext.currentTime/this.innerAudioContext.duration * 450;
                this.setData({
                    currentTime,
                    currentWidth,
                })
        })
        this.innerAudioContext.onSeeking(()=>{
            this.innerAudioContext.pause()
        })
        this.innerAudioContext.onEnded(()=>{
            this.setData({
                currentWidth: 0,
                currentTime: '00:00',
            })
            this.changePlayState(false);
        })
        this.innerAudioContext.onError((res) => {
            this.changePlayState(false);
        })
    },
    /**
     * 生命周期函数--监听页面加载
     */
    async onLoad(options) {
        this.getArticleDetail() //初始化从后端接口中获取播放参数
        this.handleCreateAudio() //初始化创建audio实例然后进行设置和监听
    },
    /**
     * 生命周期函数--监听页面隐藏
     */
    async onHide() { //隐藏前向后端提交当前记录的播放+销毁innerAudioContext
        if(this.data.isClick){
            await this.handleSubmitTime()
            this.innerAudioContext.pause()
            this.innerAudioContext.destroy()
        }
    },
    /**
     * 生命周期函数--监听页面卸载
     */
    async onUnload() { //隐藏前向后端提交当前记录的播放+销毁innerAudioContext
        if(this.data.isClick){
            await this.handleSubmitTime()
            this.innerAudioContext.pause()
            this.innerAudioContext.destroy()
        }
    },
})

  • 模块样式实现
    <view class="mp3_card">
        <view class="mp3_time">
            时长:{{timeH}}{{timeS}}</view>
        <view class="mp3_function">
            <view class="item">
                <image style="width:50rpx;height:50rpx" src="../../images/mp3left_cirletime.png" alt='左播放' data-type="left" bindtap="handleTime"></image>
            </view>
            <view class="item">
                <image hidden="{{isPlay}}" style="width:104rpx;height:104rpx" src="../../images/mp3stop.png" bindtap="handleMusicPlay"></image>
                <image hidden="{{!isPlay}}"  style="width:104rpx;height:104rpx" src="../../images/knowledge/start.png" bindtap="handleMusicPlay"></image>
            </view>
            <view class="item">
                <image style="width:50rpx;height:50rpx" src="../../images/mp3right_cirletime.png" alt='右播放' data-type="right" bindtap="handleTime"></image>
            </view>
        </view>
        <view class='mp3_schedule'>
            <view class="sechedule_num" style="width: {{currentWidth?currentWidth + 'rpx':0}}">
                <view class="schedule_icon">
                    {{currentTime}}/{{duration}}
                </view>
            </view>
        </view>
    </view>

模块的样式

.mp3_card{
    box-sizing: border-box;
    padding: 20rpx 58rpx 38rpx 58rpx;
    margin-top: 32rpx;  
    height: 270rpx;
    border-radius: 16rpx;
    background: #FFFFFF;
    box-shadow: 0 0 20rpx 0 rgba(0, 0, 0, 0.3);
}
.mp3_time{
    font-family: SourceHanSansCN-Regular;
    font-size: 24rpx;
    font-weight: normal;
    line-height: 44rpx;
    letter-spacing: 0em;
    color: #3D3D3D;
}
.mp3_function{
    margin-top: 24rpx;
    display: flex;
    flex-direction: row;
    justify-content: center;
    justify-items: center;
}
.mp3_function >.item{
    text-align: center;
    margin: auto;
    flex: 1;
}
.mp3_schedule{
    margin-top: 30rpx;
    width: 100%;  
    height: 4rpx;
    background-color:#D8D8D8 ;  
    /* border-bottom: 4rpx solid #D8D8D8; */
    position: relative;
}
.sechedule_num{
    position: relative;
    height: 4rpx;
    top: 0rpx;
    left:0rpx;
    line-height: 4rpx;
    background-color:#FAB71C;  
}
.schedule_icon{
    position: absolute;
    text-align: center;
    top: -20rpx;
    right: -140rpx;
    width: 140rpx;
    height: 40rpx;
    border-radius: 40rpx;

    /* Text/Secondary */
    background: #767676;
    font-family: SourceHanSansCN-Regular;
    font-size: 10px;
    line-height: 40rpx;
    font-weight: normal;
    letter-spacing: 0em;
    color: #FFFFFF;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值