• 微信小程序 23 播放音乐页


    23.1 磁盘动画实现


    @keyframes:设置动画帧数。from to 适用于简单的动画,只有起始帧和结束帧。百分比 多用于复杂动画,动画不止两帧范围。

    infinite:无限循环动画。

    animation

    <view class="songDetailContainer">
        <view class="author">beyondview>
        <view class="circle">view>
        <image class="needle {{isPlay? 'needleRotate':''}}" src="/static/images/song/needle.png">image>
    
        <view class="discContainer {{isPlay? 'discRotate':''}}" >
            <image class="disc" src="/static/images/song/disc.png">image>
            <image class="musicImg" src="/static/images/nvsheng.jpg">image>
        view>
    
    view>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    .discRotate {
        animation: disc 1.5s linear infinite;
        animation-delay: 0.7s;
    }
    
    @keyframes disc {
        from {
            transform: rotate(0deg);
        }
        to{
            transform: rotate(360deg);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    23.2 播放区域的搭建

    <view class="songDetailContainer">
        <view class="author">beyondview>
        <view class="circle">view>
        <image class="needle {{isPlay? 'needleRotate':''}}" src="/static/images/song/needle.png">image>
    
        <view class="discContainer {{isPlay? 'discRotate':''}}" >
            <image class="disc" src="/static/images/song/disc.png">image>
            <image class="musicImg" src="/static/images/nvsheng.jpg">image>
        view>
    
        <view class="musicControl">
            <text class="iconfont icon-zhongbo">text>
            <text class="iconfont icon-shangyishoushangyige">text>
            <text class="iconfont {{isPlay? 'icon-zanting':'icon-bofang'}} big" bindtap="handleMusicPlay">text>
            <text class="iconfont icon-xiayigexiayishou">text>
            <text class="iconfont icon-24gl-playlistMusic5">text>
        view>
    view>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    /*底部控制区域*/
    
    .musicControl {
        position: absolute;
        bottom: 40rpx;
        border-top: 1rpx solid #fff;
        width: 100%;
        display: flex;
    }
    
    .musicControl text {
        width: 20%;
        height: 120rpx;
        line-height: 120rpx;
        text-align: center;
        color: #fff;
        font-size: 50rpx;
    }
    
    .musicControl .big{
        font-size: 80rpx;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
        handleMusicPlay(){
            this.setData({
                isPlay:!this.data.isPlay
            })
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述


    23.3 利用eventChannel实现页面之间数据通讯

    data-xxx:可以往 回调函数的 event.currentTarget.dataset 里面 存入一个 数据。这个数据的名字 是你 自己定义的。就是 data- 后面的 xxx。

    eventChannel 的用法

    1. 首先我们要在 recommendSong.wxml 的 内容区 弄一个 点击事件。
    
        <scroll-view scroll-y="true" class="listScroll">
    
            <view class="scrollItem" bindtap="navigateTosongDetail" data-song="{{item}}" wx:for="{{recommendList}}" wx:key="id">
                <image src="{{item.al.picUrl}}">image>
                <view class="musicInfo">
                    <text class="musicName">{{item.al.name}}text>
                    <text class="author">{{item.ar[0].name}}text>
                view>
                <text class="iconfont icon-gengduo-shuxiang">text>
            view>
        scroll-view>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    并且 在这个 scrollItem 这里,要 传递 一个 数据 data-song

        navigateTosongDetail(event){
            wx.navigateTo({
                url: "/pages/songDetail/songDetail",
                success: function (res){
                    res.eventChannel.emit('song',event.currentTarget.dataset.song);
                }
            })
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 在 songDetail.js 的 onLoad 里面 拿到 传递过来的这个数据。
        onLoad(options) {
            //获取事件对象
            const eventChannel = this.getOpenerEventChannel();
            eventChannel.on('song', function(data) {
                console.log(data)
            })
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述


    23.4 动态加载 songDetail 页面数据

    wx.setNavigationBarTitle:设置 页面的 标题。

    this 的 作用域问题:有时候 他会 提示你 this.setData() 不是一个方法,这个时候 不要疑惑,肯定是 你当前的 this 不是 你认为的 this 了。也就是 作用域 出现了问题,你取到的 this 不对。

    解决方法:声明一个变量,让其值等于 this 。并且 一定程度上 提高 这个变量的 作用域。

        onLoad(options) {
            //获取事件对象
            let that = this; // 拿到 原本的 this,用 提高作用域的 that 接收
            const eventChannel = this.getOpenerEventChannel();
            eventChannel.on('song', function(data) {
                that.setData({
                    song: data
                })
            });
            wx.setNavigationBarTitle({
                title: this.data.song.name
            })
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    <view class="songDetailContainer">
        <view class="author">{{song.ar[0].name}}view>
        <view class="circle">view>
        <image class="needle {{isPlay? 'needleRotate':''}}" src="/static/images/song/needle.png">image>
    
        <view class="discContainer {{isPlay? 'discRotate':''}}" >
            <image class="disc" src="/static/images/song/disc.png">image>
            <image class="musicImg" src="{{song.al.picUrl}}">image>
        view>
    
        <view class="musicControl">
            <text class="iconfont icon-zhongbo">text>
            <text class="iconfont icon-shangyishoushangyige">text>
            <text class="iconfont {{isPlay? 'icon-zanting':'icon-bofang'}} big" bindtap="handleMusicPlay">text>
            <text class="iconfont icon-xiayigexiayishou">text>
            <text class="iconfont icon-24gl-playlistMusic5">text>
        view>
    view>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述


    23.5 播放和暂停音乐功能的实现

    wx.getBackgroundAudioManager():获取到 全局背景音乐管理器,它是唯一的。

    接口: http://localhost:3000/song/url?id=1907766514 获取到 歌曲播放的地址。

    // pages/songDetail/songDetail.js
    import request from "../../utils/request";
    
    Page({
    
        /**
         * 页面的初始数据
         */
        data: {
            isPlay: false, // 标识音乐是否播放
            song: {}
        },
    
        // 点击播放/暂停的 回调函数
        handleMusicPlay(){
            this.setData({
                isPlay:!this.data.isPlay
            });
            this.musicControl(this.data.isPlay,this.data.song.id)
        },
    
        // 控制音乐播放/暂停的 功能函数
        async musicControl(isPlay, musicId) {
            let backgroundAudioManager = wx.getBackgroundAudioManager();
            if (isPlay) {// 音乐开始播放
                // 获取音乐播放链接
                let musicLinkData = await request('song/url', {id: musicId});
                console.log(musicLinkData.data[0].url);
                // 创建 控制音乐播放的实例
                backgroundAudioManager.title = this.data.song.name;
                backgroundAudioManager.src = musicLinkData.data[0].url;
            } else {// 暂停播放
                backgroundAudioManager.pause();
            }
        },
    
        /**
         * 生命周期函数--监听页面加载
         */
        onLoad(options) {
            //获取事件对象
            let that = this;
            const eventChannel = this.getOpenerEventChannel();
            eventChannel.on('song', function(data) {
                that.setData({
                    song: data
                })
            });
            wx.setNavigationBarTitle({
                title: this.data.song.name
            })
        },
    
        /**
         * 生命周期函数--监听页面初次渲染完成
         */
        onReady() {
    
        },
    
        /**
         * 生命周期函数--监听页面显示
         */
        onShow() {
    
        },
    
        /**
         * 生命周期函数--监听页面隐藏
         */
        onHide() {
    
        },
    
        /**
         * 生命周期函数--监听页面卸载
         */
        onUnload() {
    
        },
    
        /**
         * 页面相关事件处理函数--监听用户下拉动作
         */
        onPullDownRefresh() {
    
        },
    
        /**
         * 页面上拉触底事件的处理函数
         */
        onReachBottom() {
    
        },
    
        /**
         * 用户点击右上角分享
         */
        onShareAppMessage() {
    
        }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102

    backgroundAudioManager.title 是必须要设置的,否则 你设置完 src 也无法 正常播放!!

  • 相关阅读:
    androd 如何使得升级更加容易 以及规范app文件使用
    [附源码]java毕业设计小区物业管理系统论文
    [Elastic-Job2.1.5源码]-11-基于Zookeeper分布式锁实现选举作业主节点原理
    Vue 项目中的自适应布局:px 转换成 vw/vh
    配置防火墙
    docker系列持续更新中
    深度相机(3D相机)
    10道不得不会的 Java容器 面试题
    图片怎么压缩到100k以下?
    SpringBoot - Swagger2的集成与使用(二)
  • 原文地址:https://blog.csdn.net/qq_52606908/article/details/125863861