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

引入ID3读写模块

2.x
宇天 2020-11-18 18:32:20 +08:00
parent ea4bdddffa
commit 2f746df5fd
7 changed files with 269 additions and 225 deletions

View File

@ -16,6 +16,7 @@
"dependencies": { "dependencies": {
"crypto.js": "^2.0.2", "crypto.js": "^2.0.2",
"iofs": "^1.5.1", "iofs": "^1.5.1",
"music-metadata": "^7.5.0",
"sqlite3": "^5.0.0" "sqlite3": "^5.0.0"
}, },
"devDependencies": { "devDependencies": {

File diff suppressed because one or more lines are too long

View File

@ -5,14 +5,15 @@
* @date 2018/12/16 17:15:07 * @date 2018/12/16 17:15:07
*/ */
@import './var.scss';
@import "./var.scss";
.app { .app {
position: relative; position: relative;
display:flex;flex-direction:column; display: flex;
width:100%;height:100%; flex-direction: column;
background:rgba(0, 0, 0, .3); width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.3);
// //
.title-bar { .title-bar {
@ -23,28 +24,39 @@
height: 26px; height: 26px;
.btn-box { .btn-box {
display:inline-flex;; display: inline-flex;
width:auto;height:12px;padding:0 8px; width: auto;
height: 12px;
padding: 0 8px;
.item { .item {
display: inline-flex; display: inline-flex;
width:12px;height:12px; width: 12px;
height: 12px;
margin: 0 3px; margin: 0 3px;
background:url(/images/btn-grey.svg) no-repeat;background-size:cover; background: url(/images/btn-grey.svg) no-repeat;
background-size: cover;
} }
&.focus { &.focus {
.quit {background-image:url(/images/btn-close.svg);} .quit {
.min {background-image:url(/images/btn-mini.svg);} background-image: url(/images/btn-close.svg);
}
.min {
background-image: url(/images/btn-mini.svg);
}
// .max {background-image:url(/images/btn-maxi.svg);} // .max {background-image:url(/images/btn-maxi.svg);}
} }
&:hover { &:hover {
.quit {background-image:url(/images/btn-close_a.svg);} .quit {
.min {background-image:url(/images/btn-mini_a.svg);} background-image: url(/images/btn-close_a.svg);
}
.min {
background-image: url(/images/btn-mini_a.svg);
}
// .max {background-image:url(/images/btn-maxi_a.svg);} // .max {background-image:url(/images/btn-maxi_a.svg);}
} }
} }
} }
.main-body { .main-body {
@ -77,7 +89,8 @@
} }
button { button {
width:42px;height:16px; width: 42px;
height: 16px;
margin-left: 12px; margin-left: 12px;
font-size: 10px; font-size: 10px;
border: 0; border: 0;
@ -98,11 +111,15 @@
width: 100%; width: 100%;
height: 99px; height: 99px;
padding-bottom: 16px; padding-bottom: 16px;
border-bottom:1px solid rgba(200, 200, 200, .1); border-bottom: 1px solid rgba(200, 200, 200, 0.1);
.album { .album {
width:80px;height:80px; width: 80px;
img {width:100%;height:100%;} height: 80px;
img {
width: 100%;
height: 100%;
}
} }
.info { .info {
@ -121,19 +138,13 @@
cite { cite {
font-size: 12px; font-size: 12px;
font-style: normal; font-style: normal;
} }
p {font-size:12px;color:#bdbdbd;} p {
}
.duration {
position:absolute;
right:32px;
top:16px;
font-size: 12px; font-size: 12px;
color: #bdbdbd; color: #bdbdbd;
} }
}
.total { .total {
position: absolute; position: absolute;
right: 32px; right: 32px;
@ -148,7 +159,7 @@
width: 100%; width: 100%;
height: 269px; height: 269px;
padding: 16px 6px; padding: 16px 6px;
border-top:1px solid rgba(32, 32, 32, .1); border-top: 1px solid rgba(32, 32, 32, 0.1);
} }
.list { .list {
@ -171,11 +182,9 @@
} }
.name { .name {
overflow:hidden;
flex: 1; flex: 1;
} }
.artist { .artist {
overflow:hidden;
width: 128px; width: 128px;
margin-left: 12px; margin-left: 12px;
} }
@ -190,13 +199,15 @@
.idx::before { .idx::before {
position: absolute; position: absolute;
left:0;top:3px; left: 0;
top: 3px;
font-size: 10px; font-size: 10px;
content:""; content: '';
} }
} }
&.active, &:hover { &.active,
&:hover {
color: #58ffdf; color: #58ffdf;
background: rgba(29, 77, 68, 0.15); background: rgba(29, 77, 68, 0.15);
} }
@ -205,13 +216,10 @@
} }
} }
.play-bar { .play-bar {
height:66px;width:100%; height: 66px;
background:rgba(255, 255, 255, .25); width: 100%;
background: rgba(255, 255, 255, 0.25);
color: #fff; color: #fff;
.stat-bar { .stat-bar {
@ -282,47 +290,52 @@
margin-left: 32px; margin-left: 32px;
.item { .item {
width:22px;height:22px; width: 22px;
height: 22px;
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: cover; background-size: cover;
transition:background .1s ease-in-out; transition: background 0.1s ease-in-out;
cursor: pointer; cursor: pointer;
&.prev { &.prev {
background-image: url(/images/ctrl/prev.png); background-image: url(/images/ctrl/prev.png);
&:hover,&:active { &:hover,
&:active {
background-image: url(/images/ctrl/prev_a.png); background-image: url(/images/ctrl/prev_a.png);
} }
} }
&.on,&.off { &.on,
width:42px;height:42px; &.off {
width: 42px;
height: 42px;
} }
&.on { &.on {
background-image: url(/images/ctrl/play.png); background-image: url(/images/ctrl/play.png);
animation: round 2s linear infinite; animation: round 2s linear infinite;
&:hover,&:active { &:hover,
&:active {
background-image: url(/images/ctrl/play_a.png); background-image: url(/images/ctrl/play_a.png);
} }
} }
&.off { &.off {
background-image: url(/images/ctrl/pause.png); background-image: url(/images/ctrl/pause.png);
&:hover,&:active { &:hover,
&:active {
background-image: url(/images/ctrl/pause_a.png); background-image: url(/images/ctrl/pause_a.png);
} }
} }
&.next { &.next {
background-image: url(/images/ctrl/next.png); background-image: url(/images/ctrl/next.png);
&:hover,&:active { &:hover,
&:active {
background-image: url(/images/ctrl/next_a.png); background-image: url(/images/ctrl/next_a.png);
} }
} }
} }
} }
@ -335,43 +348,49 @@
margin-right: 16px; margin-right: 16px;
.item { .item {
width:22px;height:22px; width: 22px;
height: 22px;
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: cover; background-size: cover;
transition:background .1s ease-in-out; transition: background 0.1s ease-in-out;
cursor: pointer; cursor: pointer;
&.volume { &.volume {
background-image: url(/images/ctrl/volume.png); background-image: url(/images/ctrl/volume.png);
&:hover,&:active { &:hover,
&:active {
background-image: url(/images/ctrl/volume_a.png); background-image: url(/images/ctrl/volume_a.png);
} }
} }
&.mute { &.mute {
background-image: url(/images/ctrl/mute.png); background-image: url(/images/ctrl/mute.png);
&:hover,&:active { &:hover,
&:active {
background-image: url(/images/ctrl/mute_a.png); background-image: url(/images/ctrl/mute_a.png);
} }
} }
&.single { &.single {
background-image: url(/images/ctrl/single.png); background-image: url(/images/ctrl/single.png);
&:hover,&:active { &:hover,
&:active {
background-image: url(/images/ctrl/single_a.png); background-image: url(/images/ctrl/single_a.png);
} }
} }
&.all { &.all {
background-image: url(/images/ctrl/all.png); background-image: url(/images/ctrl/all.png);
&:hover,&:active { &:hover,
&:active {
background-image: url(/images/ctrl/all_a.png); background-image: url(/images/ctrl/all_a.png);
} }
} }
&.rand { &.rand {
background-image: url(/images/ctrl/rand.png); background-image: url(/images/ctrl/rand.png);
&:hover,&:active { &:hover,
&:active {
background-image: url(/images/ctrl/rand_a.png); background-image: url(/images/ctrl/rand_a.png);
} }
} }
@ -379,8 +398,6 @@
} }
} }
} }
} }
@keyframes round { @keyframes round {

View File

@ -47,19 +47,19 @@
<p>经典咏流传第三季 第7期</p> <p>经典咏流传第三季 第7期</p>
</div> </div>
<span class="duration">98:54</span> <span class="total" :text="list.size()"></span>
<span class="total">118</span>
</div> </div>
<div class="scroll-box"> <div class="scroll-box">
<wc-scroll class="list"> <wc-scroll class="list">
<section
<section class="item" :for="i it in list"> class="item"
:class="{on: curr === i}"
:for="i it in list">
<span class="idx" :text="i + 1"></span> <span class="idx" :text="i + 1"></span>
<span class="name" :text="it.name"></span> <span class="name text-ell" :text="it.name"></span>
<span class="artist" :text="it.artist"></span> <span class="artist text-ell" :text="it.artist"></span>
<span class="duration" :text="it.duration"></span> <span class="duration" :text="it.duration"></span>
</section> </section>
</wc-scroll> </wc-scroll>
</div> </div>
</div> </div>

View File

@ -8,7 +8,8 @@ import Anot from '/js/lib/anot.js'
import '/js/lib/scroll/index.js' import '/js/lib/scroll/index.js'
import app from '/js/lib/socket.js' import app from '/js/lib/socket.js'
// const {} from '' // const id3 = require('jsmediatags')
const id3 = require('music-metadata')
Anot({ Anot({
$id: 'app', $id: 'app',
@ -16,13 +17,22 @@ Anot({
isplaying: true, isplaying: true,
playmode: 1, playmode: 1,
mute: false, mute: false,
curr: 2,
list: [] list: []
}, },
mounted() { async mounted() {
var list = app.dispatch('scan-dir', { path: '/Volumes/extends/music' }) var list = app.dispatch('scan-dir', { path: '/Volumes/extends/music' })
this.list = list this.list = list
console.log(list)
for (let it of this.list) {
let { album, artist, title, duration } = await this.getID3(it.path)
it.name = title || it.name
it.artist = artist || '未知歌手'
it.album = album
it.duration = Anot.filters.time(duration)
}
}, },
methods: { methods: {
play() { play() {
@ -37,6 +47,15 @@ Anot({
}, },
toggleMute() { toggleMute() {
this.mute = !this.mute this.mute = !this.mute
},
getID3(file) {
return id3.parseFile(file).then(res => {
let {
common: { album, artist, title },
format: { duration }
} = res
return { album, artist, title, duration: ~~duration }
})
} }
} }
}) })

View File

@ -19,7 +19,8 @@ CREATE TABLE IF NOT EXISTS "songs" (
"name" char(128) NOT NULL, "name" char(128) NOT NULL,
"album" char(128) NOT NULL, "album" char(128) NOT NULL,
"cover" char(256) NOT NULL, "cover" char(256) NOT NULL,
"lrc" text NOT NULL, "path" char(256) NOT NULL,
"lrc" text NOT NULL
) )
` `
// 歌曲和播放列表的关系表(多对多) // 歌曲和播放列表的关系表(多对多)

View File

@ -7,6 +7,7 @@
const { app, ipcMain, globalShortcut: GS } = require('electron') const { app, ipcMain, globalShortcut: GS } = require('electron')
const path = require('path') const path = require('path')
const fs = require('iofs') const fs = require('iofs')
const sec = require('crypto.js')
const Shortcut = require('./shortcut') const Shortcut = require('./shortcut')
const Sqlite = require('./db') const Sqlite = require('./db')
@ -91,7 +92,12 @@ ipcMain.on('app', (ev, conn) => {
}) })
.map(it => { .map(it => {
var { ext, name } = path.parse(it) var { ext, name } = path.parse(it)
return { uuid: '', ext, name, path: it } var buf = fs.origin.createReadStream(it, {
start: 0,
end: 256,
encoding: 'base64'
})
return { name, path: it, artist: '', album: '', duration: '00:00' }
}) })
ev.returnValue = list ev.returnValue = list
} else { } else {