Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limit of the maximum audio track duration? #75

Open
alfredsgenkins opened this issue May 14, 2022 · 1 comment
Open

Limit of the maximum audio track duration? #75

alfredsgenkins opened this issue May 14, 2022 · 1 comment

Comments

@alfredsgenkins
Copy link

alfredsgenkins commented May 14, 2022

Hey!

I am trying to concatenate 2 (or more) audio files that are multiple minutes in size. TO do it, I need to load each of them to crunker. However, there is a problem: the duration of each track is limited to 17.544.

I have experimented locally, and have narrowed down the issue to decodeAudioData function, used inside of the fetchAudio function. More specifically:

const TEST_AUDIO = 'https://listen.technology/old-article-cache/ZGVsZmkvNTQzNDcyNDQ=';

(async () => {
  const buffer = await fetch(TEST_AUDIO).then(res => res.arrayBuffer());
  const blob = new Blob([buffer], { type: 'audio/mp3' });
  const url = URL.createObjectURL(blob); 
  const audio = new Audio();
  audio.src = url;
  await audio.play();
  await audio.pause();
  console.log(audio.duration); // results in 75.63525
  const audioContext = new AudioContext();
  const audioBuffer = await audioContext.decodeAudioData(buffer);
  console.log(audioBuffer.duration); // results in 17.544
})()

I did not find any information about any limits with decodeAudioData, therefore, I suspect my MP3 file might be somewhat invalid.

@alfredsgenkins
Copy link
Author

alfredsgenkins commented May 14, 2022

In my case, I was able to resolve this issue by concatenating ArrayBuffers directly:

const appendBuffer = (buffer1: ArrayBuffer, buffer2: ArrayBuffer) => {
  const tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);
  tmp.set(new Uint8Array(buffer1), 0);
  tmp.set(new Uint8Array(buffer2), buffer1.byteLength);
  return tmp.buffer;
};

const trackBuffersPromises = audioTracks.map(
  ({ audioSrc }) => fetch(audioSrc).then((response) => response.arrayBuffer())
);

const trackBuffers = await Promise.all(trackBuffersPromises);
const buffer = trackBuffers.reduce((acc, buffer) => appendBuffer(acc, buffer), new ArrayBuffer(0));

I am still curious, to why this does not work natively.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant