115 lines
4.1 KiB
Vue
115 lines
4.1 KiB
Vue
<template>
|
|
<el-table :data="tableData" stripe style="width: 100%">
|
|
<el-table-column label="封面">
|
|
<template slot-scope="scope">
|
|
<el-upload :auto-upload="false" :show-file-list="false" :on-change="(res)=>{ changeCover(res,scope.row) }" action="" drag>
|
|
<img :src="scope.row.picture" style="width: 100px; height: 100px">
|
|
<div slot="error" class="image-slot el-image__error">暂无封面</div>
|
|
</img>
|
|
</el-upload>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="歌曲">
|
|
<template #default="scope">
|
|
<el-input placeholder="请输入歌曲标题" v-model="iTitle ? iTitle : iTitle = scope.row.title, iTitle" @change="(value)=>{ changeTitle(value, scope.row) }" clearable></el-input>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="歌手">
|
|
<template #default="scope">
|
|
<el-input placeholder="请输入歌手" v-model="iArtist ? iArtist : iArtist = scope.row.artist, iArtist" @change="(value)=>{ changeArtist(value, scope.row) }" clearable></el-input>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="专辑">
|
|
<template #default="scope">
|
|
<el-input placeholder="请输入专辑名称" v-model="iAlbum ? iAlbum : iAlbum = scope.row.album, iAlbum" @change="(value)=>{ changeAlbum(value, scope.row) }" clearable></el-input>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="操作">
|
|
<template #default="scope">
|
|
<el-button circle icon="el-icon-video-play" type="success" @click="handlePlay(scope.$index, scope.row)">
|
|
</el-button>
|
|
<el-button circle icon="el-icon-download" @click="handleDownload(scope.row)"></el-button>
|
|
<el-button circle icon="el-icon-delete" type="danger" @click="handleDelete(scope.$index, scope.row)">
|
|
</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</template>
|
|
|
|
<script>
|
|
import { RemoveBlobMusic } from '@/utils/utils';
|
|
import {
|
|
GetArrayBuffer,
|
|
GetImageFromURL,
|
|
WriteMetaToFlac,
|
|
WriteMetaToMp3,
|
|
} from '@/decrypt/utils';
|
|
import { parseBlob as metaParseBlob } from 'music-metadata-browser';
|
|
|
|
export default {
|
|
name: 'PreviewTable',
|
|
props: {
|
|
tableData: { type: Array, required: true },
|
|
policy: { type: Number, required: true },
|
|
},
|
|
|
|
methods: {
|
|
handlePlay(index, row) {
|
|
this.$emit('play', row.file);
|
|
},
|
|
handleDelete(index, row) {
|
|
RemoveBlobMusic(row);
|
|
this.tableData.splice(index, 1);
|
|
},
|
|
handleDownload(row) {
|
|
this.$emit('download', row);
|
|
},
|
|
async regenerate(row) {
|
|
const fileBuffer = await GetArrayBuffer(row.blob);
|
|
const musicMeta = await metaParseBlob(row.blob);
|
|
const imageInfo = await GetImageFromURL(row.picture);
|
|
try {
|
|
const newMeta = { picture: imageInfo.buffer, title: row.title, artists: row.artist?.split(' _ ') };
|
|
if (ext === 'mp3') {
|
|
fileBuffer = WriteMetaToMp3(Buffer.from(fileBuffer), newMeta, musicMeta);
|
|
row.blob = new Blob([fileBuffer], { type: row.mime });
|
|
} else if (ext === 'flac') {
|
|
fileBuffer = WriteMetaToFlac(Buffer.from(fileBuffer), newMeta, musicMeta);
|
|
row.blob = new Blob([fileBuffer], { type: row.mime });
|
|
} else {
|
|
console.info('writing metadata for ' + row.ext + ' is not being supported for now');
|
|
}
|
|
} catch (e) {
|
|
console.warn('Error while appending cover image to file ' + e);
|
|
}
|
|
row.file = URL.createObjectURL(row.blob);
|
|
},
|
|
async changeCover(file, row) {
|
|
if (row.picture?.startsWith('blob:')) {
|
|
URL.revokeObjectURL(row.picture);
|
|
}
|
|
row.picture = file.url;
|
|
URL.revokeObjectURL(row.file);
|
|
await regenerate(row);
|
|
},
|
|
async changeTitle(value, row) {
|
|
row.title = value;
|
|
URL.revokeObjectURL(row.file);
|
|
await regenerate(row);
|
|
},
|
|
async changeArtist(value, row) {
|
|
row.artist = value;
|
|
URL.revokeObjectURL(row.file);
|
|
await regenerate(row);
|
|
},
|
|
async changeAlbum(value, row) {
|
|
row.album = value;
|
|
URL.revokeObjectURL(row.file);
|
|
await regenerate(row);
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style scoped></style>
|