简易音乐播放小程序

今天想要分享的一个项目是作者自己在暑假实训期间制作的一款仿网易音乐的音乐播放小程序,将会为大家展示小程序的具体功能以及实现代码,比较适合前端初学者拿来参考。(本人也是技艺不精,若有说的不对的地方,望指摘,勿喷,友好交流)

一、项目介绍

本音乐播放小程序有歌曲列表,个人信息,搜索三个模块

二、小程序的效果图

歌曲列表界面:

这部分相当于一个简易的首页部分,包含轮播图,歌曲列表,搜索框按钮,点击搜索框按钮就会发生跳转,然后跳转到搜素界面

搜索界面:

这部分是搜索界面,在搜索框内输入想要搜索的歌曲或者歌手就会跳转到歌曲列表界面,然后在轮播图的下面展示出搜索的结果

歌曲播放界面:

点击歌曲列表后面的播放按钮就可以跳转到歌曲的播放界面并进行播放,歌曲播放界面有暂停,上一首,下一首,随机播放,单曲循环等功能

歌词滚动界面:

歌曲播放界面向左滑动便可以到达歌词部分,根据歌曲进度使对应的歌词部分显红

个人信息界面:

该部分是个人信息界面

三、部分代码实现

歌曲列表部分的:

// index.js
[ ] // 获取应用实例
const app = getApp()

Page({
  data: {
    // 轮播图数组
    'swiperList':[{
      'goods_id':'1',
      'image_src':'/images/lunbo/lunbo1.jpg',
      'open_type':'navigate'
    },
    {
      'goods_id':'2',
      'image_src':'/images/lunbo/lunbo2.jpg',
      'open_type':'navigate'
    },
    {'goods_id':'3',
      'image_src':'/images/lunbo/lunbo3.jpg',
      'open_type':'navigate'
    }
  ] ,
  //歌曲数组
  songs:[],
// 定义歌曲的数组

  },
  onLoad: function (options) {
    
  },

  onShow(){
    const app=getApp()
    
    let songs=app.globalData.data
    console.log(songs);
    this.setData({
      songs,
    })

  },
  // 点击事件函数
  gotoplay:function(e){
    var id = e.currentTarget.dataset.id;
    // 定义一个空数组
    var ids = [];
    // 遍历歌曲列表
    for(var i=0;i<this.data.songs.length;i++){
      ids.push(this.data.songs[i].id);
    }
    console.log("点击事件进入的方法");
    wx.navigateTo({
      url:'/pages/paly/play?mid='+ id + "&ids=" + ids,
    })
  }
})

歌曲播放部分:

// pages/paly/play.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    state:"play",
    id:"",
    ids:[],
    song:null,
    lyricArray:[],
    // 竖向滚动条初始值为0
    marginTop:0,
    currentIndex:0,
    // 播放模式
    mode:'loop',
    // 播放时间
    currentTime:"00:00",
    // 总时间
    timeLength:"03:30",
    max:0,
    move:0,
    likeState:"unlike"
  },

    /**
   * 生命周期函数--监听页面加载
   */
