Можете ли вы подключить AudioContext / Analyzer к HTML аудио узлу с уже загруженным sr c? - PullRequest
0 голосов
/ 06 апреля 2020

У меня есть базовый c HTML audio sr c, и я просто пытаюсь подключить узел анализатора к его выходу, чтобы показать визуализатор при воспроизведении файла. Любые идеи?

Когда я пытаюсь отобразить узел, я также заикаюсь. Когда я делаю AudioContext и присоединяю его к источнику, я не получаю вывод. Я уверен, что я просто маршрутизирую / делаю это неправильно. Любая помощь? Заранее спасибо!

js:

$(document).ready(function()
{

  const audio = document.getElementById("audio");
  const audioCtx = new AudioContext();
  const canvas = document.getElementById("canvas");
  const canvasCtx = canvas.getContext("2d");
  const co = "https://cors-anywhere.herokuapp.com/";
  const audioSrc = "https://pineprojectmusic.s3-us-west-2.amazonaws.com/StreamingSongs/Radio.mp3";
  var track;
  
  // Fetch mp3
  
  
  audio.addEventListener("play", function() 
  {
    // Circumvent Chrome autoplay AudioContext issues
    if (audioCtx.state === "suspended")
      {
        audioCtx.resume()
      };
    
    // Where we add connect all of the analyser stuff
    // track = audioCtx.createMediaElementSource(audio);
    // track.connect(audioCtx.destination);
    
    if (this.dataset.playing === "false")
    {
        alert("Playing");
        audio.play();
      this.dataset.playing = true;
    } else if (this.dataset.playing === "false")
    {
      alert("Stopped");
      audio.pause();
      this.dataset.playing = true;
    }
    
  }, false);
  
  function setUpContext()
  {
    if (typeof audioCtx != 'undefined')
      {
        audioCtx.resume();
      }
  }
  // var source = ctx.createMediaElementSource(audio);
  

  


  
  // Where we fetch the mp3 file from S3 Bucket
  
  /*
  fetch(co + audioSrc)
    .then(response => response.arrayBuffer())
    .then(data => loadSong(data)); */

function loadSong(data)
{
  console.log(data);
  // This is where we assign the arrayBuffer into a stream and the src of the file.
  data.decodeAudioData(data);
  var mediaSrc = new MediaSource();
  var mediaBuffer = mediaSrc.createMediaElementSource(decodedAudio);
  audio.src.connect(analyser);
};
  
}); // end of DOM event
#audio:focus {
  outline: none;
}

#thefile {
  position: fixed;
  top: 10px;
  left: 10px;
  z-index: 100;
}

#canvas {
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}

audio {
  position: fixed;
  left: 10px;
  bottom: 10px;
  width: calc(100% - 20px);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="content">
  <canvas id="canvas"></canvas>
  <audio id="audio" controls controlsList="nodownload" src="https://pineprojectmusic.s3-us-west-2.amazonaws.com/StreamingSongs/Radio.mp3">
  </audio>
</div>

Ответы [ 2 ]

0 голосов
/ 08 апреля 2020

Было обнаружено две проблемы, которые решили ее для меня:

  1. Я забыл добавить запись <AllowedHeader> в мою политику S3 CORS (сумасшедший).
  2. Из-за Новые функции автозапуска в веб-браузерах: вам нужно создать новый экземпляр AudioConext после взаимодействия с пользователем (я поместил свой в прослушиватель событий play для тега audio).

Звук сейчас проходит, и мы, кажется, отправляемся в гонки! Надеюсь, это поможет кому-то в будущем! :)

Код (чтобы в будущем помочь кому-то в той же лодке):

// Declare variables
const url = "https://pineprojectmusic.s3-us-west-2.amazonaws.com/StreamingSongs/Radio.mp3";
var AudioContext = (window.AudioContext || window.webkitAudioContext);
// if (audioCtx) { audioCtx = new (audioCtx) };
var source, analyser, ctx;

// Housekeeping when DOM loads
document.addEventListener("DOMContentLoaded", function () 
{
    // Make Audio File
    const audio = new Audio();
    audio.id = "audio";
    audio.src = url;
    audio.controls = true;
    audio.controlsList = "nodownload";
    audio.crossOrigin = "anonymous";
    audio.autoload = "auto";

    // Create Canvas
    const canvas = document.createElement("CANVAS");
    canvas.id = "canvas";
    canvasCtx = canvas.getContext("2d");

    // Insert it into HTML
    document.getElementById("audio_container").appendChild(audio);
    document.getElementById("audio_container").appendChild(canvas);

    audio.addEventListener("play", playAudio);

    function playAudio()
    {
        // Set up routes
        const audioCtx = new(AudioContext);
        if (!analyser) 
        { 
            analyser = audioCtx.createAnalyser();
            analyser.fftSize = 256;
        };
        if (!source) 
        { 
            source = audioCtx.createMediaElementSource(audio);
            source.connect(audioCtx.destination);
        };
        audioAnalyser();
    };
0 голосов
/ 08 апреля 2020

Выглядит как неправильная маршрутизация.

Спецификация c описала Модульную маршрутизацию topi c хорошо.
Итак, ключевой момент:

В AudioContext сигнал идет от источника к месту назначения, необязательно через другие audioNodes.
Следовательно, мы должны соединить их в правильном порядке:

Источник -> Анализатор -> Пункт назначения

См. Пример ниже:

const audioCtx = new(window.AudioContext || window.webkitAudioContext)();

// Get the source
const audio = document.querySelector('audio');
audio.onplay = () => audioCtx.resume();
const source = audioCtx.createMediaElementSource(audio);

// Create an analyser
const analyser = audioCtx.createAnalyser();
analyser.fftSize = 2 ** 8;
const bufferLength = analyser.frequencyBinCount;
const dataArray = new Uint8Array(bufferLength);

// Connect parts
source.connect(analyser);
analyser.connect(audioCtx.destination);

// Visualisation
const section = document.querySelector('section');
const v = (new Array(bufferLength)).fill().map(e => (e = document.createElement('i')) && section.appendChild(e) && e);

setInterval(() => {
  analyser.getByteTimeDomainData(dataArray);
  dataArray.forEach((d, i) => v[i].style.setProperty('--c', Math.abs(128 - d) * 2.8125 | 0))
}, 15);
html,
body {
  width: 100vw;
  height: 100vh;
  margin: 0;
  padding: 0;
  background: #000
}

section {
  display: flex;
  align-items: center;
  height: 100vh
}

section i {
  flex: 1 1 100%;
  height: calc(100vh * var(--c)/360);
  border-radius: 55%;
  background: hsl(var(--c), 95%, 45%);
}

audio {
  position: fixed;
  width: calc(100% - 2em);
  bottom: 1em;
  left: 1em;
  opacity: .3
}
<section></section>
<audio controls src="https://ice3.somafm.com/defcon-128-mp3" crossorigin="anonymous">

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...