javascript - 如何使用 FFmpeg 将专辑封面添加到 mp3 流?

标签 javascript node.js ffmpeg mp3 fluent-ffmpeg

我遇到了一些问题,如果我能得到一些见解,我将不胜感激。

我想做的是为将从前端下载的 mp3 文件添加专辑封面。

上下文

我正在从 YouTube 下载视频流并使用 fluent-ffmpeg 将其转换为 mp3。
为了获取视频,我使用了 ytdl npm 模块。

然后我将这个流通过管道传输到前端。

我发现了什么

fluent-ffmpeg 提供 pipe()saveToFile()

我想的是,当我使用 saveToFile() 函数并将我的流实际保存到 mp3 文件中时,它起作用了,我确实得到了专辑封面。

但是当我将流通过管道传输到前端甚至到文件中时,歌曲会正确保存到文件中,但没有专辑封面。

这是我的代码

后端(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');

然后将其通过管道传输到我的前端。

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);
  });

前端( 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);
    });

最佳答案

不幸的是,似乎没有可能的解决方案来用流完成这个任务。我研究了很多但只找到了为什么我们不能用 FFmpeg 和管道流做到这一点的解释。 njoyard 写道:

Actually this problem is not specific to Windows. Most formats write stream information (duration, bitrate, keyframe position...) at the beginning of the file, and thus ffmpeg can only write this information when its output is seekable (because it has to finish processing streams to the end before knowing what to write). Pipes are not seekable, so you won't get this information when using an output pipe.

As for your note about the output format, ffmpeg determines the output format from the output file extension, which is not possible with pipes; that's why you have to specify the output format explicitly.

这里有一个链接可以自己找:https://github.com/fluent-ffmpeg/node-fluent-ffmpeg/issues/159

因此,我看到的唯一解决方案是使用 saveToFile() 方法保存文件并将其附加到响应。

关于javascript - 如何使用 FFmpeg 将专辑封面添加到 mp3 流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51705914/

相关文章:

javascript - 在移动设备的视频标签 (HTML5) 中使用时停止下载背景视频

php - 表单/PHP/Ajax 加载?

javascript - ExpressJS 需要

linux - 哪个 Node 指向usr/bin/node,cd usr/bin/node不存在

javascript - Bootstrap 对齐

macos - 在 OS X El Capitan 10.11.1 上配置 ffmpeg 时出错

ffmpeg - 如何将 ffmpeg 命令转换为使用 ffmpy?

javascript - 文件输入 : Compare file type and accept only picture formats (jpg, bmp 等)

php - 我们可以在保存功能中设置图像帧的大小吗?

javascript - 当我在分派(dispatch)后更新 vue 组件中的状态时,防止状态更新