写在前面

  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. Swift 3.0 Date的简单使用

    // // ViewController.swift // Date的使用 // // Created by 思 彭 on 16/9/20. // Copyright © 2016年 思 彭. All ...

  2. springcloud随便写点

    eureka  注册注册 ribbon 负载均衡 feign  声名式client hystrix  断路器 zuul  网关,智能路由,过滤 config 集群配置 bus 分布式的节点用轻量的消息 ...

  3. centos7安装Scala、Spark(伪分布式)

    centos7安装spark(伪分布式) spark是由scala语言开发的,首先需要安装scala. Scala安装 下载scala-2.11.8,(与spark版本要对应) 命令:wget htt ...

  4. java发送邮件(一)--补充添加附件

    今天来记录一下如何使用java来发送邮件 背景 之前项目有个需求,当产品出现故障时会把情况上送给服务器,服务器发送邮件将故障产品的位置以及故障信息等告知维修人员.发送邮件的接口不是我负责的,但是有兴趣 ...

  5. JavaScript日期格式化处理

    /** * 获取年月,如:2018-08 */ export function getMonth () { return formatDate(new Date(), 'yyyy-MM') } /** ...

  6. linux文本处理三剑客命令及用法

    grep:文本过滤工具 功能说明: sed :字符流编辑器 功能说明: awk :

  7. MFC控件使用大全

    https://blog.csdn.net/daoming1112/article/details/54698113

  8. 开始写下自己的python的cocos2d, pyglet学习

    开始写下自己的python的cocos2d, pyglet学习 2014年01月18日 13:52:36 我要做程序达人 阅读数 9051更多 分类专栏: python的cocos2d和pyglet ...

  9. Lua 打印 table (支持双向引用的table)

    网上搜了一下,挺多打印table的方案,基本思路都是一层一层递归遍历table.(我就是参考这种思路做的^_^) 但大部分都不支持双向引用的打印.我所指的双向引用,就是a引用b, b又直接或间接引用a ...

  10. 树莓派安装Firefox+Selenium+geckodriver

    相关参考博客[Selenium]Raspbian+Selenium+Firefoxfirefox.geckodriver.exe.selenium-server-standlone版本对应及下载地址树 ...