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

View File

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

View File

@ -8,7 +8,8 @@ import Anot from '/js/lib/anot.js'
import '/js/lib/scroll/index.js'
import app from '/js/lib/socket.js'
// const {} from ''
// const id3 = require('jsmediatags')
const id3 = require('music-metadata')
Anot({
$id: 'app',
@ -16,13 +17,22 @@ Anot({
isplaying: true,
playmode: 1,
mute: false,
curr: 2,
list: []
},
mounted() {
async mounted() {
var list = app.dispatch('scan-dir', { path: '/Volumes/extends/music' })
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: {
play() {
@ -37,6 +47,15 @@ Anot({
},
toggleMute() {
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,
"album" char(128) 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 path = require('path')
const fs = require('iofs')
const sec = require('crypto.js')
const Shortcut = require('./shortcut')
const Sqlite = require('./db')
@ -91,7 +92,12 @@ ipcMain.on('app', (ev, conn) => {
})
.map(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
} else {