简体   繁体   English

使用 Javascript AudioContext 将预加载的音频文件合并为一个

[英]Concatenating preloaded audio files into one using Javascript AudioContext

I have an array of preloaded base64 encoded audio files, such as the two found in the javascript object below ("hello" and "world").我有一组预加载的 base64 编码音频文件,例如在下面的 javascript object 中找到的两个(“hello”和“world”)。 I wish to concatenate both audio and add a 1 second space between them.我希望连接两个音频并在它们之间添加 1 秒的空间。 I think the output should be an ArrayBuffer, or something that I can then use to either concatenate more audio, or export / play as desired.我认为 output 应该是一个 ArrayBuffer,或者我可以用来连接更多音频或根据需要导出/播放的东西。

NB: I do not wish to play them with a 1 second delay (ie I am aware of how to independently load the first file, play it, timeout for a second, and then load and play the second file. I attempt this, rather poorly, in the code for Just Play. But this is not what I am looking for since I want to construct a combined audio file with both samples separated by a one second interval).注意:我希望以 1 秒的延迟播放它们(即我知道如何独立加载第一个文件,播放它,超时一秒钟,然后加载并播放第二个文件。我尝试这样做,而不是糟糕的是,在 Just Play 的代码中。但这不是我想要的,因为我想构建一个组合音频文件,其中两个样本间隔一秒)。

To complete this answer, what would be the best way to generalize this concept when providing an array of multiple short audio bits (such as a sentence) which should be concatenated together?为了完成这个答案,当提供一个应该连接在一起的多个短音频位(例如一个句子)的数组时,概括这个概念的最佳方法是什么? I feel that recursive calls is tempting but I am unsure of what the impact would be memory-wise?我觉得递归调用很诱人,但我不确定内存方面的影响是什么?

I have tried so many things to get this to work, it's hard to say where I started and where I'm at right now... But I guess the closest post I've found is this one: Download File from Bytes in JavaScript我已经尝试了很多事情来让它工作,很难说我从哪里开始以及我现在在哪里......但我想我找到的最接近的帖子是这个: 从 JavaScript 中的字节下载文件

