写在前面

  1.入门几天小白的作品,希望为您有帮助,有好的意见或简易烦请赐教

  2.微信小程序审核音乐类别已经下架,想要发布选题需慎重。附一个参考链接,感谢https://www.hishop.com.cn/xiaocx/show_53774.html

  3.写的过程中参考了前辈们的方法,借过几位博客园、CSDN、简书前辈的路,这里表示感谢。

  4.官方API很重要

写在第二

  资深大牛在地铁上问我有没有玩过微信小程序,自觉惭愧。于是萌发了写个小程序长长见识的想法,毕竟,谁都想要做一位行业大牛嘛。

写这个小程序花了4天,中间第一天无从下手,第二天开悟,到后两天的优化。这中间我收获极大,感谢生活。OK,废话不多说。进入正文

正文在这里

  先看效果吧 求求你点开我吧

  小程序有两个页面,主页与播放页,因为采用了leanCloud作为后台数据开发,所以有一个lib包

  树结构,上图 附微信小程序使用leanCloud链接

  index页的功能描述:提供音乐查找与选择,搜索框不输入点击搜索得到数据库中所以音乐文件(.mp3格式),支持对歌名或歌手的模糊查询;

点击列表中的某一首即可跳转至播放页进行播放,从播放页清单回退至index页时,index页底部有播放小窗,点击可回到播放页

  看这里:

  

  代码送上:index.wxml

<view class='theMain' style='background-image:url({{bgimage}});'>
<view>
<image class='image1'src="{{imageUrl}}" mode='aspectFit' wx:if="{{!searchTop}}">
</image>
</view>
<view class='page_row'>
<view class="search">
<view class="df search_arr">
<icon class="searchcion" size='20' type='search'></icon>
<input class="searchInput" placeholder="请输入歌名,歌手" value="{{searchValue}}" bindinput='searchValueInput'/>
</view>
</view>
<view class='sousuo' bindtap='sousuoButton'>搜索</view>
</view>
<view class='listBar'>
<text class="search_top" style='width:80%;' wx:if="{{searchTop}}">搜索结果</text>
</view>
<view wx:for='{{json}}' class='music_list' bindtap='playTheMusic'data-name="{{item.name}}" data-url="{{item.url}}">
<text class='musictext'>{{item.name}}</text>
<view class='url'>{{item.url}}</view>
</view> <view class="search_no" wx:if="{{!centent_Show}}">
<text>暂时没有库存,联系冯大神上传哈</text>
</view>
<view class='littlebar' bindtap='littlebar'>
<view class='littleImage' style='background-image:url({{imageUrl}});'></view>
<view class='littleName'>
<text class='songNameText'>{{songName}}</text>
</view>
</view>
</view>

  index.wxss这个css样式代码我觉得就没啥可看的啦,这个还是看自己喜好调,如果需要的话,文章最下方附有Github链接,

重要的还是在index.js上啦,一起来看看(我觉得不错的地方直接在代码上标注了,可以参考一下)

