修复歌词显示;修复向前 调整播放进度时歌词不更新的bug;增加歌词编辑功能
parent
4b39ce1990
commit
36cdc379c9
|
@ -25,6 +25,7 @@
|
||||||
- [x] KTV模式
|
- [x] KTV模式
|
||||||
- [x] 歌曲ID3信息修改
|
- [x] 歌曲ID3信息修改
|
||||||
- [x] 酷狗歌手列表(完成20%)
|
- [x] 酷狗歌手列表(完成20%)
|
||||||
|
- [x] 歌词编辑
|
||||||
- [ ] 酷狗音乐排行榜
|
- [ ] 酷狗音乐排行榜
|
||||||
- [ ] 酷狗音乐MV
|
- [ ] 酷狗音乐MV
|
||||||
- [ ] 试听列表
|
- [ ] 试听列表
|
||||||
|
@ -43,6 +44,7 @@
|
||||||
## 测试项目
|
## 测试项目
|
||||||
> 目前项目还没 开发完成, 所以暂时没打包
|
> 目前项目还没 开发完成, 所以暂时没打包
|
||||||
>> 想体验的童鞋, 可以下载本项目源码, 然后执行以下命令(需要安装有nodejs环境)
|
>> 想体验的童鞋, 可以下载本项目源码, 然后执行以下命令(需要安装有nodejs环境)
|
||||||
|
>> **另外,有外部依赖`ffprobe`需要手动安装**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd project #你下载的项目所在的目录
|
cd project #你下载的项目所在的目录
|
||||||
|
|
File diff suppressed because one or more lines are too long
18
css/app.scss
18
css/app.scss
|
@ -204,7 +204,10 @@ table {overflow:auto;display:table;width:100%;line-height:2.5rem;
|
||||||
.contrl-bar {background:rgba(233, 233, 233, .1);
|
.contrl-bar {background:rgba(233, 233, 233, .1);
|
||||||
|
|
||||||
.play-box .item,
|
.play-box .item,
|
||||||
.stat-box .ctrl {color:#fff;}
|
.stat-box .ctrl {color:#fff;
|
||||||
|
|
||||||
|
&:hover {color:nth($cr, 1)}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,6 +220,7 @@ table {overflow:auto;display:table;width:100%;line-height:2.5rem;
|
||||||
|
|
||||||
img {width:30rem;height:30rem;border:.5rem solid rgba(255, 255, 255, .5);border-radius:50%;}
|
img {width:30rem;height:30rem;border:.5rem solid rgba(255, 255, 255, .5);border-radius:50%;}
|
||||||
.summary {flex:1; padding:0 5rem}
|
.summary {flex:1; padding:0 5rem}
|
||||||
|
pre {overflow:auto;height:30rem}
|
||||||
h3 {line-height:3;font-size:1.8rem;}
|
h3 {line-height:3;font-size:1.8rem;}
|
||||||
}
|
}
|
||||||
.lrc-box {flex:0 10rem;display:flex;flex-flow:column wrap;padding:0 5rem;line-height:5rem;color:#fff;font-size:3rem;
|
.lrc-box {flex:0 10rem;display:flex;flex-flow:column wrap;padding:0 5rem;line-height:5rem;color:#fff;font-size:3rem;
|
||||||
|
@ -230,6 +234,18 @@ table {overflow:auto;display:table;width:100%;line-height:2.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.tool-box {position:absolute;right:0;top:15rem;width:13rem;height:auto;padding:1.5rem 0;background:rgba(255, 255, 255, .1);border-radius:.3rem 0 0 .3rem;opacity:.3;transform:translateX(8.8rem);@include ts();
|
||||||
|
|
||||||
|
.item {height:3.4rem;padding:0 .8rem;line-height:3.4rem;
|
||||||
|
|
||||||
|
&:hover {background:rgba(255, 255, 255, .1);}
|
||||||
|
}
|
||||||
|
i {padding:0 1rem 0 .8rem}
|
||||||
|
|
||||||
|
&:hover {opacity:1;transform:translateX(0)}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
24
index.html
24
index.html
|
@ -113,13 +113,17 @@
|
||||||
|
|
||||||
<div class="inner-content">
|
<div class="inner-content">
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<img :attr-src="curr.cover" />
|
<img :attr-src="curr.cover" :click="toggleLrcView" />
|
||||||
<div class="summary">
|
<div class="summary" :visible="!allLrcView">
|
||||||
<h3 :text="curr.title"></h3>
|
<h3 :text="curr.title"></h3>
|
||||||
<section>歌手: {{curr.artist}}</section>
|
<section>歌手: {{curr.artist}}</section>
|
||||||
<section>专辑: {{curr.album}}</section>
|
<section>专辑: {{curr.album}}</section>
|
||||||
<section>时长: {{curr.duration | time}}</section>
|
<section>时长: {{curr.duration | time}}</section>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="summary" :visible="allLrcView">
|
||||||
|
<pre class="summary" :text="allLrc"></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="lrc-box">
|
<div class="lrc-box">
|
||||||
|
@ -130,6 +134,22 @@
|
||||||
<span :text="lrc.r.txt" :css="{background: lrc.r.bg}"></span>
|
<span :text="lrc.r.txt" :css="{background: lrc.r.bg}"></span>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="tool-box">
|
||||||
|
<section class="item" :click="forwardLrc(-0.5)">
|
||||||
|
<i class="do-icon-trigon-up"></i>歌词 -0.5s
|
||||||
|
</section>
|
||||||
|
<section class="item">
|
||||||
|
<i class="do-icon-search"></i>歌词有误
|
||||||
|
</section>
|
||||||
|
<section class="item" :click="layer.alert('歌词编辑功能暂时未开放')">
|
||||||
|
<i class="do-icon-edit"></i>歌词编辑
|
||||||
|
</section>
|
||||||
|
<section class="item" :click="forwardLrc(0.5)">
|
||||||
|
<i class="do-icon-trigon-down"></i>歌词 +0.5s
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
16
js/app.js
16
js/app.js
|
@ -84,6 +84,8 @@ Anot({
|
||||||
duration: 0
|
duration: 0
|
||||||
},
|
},
|
||||||
ctrlLrc: '暂无歌词...',
|
ctrlLrc: '暂无歌词...',
|
||||||
|
allLrcView: false,
|
||||||
|
allLrc: '',
|
||||||
lrc: {
|
lrc: {
|
||||||
l: { bg: '', txt: '' },
|
l: { bg: '', txt: '' },
|
||||||
r: { bg: '', txt: '' }
|
r: { bg: '', txt: '' }
|
||||||
|
@ -175,6 +177,11 @@ Anot({
|
||||||
this.lrc = lrc
|
this.lrc = lrc
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// ktv模式的歌词
|
||||||
|
LYRICS.on('view-all', lrc => {
|
||||||
|
this.allLrc = lrc
|
||||||
|
})
|
||||||
|
|
||||||
this.activeModule(this.mod)
|
this.activeModule(this.mod)
|
||||||
|
|
||||||
remote.app.on('browser-window-focus', _ => {
|
remote.app.on('browser-window-focus', _ => {
|
||||||
|
@ -215,6 +222,10 @@ Anot({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
toggleLrcView() {
|
||||||
|
this.allLrcView = !this.allLrcView
|
||||||
|
},
|
||||||
|
|
||||||
toggleOptBox() {
|
toggleOptBox() {
|
||||||
this.optBoxShow = !this.optBoxShow
|
this.optBoxShow = !this.optBoxShow
|
||||||
},
|
},
|
||||||
|
@ -250,6 +261,11 @@ Anot({
|
||||||
Anot.ls('volume', volume)
|
Anot.ls('volume', volume)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
forwardLrc(time) {
|
||||||
|
LYRICS.forward(time)
|
||||||
|
layer.toast(`歌词已${time > 0 ? '提前' : '延后'} ${time} 秒`)
|
||||||
|
},
|
||||||
|
|
||||||
__draw__() {
|
__draw__() {
|
||||||
let play = this.isPlaying
|
let play = this.isPlaying
|
||||||
let rx = (play ? 112 : 40) + this.__HEIGHT__ / 2 // 旋转唱片的圆心坐标X
|
let rx = (play ? 112 : 40) + this.__HEIGHT__ / 2 // 旋转唱片的圆心坐标X
|
||||||
|
|
|
@ -12,6 +12,7 @@ const { EventEmitter } = require('events')
|
||||||
const util = require('util')
|
const util = require('util')
|
||||||
|
|
||||||
class Lyrics {
|
class Lyrics {
|
||||||
|
// 歌词初始化
|
||||||
__init__(lrcFile) {
|
__init__(lrcFile) {
|
||||||
this.lib = []
|
this.lib = []
|
||||||
this.curr = []
|
this.curr = []
|
||||||
|
@ -25,6 +26,10 @@ class Lyrics {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.__LRC__ = lrcFile
|
||||||
|
|
||||||
|
// log(this.__LRC__)
|
||||||
|
|
||||||
let lrc = fs
|
let lrc = fs
|
||||||
.cat(lrcFile)
|
.cat(lrcFile)
|
||||||
.toString('utf8')
|
.toString('utf8')
|
||||||
|
@ -44,6 +49,12 @@ class Lyrics {
|
||||||
})
|
})
|
||||||
.filter(it => it)
|
.filter(it => it)
|
||||||
|
|
||||||
|
this.lib.sort((a, b) => {
|
||||||
|
return a.start - b.start
|
||||||
|
})
|
||||||
|
|
||||||
|
let lrcPreView = ''
|
||||||
|
|
||||||
for (let i = 0, it; (it = this.lib[i++]); ) {
|
for (let i = 0, it; (it = this.lib[i++]); ) {
|
||||||
if (this.lib[i]) {
|
if (this.lib[i]) {
|
||||||
it.duration = +(this.lib[i].start - it.start).toFixed(2)
|
it.duration = +(this.lib[i].start - it.start).toFixed(2)
|
||||||
|
@ -52,14 +63,19 @@ class Lyrics {
|
||||||
it.duration = 3
|
it.duration = 3
|
||||||
it.end = it.start + 3
|
it.end = it.start + 3
|
||||||
}
|
}
|
||||||
|
lrcPreView += it.txt + '\n'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.emit('view-all', lrcPreView)
|
||||||
this.tmpLib = this.lib.concat()
|
this.tmpLib = this.lib.concat()
|
||||||
|
|
||||||
return this.lib.length > 0
|
return this.lib.length > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 歌词跳转
|
||||||
seek(time) {
|
seek(time) {
|
||||||
this.tmpLib = []
|
this.tmpLib = []
|
||||||
|
this.curr = [] //清除当前输出, 避免进度向前跳转的时候歌词无法更新
|
||||||
for (let it of this.lib) {
|
for (let it of this.lib) {
|
||||||
if (it.start > time) {
|
if (it.start > time) {
|
||||||
this.tmpLib.push(it)
|
this.tmpLib.push(it)
|
||||||
|
@ -67,6 +83,37 @@ class Lyrics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 歌词向前调整指定时间
|
||||||
|
forward(time = 0) {
|
||||||
|
if (!this.__LRC__) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
clearTimeout(this.__TIMER__)
|
||||||
|
// 避免时间小于0
|
||||||
|
if (this.lib[0].start < time) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let lrc = ''
|
||||||
|
for (let it of this.lib) {
|
||||||
|
// 这里使用减法, 才与期望的 "前进" 一致
|
||||||
|
it.start = +(it.start - time).toFixed(2)
|
||||||
|
it.end = +(it.end - time).toFixed(2)
|
||||||
|
let _t = (it.start + '').split('.')
|
||||||
|
if (_t.length < 2) {
|
||||||
|
_t[1] = 0
|
||||||
|
}
|
||||||
|
_t[0] = Anot.filters.time(_t[0])
|
||||||
|
_t[1] = (_t[1] + '').padStart(2, '0')
|
||||||
|
lrc += `[${_t[0]}.${_t[1]}]${it.txt}\n`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 延时3秒写入
|
||||||
|
this.__TIMER__ = setTimeout(() => {
|
||||||
|
fs.echo(lrc, this.__LRC__)
|
||||||
|
}, 3000)
|
||||||
|
}
|
||||||
|
|
||||||
|
//更新当前时间, 并自动触发当前歌词返回
|
||||||
update(time) {
|
update(time) {
|
||||||
if (!this.lib.length) {
|
if (!this.lib.length) {
|
||||||
this.lrc = {
|
this.lrc = {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "sonist",
|
"name": "sonist",
|
||||||
"version": "0.0.9",
|
"version": "0.1.0",
|
||||||
"description": "Music Player",
|
"description": "Music Player",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
Reference in New Issue