import { spawn } from 'child_process' import ffmpeg from 'fluent-ffmpeg' import path from 'path' function parseTitle (data) { let tt = data.title // Remove []'s from the beginning tt = tt.replace(/^\[\w+\]\s?/i, '') // Remove "Official Video/Audio" tag tt = tt.replace(/\s?(?:[()[]])?Official\s?[\w]+(?:[()[]])?/i, '') // Remove "Audio" tag tt = tt.replace(/\s?(?:[()[]])Audio?(?:[()[]])/i, '') // Remove "lyrics" tag tt = tt.replace(/\s?(?:[()[]])?lyrics?\s?(?:[\w]+)?(?:[()[]])?\s?/i, '') // Artist / Title split const at = tt.split(' - ', 2) let artist let title if (at.length > 1) { artist = at[0] title = tt.substring(artist.length + 3) } else { artist = data.artist title = tt } data.title = title data.artist = artist return data } function getVideoInfo (arg) { const yt = spawn('youtube-dl', ['--no-playlist', '-j', '-f', 'bestaudio/best', arg]) let output = '' yt.stdout.on('data', function (chunk) { output += chunk.toString('utf8') }) return new Promise((resolve, reject) => { yt.on('close', function () { const ftdata = output.trim().split('\n') if (ftdata.length > 1) { const composite = [] for (const i in ftdata) { let dat try { dat = JSON.parse(ftdata[i]) } catch (e) { console.error(e) continue } delete dat.formats composite.push(dat) } return resolve(composite) } const data = JSON.parse(output) delete data.formats resolve(data) }) }) } function fetchVideo (data) { return new Promise((resolve, reject) => { const tempName = path.join(process.cwd(), `/tmp.yt.${data.id}.mp3`) ffmpeg(data.url || data.file) .audioCodec('libmp3lame') .format('mp3') .on('error', reject) .on('end', function () { resolve({ title: data.title, artist: data.uploader, url: data.webpage_url, art: data.thumbnail, source: tempName }) }) .output(tempName) .run() }) } export { parseTitle, getVideoInfo, fetchVideo }