Как воспроизводить аудио с URL-адреса по частям (потоковое) с помощью Javascript

#javascript #reactjs #audio

#javascript #reactjs #Аудио

Вопрос:

У меня есть URL, который извлекает музыкальный файл из корзины AWS S3.

для начала воспроизведения песни требуется около 10-15 секунд, потому что она сначала извлекается перед воспроизведением.

Я хочу иметь возможность извлекать песню по частям и воспроизводить их в аудиоплеере html5.

Таким образом, как только пользователь воспроизводит песню, она начинает потоковое воспроизведение, пока извлекается другая песня.

 import React, { useEffect } from 'react';
import Waveform from './Waveform';

const appendBuffer = (buffer1, buffer2, context) => {
  const numberOfChannels = Math.min(
    buffer1.numberOfChannels,
    buffer2.numberOfChannels
  );
  const tmp = context.createBuffer(
    numberOfChannels,
    buffer1.length   buffer2.length,
    buffer1.sampleRate
  );
  for (let i = 0; i < numberOfChannels; i  ) {
    const channel = tmp.getChannelData(i);
    channel.set(buffer1.getChannelData(i), 0);
    channel.set(buffer2.getChannelData(i), buffer1.length);
  }
  return tmp;
};
const Player = ({ selectedTrack }) => {
  // const [blob, setBlob] = useState();

  const getData = async (selectedTrack) => {
    const fetchedData = await fetch(selectedTrack);
    const reader = await fetchedData.body.getReader();
    const context = new AudioContext();
    reader.read().then(async function processAudio({ done, value }) {
      if (done) {
        console.log('Stream finished. Content received:');
        return;
      }
      try {
        console.log('processAudio -> value', value.buffer);
        const buffer = await context.decodeAudioData(value.buffer);

        const source = context.createBufferSource();
        const newaudioBuffer =
          source amp;amp; source.buffer
            ? appendBuffer(source.buffer, buffer, context)
            : buffer;
        source.buffer = newaudioBuffer;
        source.connect(context.destination);
        source.start(source.buffer.duration);
        console.log(
          'processAudio -> source.buffer.duration',
          source.buffer.duration
        );
      } catch (error) {
        console.log('processAudio -> error', error);
      }
      return reader.read().then(processAudio);
    });
  };

  useEffect(() => {
    getData(selectedTrack);
  }, [selectedTrack]);

  return (
    <div className="player">
      <Waveform url={selectedTrack} />
      <br />
    </div>
  );
};

export default Player;
  

то, что у меня есть сейчас, получает код по частям, но воспроизводится так быстро, и нет способа заставить его воспроизводиться один за другим

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

1. Звучит круто. Что вы пытались создать для этого. Не могли бы вы показать нам соответствующий код и попытку?

2. это сделано @EmielZuurbier