Скачать аудиофрагмент с помощью XHR

#javascript #xmlhttprequest #web-audio-api

Вопрос:

Я хотел бы загрузить фрагменты больших аудиофайлов и обработать их для визуализации звука (с помощью API Webaudio). Я хотел бы использовать XHR для загрузки этих фрагментов.

Давайте возьмем https://traffic.megaphone.fm/MERE7176906291.mp3?updated=1632752564 в качестве примера. Допустим, я хочу получить фрагмент #t=300,330 (начиная с полуминутного фрагмента 5:00 ). Мне нужно было бы установить заголовок Range: range_from-range_to в запросе XHR. Как мне вычислить начальное и конечное смещение байтов?

Просмотр ffprobe выходных данных для получения выборки и скорости передачи данных:

 $ ffprobe MERE7176906291.mp3?updated=1632752564 
ffprobe version 4.3.2-0 deb11u1ubuntu1 Copyright (c) 2007-2021 the FFmpeg developers
  built with gcc 10 (Ubuntu 10.2.1-20ubuntu1)
  configuration: --prefix=/usr --extra-version=0 deb11u1ubuntu1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-pocketsphinx --enable-libmfx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
[mp3 @ 0x559e92dc3b40] Skipping 1 bytes of junk at 38361.
[mp3 @ 0x559e92dc3b40] Estimating duration from bitrate, this may be inaccurate
Input #0, mp3, from 'MERE7176906291.mp3?updated=1632752564':
  Metadata:
    title           :  Miranda Kerr on Motherhood, Her Modern Family, and Why She Proudly Calls Herself a “Turtle”
    lyrics-ENG      : <p>Model and Kora Organics founder Miranda Kerr dishes on the art of a cheeky wink, her award-winning skincare line, and how she fell in love with Katy Perry.</p>
    album           : Ladies First with Laura Brown
    genre           : Podcast
    date            : 2020
  Duration: 00:35:04.69, start: 0.000000, bitrate: 128 kb/s
    Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 128 kb/s
    Stream #0:1: Video: mjpeg (Progressive), yuvj420p(pc, bt470bg/unknown/unknown), 500x500 [SAR 72:72 DAR 1:1], 90k tbr, 90k tbn, 90k tbc (attached pic)
    Metadata:
      title           : image
      comment         : Other
 

Например, я вижу ссылку на отметку 7:40 времени в своем браузере, и я отправляю запрос на вкладке «Сеть» инструментов разработки с заголовком Range: bytes=4816896- . В ответе я вижу заголовок Content-Range: bytes 4816896-33713332/33713333 .

У меня есть несколько вопросов:

  1. Как рассчитать смещение в байтах?
  2. Зависит ли это от аудиоформата, поскольку форматы mp3, flac и т.д. Сжимают данные?

Комментарии:

1. Да, это зависит от формата аудио. Для формата OGG вам потребуется загрузить заголовок (первые байты файла), декодировать индексы ключевых кадров, преобразовать в временные интервалы и умножить, чтобы получить смещение в байтах. Я мало что знаю о других форматах. Я бы рекомендовал другой подход, если только вы не планируете делать это как длительный исследовательский проект.

2. Спасибо @MichaelG. Очевидно, что браузер способен это сделать, разве для этого не существует какой-либо библиотеки с открытым исходным кодом с широким спектром поддержки различных аудиоформатов? В конце концов, такие браузеры, как Chromium, имеют открытый исходный код. Я попытался загрузить фрагмент с fetch помощью API с #t=start,end помощью фрагмента, но безрезультатно. Он загружает весь mp3-файл целиком.

3. На данный момент поддержка браузера ограничена видео, поэтому, к сожалению, она не будет работать для mp3. Реализовать это сложно даже для инженерных команд Google и Mozilla. Я не уверен, что библиотеке с открытым исходным кодом будет разрешено декодировать собственный формат, но если вы сможете его найти, возможно, удастся скомпилировать в WASM и импортировать его в свой проект JS.

4. Эй, @MichaelG, не могли бы вы, пожалуйста, уточнить, что поддержка ограничивается только видео? Очевидно, что я могу искать случайные местоположения аудио в браузере (FF, Chrome, Edge) для различных форматов. То есть поддержка фрагментов мультимедиа для аудио, по-видимому, существует во всех современных браузерах. Итак, не могли бы вы, пожалуйста, пояснить, почему вы сказали, что поддержка ограничена только видео? Спасибо!

5. Это примечание от caniuse: «Похоже,что поддерживается только элемент управления #t=n, n для выбора диапазона видео и, возможно, трек=(имя) и идентификатор=(имя) (еще не протестировано)». Пожалуйста, обратите внимание, что вы специально спрашивали о вычислении смещений байтов, а не об использовании API медиа-фрагментов. Я не буду публиковать ответ, потому что не могу помочь вам рассчитать смещения байтов, но, пожалуйста, не удивляйтесь, если этого не сделает никто другой. (Это очень трудно.) Вероятно, лучше перефразировать свой вопрос, чем продолжать эти длинные комментарии.