微信小程序 23 播放音乐页

23.1 磁盘动画实现


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

infinite:无限循环动画。

animation

<view class="songDetailContainer">
    <view class="author">beyond</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="/static/images/nvsheng.jpg"></image>
    </view>

</view>
.discRotate {
    animation: disc 1.5s linear infinite;
    animation-delay: 0.7s;
}

@keyframes disc {
    from {
        transform: rotate(0deg);
    }
    to{
        transform: rotate(360deg);
    }
}

23.2 播放区域的搭建

<view class="songDetailContainer">
    <view class="author">beyond</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="/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>
/*底部控制区域*/

.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;
}
    handleMusicPlay(){
        this.setData({
            isPlay:!this.data.isPlay
        })
    },

在这里插入图片描述


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>

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

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

在这里插入图片描述


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
        })
    },
<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>

在这里插入图片描述


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() {

    }
})

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值