代码:

wxml:

    

<view class="page">

<view class="lrc" style="margin-top:{{marginTop}}px;height:{{lrcHeight}}px">
<block wx:for="{{lry}}" wx:key="">
<view class="lry {{currentIndex == index ? 'currentTime' : ''}}">{{item[1]}}</view>
</block>
</view>
<image class="pic_sig" src="{{pic}}"></image>
<view class="bottom">
<view class="state">
<image class="state_chose" bindtap="before" src="../images/pre.png"></image>
<image class="state_play" bindtap="playAndPause" src="{{isPlaying ? '../images/pause.png' : '../images/play.png'}}"></image>
<image class="state_chose" bindtap="next" src="../images/next.png"></image>
</view>
<view class="controller">
<text class="time-start">{{songState.currentPosition}}</text>
<view class="time-bar">
<view class="time-play" style="transform: translateX({{songState.progress}}%)"></view>
</view>
<text class="time-total">{{songState.duration}}</text>
</view>
</view>
</view>

js:

  const app = getApp()

import api from '../../api/API.js'

Page({

data: {

isPlaying: true,

currentIndex: 0,

marginTop: 0,

lrcHeight:200,

songState: {

progress: 0,

currentPosition: '00:00',

duration: '00:00',

datalist: [],

lry: [],

}

},

onLoad: function (options) {

var that = this;

that.setData({

datalist: wx.getStorageSync('song'),

songIndex: options.songIndex,

})

that.requestDataSong(options.songId)

that.songLrc(options.songId)

//自动播放下一首

wx.onBackgroundAudioStop(function () {

that.next()

})

},

requestDataSong: function (songId) {

var that = this

app.requestData('http://ting.baidu.com/data/music/links?songIds=' + songId, {}, (err, data) => {

that.setData({

pic: data.data.songList["0"].songPicRadio,

bigData: data.data.songList["0"],

})

wx.playBackgroundAudio({

dataUrl: data.data.songList["0"].songLink,

})

})

that.playSong()

},

playSong: function () {

var that = this

let inv = setInterval(function () {

wx.getBackgroundAudioPlayerState({

success: function (res) {

if (res.status == 1) {

that.setData({

isPlaying: true,

songState: {

progress: res.currentPosition / res.duration * 100,

currentPosition: that.timeToString(res.currentPosition),

duration: that.timeToString(res.duration),

}

})

var i = that.data.currentIndex

if (i < that.data.lry.length) {

if (res.currentPosition - 4 >= parseInt(that.data.lry[i][0])) {

that.setData({

currentIndex: i + 1

})

}

}

if (that.data.currentIndex >= 6) {

that.setData({

marginTop: -(that.data.currentIndex - 6) * 20,

lrcHeight:200 + (that.data.currentIndex - 6) * 20

})

}

} else {

that.setData({

isPlaying: false

})

clearInterval(inv)

}

}

})

}, 1000)

},

playAndPause: function () {

var that = this

if (that.data.isPlaying) {

wx.pauseBackgroundAudio()

} else {

wx.playBackgroundAudio()

}

that.playSong()

that.setData({

isPlaying: !that.data.isPlaying

})

},

//上一首

before: function () {

var that = this

that.setData({

currentIndex: 0,

marginTop: 0,

lrcHeight:200,

})

if (that.data.songIndex == 0) {

that.requestDataSong(that.data.datalist[that.data.datalist.length - 1].song_id)

that.songLrc(that.data.datalist[that.data.datalist.length - 1].song_id)

that.setData({

songIndex: that.data.datalist.length - 1

})

} else {

that.requestDataSong(that.data.datalist[that.data.songIndex - 1].song_id)

that.songLrc(that.data.datalist[that.data.songIndex - 1].song_id)

that.setData({

songIndex: that.data.songIndex - 1

})

}

},

//下一首

next: function () {

var that = this

that.setData({

currentIndex: 0,

marginTop: 0,

lrcHeight:200,

})

if (that.data.songIndex == that.data.datalist.length - 1) {

that.requestDataSong(that.data.datalist[0].song_id)

that.songLrc(that.data.datalist[0].song_id)

that.setData({

songIndex: 0

})

} else {

that.setData({

songIndex: parseInt(that.data.songIndex) + 1

})

that.requestDataSong(that.data.datalist[that.data.songIndex].song_id)

that.songLrc(that.data.datalist[that.data.songIndex].song_id)

}

},

//请求歌词

songLrc: function (songid) {

var that = this

app.requestData('http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.song.lry&songid=' + songid, {}, (err, data) => {

if (data.lrcContent == undefined) {

var lrc = "无歌词";

} else {

var lrc = data.lrcContent;

}

that.setData({

lry: that.sliceNull(that.parseLyric(lrc))

})

})

},

//去除空白

sliceNull: function (lrc) {

var result = []

for (var i = 0; i < lrc.length; i++) {

if (lrc[i][1] == "") {

} else {

result.push(lrc[i]);

}

}

return result

},

parseLyric: function (text) {

//将文本分隔成一行一行,存入数组

var lines = text.split('\n'),

//用于匹配时间的正则表达式,匹配的结果类似[xx:xx.xx]

pattern = /\[\d{2}:\d{2}.\d{2}\]/g,

//保存最终结果的数组

result = [];

//去掉不含时间的行

while (!pattern.test(lines[0])) {

lines = lines.slice(1);

};

//上面用'\n'生成生成数组时,结果中最后一个为空元素,这里将去掉

lines[lines.length - 1].length === 0 && lines.pop();

lines.forEach(function (v /*数组元素值*/, i /*元素索引*/, a /*数组本身*/) {

//提取出时间[xx:xx.xx]

var time = v.match(pattern),

//提取歌词

value = v.replace(pattern, '');

//因为一行里面可能有多个时间,所以time有可能是[xx:xx.xx][xx:xx.xx][xx:xx.xx]的形式,需要进一步分隔

time.forEach(function (v1, i1, a1) {

//去掉时间里的中括号得到xx:xx.xx

var t = v1.slice(1, -1).split(':');

//将结果压入最终数组

result.push([parseInt(t[0], 10) * 60 + parseFloat(t[1]), value]);

});

});

//最后将结果数组中的元素按时间大小排序,以便保存之后正常显示歌词

result.sort(function (a, b) {

return a[0] - b[0];

});

return result;

},

timeToString: function (duration) {

let str = '';

let minute = parseInt(duration / 60) < 10 ? ('0' + parseInt(duration / 60)) : (parseInt(duration / 60));

let second = duration % 60 < 10 ? ('0' + duration % 60) : (duration % 60);

str = minute + ':' + second;

return str;

},

})  