const AV = require("../../libs/av-weapp-min");//这里是对LeanCloud的引用,大家需要的话可问度娘,很多详细教程,我还是蛮喜欢这个工具的
var app=getApp()
Page({ /**
* 页面的初始数据
*/
data: {
imageUrl: "http://lc-9qxpppvr.cn-n1.lcfile.com/9c1af72ea0506789a9b9.jpg",
searchValue:'',      //搜索值
centent_Show: true, //这个可看wxml中的wx:if属性,用来动态显示与隐藏
searchTop:false, //同上
bgimage: '', //背景图片,在得到搜索结果的时候显示
toName:'',
songName:''
}, searchValueInput: function (e) {//得到搜索框的内容并渲染到data下的searchValue中
var value = e.detail.value;
this.setData({
searchValue: value,
});
}, sousuoButton:function(){//对LeanCloud数据库的查询操作
var that=this; //这里非常重要,注意,此函数中then方法内还有一个函数,而该函数需要用到setData渲染数据。经过两层不可以直接用this.setData
var nameQuery1 = new AV.Query('_File');
nameQuery1.contains('name', that.data.searchValue);
var nameQuery2 = new AV.Query('_File');
nameQuery2.contains('name', '.mp3');
var query = new AV.Query.and(nameQuery1, nameQuery2);//这里相当于数据库where语句下的and操作
query.find().then(function (results) {
// results is an array of AV.Object.
//将data转成json格式
//转为数组
var jsonObj = JSON.parse(JSON.stringify(results));
app.globalData.musicList=jsonObj.concat(); //设置了全局变量,concat()方法为数组的复制,playing页面需要。具体用法可问度娘,app对象为顶部创建的对象
if (jsonObj.length == 0) {
that.setData({
centent_Show: false,
});
return;
}
that.setData({
json: app.globalData.musicList,
searchTop:true,
bgimage: "http://lc-9qxpppvr.cn-n1.lcfile.com/9c1af72ea0506789a9b9.jpg",
centent_Show:true
});
console.log(that.data.c)
}, function (error) {
console.log(error);
// error is an instance of AVError.
});
},
//点击底部音乐bar进入play界面
littlebar: function () { //这里有一个较难解决的问题,我会在下面单独写出,大神要是有思路请赐教,毕竟我才入门4天,很多都不懂
var pages=getCurrentPages();
var playingPage=pages[pages.length-2];
playingPage.setData({
angle:app.globalData.angle,
})
wx.navigateBack();
},
//点击清单跳转到播放界面
  //data-name="{{item.name}}" data-url="{{item.url}}"
//只有在列表渲染的view控件中设置这些属性,该函数才可得到点击后对应的属性(可见上面的index.wxml) playTheMusic:function(e){
    console.log(e.currentTarget.dataset.name);  //一个调试方法,调试器输出点击的歌曲名
this.setData({
toName: e.currentTarget.dataset.name
});
var songUrl = e.currentTarget.dataset.url;
var songName = e.currentTarget.dataset.name;
app.globalData.songName = songName;
var theUrl = "../playing/playing?songUrl=" + songUrl + "&songName=" + songName //url携带参数
wx.
redirectTo({ //此种跳转当前页面数据会保存在页面栈中,可以回退,可问度娘
    url: theUrl,
  })
  },

  /**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
/**
* 监听音乐播放
*/
wx.onBackgroundAudioPlay(function () {
// callback
console.log('onBackgroundAudioPlay')
})
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function
this.setData({
songName: app.globalData.songName ,
json: app.globalData.musicList,
searchTop: true,
});
}
})

  好了,这里我想谈一下在index.js中我提到的单独讲的内容。情景在于微信小程序界面之间的跳转,使用wx.navigateTo()方法跳转到另一个页面时可以将当前页面存入页面栈,再通过wx.navigateBack()方法对页面栈出栈操作,可回退到当前页面,使用wx.redirectTo()直接跳转,不存入页面栈。在这个程序中,index->playing->index->playing重复多次无法直接实现。这个问题我想了很久还是没有完美的将其解决。

  我的暂时逻辑是:点击对应音乐使用wx.redirectTo()方法,不保存页面栈,跳转至playing页;在playing页点击list图标使用wx.navigateTo(),保存页面栈,同时跳到index页,这时候会调用onShow()函数,将保存的list信息渲染到index页面上;点击index底部的播放小框调用wx.navigateBack()方法回到playing页(playing页的数据较多,所以采用了这种逻辑)

  哪位大哥有更好解决方法烦请赐教哈

  接下来是playing页:(推荐使用wx.getBackgroundAudioManager()接口对音乐行为进行操作

  此页面需要完成播放、暂停、上一曲、下一曲、回到index页、动态显示播放时间和总长度(部分实现)、快进(还未实现)

  看界面:

  

  然后上代码了:
  playing.wxml:图标来源于百度图片,简单ps抠图后传至云端使用;中间专辑图旋转感谢这篇博客,其中的旋转快慢,每次角度可通过调节常量值实现,下面代码有标注

<view class='Main'>
<view class='songNameView'>
<text></text>
<text class='songName'>{{name}}</text>
</view>
<view class='imageView' style="background-image: url({{imageUrl}});" animation="{{animationData}}">
</view>
<view class="backIndex" bindtap='backIndex' style='background-image:url({{homeImage}})'></view>
<view class='line'>
<view class='nowView'>
<text class='now'>{{cur}}</text>
</view>
<view class='theLine'></view>
<view class='allTimeView'>
<text class='allTime'>{{duration}}</text>
</view>
</view>
<view class="button">
<view class='back MusicIcon' style="background-image: url({{backUrl}});" bindtap='theBack'></view>
<view class='center MusicIcon' style="background-image: url({{playOrStopUrl}});" bindtap='play'></view>
<view class='next MusicIcon' style="background-image: url({{nextUrl}});" bindtap='theNext'></view>
</view>
</view>

同样,playing.wxss可在我的Github中查看

下面是展示playing.js的时刻,各种逻辑在代码中直接标注了

// pages/playing/playing.js
const AV = require("../../libs/av-weapp-min");
var app = getApp()
Page({ /**
* 页面的初始数据
*/
data: {
name:'测试',
url:'',
imageUrl:'http://lc-9qxpppvr.cn-n1.lcfile.com/9c1af72ea0506789a9b9.jpg',
homeImage:"http://lc-9qxpppvr.cn-n1.lcfile.com/a9603240aab63a7950b0.png",
animationData: {},
isPlay:false, //播放标志
thePosition:0, //用来保存暂停时播放位置
angle:0, //用来不断保存旋转次数,用于解决界面多次跳转后旋转失速问题
cur:'--:--', //当前时间
duration:'--:--' //总时长 },
//返回到清单页 //此处在上面有提及,点击list图标到index页面,并将跳转前最后一个旋转角度渲染给全局变量
backIndex: function () {
wx.navigateTo({
url: '../index/index',
});
app.globalData.angle=this.data.angle;
}, /**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
//加载传递过来的参数
  //options为随url传递过来的参数
this.setData({
name: options.songName,
url: options.songUrl,
imageUrl:"http://lc-9qxpppvr.cn-n1.lcfile.com/9c1af72ea0506789a9b9.jpg",
backUrl:"http://lc-9qxpppvr.cn-n1.lcfile.com/2574f1888750f8eaea88.png",
nextUrl:"http://lc-9qxpppvr.cn-n1.lcfile.com/299a6353324cb312b00e.png",
playOrStopUrl:"http://lc-9qxpppvr.cn-n1.lcfile.com/56885a2b7b3e478dd0c6.png",
isPlay:true
})
//加载页面时执行播放动作
wx.playBackgroundAudio({
dataUrl: this.data.url,
})
},
//播放/暂停
play:function(){
const backgroundAudioManager = wx.getBackgroundAudioManager();
var theTime;
var allTime;
if(this.data.isPlay){
wx.pauseBackgroundAudio(); //推荐都使用这个API,我之前不知道这个API,导致在后来的开发中无法实现上面列举的全部功能
theTime = backgroundAudioManager.currentTime;//不甘心,所以在点击播放或暂停时可对页面进行时间的动态渲染,也算是完成了一点吧
allTime = backgroundAudioManager.duration;
var theString1 = theTime.toFixed(0);
var theInt1 = parseInt(theString1);
var m1 = theInt1 / 60;
var mString1 = m1.toFixed(0); //截取小数点后0位数字,结果为String类型
var mInt1 = parseInt(mString1); //转number
var s1 = theInt1 % 60 / 100;
var cur = mInt1 + s1;
var theString = allTime.toFixed(0);
var theInt = parseInt(theString);
var m = theInt/60;
var mString = m.toFixed(0);
var mInt = parseInt(mString);
var s = theInt%60/100;
var all = mInt+s;
this.setData({
playOrStopUrl:"http://lc-9qxpppvr.cn-n1.lcfile.com/22a26757fca8c46a2940.png",//替换为暂停图标
isPlay: false, //渲染一些需要的数据
thePosition: theTime,
duration:all,
cur: cur
});
}else{
backgroundAudioManager.seek(this.data.thePosition);
backgroundAudioManager.play();
this.setData({
playOrStopUrl: "http://lc-9qxpppvr.cn-n1.lcfile.com/56885a2b7b3e478dd0c6.png",
isPlay:true
});
}
}, //下一首
theNext:function(){//对全局变量下的查找清单进行操作,如果当前歌曲为最后一首,跳转到第一首
var j;
var musicList = getApp().globalData.musicList.concat();
for (var i = 0; i < musicList.length;i++){
if(musicList[i].name==this.data.name){
j=i;
break;
}else{
j=-1;
}
}
if (musicList.length-1==j){
this.setData({
name: musicList[0].name,
url: musicList[0].url
});
}else{
this.setData({
name: musicList[j+1].name,
url: musicList[j + 1].url
});
}
wx.playBackgroundAudio({
dataUrl: this.data.url,
})
}, //上一首
theBack:function(){//若为第一首,跳转到最后一首
var j;
var theLength=0;
var musicList = getApp().globalData.musicList.concat();
theLength=musicList.length;
for (var i = 0; i < musicList.length; i++) {
if (musicList[i].name == this.data.name) {
j = i;
break;
} else {
j = 1;
}
}
if (j==0) {
this.setData({
name: musicList[theLength-1].name,
url: musicList[theLength-1].url
});
} else {
this.setData({
name: musicList[j-1].name,
url: musicList[j-1].url
});
}
wx.playBackgroundAudio({
dataUrl: this.data.url,
})
},/**
* 生命周期函数--监听页面显示
*/
onShow: function () {//这里为专辑图旋转函数,调用wx.createAnimation()接口,更多参数详情可看官方API
var animation = wx.createAnimation({
duration: 1000,
timingFunction: 'ease',
}) this.animation = animation // animation.scale(2, 2).rotate(45).step() this.setData({
animationData: animation.export()
})
var n = 0;
//连续动画需要添加定时器,所传参数每次+1就行
setInterval(function () {
n=this.data.angle;
if(this.data.isPlay){//暂停时停止旋转,播放旋转的逻辑
n = n + 1;
}else{
n=n;
}
this.setData({
angle: n,
})
this.animation.rotate(8 * n).step()//8为每次转8°,应该是,个人喜好设置
this.setData({
animationData: this.animation.export()
})
}.bind(this), 360)//360ms转一个角度,个人喜好设置
}
})

  OK,到这里就可以实现一个演示视频中所有功能的简易播放器了,是不是觉得很简单。

  相对于网上很多前辈的功能完善的音乐播放器来说,我这个真的是望尘莫及,未来还有很长的路要走。但是东西出来了嘛, 还是很开心的;当然,我还是会不断的去完善它的,这之中的playing页面的专辑图浮动旋转效果是我最惊喜的了,之前只是想加个阴影,没想到阴影可以跟随旋转,贼帅。

  感谢可爱的你看了这篇博客

  附Github:https://github.com/fengjirong/musicByfeng

微信小程序音乐播放器的更多相关文章

  1. 微信小程序音乐播放器组件

    wxml <image bindtap="click" src="{{isPlay?'/images/':'/images/'}}"/> JS Pa ...

  2. 微信小程序音乐播放

    最近在写一个艾美食艾音乐的微信小程序,其中有用到音乐播放的功能,基本播放切换功能已经实现,但是在反复切换歌曲.重新进入歌曲以及单曲循环.列表循环的测试过程中还是发生了bug,特此写一篇文章,捋一下思路 ...

  3. 微信小程序——音频播放器

    先来个效果图韵下味: 需求: 音频的播放,暂停,中间按钮状态的变化,播放时实时更新播放进度: 前进15s,后退15s: 进度条拖动. 一开始想着这3个功能应该挺简单的.不就是播放,暂停,前进,后退么~ ...

  4. 微信小程序---音乐播放和控制

    1.效果图如下: 2.代码如下: //index.js //获取应用实例 var app = getApp() Page({ data: { motto: 'Hello World', userInf ...

  5. 微信小程序自运营器 微信小程序自动运营器(让你的微信小程序,公众号零运营成本,24小时全自动运营)

    自动发单,自动评价,自动评论,自动推广 微信小程序自运营器  微信小程序自动运营器(让你的微信小程序,公众号零运营成本,24小时全自动运营) 我们会根据你的微信公众号或微信小程序定制开发带有一定AI智 ...

  6. 微信小程序api拦截器

    微信小程序api拦截器 完美兼容原生小程序项目 完美兼用小程序api的原本调用方式,无痛迁移 小程序api全Promise化 和axios一样的请求方式 小程序api自定义拦截调用参数和返回结果 强大 ...

  7. 微信小程序音频播放 InnerAudioContext 的用法

    今天项目上涉及到了微信小程序播放音频功能,所以今天跟着一些教程做了个简单的播放器 1.实现思路 刚开始想着有没有现成的组件可以直接用,找到了微信的媒体组件 audio,奈何看着 1.6.0版本开始,该 ...

  8. vue小练习--音乐播放器

    1 首先建一个文件夹 放几首歌曲 2 看代码 1)基本版本 <!DOCTYPE html> <html lang="zh-CN"> <head> ...

  9. 微信小程序 - 音频播放(1.2版本和1.2版本之后)

    不多说了,直接贴code // 1.2版本以后便不在维护 wx.getBackgroundAudioManager({ success:function(res){ var status =res.s ...

