This repository has been archived on 2023-08-30. You can view files and clone it, but cannot push or open issues/pull-requests.
appcat
/
sonist
Archived
1
0
Fork 0
2.x
宇天 2019-08-31 23:59:20 +08:00
parent a886037773
commit ba238b8aa2
14 changed files with 181 additions and 135 deletions

View File

@ -1,6 +1,6 @@
{
"name": "sonist",
"version": "1.1.0",
"version": "1.2.0",
"description": "Music Player",
"main": "src/main.js",
"scripts": {

View File

@ -41,6 +41,10 @@ const PLAY_MODE = {
2: 'random'
}
// window.onblur = function() {
// location.reload()
// }
// 本地音乐和试用音乐列表
window.LS = store.collection('local')
window.TS = store.collection('temp')
@ -48,7 +52,7 @@ window.TS = store.collection('temp')
window.SONIST = new AudioPlayer()
window.LYRICS = new Lyrics()
let appInit = ipcRenderer.sendSync('get-init')
let appInit = ipcRenderer.sendSync('sonist', { type: 'get-init' })
Anot.ss('app-init', appInit)

View File

@ -95,13 +95,17 @@ export default {
SONIST.clear()
SONIST.push(LS.getAll())
ipcRenderer.send('set-music', LS.getAll())
ipcRenderer.send('sonist', { type: 'set-music', data: LS.getAll() })
this.updateCurr(song)
this.draw(true)
}
ipcRenderer.send('save-lrc', { id, lrc: json.lyrics })
ipcRenderer.send('sonist', {
type: 'save-lrc',
id,
data: json.lyrics
})
LYRICS.__init__(id)
layer.toast('歌词应用成功...')

View File

@ -34,7 +34,7 @@ export default Anot({
},
mounted() {
appInit = JSON.parse(Anot.ss('app-init'))
dbCache = ipcRenderer.sendSync('get-music')
dbCache = ipcRenderer.sendSync('sonist', { type: 'get-music' })
LS.insert(dbCache)
@ -112,11 +112,15 @@ export default Anot({
this.__APP__.updateCurr(it)
this.__APP__.draw(true)
ipcRenderer.send('save-lrc', {
ipcRenderer.send('sonist', {
type: 'save-lrc',
id: it.id,
lrc: json.lyrics
data: json.lyrics
})
ipcRenderer.send('sonist', {
type: 'set-music',
data: LS.getAll()
})
ipcRenderer.send('set-music', LS.getAll())
LYRICS.__init__(it.id)
})
@ -145,7 +149,7 @@ export default Anot({
SONIST.clear()
SONIST.push(dbCache)
ipcRenderer.send('set-music', dbCache)
ipcRenderer.send('sonist', { type: 'set-music', data: dbCache })
dbCache = null
layer.toast(`刷新缓存完成,新增${this.__NEW_NUM__}`)
@ -188,7 +192,10 @@ export default Anot({
return
}
if (appInit.musicPath) {
this.__LIST__ = ipcRenderer.sendSync('scan-dir', appInit.musicPath)
this.__LIST__ = ipcRenderer.sendSync('sonist', {
type: 'scan-dir',
path: appInit.musicPath
})
if (this.__LIST__) {
this.__tmp__ = [] //创建一个临时的数组, 用于存放扫描的音乐
this.__APP__.loading = true
@ -235,7 +242,7 @@ export default Anot({
SONIST.clear()
SONIST.push(LS.getAll())
ipcRenderer.send('set-music', LS.getAll())
ipcRenderer.send('sonist', { type: 'set-music', data: LS.getAll() })
},
handleMenu(it, idx, ev) {
let that = this
@ -278,7 +285,10 @@ export default Anot({
SONIST.clear()
SONIST.push(LS.getAll())
ipcRenderer.send('set-music', LS.getAll())
ipcRenderer.send('sonist', {
type: 'set-music',
data: LS.getAll()
})
}
)
} else {

View File

@ -15,7 +15,7 @@ const {
const log = console.log
let appInit = ipcRenderer.sendSync('get-init')
let appInit = ipcRenderer.sendSync('sonist', { type: 'get-init' })
export default Anot({
$id: 'profile',
@ -24,7 +24,8 @@ export default Anot({
allowPlayOnBack: appInit.allowPlayOnBack,
autoLrc: appInit.autoLrc,
theme: appInit.theme || 1,
musicPath: appInit.musicPath || ''
musicPath: appInit.musicPath || '',
allowGS: !!appInit.allowGS
},
version: app.getVersion(),
cmd: process.platform === 'darwin' ? '⌘' : 'Ctrl',
@ -34,6 +35,15 @@ export default Anot({
'setting.theme'(v) {
v = +v
this.__APP__.theme = v
},
'setting.allowGS'(v) {
if (v) {
log('++++++++++++')
ipcRenderer.send('sonist', { type: 'enable-gs' })
} else {
log('-----------')
ipcRenderer.send('sonist', { type: 'disable-gs' })
}
}
},
methods: {
@ -58,7 +68,7 @@ export default Anot({
Object.assign(appInit, setting)
ipcRenderer.send('set-init', appInit)
ipcRenderer.send('sonist', { type: 'set-init', data: appInit })
Anot.ss('app-init', appInit)

View File

@ -23,7 +23,7 @@ export default Anot({
list: [] // 搜索结果列表
},
mounted() {
dict.audition = ipcRenderer.sendSync('get-temp')
dict.audition = ipcRenderer.sendSync('sonist', { type: 'get-temp' })
TS.insert(dict.audition)
this.__APP__ = Anot.vmodels.app
@ -91,14 +91,18 @@ export default Anot({
song.cover = json.img
ipcRenderer.send('save-lrc', { id: song.id, lrc: json.lyrics })
ipcRenderer.send('sonist', {
type: 'save-lrc',
id: song.id,
data: json.lyrics
})
request.get(json.play_url, { dataType: 'arraybuffer' }).then(res => {
song.path = ipcRenderer.sendSync('save-cache', {
buff: Buffer.from(res.body),
song.path = ipcRenderer.sendSync('sonist', {
type: 'save-cache',
data: Buffer.from(res.body),
file: song.kgHash
})
log(song)
TS.insert(song)
dict.audition.push(song)
@ -108,7 +112,7 @@ export default Anot({
this.curr = it.id
})
ipcRenderer.send('set-temp', TS.getAll())
ipcRenderer.send('sonist', { type: 'set-temp', data: TS.getAll() })
})
})
},

View File

@ -21,7 +21,7 @@ class Lyrics {
r: { bg: '', txt: '' }
}
let lrc = ipcRenderer.sendSync('read-lrc', id)
let lrc = ipcRenderer.sendSync('sonist', { type: 'read-lrc', id })
if (!id || lrc === null) {
log('no lrc file', id)
return false
@ -29,8 +29,6 @@ class Lyrics {
this.__ID__ = id
log(id)
this.lib = lrc
.split('\n')
.map(it => {
@ -106,7 +104,11 @@ class Lyrics {
// 延时3秒写入
this.__TIMER__ = setTimeout(() => {
ipcRenderer.send('save-lrc', { id: this.__ID__, lrc })
ipcRenderer.send('sonist', {
type: 'save-lrc',
id: this.__ID__,
data: lrc
})
}, 3000)
}

View File

@ -32,7 +32,7 @@ const MIME_TYPES = {
require('./tools/init')
const createTray = require('./tools/tray')
const createMenu = require('./tools/menu')
const Shortcut = require('./tools/shortcut')
const { createMainWindow, createErrorWindow } = require('./tools/windows')
const ROOT = __dirname
@ -75,7 +75,6 @@ app.once('ready', () => {
win.webContents.send('dock-click')
}
})
Shortcut.__init__(win)
} else {
createErrorWindow()
}

View File

@ -6,10 +6,10 @@
'use strict'
const { app, ipcMain } = require('electron')
const { app, ipcMain, globalShortcut: GS } = require('electron')
const path = require('path')
// const http = require('http')
const fs = require('iofs')
const Shortcut = require('./shortcut')
/* ********** 修复环境变量 start *********** */
let PATH_SET = new Set()
@ -43,92 +43,97 @@ if (!fs.exists(APP_ROOT)) {
}
const SUPPORTED_EXTS = ['.mp3', '.webm', '.ogg', '.flac', '.m4a', '.aac']
const DB = {
read(file) {
let cache = (fs.cat(file) || '[]').toString('utf-8')
try {
return JSON.parse(cache)
} catch (err) {
return cache
}
},
save(file, data) {
fs.echo(JSON.stringify(data), file)
}
}
/* ----------------------------------------------------------------- */
/* --------------------- 事件开始 ------------------------- */
/* ---------------------------------------------------------------- */
// 获取应用配置
ipcMain.on('get-init', (ev, val) => {
let cache = fs.cat(INIT_FILE).toString('utf-8')
cache = JSON.parse(cache)
ev.returnValue = cache
})
// 设置应用配置
ipcMain.on('set-init', (ev, val) => {
fs.echo(JSON.stringify(val), INIT_FILE)
})
// 获取音乐数据库
ipcMain.on('get-music', (ev, val) => {
let cache = fs.cat(DB_FILE).toString('utf-8')
cache = JSON.parse(cache)
ev.returnValue = cache
})
// 更新音乐数据库
ipcMain.on('set-music', (ev, val) => {
fs.echo(JSON.stringify(val), DB_FILE)
})
// 获取临时音乐数据库
ipcMain.on('get-temp', (ev, val) => {
let cache = (fs.cat(TEMP_DB) || '[]').toString('utf-8')
cache = JSON.parse(cache)
ev.returnValue = cache
})
// 更新临时音乐数据库
ipcMain.on('set-temp', (ev, val) => {
fs.echo(JSON.stringify(val), TEMP_DB)
})
/**
* 保存歌词文件
*/
ipcMain.on('save-lrc', (ev, obj) => {
fs.echo(obj.lrc, path.join(LRC_DIR, `${obj.id}.lrc`))
})
/**
* 读取歌词文件
*/
ipcMain.on('read-lrc', (ev, id) => {
let file = path.join(LRC_DIR, `${id}.lrc`)
if (fs.exists(file)) {
ev.returnValue = fs.cat(file).toString('utf8')
} else {
ev.returnValue = null
}
})
/**
* 保存音乐文件
*/
ipcMain.on('save-cache', (ev, obj) => {
let savefile = path.join(CACHE_DIR, obj.file)
fs.echo(obj.buff, savefile)
ev.returnValue = `file://${savefile}`
})
/**
* 扫描目录
*/
ipcMain.on('scan-dir', (ev, dir) => {
if (fs.isdir(dir)) {
let list = fs.ls(dir, true).filter(_ => {
if (fs.isdir(_)) {
return false
ipcMain.on('sonist', (ev, conn) => {
switch (conn.type) {
// 获取应用配置
case 'get-init':
ev.returnValue = DB.read(INIT_FILE)
break
// 设置应用配置
case 'set-init':
DB.save(INIT_FILE, conn.data)
break
// 获取音乐数据库
case 'get-music':
ev.returnValue = DB.read(DB_FILE)
break
// 更新音乐数据库
case 'set-music':
DB.save(DB_FILE, conn.data)
break
// 获取临时音乐数据库
case 'get-temp':
ev.returnValue = DB.read(TEMP_DB)
break
// 更新临时音乐数据库
case 'set-temp':
DB.save(TEMP_DB, conn.data)
break
// 读取歌词文件
case 'read-lrc':
let lrc = path.join(LRC_DIR, `${conn.id}.lrc`)
if (fs.exists(lrc)) {
ev.returnValue = DB.read(lrc)
} else {
let { ext, name } = path.parse(_)
if (!ext || name.startsWith('.')) {
return false
}
return SUPPORTED_EXTS.includes(ext)
ev.returnValue = null
}
})
ev.returnValue = list
} else {
ev.returnValue = null
break
// 保存歌词文件
case 'save-lrc':
fs.echo(conn.data, path.join(LRC_DIR, `${conn.id}.lrc`))
break
// 保存音乐文件
case 'save-cache':
let file = path.join(CACHE_DIR, conn.file)
fs.echo(conn.data, file)
ev.returnValue = `file://${file}`
break
// 扫描目录
case 'scan-dir':
if (fs.isdir(conn.path)) {
let list = fs.ls(conn.path, true).filter(_ => {
if (fs.isdir(_)) {
return false
} else {
let { ext, name } = path.parse(_)
if (!ext || name.startsWith('.')) {
return false
}
return SUPPORTED_EXTS.includes(ext)
}
})
ev.returnValue = list
} else {
ev.returnValue = null
}
break
// 启用全局快捷键
case 'enable-gs':
Shortcut.__init__()
break
// 禁用全局快捷键
case 'disable-gs':
GS.unregisterAll()
break
}
})

View File

@ -6,52 +6,52 @@
'use strict'
const { globalShortcut: GS } = require('electron')
const { app, globalShortcut: GS } = require('electron')
module.exports = {
__init__(win) {
__init__() {
// 播放控制...
GS.register('MediaNextTrack', _ => {
win.emit('gs-ctrl', 'next')
app.__MAIN__.emit('gs-ctrl', 'next')
})
GS.register('MediaPreviousTrack', _ => {
win.emit('gs-ctrl', 'prev')
app.__MAIN__.emit('gs-ctrl', 'prev')
})
GS.register('MediaStop', _ => {
win.emit('gs-ctrl', 'stop')
app.__MAIN__.emit('gs-ctrl', 'stop')
})
GS.register('MediaPlayPause', _ => {
win.emit('gs-ctrl', 'play')
app.__MAIN__.emit('gs-ctrl', 'play')
})
// others
GS.register('Super+Alt+Space', _ => {
win.emit('gs-ctrl', 'play')
app.__MAIN__.emit('gs-ctrl', 'play')
})
GS.register('Super+Alt+Left', _ => {
win.emit('gs-ctrl', 'prev')
app.__MAIN__.emit('gs-ctrl', 'prev')
})
GS.register('Super+Alt+Right', _ => {
win.emit('gs-ctrl', 'next')
app.__MAIN__.emit('gs-ctrl', 'next')
})
GS.register('Super+Alt+Up', _ => {
win.emit('gs-ctrl', 'vu')
app.__MAIN__.emit('gs-ctrl', 'vu')
})
GS.register('Super+Alt+Down', _ => {
win.emit('gs-ctrl', 'vd')
app.__MAIN__.emit('gs-ctrl', 'vd')
})
GS.register('Super+Alt+R', _ => {
win.emit('gs-ctrl', 'lrc')
app.__MAIN__.emit('gs-ctrl', 'lrc')
})
GS.register('Super+Alt+Shift+M', _ => {
win.emit('gs-ctrl', 'mini')
app.__MAIN__.emit('gs-ctrl', 'mini')
})
}
}

View File

@ -33,7 +33,7 @@ exports.createMainWindow = function(icon) {
win.on('ready-to-show', _ => {
win.show()
// win.openDevTools()
win.openDevTools()
})
return win

View File

@ -14,17 +14,17 @@
<th>时长</th>
</tr>
</thead>
<tbody>
<tbodyclass="ac">
<tr
:class="{active: it.id === curr}"
:for="it in list"
:on-contextmenu="handleMenu(it, $index, $event)"
:dblclick="play(it, $index)">
<td class="ac idx" :text="$index + 1 + '.'"></td>
<td :text="it.title"></td>
<td class="ac" :text="it.artist"></td>
<td class="ac" :text="it.album"></td>
<td class="ac" :text="it.duration | time"></td>
<td class="idx" :text="$index + 1 + '.'"></td>
<td :text="it.title | truncate(10)" :attr-title="it.title"></td>
<td :text="it.artist | truncate(10)" :attr-title="it.artist"></td>
<td :text="it.album | truncate(10)" :attr-title="it.album"></td>
<td :text="it.duration | time"></td>
</tr>
</tbody>
</table>

View File

@ -91,6 +91,14 @@
</section>
<section class="block">
<span class="label">启用全局快捷键</span>
<div class="field">
<anot-switch :value="setting.allowGS"></anot-switch><span>(即使app在后台也能控制)</span>
</div>
</section>
<section class="block">
<span class="label">关于Sonist</span>
<div class="desc">

View File

@ -26,16 +26,16 @@
<th>时长</th>
</tr>
</thead>
<tbody>
<tbodyclass="ac">
<tr
:for="it in list"
:class="{active: it.kgHash === curr}"
:dblclick="play(it, $index)">
<td class="idx" :text="$index + 1 + '.'"></td>
<td :text="it.title"></td>
<td class="ac" :text="it.artist"></td>
<td class="ac" :text="it.album"></td>
<td class="ac" :text="it.duration | time"></td>
<td :text="it.title | truncate(10)" :attr-title="it.title"></td>
<td :text="it.artist | truncate(10)" :attr-title="it.artist"></td>
<td :text="it.album | truncate(10)" :attr-title="it.album"></td>
<td :text="it.duration | time"></td>
</tr>
</tbody>
</table>