I'm having a bit of an issue and I'd really appreciate it if I could get some insights.
What I am trying to do is to add an album cover to the mp3 file that will be downloaded from the front-end.
Context
I'm downloading a video stream from YouTube and converting it to mp3 using fluent-ffmpeg
.
To get the video I use the ytdl
npm module.
I then pipe this stream to the front-end.
What I've found
fluent-ffmpeg
offers either pipe()
or saveToFile()
.
What I figured is that when I use the saveToFile()
function and actually save my stream into an mp3 file, it works, I do get the album cover.
But when I pipe the stream to front-end or even into a file, the song is saved properly into a file but without the album cover.
Here is my code
Back-end (NodeJS)
let video = ytdl(`http://youtube.com/watch?v=${videoId}`, {
filter: (format) => format.container === 'mp4' && format.audioEncoding,
quality: 'lowest'
});
let stream = new FFmpeg()
.input(video)
.addInput(`https://i.ytimg.com/vi/${videoId}/default.jpg`)
.outputOptions([
'-map 0:1',
'-map 1:0',
'-c copy',
'-c:a libmp3lame',
'-id3v2_version 3',
'-metadata:s:v title="Album cover"',
'-metadata:s:v comment="Cover (front)"'
])
.format('mp3');
And then piping it to my front-end.
stream.pipe(res);
stream
.on('end', () => {
console.log('******* Stream end *******');
res.end.bind(res);
})
.on('error', (err) => {
console.log('ERR', err);
res.status(500).end.bind(res);
});
Front-end (React)
axios.get(url)
.then(res => {
axios(`${url}/download`, {
method: 'GET',
responseType: 'blob'
})
.then(stream => {
const file = new Blob(
[stream.data],
{ type: 'audio/mpeg' });
//Build a URL from the file
const fileURL = URL.createObjectURL(file);
})
.catch(err => {
console.log('ERROR', err);
});
})
.catch(err => {
console.log('ERROR', err);
});