微信小程序音乐播放器

时间:2022-08-29 20:19:09

写在前面

  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. vue小练习--音乐播放器

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

  8. 微信小程序 - 音频播放(1&period;2版本和1&period;2版本之后)

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

  9. 微信小程序实例源码大全

    微信小程序实例源码大全下载 微信小应用示例代码(phodal/weapp-quick)源码链接:https://github.com/phodal/weapp-quick 微信小应用地图定位demo( ...

随机推荐

  1. 网站性能工具Yslow的使用方法

    Yslow是雅虎开发的基于网页性能分析浏览器插件,从年初我使用了YSlow后,改变了博客模板大量冗余代码,不仅提升了网页的打开速度,这款插件还帮助我分析了不少其他网站的代码,之前我还特意写了提高网站速 ...

  2. iOS项目开发中的目录结构

    目录结构: 1.AppDelegate   这个目录下放的是AppDelegate.h(.m)文件,是整个应用的入口文件,所以单独拿出来.   2.Models   这个目录下放一些与数据相关的Mod ...

  3. WCF的配置文件中的要素

    Windows Communication Foundation Configuration Schema

  4. Toolbar Painter 工具条制作

    工具条制作工具(ToolBarPainter2013.exe),专为程序猿设计,界面开发必备.当用VC编程制作工具条时,需要为工具栏上每一个button添加图标,是一件极其繁琐的事情,该工具可利用已有 ...

  5. 读书笔记——thinking in java

    1.一切都是对象,用引用操作对象 1.1程序存储的地方 引用存放在堆栈区(通用的RAM),所有对象存储在堆(一种通用的内存池).堆和堆栈的区别:堆栈中的这些引用,java系统是要知道确切的生命周期,堆 ...

  6. Web测试——翻页功能测试用例

    参考:https://wenku.baidu.com/view/e6462707de80d4d8d15a4f1e.html?rec_flag=default&mark_pay_doc=2&am ...

  7. JPasswordField密码框,JList列表框

    [JPasswordField密码框] //导入Java类 import javax.swing.*; import java.awt.*; import java.awt.event.ActionE ...

  8. Spring在项目中需要的配置

    要想了解Spring,首先要了解三层架构.....自行百度. 1.Spring相关概念: 少数jar+某一个功能的配置文件 Spring容器(轻量级):帮我们管理业务逻辑层,有很多业务逻辑对象,需要对 ...

  9. spring深入学习&lpar;二&rpar;-----bean的生命周期、IOC容器bean装配

    bean的生命周期 1.实例化Bean对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBea ...

  10. 微软改名部又出动啦!微软宣布VSTS改名为Azure DevOps

    本篇为翻译,原文地址:https://azure.microsoft.com/en-us/blog/introducing-azure-devops/ 作者:Jamie Cool,Azure DevO ...