随机推荐

  1. Dell 12V/18A电源适配器接口改造

    手头有几个航模用的充电器,原来一直用实验室电源,不方便移动,为了便携省地方,就想配个合适的电源.在网上找了下,航模专用的适配器价格太高,国产的杂牌适配器功率虚标严重并且可靠性是个问题,工业用的电源基本 ...

  2. libev 源码解析

    一  libev简介 libev是一个轻量级的事件通知库,具备支持多种事件通知能力,通过对libev的源码的阅读,可以清楚了解事件通知实现内部机制. 二 核心数据结构 在libev中关键的数据结构是, ...

  3. 李宏毅 Gradient Descent Demo 代码讲解

    何为梯度下降,直白点就是,链式求导法则,不断更新变量值. 这里讲解的代码为李宏毅老师机器学习课程中 class 4 回归展示 中的代码demo   Loss函数 python代码如下 import n ...

  4. 【DSP开发】串行 RapidIO: 高性能嵌入式互连技术

    串行 RapidIO: 高性能嵌入式互连技术 作者: 德州仪器技术应用工程师 冯华亮/ Brighton Feng/ bf@ti.com 摘要 串行RapidIO针对高性能嵌入式系统芯片间和板间互连而 ...

  5. springboot整合elasticSearch客户端

    一 ES客户端 ES提供多种不同的客户端: 1.TransportClient ES提供的传统客户端,官方计划8.0版本删除此客户端. 2.RestClient RestClient是官方推荐使用的, ...

  6. 基于模板匹配的目标跟踪(OpenCV)

    基于VS2010+ OpenCV2.代码可以读入视频,也可以读摄像头,两者的选择只需要在代码中稍微修改即可.对于视频来说,运行会先显示第一帧,然后我们用鼠标框选要跟踪的目标,然后跟踪器开始跟踪每一帧. ...

  7. yum方式安装mono

    https://blog.csdn.net/qq_21153619/article/details/81459359 这样应该比较简单 yum方式按照mono rpm --import "h ...

  8. P1541 乌龟棋(动态规划)

    (点击此处查看原题) 题意 此处有n个位置,记为1~n,每个位置上都对应一个权值,乌龟从编号为1的位置出发,利用m张爬行卡片到达位置n,爬行卡牌有四种,分别可以让乌龟移动1,2,3,4步,并保证将m张 ...

  9. centerOS7安装lnmp环境

    视频地址: https://www.bilibili.com/video/av55251610?p=65 安装nginx http://nginx.org 点击 download vim /etc/y ...

  10. php双向队列的实现

    队列是一种线性表,按照先进先出的原则进行   单向队列:只能从头进,从尾出   双向队列:头尾都可以进出   class DuiLie {   private $array = array();//声 ...