Skip to content

Instantly share code, notes, and snippets.

@vlakam
Last active September 25, 2018 16:21
Show Gist options
  • Save vlakam/2e59d59c3ca8fd51342002d50952a5a2 to your computer and use it in GitHub Desktop.
Save vlakam/2e59d59c3ca8fd51342002d50952a5a2 to your computer and use it in GitHub Desktop.
m3u downloader and id3tag fixer
const m3u = require('m3ujs');
const {promisify} = require('util');
const sanitize = require("sanitize-filename");
const fetch = require('node-fetch');
const ID3Writer = require('browser-id3-writer');
const fs = require('fs');
const path = require("path");
const readFileAsync = promisify(fs.readFile);
const writeFileAsync = promisify(fs.writeFile);
const jsmediatags = require("jsmediatags");
var content = fs.readFileSync('./playlist.m3u').toString();
var parsed = m3u.parse(content);
var tracks = parsed.tracks;
function wait(ms) {return new Promise(function(resolve) {setTimeout(function () {resolve();}, ms)})}
function tagReadAsync(from) {
return new Promise((resolve, reject) => {
new jsmediatags.Reader(from)
.setTagsToRead(['artist', 'title'])
.read({
onSuccess(meta) {
resolve({
artist: meta.tags.title,
title: meta.tags.artist
})
},
onError(error) {
resolve({
});
console.log(error.info);
}
})
});
}
async function saveTrack(track) {
var name = sanitize(track.title);
var artist = name.split('-')[0].trim();
var title = name.split('-')[1].trim();
var url = track.file;
var savePath = path.resolve(__dirname, 'music', name + '.mp3');
const res = await fetch(url);
const fileStream = fs.createWriteStream(savePath);
await new Promise((resolve, reject) => {
res.body.pipe(fileStream);
res.body.on('error', (err) => { reject(err);});
fileStream.on('finish', () => {
resolve();
});
});
console.log(`Finished downloading: ${name}`);
return {
savePath, artist, title
};
}
async function fixTags(data) {
let { savePath, artist, title } = data;
let originalTags = await tagReadAsync(savePath);
if (originalTags.artist && originalTags.title) {
return;
} else {
artist = originalTags.artist || artist;
title = originalTags.title || title;
}
const songBuffer = await readFileAsync(savePath);
const writer = new ID3Writer(songBuffer);
writer.setFrame('TIT2', title).setFrame('TPE1', [artist]);
writer.addTag();
const taggedSongBuffer = Buffer.from(writer.arrayBuffer);
await writeFileAsync(savePath, taggedSongBuffer);
}
(async function() {
for(let track in tracks) {
let a = await saveTrack(tracks[track]);
let b = fixTags(a);
await wait(25);
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment