0

在 javascript 网页上,我使用 HTML5 Media API 生成音频消息,然后通过 socketio 将其发送到 nodejs 服务器,该服务器将文件保存在磁盘上。这一切都有效。

Javascript块,客户端:

navigator.mediaDevices
  .getUserMedia({ audio: true })
    .then(stream => {

      const mediaRecorder = new MediaRecorder(stream)
      ...
      }

服务器端我成功保存了 webm/opus 文件:

$ ll audiofiles/audiofile.webm
-rw-rw-r-- 1 username 180K May 29 21:04 audiofiles/audiofile.webm

使用 vlc 播放器,我看到以秒为单位的持续时间几乎是 28 秒。

让我们检查一下 mediainfo / ffmpeg:

使用mediainfo

$ mediainfo audiofiles/audiofile.webm
General
Complete name                            : audiofiles/audiofile.webm
Format                                   : WebM
Format version                           : Version 4 / Version 2
File size                                : 180 KiB
Writing application                      : Chrome
Writing library                          : Chrome
IsTruncated                              : Yes

Audio
ID                                       : 1
Format                                   : Opus
Codec ID                                 : A_OPUS
Channel(s)                               : 1 channel
Channel positions                        : Front: C
Sampling rate                            : 48.0 kHz
Bit depth                                : 32 bits
Compression mode                         : Lossy
Language                                 : English
Default                                  : Yes
Forced                                   : No

使用ffmpeg

$ ffmpeg -hide_banner -i audiofiles/audiofile.webm
Input #0, matroska,webm, from 'audiofiles/audiofile.webm':
  Metadata:
    encoder         : Chrome
  Duration: N/A, start: 0.000000, bitrate: N/A
    Stream #0:0(eng): Audio: opus, 48000 Hz, mono, fltp (default)
At least one output file must be specified

我的问题是:

如何在节点服务器日志文件上跟踪服务器端 webm 音频文件的长度(以秒为单位)?

我需要有文件的近似持续时间(以秒为单位)。可能使用 nodejs 函数。

运行时的一个糟糕/粗略的解决方案可能是凭经验将文件的字节长度与以秒为单位的长度进行映射……例如,对于特定的编码/格式:1000 字节 ~= 1 秒。

有什么更好的方法来测量音频文件的持续时间,可能在 nodejs 代码中?

4

2 回答 2

0

Node.js并不以其音频可能性而闻名。

我喜欢你映射文件长度以确定持续时间的经验方法,如果你可以提取采样率或类似的信息来进行计算,我相信你可以获得一些结果,但是如果你可以访问ffmpeg您的环境,我会亲自使用子流程来获取该信息:

const { exec } = require('child_process');

let your_webm_file = 'audiofiles/audiofile.webm';

// https://trac.ffmpeg.org/wiki/FFprobeTips#Duration
let cmd_ffprobe_duration = `ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 ${your_webm_file}`;

exec(cmd_ffprobe_duration, (error, duration, stderr) => {
  if (error || stderr)
    return console.error('Can\'t determine webm file duration');
  console.log(duration);  // 30.543000
});

对于像我这样不知道什么是ll的人。

于 2020-05-29T22:02:30.917 回答
0

这里有一个解决方案,从 Tgrif 提案开始。下面的 bash 脚本将输入的 webm 文件转换为中间/临时 wav 文件。

$ cat com/duration
#!/bin/bash

#
# calculate duration in seconds of a webm file
# converting it in a wav temporary file
#
# usage: com/duration audiofiles/audiofile.webm
#

INPUT_FILE=$1
TMP_FILE=$1.wav

ffmpeg -loglevel panic -i $INPUT_FILE -y $TMP_FILE
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $TMP_FILE
rm $TMP_FILE

用法:

$ com/duration audiofiles/audiofile.webm 
28.380000


$ time com/duration audiofiles/audiofile.webm 
28.380000

real    0m0.182s
user    0m0.151s
sys 0m0.031s

我的脚本在我看来更像是一种解决方法,但我仍然要求更好(更快)的解决方案

升级

我采用的另一种解决方案/解决方法是仅在浏览器 js 程序上使用计时器(Performance.now())测量从MediaRecorder.start()MediaRecorder.stop()

于 2020-05-30T13:08:29.587 回答