资讯专栏INFORMATION COLUMN

指尖一点歌声来--微信小程序之仿网易云音乐心得

KitorinZero / 2378人阅读

摘要:为了提高自己,最近在学习微信小程序,选题是仿网易云音乐。查文档发现,小程序中图片加载完成后,有一个加载完成事件。前者在微信客户端版本就不开始维护了,后者低版本需做兼容处理。目前还有一些功能暂未实现,会在以后继续完善项目,继续学习。

为了提高自己,最近在学习微信小程序,选题是仿网易云音乐。期间踩过了大把的坑,bug出现的难受和解决bug欢喜,一直是伴随我阶段性学习这个项目的心情。初步完成了项目的主要功能,来分享一下自己的心路历程。

实现功能

列表式渲染数据

图片轮播

传参页面跳转

按钮点击弹窗

音乐播放、暂停、上一曲、下一曲

选歌播放

嵌套template页及传递数据

项目展示

首屏


(图一)

页面的切换


(图二)

播放效果


(图三)

暂停、上一首、下一首


(图四)

弹窗及选歌


(图五)

项目实现 项目思想

*

小程序的开发模式是MVVM模式。简单的讲就是页面绑定的值改变,页面就发生改变;页面改变,页面的绑定的值改变。这样的话,列表式渲染就十分好用。只用写一个通用的骨架,然后使用列表渲染生成页面,这样非常省时间省力气。所以这个项目,大量充斥着列表渲染。

有的页面部分可能会出现在好几个页面上。在这个项目里,页面顶部的部分出现在多个部分中,同时小程序里很多地方需要用到**弹性布局居中效果**于是我便把常用css样式写在app.wxss中,这样可以复用。

页面右上角的四根竖线出现在多个页面中,那变可以多带带拿出来写,然后在通过template,导入至不同的页面中去。

选歌很需要解决的一点就是怎么才知道选择的是哪一首歌,歌单是哪一个歌单。一个页面获取到其他页面想传递过来的数据的方式有很多。其一、可以通过url跳转的时候,传参跳转,再通过跳转页面中onload事件添加options参数获得。其二、可以通过点击事件改变全局属性globalData的某项的值,然后再跳转页面中得到globalData中相应的值,便能知道页面跳转中想传递的值。这个项目使用了这两种方式,url传参获取播放第几首歌曲,全局属性globalData传递歌单。

项目资源

后台数据使用的是Easy Mock假数据,一个方便的数据构建平台。
当然还有方便的weui框架了,这个框架可以去github上拷贝,然后再根据weui示例,找到想要的想过,再去下载好了的文件里找到对应的代码,试一试便知道要如何使用了。
图片和音乐的话,因为使用的是网络地址。如果直接从网站上,按F12找到资源然后提取的话,通常提取的资源过几天便会失效。所以我们需要百度音乐外链、图片外链,然后会有相应的网站,可以生成一个长期不失效的链接,供我们下载图片和音乐。

踩过的坑与爬坑路 坑爹的图片问题:

项目起步第一个问题便是图片存放与加载。一些需要推送的消息以图片的形式展示,那么这个图是千万不能存在本地,需要通过src链接网络地址然后下载显示。那么问题来了:首页结构已经出来,图片却要延迟出来。页面则会出现这种情况:

经过思考,发现首页图片轮播条有很多张图片,他们会同时加载。而需求最急的是显示好第一张图片,第一张图片加载完成后,再加载其他图片。这样能减少页面首加载中,图片加载的将近一半的网速占用。查文档发现,小程序中图片加载完成后,有一个加载完成事件bindload
因为使用的是列表渲染来填充页面,所以便可以让绑定渲染图片的数据showImage起始为空,这样页面就先不会渲染,然后第一张图加载完后,再给showImage赋值,然后就会自动渲染页面,加载其他图片了。这样就能提高页面的加载速度。
(备注:这里有些像懒加载的味道,在用户需要的时候加载图片)


这里有一个小小的技巧,第一张图的swiper-item不参与页面渲染,这样第一张图就一定会进行加载。在第一张图加载完成后,再进行页面渲染。同时让swiper开始轮播效果和生成指示点。

播放页面动画和还原

音频的后台播放

在播放界面时,一开始使用的组件,洋洋洒洒敲下了一连串的代码,播放音乐,一切正常。但当我们前往另一个页面时,播放的音乐就没声音了。查了文档才知道audio并不能实现后台播放,实现后台播放的是wx.getBackgroundAudioPlayerState()wx.getBackgroundAudioManager()两个api。前者在微信客户端1.2.0版本就不开始维护了,后者低版本需做兼容处理。这个项目我使用的是第二个api。
(备注:wx.getBackgroundAudioManager()官方文档)

值得注意的是,当音频对象的src取得链接时,就自动开始播放。

播放状态。

歌曲播放时页面动起来,歌曲未播放时静止

看见动画了,第一个反应是css的animation,后来经过思考,如果不进行dom操作就要控制动画的进行与否需要做的数据绑定就会很多,不方便使用。于是查文档发现`wx.createAnimation(OBJECT)`这个api,但使用这个api,如果需要做到动画的循环播放,要写的js也很多很麻烦。经过了各种踩坑,根据小程序中的`progress`进度条组件,发现一个很棒的方法,那就是行内样式绑定数据。

(备注:指针动画简单,进行一次就结束,这里不提。。)




(备注:进度条是小程序自带的组件,已播放时间完成方式和进度条相似,这里与动画效果一并提出)

这样,只用在播放时,设计计时器,定时的按比列更改rotata、left、progress、的值,页面就会有相关改变。这个函数中,一开始便是清除计时器,因为有一个坑点:点击下一曲或上一曲时,计时器并未清除,那么,便会有两个计时器同时作用于一个值得改变(这种头疼的情况相信很多人都遇到过)。把三个计时器(转盘、按钮、进度条)在函数运行的开始就做清除,这样就让每次调用函数时,都先清除上一层的计时器,做到只有一个计时器作用于一个值。这种方式,用少量的代码,形成了可控的动画效果,很是方便。

(我在这收获了另一种写动画效果的方式,哈哈)
next: function () {
        // 全局定义了proSet rotSet timeSet,因为需要清除计时器
        var timeCount;
        clearInterval(proSet);
        clearInterval(rotSet);
        clearInterval(timeSet);
        proSet = setInterval(() => {
            if (this.data.progress >= 100) {
                i++;
                if(i==this.data.music.length){
                    i=0;
                }
                app.globalData.i=i;
                backgroundAudioManager.stop();                            
                this.nameBackMusic();
                timeCount = 0;
                this.setData({
                    progress: 0,
                    left: 0,
                    songTime: this.data.music[i].songTime,
                    songer: this.data.music[i].songer,
                    songName: this.data.music[i].songName,
                    time: secondToDate(this.data.music[i].songTime)
                });
            }
            else if (this.data.run == 0) {
                clearInterval(proSet);
                clearInterval(rotSet);
                clearInterval(timeSet);
            }
            this.setData({
                progress: 0.01 + this.data.progress,
                left: 0.0458 + this.data.left
            });
        }, this.data.music[i].songTime / 10);
        rotSet = setInterval(() => {
            this.setData({
                rotate: 1 + this.data.rotate,
            });
        }, 24);
        timeCount = backgroundAudioManager.currentTime;
        if (typeof (backgroundAudioManager.currentTime) === "undefined")
        {
            timeCount = 0;
        }
        timeSet = setInterval(()=>{
            timeCount++;
            this.setData({
                currentTime: secondToDate(timeCount), 
                //secondToDate用来把n秒转换为xx:xx的显示形式
            });
        },1000)
    }

页面还原

在播放界面中,设计一个值run初始值为0,用来记录是否播放,播放时run为1,暂停时run为0。在页面跳转在返回播放页面时,之前因为播放设置的data值会全部还原,导致页面静态显示(进度条不动、时间不增加等)。这个时候,全局属性globalData就上场了。不论是在选歌、播放、暂停的时候,globalData中的变量记录播放的状态(是否播放、播放哪一首歌等)。而播放页面重新打开会执行onShow()生命周期函数,这个时候变可以从全局变量中得到播放的状态,然后决定播放页面是否要动起来和相应的数据)。


因为页面第一次加载也会执行onShow()函数,而暂停音乐时backgroundAudioManager.paused返回true,播放时放回fals,没有音乐播放时返回undefined,如果单纯的用:if(backgroundAudioManager.paused)则会判断无音乐和音乐播放时都为假,这样两种不同的情况执行相同的操作,则会发生意外,所以需要添加这样的判断
if (typeof (backgroundAudioManager.paused) !== "undefined") 用以区分播放和无音乐事件。

结语

一路学习过来,期间碰到的大大小小的问题数不胜数,收获很大。目前还有一些功能暂未实现,会在以后继续完善项目,继续学习。

这个项目给我最大的启示就是文档是一个好东西,锻炼看文档的能力会自己接受新东西的速度变快。再就是很多时候解决问题的方法多种多样,写代码时可以多做几次考虑用哪种方式实现一个功能,这样既让项目变得更高校,也让自己变得更优秀。

个人邮箱:QiuShuiZC@163.com

github地址:秋水白

wx: zcfusheng

大家可以一起交流学习,如果觉得这个项目不错的话,用star来砸我吧。

(备注:我给项目里放的音乐都是周董和姿妈的,哈哈,毕竟男杰伦,女燕姿)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/92150.html

相关文章

  • 信小程序使用音乐api的方法,以及信小程序播放背景音乐失败的解决方案汇总

    摘要:下一步准备使用网易云代替音乐。已经开发新的网易云代替音乐了,需要的可以看看这篇文章为微信小程序开发的网易云音乐库 项目要做一个可以为日记添加音乐的小程序,所以要用到音乐api,参考了一些文章后我们封装了一个qq音乐api库(完成了动态token获取,音乐搜索,音乐专辑图片,音乐名称,歌手名称,播放),有需要的可以到Github自提。 小程序qq音乐api库Gihub地址https://...

    Sleepy 评论0 收藏0
  • 信小程序资源汇总

    awesome-github-wechat-weapp 是由OpenDigg整理并维护的微信小程序开源项目库集合。我们会定期同步上的项目到这里,也欢迎各位 UI组件开发框架实用库开发工具服务端项目实例Demo UI组件 weui-wxss ★1873 - 同微信原生视觉体验一致的基础样式库zanui-weapp ★794 - 好用易扩展的小程序 UI 库wx-charts ★449 - 微信小程...

    Olivia 评论0 收藏0
  • 信小程序实战(之仿美丽说

    摘要:被美丽说少女粉吸引,就想着自己也写一个来练练手,正好最近在学习微信小程序。微信小程序的组件真的很强大,以前写图片切换功能都好麻烦,小圆点的切换都要自己写。 被美丽说少女粉吸引,就想着自己也写一个来练练手,正好最近在学习微信小程序。接下来让我们分享一下我的学习历程吧! 选题 其实纠结了好久该仿什么,看到别人都写的差不多了,自己却还没有动手,很着急,那两天一直在思考在查找,弄得自己特别烦躁...

    wangdai 评论0 收藏0
  • 信小程序实战(之仿美丽说

    摘要:被美丽说少女粉吸引,就想着自己也写一个来练练手,正好最近在学习微信小程序。微信小程序的组件真的很强大,以前写图片切换功能都好麻烦,小圆点的切换都要自己写。 被美丽说少女粉吸引,就想着自己也写一个来练练手,正好最近在学习微信小程序。接下来让我们分享一下我的学习历程吧! 选题 其实纠结了好久该仿什么,看到别人都写的差不多了,自己却还没有动手,很着急,那两天一直在思考在查找,弄得自己特别烦躁...

    acrazing 评论0 收藏0
  • 信小程序实战(之仿美丽说

    摘要:被美丽说少女粉吸引,就想着自己也写一个来练练手,正好最近在学习微信小程序。微信小程序的组件真的很强大,以前写图片切换功能都好麻烦,小圆点的切换都要自己写。 被美丽说少女粉吸引,就想着自己也写一个来练练手,正好最近在学习微信小程序。接下来让我们分享一下我的学习历程吧! 选题 其实纠结了好久该仿什么,看到别人都写的差不多了,自己却还没有动手,很着急,那两天一直在思考在查找,弄得自己特别烦躁...

    zsirfs 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<