Как узнать продолжительность аудиофайла webm (opus) в секундах (в программе js)? - PullRequest
0 голосов
/ 29 мая 2020

На веб-странице 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

Использование vl c player, я вижу, что продолжительность в секундах составляет почти 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.

Плохое / грубое решение во время выполнения может заключаться в эмпирическом сопоставлении длины файла в байтах с длиной в секундах ... Например, для спецификаций c кодировка / формат: 1000 байтов ~ = 1 se c.

Есть ли лучшая идея измерить продолжительность аудиофайла, возможно, в коде nodejs?

Ответы [ 2 ]

0 голосов
/ 30 мая 2020

Вот решение, исходя из предложения 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()

0 голосов
/ 30 мая 2020

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 .

...