我正在尝试向我的node.js Web应用程序添加一项功能,以便当用户输入多个音频文件时,我可以提取并显示每个文件的元数据信息,例如标题/艺术家/专辑/年份等。我正在尝试添加它,以便它适用于大多数音频文件(mp3/wav/flac/等..),理想情况下尽可能多的音频类型。
这个示例(带有 github 链接)显示了它的可能性:https://audio-tag-analyzer.netlify.app/ 几乎完全按照我想要的方式进行。这个网站的代码是一个反应应用程序,但我不熟悉。
我研究了几种不同的可能解决方案来在我的 Node.js Web 应用程序中实现我的目标:
不起作用,因为文件默认文件输入选择返回一个仅具有名称/大小/类型信息(无元数据)的 FileList 对象
使用这个包:https://github.com/Borewit/music-metadata如果你有完整的文件路径,你可以使用parseFile输入选项,如果不将文件上传到我的本地服务器,我无法在浏览器中获取它我想避免
使用此包:https://github.com/Borewit/music-metadata
此包的 parseStream 示例代码需要“someReadStream”作为输入,如下所示:
mm.parseStream(someReadStream, {mimeType: 'audio/mpeg', size: 26838})
.then( metadata => {
console.log(util.inspect(metadata, {showHidden: false, depth: null}));
someReadStream.destroy();
});
我一直在研究这个解决方案,但还无法让它工作,我通过这个html代码读取文件输入:
<input style="cursor: pointer;" type="file" id="file" multiple="multiple" />
我是否应该在输入文件时监视事件,然后以某种方式在前端创建一个 readFileStream,然后将该 readFileStream 传递到我的后端,以便我可以运行包来提取元数据信息?
我会使用不同的库,因为该库似乎没有不需要 React、Angular 或其他一些工具(如 browserify)才能工作的前端。注意:我尝试让它与 browserify 一起使用,但遇到了很多问题。我花了太多的时间试图让它变得有趣,哈哈。
无论如何,这是使用
jsmediatags
获取所有标签的好方法
$(document).ready(() => {
function readSong(file) {
return new Promise((resolve, reject) => {
window.jsmediatags.read(file, {
onSuccess: (tag) => {
resolve(tag.tags);
},
onError: (error) => {
reject(error);
}
});
});
}
$("#file").change(async (event) => {
var fileList = event.target.files;
try {
const tags = await readSong(fileList[0]);
console.log(tags);
} catch(e) {
console.log(e);
}
});
});
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsmediatags/3.9.3/jsmediatags.min.js"></script>
<script src="./lib/index.js"></script>
</head>
<body>
<input style="cursor: pointer;" type="file" id="file" multiple="multiple" />
</body>
</html>
以下代码是如何使用 music-metadata 解析音频文件的示例:
async function run() {
console.log('Loading music-metadata...');
const mm = await import('https://cdn.jsdelivr.net/npm/[email protected]/+esm');
console.log('Ready for parsing.');
// Listen for file upload
const fileInput = document.getElementById('file');
const output = document.getElementById('output');
fileInput.addEventListener('change', async (event) => {
const file = event.target.files[0]; // Get the first file
if (file) {
output.textContent = 'Loading metadata...';
try {
// Parse the file (Blob)
console.log('Parsing file...');
const metadata = await mm.parseBlob(file);
// Show metadata info in the output
output.textContent = JSON.stringify(metadata, null, 2);
console.log('Done.');
} catch (err) {
output.textContent = 'Error parsing file: ' + err.message;
}
} else {
output.textContent = 'No file selected';
}
});
}
run();
<!DOCTYPE html>
<html>
<head>
<title>Parse any audio with music-metadata</title>
<meta charset="UTF-8" />
</head>
<body>
<h1>Select an audio file which like to have parsed</h1>
<input style="cursor: pointer;" type="file" id="file" accept="audio/*" />
<pre id="output"></pre>
</body>
</html>