wxss:

.page {

position: fixed;

left: 0;

margin: 0;

width: 100%;

height: 100%;

background-color: #fff;

font-family: Arial, Helvetica, sans-serif;

font-size: 34rpx;

}

.lrc,.pic_sig {

width: 100%;

display: flex;

flex-direction: column;

align-items: center;

font-size: 30rpx;

overflow: hidden;

}

.pic_sig {

height: 240px;

position: fixed;

left: 0;

top: 0;

}

.lrc {

position: fixed;

left: 0;

top: 240px;

}

.lry {

height: 20px;

line-height:20px;

text-align: center;

}

.currentTime {

color: #be241c;

/*height: 30px;

line-height: 30px;*/

}

.bottom {

position: fixed;

bottom: 0;

width: 100%;

}

.state {

display: flex;

flex-direction: row;

justify-content: space-between;

align-items: center;

}

.state_chose {

width: 58rpx;

height: 58rpx;

margin-left: 60rpx;

margin-right: 60rpx;

}

.state_play {

width: 100rpx;

height: 100rpx;

}

.controller{

height: 80rpx;

display: flex;

justify-content: space-between;

align-items: center;

}

.time-start, .time-total{

flex: none;

color: #808080;

width: 110rpx;

text-align: center;

font-size: 24rpx;

}

.time-bar{

position: relative;

flex: auto;

height: 4rpx;

overflow: hidden;

background: lightgray;

}

.time-play{

position: absolute;

left: -100%;

width: 100%;

height: 100%;

background: #be241c;

transition: all 1s linear;

}

.progress{

height: 80rpx;

display: flex;

justify-content: space-between;

align-items: center;

}

主要代码就是js里面的歌词处理可以粘贴下来研究下

  