I am also somewhat confused as to why some snippets use UInt8Arrays while others use Float32s or Int16s... The below code "works" to listen to the code.对于为什么有些片段使用 UInt8Arrays 而其他片段使用 Float32s 或 Int16s,我也有些困惑……下面的代码“工作”来收听代码。 On Chrome, it also plays "hello" for the concatenated version, but not on Firefox.在 Chrome 上,它还为串联版本播放“hello”,但在 Firefox 上不播放。 Either way, it does not play "hello [1s] world":(无论哪种方式,它都不会播放“hello [1s] world”:(

 const sampleRate = 48000; const ctx = new (window.AudioContext || window.webkitAudioContext)( {"sampleRate": sampleRate} ); function concatAudio( buffer1, pause, buffer2 ) { let silenceLength = pause*sampleRate; let a = new Uint8Array( buffer1.length + silenceLength + buffer2.length ); for( let i=0; i<buffer1.length; i++ ) a[i]=buffer1[i]; for( let i=0; i<silenceLength; i++ ) a[buffer1.length+i]=0; for( let i=0; i<buffer2.length; i++ ) a[buffer1.length+silenceLength+i]=buffer2[i]; return a.buffer; } function concatAndPlay() { let concatenatedBuffer = concatAudio( base64ToArrayBuffer( ogg48k.hello ), 1000, base64ToArrayBuffer( ogg48k.world ) ); ctx.decodeAudioData( concatenatedBuffer ).then( function( decodedData ) { // following code copied from: https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode var source = ctx.createBufferSource(); // set the buffer in the AudioBufferSourceNode source.buffer = decodedData; // connect the AudioBufferSourceNode to the // destination so we can hear the sound source.connect(ctx.destination); // start the source playing source.start(); }); } function justListen() { var hello = base64ToArrayBuffer( ogg48k.hello ); console.log(hello.length); // I was hoping to use this for the sample duration, but somehow length/sampleRate is way lower than the duration... var d = playByteArray( hello ); setTimeout( function(){playByteArray( base64ToArrayBuffer( ogg48k.world ) )}, 1000+800 ); // this is imperfect since I would need to retrieve the duration of the first audio, instead of manually inputing 800ms } // following code copied from: https://stackoverflow.com/questions/35038884/download-file-from-bytes-in-javascript function base64ToArrayBuffer(base64) { var binary_string = window.atob(base64); var len = binary_string.length; var bytes = new Uint8Array(len); for (var i = 0; i < len; i++) { bytes[i] = binary_string.charCodeAt(i); } return bytes; } // following code copied from: https://stackoverflow.com/questions/24151121/how-to-play-wav-audio-byte-array-via-javascript-html5 function playByteArray( bytes ) { var buffer = new Uint8Array( bytes.length ); buffer.set( new Uint8Array(bytes), 0 ); ctx.decodeAudioData(buffer.buffer, play); } function play( audioBuffer ) { var source = ctx.createBufferSource(); source.buffer = audioBuffer; source.connect( ctx.destination ); source.start(0); } const ogg48k = { "hello": "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", "world": "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", };
 <,DOCTYPE html> <html> <body> <button onclick="concatAndPlay()">Concatenate and Play</button> (does not work)<br> <button onclick="justListen()">just listen</button>("works", sort of, but not what I want)<br> </body> </html>

So I was able to adapt code from an answer which repeats a piece of audio and it seems to work.因此,我能够从重复一段音频的答案中调整代码并且它似乎有效。 Here is the answer which helped: Web Audio API append/concatenate different AudioBuffers and play them as one song这是有帮助的答案: Web 音频 API 附加/连接不同的音频缓冲区并将它们作为一首歌曲播放

And below is a snippet which "solves" my problem, though I am still a bit unsure why it works with respect to the conversion to UInt8 rather than Int16 or Float32.下面是一个“解决”我的问题的片段,尽管我仍然有点不确定为什么它在转换为 UInt8 而不是 Int16 或 Float32 方面起作用。

If this ends up being the "best" (or "only") answer here I'll accept my own answer to help others down the line, but to my eyes this answer is still incomplete:如果这最终成为这里的“最佳”(或“唯一”)答案,我将接受我自己的答案以帮助其他人,但在我看来,这个答案仍然不完整:

  1. It does not offer guidance as to how to generalize with an array of "arbitrary" length, say about 20, small audio snippets (given that the total audio duration should stay within 3 minutes or so).它没有提供关于如何用“任意”长度的数组进行概括的指导,比如大约 20 个小音频片段(假设总音频持续时间应保持在 3 分钟左右)。 Especially with respect to memory management (eg is recursivity a good option)?特别是关于 memory 管理(例如递归是一个不错的选择)?
  2. I am wary of what may happen if two audio files do not have the same number of channels (ie one is mono and one is stereo), and/or if they do not use the same sampling rates... I will try to see what happens in these cases by trial and error...我很担心如果两个音频文件没有相同数量的通道(即一个是 mono,一个是立体声)和/或如果它们不使用相同的采样率会发生什么......我会试着看看通过反复试验在这些情况下会发生什么......

 const sampleRate = 48000; const ctx = new (window.AudioContext || window.webkitAudioContext)( {"sampleRate": sampleRate} ); function concatAndPlay() { b1 = base64ToArrayBuffer( ogg48k.hello ).buffer; b2 = base64ToArrayBuffer( ogg48k.world ).buffer; ctx.decodeAudioData(b1, x=> ctx.decodeAudioData(b2, y=> { var audioSource = ctx.createBufferSource(); audioSource.connect(ctx.destination); // Concatenate the two buffers into one. audioSource.buffer = appendBuffer(x, 1, y); audioSource.connect( ctx.destination ); audioSource.start(0); } ) ); // following code adapted from: https://stackoverflow.com/questions/14143652/web-audio-api-append-concatenate-different-audiobuffers-and-play-them-as-one-son function appendBuffer(buffer1, pause, buffer2) { var numberOfChannels = Math.min( buffer1.numberOfChannels, buffer2.numberOfChannels ); var tmp = ctx.createBuffer( numberOfChannels, (buffer1.length + buffer2.length + pause*buffer1.sampleRate), buffer1.sampleRate ); for (var i=0; i<numberOfChannels; i++) { var channel = tmp.getChannelData(i); channel.set( buffer1.getChannelData(i), 0); channel.set( buffer2.getChannelData(i), buffer1.length+pause*buffer1.sampleRate); } return tmp; } } function justListen() { var hello = base64ToArrayBuffer( ogg48k.hello ); console.log(hello.length); // I was hoping to use this for the sample duration, but somehow length/sampleRate is way lower than the duration... var d = playByteArray( hello ); setTimeout( function(){playByteArray( base64ToArrayBuffer( ogg48k.world ) )}, 1000+800 ); // this is imperfect since I would need to retrieve the duration of the first audio, instead of manually inputing 800ms } // following code copied from: https://stackoverflow.com/questions/35038884/download-file-from-bytes-in-javascript function base64ToArrayBuffer(base64) { var binary_string = window.atob(base64); var len = binary_string.length; var bytes = new Uint8Array(len); for (var i = 0; i < len; i++) { bytes[i] = binary_string.charCodeAt(i); } return bytes; } // following code copied from: https://stackoverflow.com/questions/24151121/how-to-play-wav-audio-byte-array-via-javascript-html5 function playByteArray( bytes ) { var buffer = new Uint8Array( bytes.length ); buffer.set( new Uint8Array(bytes), 0 ); ctx.decodeAudioData(buffer.buffer, play); } function play( audioBuffer ) { var source = ctx.createBufferSource(); source.buffer = audioBuffer; source.connect( ctx.destination ); source.start(0); } const ogg48k = { "hello": "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", "world": "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", };
 <,DOCTYPE html> <html> <body> <button onclick="concatAndPlay()">Concatenate and Play</button> (now works)<br> <button onclick="justListen()">just listen</button>("works", sort of, though I cannot get the correct spacing programatically)<br> </body> </html>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM