实现音频的播放只需要使用 Audio
标签即可,但是由于一些安全策略会禁止载入文件,所以我们要关闭安全策略。
关闭掉 webSecurity
,这样就可以读取本地的音频文件了,记得重启 Electron。
mainWindow = createMainWindow({
width: 400,
height: 560,
frame: false,
transparent: true,
show: false,
webPreferences: {
webSecurity: false
}
})
我们先实现功能,之后再美化界面,我们现在通过 remote 访问主进程的一些模块,来选取文件夹,对 Mp3 文件进行排序,通过监听 svelte 的 state
状态修改事件,来监视播放地址的修改,这里一定要加上文件协议 file://
要不然会报错,这里没有做平台兼容,平台的路径少许不同。
<Back/>
<div>
<button on:click="next()">next</button>
<button on:click="prev()">prev</button>
<button on:click="file()">file</button>
</div>
<script>
import {
ipcRenderer,
remote
} from "electron";
const {
dialog,
app
} = remote
const {
readdir
} = remote.require('fs-extra')
import {
resolve
} from 'path'
export default {
data() {
return {
currentSrc: '',
index: 0,
files: []
};
},
components: {
Back: '../components/Back.svelte'
},
oncreate() {
this.player = new Audio()
document.querySelector('#app').appendChild(this.player)
this.player.onended = this.next // 播放完成下一首
this.on('state', ({
changed
}) => {
if (changed.currentSrc) {
this.player.src = this.get().currentSrc
this.play()
}
})
},
methods: {
next() { // 下一曲
const {
index,
files
} = this.get()
let i = index + 1
if (i > files.length - 1) { // 边界守护
i = files.length - 1
}
this.set({
index: i,
currentSrc: "file://" + files[i]
})
},
prev() { // 上一曲
const {
index,
files
} = this.get()
let i = index - 1
if (i < 0) { // 边界守护
i = 0
}
this.set({
index: i,
currentSrc: "file://" + files[i]
})
},
play() { // 播放
this.player.play()
},
pause() { // 暂停
this.play.pause()
},
file() { // 选取文件
dialog.showOpenDialog({
title: '选择音乐目录',
defaultPath: app.getPath('home'),
properties: ['openDirectory']
}, async(folders) => {
if (folders.length > 0) {
const folder = folders[0]
let files = await readdir(folder)
const compare = (a, b) => { // 比较字符串前面的数字
let t1 = a.split('-')[0];
let t2 = b.split('-');
return parseInt(t1) - parseInt(t2)
}
files = files.sort(compare).map(file => resolve(folder, file)) // 文件排序
this.set({
files,
currentSrc: "file://" + files[0]
})
}
})
}
}
};
</script>