【问题标题】:FFmpeg converting from video to audio missing durationFFmpeg从视频转换为音频缺少持续时间
【发布时间】:2015-02-08 00:39:28
【问题描述】:

我正在尝试通过他们的直接视频 URL 加载 YouTube 视频(使用 ytdl-core 检索)。我使用request 库加载它们。然后我将结果通过管道传输到一个流中,该流用作 ffmpeg 的输入(通过fluent-ffmpeg)。代码如下所示:

var getAudioStream = function(req, res) {
    var requestUrl = 'http://youtube.com/watch?v=' + req.params.videoId;
    var audioStream = new PassThrough();
    var videoUrl;

    ytdl.getInfo(requestUrl, { downloadURL: true }, function(err, info) {
      res.setHeader('Content-Type', 'audio/x-wav');
      res.setHeader('Accept-Ranges', 'bytes');
      videoUrl = info.formats ? info.formats[0].url : '';
      request(videoUrl).pipe(audioStream);

      ffmpeg()
        .input(audioStream)
        .outputOptions('-map_metadata 0')
        .format('wav')
        .pipe(res);
    });
  };

这实际上工作得很好,前端成功地只接收到 WAV 格式的音频并且可以播放。但是,音频缺少有关其大小或持续时间(以及所有其他元数据)的任何信息。这也使它无法搜索。

我假设这在ffmpeg 阶段的某个地方丢失了,因为如果我通过传递给request 的URL 直接加载视频,它可以正常加载和播放,并且具有设定的持续时间/可搜索。有什么想法吗?

【问题讨论】:

    标签: javascript node.js express ffmpeg


    【解决方案1】:

    在完成之前无法知道输出大小和持续时间。在大多数情况下,FFmpeg 无法提前知道这些信息。即使可以,您执行 FFmpeg 的方式也会阻止您访问额外的信息。

    此外,为了支持搜索,您需要支持范围请求。这也是不可能的,除非将文件编码为请求的字节并从那里开始流式传输。

    基本上,根据您所做工作的性质,这是不可能的。

    【讨论】:

    • 如果我通过其他方法知道,是否可以硬编码持续时间?
    • @Jakemmarsh 你知道你最终会得到的输出文件的样本精确长度吗?如何?如果您知道这些信息,那么您可以编写自己的复用器来处理 RIFF/WAVE 块。 ccrma.stanford.edu/courses/422/projects/WaveFormat 然后您可以从 FFmpeg 请求原始 PCM 样本并自己将它们打包到 WAVE 文件中。
    • 由于我是通过 ytdl 从 YouTube 获取视频的,因此我预先获得了以秒为单位的持续时间。除非我误解了实现这一目标需要什么?
    • @Jakemmarsh 以秒为单位的持续时间不准确,它是一个近似值。当从原始格式中提取并转换为原始 PCM 样本时,该视频的播放时间会略有不同。一旦完成,您会发现以秒为单位的持续时间无论如何都不够准确。对于 CD 质量的音频,每秒有 44,100 个样本。准确编码 WAVE 标头要求您知道文件的确切长度,而不是大约长度。减少 20,000 个样本并不准确,除非您不介意生成损坏的文件。
    猜你喜欢
    • 2020-09-30
    • 2016-06-08
    • 2021-11-28
    • 1970-01-01
    • 2016-12-17
    • 2015-05-29
    • 2020-12-11
    • 2020-08-25
    • 2015-11-27
    相关资源
    最近更新 更多