小程序歌词展示,格式lrc歌词的更多相关文章

  1. 微信小程序信息展示列表

    微信小程序信息展示列表 效果展示: 代码展示: wxml <view class="head"> <view class="head_item" ...

  2. 微信小程序:解决小程序中有些格式如webpiPhone手机暂不支持的问题

    问题:小程序中有些格式是iPhone手机暂不支持的,如goods_introduce中的webp格式,在小程序的模拟器中是可以正常显示webp格式的,但是一旦你做真机调试,很可能某些iPhone手机是 ...

  3. 【微信小程序】处理时间格式,时间戳转化展示时间格式问题,调用外部js的默认方法function的问题

    默认的 小程序中new Date()显示的时间是这样的: 格式化时间的显示怎么做: 小程序的根目录下util目录下默认有一个util.js文件 其中util.js文件内容是: //数据转化 funct ...

  4. 微信小程序显示html格式内容(wxParse使用及循环解析数据渲染)

    小程序默认是不支持html格式的内容显示的,那我们需要显示html内容的时候,就可以通过wxParse来实现. 首先我们下载wxParse,github地址:https://github.com/ic ...

  5. 微信小程序信息展示

    概述 使用第三方在线API模拟数据,进行微信小程序开发.不会后端开发也可以体验微信小程序. 详细 代码下载:http://www.demodashi.com/demo/10719.html 一.准备工 ...

  6. uniapp微信小程序保存base64格式图片的方法

    uniapp保存base64格式图片的方法首先第一要先获取用户的权限 saveAlbum(){//获取权限保存相册 uni.getSetting({//获取用户的当前设置 success:(res)= ...

  7. 「小程序JAVA实战」小程序视频展示页开发(52)

    转自:https://idig8.com/2018/09/22/xiaochengxujavashizhanxiaochengxushipinzhanshiyekaifa51/ 这次说下,小程序的视频 ...

  8. 微信小程序 解析html格式内容

    需要引入html-view文件 1/js 代码 const HtmlParser=require('../../utils/html-view/index') data: { coupon_text: ...

  9. 小程序base64图片格式保存至手机相册

    // 保存图片至相册 saveImg() { //获取文件管理器对象 const fs = wx.getFileSystemManager() //文件保存路径 const Imgpath = wx. ...

随机推荐

  1. rabbitmq集群故障恢复详解

    RabbitMQ的mirror queue(镜像队列)机制是最简单的队列HA方案,它通过在cluster的基础上增加ha-mode.ha-param等policy选项,可以根据 需求将cluster中 ...

  2. PHP获取Linux当前目录下文件并实现下载功能

    使用nginx转发过去给php server{ listen 9099; server_name 18.5.6.2; location / { proxy_http_version 1.1; root ...

  3. 理解Linux文件系统之 inode

    一.inode是什么? 理解inode,要从文件储存说起. 文件储存在硬盘上,硬盘的最小存储单位叫做”扇区”(Sector).每个扇区储存512字节(相当于0.5KB). 操作系统读取硬盘的时候,不会 ...

  4. SVM学习笔记4-核函数和离群点的处理

    核函数在svm里,核函数是这样定义的.核函数是一个n*n(样本个数)的矩阵,其中:$K_{ij}=exp(-\frac{||x^{(i)}-x^{(j)}||^{2}}{2\sigma ^{2}})$ ...

  5. 排它平方数|2013年蓝桥杯A组题解析第二题-fishers

    排它平方数 小明正看着 203879 这个数字发呆. 原来,203879 * 203879 = 41566646641 这有什么神奇呢?仔细观察,203879 是个6位数,并且它的每个数位上的数字都是 ...

  6. ocacle sql: 两张表左连接 ,1对多,取一条数据,取按时间最新的

    说明: MBGL_GZJH jh_id 对应 mbgl_gzjh_fkmx jh_id mbgl_gzjh_fkmx jh_id 有重复多条,但是 FKRQ 不一样,我们去 FKRQ 最新的一条. s ...

  7. (转) K-Means聚类的Python实践

    本文转自: http://python.jobbole.com/87343/ K-Means聚类的Python实践 2017/02/11 · 实践项目 · K-means, 机器学习 分享到:1 原文 ...

  8. 【Hadoop 分布式部署 九:分布式协作框架Zookeeper架构 分布式安装部署 】

    1.首先将运行在本地上的  zookeeper 给停止掉 2.到/opt/softwares 目录下  将  zookeeper解压到  /opt/app 目录下 命令:  tar -zxvf zoo ...

  9. 嵌入式Linux要学哪些东西?你真的造吗?

    嵌入式Linux要学哪些?一些人总在寻思,怕走了弯路,又怕学的东西离企业需求远.那么今天就请华清远见高级讲师曹大神告诉你,9点浅析嵌入式学习步骤.下面是他本人亲笔. 1.要学习Linux,首先要会用, ...

  10. ComponentOne 2017 V1 发布

    在刚刚庆祝完Visual Studio20周年之后,我们迎来了ComponentOne 2017年第一个重要的版本. ComponentOne Studio与Visual Studio 2017配合发 ...