// 控制歌曲的播放状态
playOrPause:function(){
  var musicState=this.data.state;
  if(musicState=='play'){
    this.setData({
      state:'pause'
    })
    this.audioCtx.pause()
  }else{
    this.setData({
      state:'play'
    })
    this.audioCtx.play()
  }
},
  // 上一首歌曲的函数
  prevSong:function(){
    var currentId = this.data.id;
    // 定义一个变量记录当前歌曲的下标
    var index = 0;
    // 根据id值找出当前歌曲的下标
    for(var i =0;i<this.data.ids.length;i++){
      // 判断一下当前歌曲是否一致
      if(currentId == this.data.ids[i]){
        index = i;
        break;
      }
    }
      var prevIndex =index ==0?this.data.ids.length-1 : index-1;
      var prevId = this.data.ids[prevIndex];
      // 修改当前歌曲的id
      this.setData({
        id:prevId
      })
      // 调用获取歌曲详情的函数
      this.getSongInfoById();
      // 播放新的歌曲
      this.audioCtx.play();
  },
  // 下一首歌曲的函数
  nextSong:function(){
    var currentId = this.data.id;
    // 定义一个变量记录当前歌曲的下标
    var index = 0;
    // 根据id值找出当前歌曲的下标
    for(var i =0;i<this.data.ids.length;i++){
      // 判断一下当前歌曲是否一致
      if(currentId == this.data.ids[i]){
        index = i;
        break;
      }
    }
      var nextIndex =index ==this.data.ids.length-1 ? 0: index+1;
      var nextId = this.data.ids[nextIndex];
      // 修改当前歌曲的id
      this.setData({
        id:nextId
      })
      // 调用获取歌曲详情的函数
      this.getSongInfoById();
      // 播放新的歌曲
      this.audioCtx.play();
  },
  // 切换播放模式的方法
  changeMode:function(params){
    var currentMode =this.data.mode;
    if(currentMode=='loop'){
      this.setData({
        mode:'single'
      })
    }else{
      this.setData({
        mode:'loop'
      })
    }
  },
  // 当歌曲播放完后的函数
  changeMusic:function () {
    // 判断当前的模式
    var mode = this.data.mode;
    var currentId = this.data.id;
    // 单曲循环
    if(mode == 'single'){
      // 单曲循环设置自己原本的id
      this.setData({
        id:currentId 
      })
      // 刷新播放状态
      this.getSongInfoById();
      this.audioCtx.play();
    }else{
      this.nextSong();
    }
  },
  // 收藏歌曲的方法
  songLove:function(params){
    var currentState =this.data.likeState;
    if(currentState=='unlike'){
      this.setData({
        likeState:'like'
      })
    }else{
      this.setData({
        likeState:'unlike'
      })
    }
  },
  // 根据歌曲id来获取歌词的方法
  getLyricById:function(){
    var that = this;
    var currentId = this.data.id;
    wx.request({
      url: 'http://music.163.com/api/song/lyric?os=pc&id='+ currentId +'&lv=-1&kv=-1&tv=-1',
      success:function(result){
        // 解析歌词在字符串里
        var lyrics = result.data.lrc.lyric;
        // 调用解析歌词的方法
        var result = that.parseLyric(lyrics);
        // 调用去掉空歌词的方法
        var finalResult = that.sliceNull(result);
        that.setData({
          lyricArray:finalResult
        })
      }
    })
  },
  // 解析歌词的方法(正则表达式)
  parseLyric:function(lyrics){
    // 存储时间和歌词且一一对应
    var lyricResult =[];
    // 将歌词组成的字符串组成每句歌词组成的数组
    var lyricArray = lyrics.split("\n");
    // 判断最后一个元素是否为空。如果为空则删除
    if(lyricArray[lyricArray.length-1] == ""){
      lyricArray.pop();
    }
    var pattern = /\[\d{2}:\d{2}\.\d{2,3}\]/;
    // 遍历数组中的每一句歌词
    lyricArray.forEach(function(v,i,a){
      var real_lyric = v.replace(pattern,"");
      // 对每一句歌词处理,将时间单独提取出来
      var time = v.match(pattern);
      
      // 时间里的中括号不要
      // js中的最后一个元素的下标是长度-1或者-1
      if(time !=null){
      var timeResult = time[0].slice(1,-1);
      // 对结果进行一个切分
      var timeArray = timeResult.split(":");
      var finalTime = parseFloat(timeArray[0])*60 +parseFloat(timeArray[1]);
      lyricResult.push([finalTime,real_lyric]);
      }
    })
    // 返回歌词时间数组
    return lyricResult;
  },
  // 去掉空歌词,保留非空歌词的方法
  sliceNull:function(lyricArray){
    var result = [];
    for(var i=0;i<lyricArray.length;i++){
      if(lyricArray[i][1]!=""){
        result.push(lyricArray[i]);
      }
    }
    return result;
  },
  // 歌词与时间匹配的方法
  //播放进度触发
  changeTime:function(e){
    var currentTime = e.detail.currentTime;
    var lyricArray = this.data.lyricArray;
    if(this.data.currentIndex>=8){
      this.setData({
        marginTop:(this.data.currentIndex-8)*30
      })
    }
    if(this.data.currentIndex == lyricArray.length-2){
      if(currentTime>=lyricArray[lyricArray.length-1][0]){
        this.setData({
          currentIndex:lyricArray.length-1
        })
      }
    }else{
      for(var i=0;i<lyricArray.length-1;i++){
        if(currentTime>=lyricArray[i][0] && currentTime<lyricArray[i+1][0]){
          this.setData({
            currentIndex:i
          })
        }
      }
    }
    //进度条更新
    var timeLength = e.detail.duration;
    var sum_m = Math.floor(timeLength/60);
    var sum_s = Math.floor(timeLength%60);
    // 个位数补齐0
    if(sum_m<10){
      sum_m="0"+sum_m
    }
    if(sum_s<10){
      sum_s="0"+sum_s
    }
    // 定义播放时间
    var play_m = Math.floor(currentTime/60);
    var play_s = Math.floor(currentTime%60);
    // 个位数补齐0
    if(play_m<10){
      play_m="0"+play_m
    }
    if(play_s<10){
      play_s="0"+play_s
    }
    // 进度条更新
    this.setData({
      currentTime:play_m+":"+play_s,
      timeLength:sum_m+":"+sum_s,
      max:timeLength,
      move:currentTime
    })

  },
  // 进度条拖拽的方法
  sliderChange:function(e){
    var that = this;
    var currentValue = e.detail.value;
     this.setData({
       move:currentValue
     })
    //  跳转到指定播放的秒数位置
     that.audioCtx.seek(currentValue);
    // 修改当前播放时间
    // this.setData({
    //   action:{
    //     method:'setCurrentTime',
    //     data:currentValue
    //   }
    // })
  },
  // 根据歌曲的id找歌曲的详情
  getSongInfoById:function(){
    var currentId = this.data.id;
    var that = this;
    wx.request({
      url: 'https://music.163.com/api/song/detail/?id='+ currentId + '&ids=['+ currentId +']',
      success:function(result){
        var musicInfo = result.data.songs[0];
        console.log(musicInfo);
        that.setData({
          song:musicInfo
        })
      }
    })
  },

  onLoad:function (options) {
    var mid = options.mid;
    var idStr = options.ids;
    var ids = idStr.split(",");
    this.setData({
      id:mid,
      ids:ids
    })
    this.getSongInfoById();
    this.getLyricById();
        
    },
  
 /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady:function() {
     this.audioCtx = wx.createAudioContext('myAudio');
    this.audioCtx.play();
  },
  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})
