完成专辑封面和音量调节
parent
523dd10cbc
commit
94df364ce5
File diff suppressed because one or more lines are too long
|
@ -160,6 +160,13 @@ table {overflow:auto;display:table;width:100%;line-height:2.5rem;
|
||||||
&:hover {color:nth($ct, 1)}
|
&:hover {color:nth($ct, 1)}
|
||||||
&:active {color:nth($ct, 3)}
|
&:active {color:nth($ct, 3)}
|
||||||
&.lrc {margin-right:2rem;font-size:1.6rem;}
|
&.lrc {margin-right:2rem;font-size:1.6rem;}
|
||||||
|
|
||||||
|
.volume-ctrl {display:none;flex-direction:column;justify-content:flex-end;position:absolute;left:.5rem;bottom:3rem;width:2.4rem;height:12rem;padding:1rem .8rem;background:#fff;border-radius:.3rem;box-shadow:0 0 1rem rgba(0, 0, 0, .1);
|
||||||
|
|
||||||
|
em {flex:0 0;border-radius:.5rem;background:nth($ct, 1)}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.volume:hover .volume-ctrl {display:flex}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ class AudioPlayer {
|
||||||
this.__LIST__ = [] // 播放列表
|
this.__LIST__ = [] // 播放列表
|
||||||
this.__CURR__ = -1 // 当前播放的歌曲的id
|
this.__CURR__ = -1 // 当前播放的歌曲的id
|
||||||
this.__PLAY_MODE__ = 'all' // all | single | random
|
this.__PLAY_MODE__ = 'all' // all | single | random
|
||||||
this.__PLAYER__.valume = 0.7
|
this.__PLAYER__.volume = 0.7
|
||||||
|
|
||||||
this.__init__()
|
this.__init__()
|
||||||
}
|
}
|
||||||
|
@ -48,8 +48,8 @@ class AudioPlayer {
|
||||||
return this.__PLAYER__.muted
|
return this.__PLAYER__.muted
|
||||||
}
|
}
|
||||||
|
|
||||||
set valume(val) {
|
set volume(val) {
|
||||||
this.__PLAYER__.valume = val / 100
|
this.__PLAYER__.volume = val / 100
|
||||||
}
|
}
|
||||||
|
|
||||||
set mode(val = 'all') {
|
set mode(val = 'all') {
|
||||||
|
|
14
index.html
14
index.html
|
@ -130,7 +130,19 @@
|
||||||
}"
|
}"
|
||||||
:click="togglePlayMode">
|
:click="togglePlayMode">
|
||||||
</span>
|
</span>
|
||||||
<span class="ctrl do-icon-unmute"></span>
|
<section class="ctrl volume">
|
||||||
|
<i
|
||||||
|
:class="{
|
||||||
|
'do-icon-unmute' : volume > 0,
|
||||||
|
'do-icon-mute' : volume === 0
|
||||||
|
}">
|
||||||
|
</i>
|
||||||
|
<span
|
||||||
|
class="volume-ctrl"
|
||||||
|
:click="changeValume">
|
||||||
|
<em :css="{flex: '0 ' + volume + '%'}"></em>
|
||||||
|
</span>
|
||||||
|
</section>
|
||||||
<span class="ctrl s-icon-eq"></span>
|
<span class="ctrl s-icon-eq"></span>
|
||||||
<span class="ctrl lrc">词</span>
|
<span class="ctrl lrc">词</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
30
js/api.js
30
js/api.js
|
@ -104,5 +104,35 @@ export default {
|
||||||
return JSON.parse(res.text)
|
return JSON.parse(res.text)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
search(keyword) {
|
||||||
|
return request
|
||||||
|
.get('https://songsearch.kugou.com/song_search_v2')
|
||||||
|
.send({
|
||||||
|
keyword,
|
||||||
|
platform: 'WebFilter',
|
||||||
|
tag: ''
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
return JSON.parse(res.text).data.lists
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
getSongInfoByHash(hash, album_id = '') {
|
||||||
|
return request
|
||||||
|
.get('https://wwwapi.kugou.com/yy')
|
||||||
|
.send({
|
||||||
|
r: 'play/getdata',
|
||||||
|
hash,
|
||||||
|
album_id
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
return JSON.parse(res.text).data
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
53
js/app.js
53
js/app.js
|
@ -25,6 +25,7 @@ const { remote } = require('electron')
|
||||||
const WIN = remote.getCurrentWindow()
|
const WIN = remote.getCurrentWindow()
|
||||||
const HOME_PATH = remote.app.getPath('appData')
|
const HOME_PATH = remote.app.getPath('appData')
|
||||||
const APP_INI_PATH = path.join(HOME_PATH, 'app.ini')
|
const APP_INI_PATH = path.join(HOME_PATH, 'app.ini')
|
||||||
|
const LYRICS_PATH = path.join(HOME_PATH, 'lyrics')
|
||||||
const PLAY_MODE = {
|
const PLAY_MODE = {
|
||||||
0: 'all',
|
0: 'all',
|
||||||
1: 'single',
|
1: 'single',
|
||||||
|
@ -48,12 +49,14 @@ appInit = JSON.parse(appInit)
|
||||||
Anot({
|
Anot({
|
||||||
$id: 'app',
|
$id: 'app',
|
||||||
state: {
|
state: {
|
||||||
theme: 1, // 1:macos, 2: deepin
|
theme: appInit.theme || 1, // 1:macos, 2: deepin
|
||||||
winFocus: false,
|
winFocus: false,
|
||||||
mod: 'local',
|
mod: 'local',
|
||||||
playMode: Anot.ls('play-mode') >>> 0, // 0:all | 1:single | 2:random
|
playMode: Anot.ls('play-mode') >>> 0, // 0:all | 1:single | 2:random
|
||||||
isPlaying: false,
|
isPlaying: false,
|
||||||
optBoxShow: false,
|
optBoxShow: false,
|
||||||
|
volumeCtrlShow: false,
|
||||||
|
volume: Anot.ls('volume') || 70,
|
||||||
curr: {
|
curr: {
|
||||||
id: '',
|
id: '',
|
||||||
index: 0,
|
index: 0,
|
||||||
|
@ -62,10 +65,7 @@ Anot({
|
||||||
album: '',
|
album: '',
|
||||||
time: 0,
|
time: 0,
|
||||||
duration: 0
|
duration: 0
|
||||||
},
|
}
|
||||||
|
|
||||||
currTimeBar: '',
|
|
||||||
currTimeBarPercent: 0
|
|
||||||
},
|
},
|
||||||
skip: [],
|
skip: [],
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -77,13 +77,6 @@ Anot({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'curr.*'() {
|
|
||||||
let { time, duration } = this.curr
|
|
||||||
let x = time / duration
|
|
||||||
|
|
||||||
this.currTimeBar = `matrix(1, 0, 0, 1, ${x * this.__TB_WIDTH__}, 0)`
|
|
||||||
this.currTimeBarPercent = 100 * x + '%'
|
|
||||||
},
|
|
||||||
mod(val) {
|
mod(val) {
|
||||||
this.activeModule(val)
|
this.activeModule(val)
|
||||||
}
|
}
|
||||||
|
@ -193,6 +186,20 @@ Anot({
|
||||||
Anot.ls('play-mode', mod)
|
Anot.ls('play-mode', mod)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 修改音量
|
||||||
|
changeValume(ev) {
|
||||||
|
let volume = 535 - ev.pageY
|
||||||
|
if (volume < 0) {
|
||||||
|
volume = 0
|
||||||
|
}
|
||||||
|
if (volume > 100) {
|
||||||
|
volume = 100
|
||||||
|
}
|
||||||
|
this.volume = volume
|
||||||
|
SONIST.volume = volume
|
||||||
|
Anot.ls('volume', volume)
|
||||||
|
},
|
||||||
|
|
||||||
draw() {
|
draw() {
|
||||||
let img1 = new Image()
|
let img1 = new Image()
|
||||||
let img2 = new Image()
|
let img2 = new Image()
|
||||||
|
@ -286,15 +293,12 @@ Anot({
|
||||||
}
|
}
|
||||||
this.isPlaying = false
|
this.isPlaying = false
|
||||||
_p.then(it => {
|
_p.then(it => {
|
||||||
this.curr = {
|
if (this.mod === 'local') {
|
||||||
...it,
|
Local.__updateSong__(it)
|
||||||
time: 0,
|
|
||||||
cover:
|
|
||||||
'http://imge.kugou.com/stdmusic/480/20170906/20170906161516611883.jpg'
|
|
||||||
}
|
}
|
||||||
// 通知子模块歌曲已经改变
|
// 通知子模块歌曲已经改变
|
||||||
this.$fire('child!curr', it.id)
|
this.$fire('child!curr', it.id)
|
||||||
this.play()
|
this.play(it)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -302,16 +306,17 @@ Anot({
|
||||||
this.isPlaying = false
|
this.isPlaying = false
|
||||||
},
|
},
|
||||||
|
|
||||||
|
updateCurr(obj) {
|
||||||
|
let old = this.curr.$model
|
||||||
|
this.curr = Object.assign(old, obj)
|
||||||
|
},
|
||||||
|
|
||||||
play(song) {
|
play(song) {
|
||||||
// 有参数的,说明是播放回调通知
|
// 有参数的,说明是播放回调通知
|
||||||
// 此时仅更新播放控制条的信息即可
|
// 此时仅更新播放控制条的信息即可
|
||||||
if (song) {
|
if (song) {
|
||||||
this.curr = {
|
song.time = 0
|
||||||
...song,
|
this.updateCurr(song)
|
||||||
time: 0,
|
|
||||||
cover:
|
|
||||||
'http://imge.kugou.com/stdmusic/480/20170906/20170906161516611883.jpg'
|
|
||||||
}
|
|
||||||
this.isPlaying = true
|
this.isPlaying = true
|
||||||
} else {
|
} else {
|
||||||
if (SONIST.stat === 'ready') {
|
if (SONIST.stat === 'ready') {
|
||||||
|
|
|
@ -17,6 +17,7 @@ const { app, dialog } = require('electron').remote
|
||||||
const log = console.log
|
const log = console.log
|
||||||
const HOME_PATH = app.getPath('appData')
|
const HOME_PATH = app.getPath('appData')
|
||||||
const MUSIC_DB_PATH = path.join(HOME_PATH, 'music.db')
|
const MUSIC_DB_PATH = path.join(HOME_PATH, 'music.db')
|
||||||
|
const LYRICS_PATH = path.join(HOME_PATH, 'lyrics')
|
||||||
|
|
||||||
let appInit = {}
|
let appInit = {}
|
||||||
let dbCache = fs.cat(MUSIC_DB_PATH)
|
let dbCache = fs.cat(MUSIC_DB_PATH)
|
||||||
|
@ -56,16 +57,65 @@ export default Anot({
|
||||||
methods: {
|
methods: {
|
||||||
__init__() {
|
__init__() {
|
||||||
appInit = JSON.parse(Anot.ss('app-init'))
|
appInit = JSON.parse(Anot.ss('app-init'))
|
||||||
log(appInit)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
play(idx) {
|
play(song, idx) {
|
||||||
|
if (song.id === this.curr) {
|
||||||
|
return
|
||||||
|
}
|
||||||
SONIST.play(idx).then(it => {
|
SONIST.play(idx).then(it => {
|
||||||
this.__APP__.play(it)
|
this.__APP__.play(it)
|
||||||
this.curr = it.id
|
this.curr = it.id
|
||||||
|
|
||||||
|
this.__updateSong__(it, idx)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
__updateSong__(it, idx) {
|
||||||
|
if (!it.cover) {
|
||||||
|
if (idx === undefined) {
|
||||||
|
for (let i in this.list.$model) {
|
||||||
|
if (this.list[i].id === it.id) {
|
||||||
|
idx = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let _P = Promise.resolve(true)
|
||||||
|
if (!it.kgHash) {
|
||||||
|
_P = Api.search(`${it.artist} ${it.title}`).then(list => {
|
||||||
|
if (list.length) {
|
||||||
|
let { AlbumID, FileHash } = list[0]
|
||||||
|
it.kgHash = FileHash
|
||||||
|
it.albumId = AlbumID
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_P.then(next => {
|
||||||
|
if (next) {
|
||||||
|
Api.getSongInfoByHash(it.kgHash, it.albumId).then(json => {
|
||||||
|
it.album = json.album_name
|
||||||
|
it.albumId = json.album_id
|
||||||
|
it.kgHash = json.hash
|
||||||
|
it.cover = json.img
|
||||||
|
it.lyrics = path.join(LYRICS_PATH, `${it.id}.lrc`)
|
||||||
|
|
||||||
|
this.list.set(idx, it)
|
||||||
|
LS.insert(it)
|
||||||
|
|
||||||
|
this.__APP__.updateCurr(it)
|
||||||
|
this.__APP__.draw()
|
||||||
|
|
||||||
|
fs.echo(json.lyrics, it.lyrics)
|
||||||
|
fs.echo(JSON.stringify(LS.getAll(), '', 2), MUSIC_DB_PATH)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
__checkSong__() {
|
__checkSong__() {
|
||||||
let song = this.__LIST__.pop()
|
let song = this.__LIST__.pop()
|
||||||
|
|
||||||
|
|
1
main.js
1
main.js
|
@ -42,6 +42,7 @@ protocol.registerStandardSchemes(['app'], { secure: true })
|
||||||
let appPath = app.getPath('appData')
|
let appPath = app.getPath('appData')
|
||||||
if (!fs.exists(appPath)) {
|
if (!fs.exists(appPath)) {
|
||||||
fs.mkdir(appPath)
|
fs.mkdir(appPath)
|
||||||
|
fs.mkdir(path.join(appPath, 'lyrics'))
|
||||||
fs.echo('{}', path.join(appPath, 'app.ini'))
|
fs.echo('{}', path.join(appPath, 'app.ini'))
|
||||||
fs.echo('[]', path.join(appPath, 'music.db'))
|
fs.echo('[]', path.join(appPath, 'music.db'))
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<tr
|
<tr
|
||||||
:class="{active: it.id === curr}"
|
:class="{active: it.id === curr}"
|
||||||
:for="it in list"
|
:for="it in list"
|
||||||
:dblclick="play($index)">
|
:dblclick="play(it, $index)">
|
||||||
<td class="ac"><i class="stat s-icon-music"></i></td>
|
<td class="ac"><i class="stat s-icon-music"></i></td>
|
||||||
<td :text="it.title"></td>
|
<td :text="it.title"></td>
|
||||||
<td class="ac" :text="it.artist"></td>
|
<td class="ac" :text="it.artist"></td>
|
||||||
|
|
Reference in New Issue