小程序歌词展示,格式lrc歌词
代码:
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歌词的更多相关文章
- 微信小程序信息展示列表
微信小程序信息展示列表 效果展示: 代码展示: wxml <view class="head"> <view class="head_item" ...
- 微信小程序:解决小程序中有些格式如webpiPhone手机暂不支持的问题
问题:小程序中有些格式是iPhone手机暂不支持的,如goods_introduce中的webp格式,在小程序的模拟器中是可以正常显示webp格式的,但是一旦你做真机调试,很可能某些iPhone手机是 ...
- 【微信小程序】处理时间格式,时间戳转化展示时间格式问题,调用外部js的默认方法function的问题
默认的 小程序中new Date()显示的时间是这样的: 格式化时间的显示怎么做: 小程序的根目录下util目录下默认有一个util.js文件 其中util.js文件内容是: //数据转化 funct ...
- 微信小程序显示html格式内容(wxParse使用及循环解析数据渲染)
小程序默认是不支持html格式的内容显示的,那我们需要显示html内容的时候,就可以通过wxParse来实现. 首先我们下载wxParse,github地址:https://github.com/ic ...
- 微信小程序信息展示
概述 使用第三方在线API模拟数据,进行微信小程序开发.不会后端开发也可以体验微信小程序. 详细 代码下载:http://www.demodashi.com/demo/10719.html 一.准备工 ...
- uniapp微信小程序保存base64格式图片的方法
uniapp保存base64格式图片的方法首先第一要先获取用户的权限 saveAlbum(){//获取权限保存相册 uni.getSetting({//获取用户的当前设置 success:(res)= ...
- 「小程序JAVA实战」小程序视频展示页开发(52)
转自:https://idig8.com/2018/09/22/xiaochengxujavashizhanxiaochengxushipinzhanshiyekaifa51/ 这次说下,小程序的视频 ...
- 微信小程序 解析html格式内容
需要引入html-view文件 1/js 代码 const HtmlParser=require('../../utils/html-view/index') data: { coupon_text: ...
- 小程序base64图片格式保存至手机相册
// 保存图片至相册 saveImg() { //获取文件管理器对象 const fs = wx.getFileSystemManager() //文件保存路径 const Imgpath = wx. ...
随机推荐
- Java能抵挡住JavaScript的进攻吗?
JavaScript的进攻 公元2014年,Java 第八代国王终于登上了王位. 第一次早朝,国王坐在高高的宝座上,看着毕恭毕敬的大臣,第一次体会到了皇权的威力. 德高望重的IO大臣颤悠悠地走上前来: ...
- Java 之 FileReader FileInputStream InputStreamReader BufferedReader 作用与区别
ava.io下面有两个抽象类:InputStream和ReaderInputStream是表示字节输入流的所有类的超类Reader是用于读取字符流的抽象类InputStream提供的是字节流的读取,而 ...
- 20145326蔡馨熤《网络对抗》——MSF基础应用
20145326蔡馨熤<网络对抗>——MSF基础应用 实验后回答问题 用自己的话解释什么是exploit,payload,encode. exploit:起运输的作用,将数据传输到对方主机 ...
- STM32的FLASH ID加密
#define FLASH_ID_OFFSET 30000 //任意定义一个数 //把地址直接减去或者加上一个数是不要程序中直接出现这个地址 volatile u32 Flash_ID_addr ...
- JS实现页面字体繁简转换
封装的JS代码 // 网页简繁体转换 // 本js用于客户在网站页面选择繁体中文或简体中文显示,默认是正常显示,即简繁体同时显示 // 在用户第一次访问网页时,会自动检测客户端语言进行操作并提示.此功 ...
- 【python018--函数参数】
1.形参和实参 >>> def MyFirstFunction(name): '函数定义过程中的name是叫形参' #因为Ta只是一个形式,表示占据一个参数位置 p ...
- 关于二进制——lowbit运算
lowbit(n)意思即为找出n在二进制表示下最后一位1即其后面的0所组成的数值,别的东西算法书上有,这里提出一个重要的公式 lowbit(n)=n&(~n+1)=n&(-n),这个有 ...
- Bootstrap3基础 container 浏览器宽度与容器宽度的四种配合
内容 参数 OS Windows 10 x64 browser Firefox 65.0.2 framework Bootstrap 3.3.7 editor ...
- upc组队赛1 流连人间的苏苏
流连人间的苏苏 题目描述 苏苏在做红尘仙的任务时,发现坐落于风景秀丽.四季如春的昆明市的云南中医学院. 没过多久,苏苏就喜欢上了这个学校.以致于苏苏忘了回涂山的时间,现在她只剩下d天的时间待在云南中医 ...
- 【做题】51NOD1753 相似子串——哈希
题意:两个字符串相似定义为: 1.两个字符串长度相等 2.两个字符串对应位置上至多有一个位置所对应的字符不相同 给定一个字符串\(s\),\(T\)次询问两个子串在给定的规则下是否相似.给定的规则指每 ...