<!--pages/paly/play.wxml-->
<view class="content">
<image class="big_img"
src="{{song.album.picUrl}}"></image>
<view class="title">{{song.name}}</view>
<!-- 中间封面和歌词 -->
<view class="middle">
<swiper class="middle-swiper">
<!-- 封面区域 -->
<swiper-item class="cd-wrapper">
<view class="cd-image">
<image style="animation-play-state:{{state == 'play'? 'running': 'paused'}}" src="{{song.album.picUrl}}"></image>
</view>
</swiper-item>
<!-- 歌词区域 -->
<swiper-item>
<!-- scroll-view可以滚动 -->
<scroll-view class="lyric-wrapper" scroll-y="true" scroll-top="{{marginTop}}">
<!-- 存放所有歌词 -->
<view class="contentArray">
<block wx:for="{{lyricArray}}" wx:for-index="index" wx:for-item="lyric">
<text class="{{currentIndex == index?'currentLyric':''}}">{{lyric[1]}}</text>
</block>
</view>
</scroll-view>
</swiper-item>
</swiper>
</view>
<!-- 播放控制按钮 -->
<!-- 进度条 -->
<view class="timeBox">
<view class="play_time">{{currentTime}}</view>
<!-- max代表总的长度,value是当前进度 -->
<slider bindchange="sliderChange" activeColor="red" block-size="14" max="{{max}}" value="{{move}}"></slider>
<view class="end_time">{{timeLength}}</view>
</view>
<!-- 播放相关的按钮 -->
<view class="controls">
<!-- 切换上一首歌曲 -->
<image bindtap="changeMode" src="/images/tabar/{{mode =='loop'? 'loop' : 'single'}}.png"></image>
<image bindtap="prevSong" src="/images/tabar/prev.png"></image>
<image  bindtap="playOrPause" src="/images/tabar/{{state =='play'? 'pause' : 'play'}}.png"></image>
<image bindtap="nextSong" src="/images/tabar/next.png"></image> 
<image bindtap="songLove" src="/images/tabar/{{likeState =='unlike'? 'unlike1':'like'}}.png"></image>
</view>
</view>
<!-- 当播放进度改变时触发changtime函数 -->
<audio bindended="changeMusic" bindtimeupdate="changeTime" src="http://music.163.com/song/media/outer/url?id={{id}}.mp3" id="myAudio">
</audio>

最后,说一下本人的学习心得,前端相关学习视频推荐,b站黑马程序员pink老师系列,本人认为作为前端的初学者来说,pink老师的课风趣幽默,技术知识点讲的非常细致,其他的同学们可以去参考看看。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
以下是一个基于51单片机定时器的简易音乐播放代码: ```c #include <reg51.h> typedef unsigned char uchar; typedef unsigned int uint; // 音乐节拍数组,每个元素表示占空比,范围0~255 uchar music[] = { 100, 100, 100, 50, 150, 150, 150, 50, 100, 100, 100, 50, 150, 150, 150, 50 }; // 每个音符的持续时间,单位为20ms uchar duration[] = { 10, 10, 10, 5, 15, 15, 15, 5, 10, 10, 10, 5, 15, 15, 15, 5 }; uchar index = 0; // 当前播放的音符索引 void timer0_init() { TMOD |= 0x01; // 设置为工作模式1 TH0 = (65536 - 50000) / 256; // 定时器初值,定时20ms TL0 = (65536 - 50000) % 256; EA = 1; // 打开总中断开关 ET0 = 1; // 打开定时器0中断开关 TR0 = 1; // 启动定时器0 } void main() { timer0_init(); while(1); } void timer0_isr() interrupt 1 { static uchar count = 0; TH0 = (65536 - 50000) / 256; // 重新赋初值 TL0 = (65536 - 50000) % 256; P1 = (count < music[index] ? 0x01 : 0x00); // 控制P1.0输出高电平或低电平 count++; if (count >= duration[index]) // 当前音符播放结束 { count = 0; index++; if (index >= sizeof(music)) // 播放完毕,从头开始 { index = 0; } } } ``` 该代码使用定时器0产生20ms的中断,每次中断时控制P1.0输出高电平或低电平,从而产生音乐声音。音乐节拍和每个音符的持续时间以数组的形式存储,通过index来控制当前播放的音符。当当前音符播放结束时,index自增,如果已经播放完毕,则从头开始播放

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

容貌平和

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值