是否可以合并两个音频'base64data'字符串以创建一个唯一的音频文件?



是否可以合并两个音频'base64data'字符串来创建一个唯一的音频文件?

我在字符串中有两个循环音频base64波,像这样:

data:audio/x-wav;base64,UklGRuIfQVZFZm1R7SH$WP90AhICLwKT...

我想我正在做一件非常愚蠢的事情,但我想知道这是否可能。

我试图合并两个波成一个,我可以在一个音频HTML元素中播放。我想提取秒的base64数据合并到一个,然后播放它,但导航器返回一个错误。

这是我的javascript代码:
var audio_Data1 = base64_audio1;
var audio_Data2 = base64_audio1.split(',')[1];
var audio_final = audio_Data1 + audio_Data2;
audioControl.src = audio_final;
audioControl.play();
我感谢你的建议谢谢! 编辑:

我正在尝试解码base64块来缓冲数据,并再次将缓冲区连接为base64编码。

问题:返回的base64是"AA==">

我想"AA=="是0字节。当我连接缓冲区时,我正在做一些不好的事情:

var myB64Data  = myB64WavString.split(',');
var myB64Chunk = myB64Data[1];
var myBuffer1 =  base64ToArrayBuffer(myB64Chunk);
var myBuffer2 = ""; //Same process
var myFinalBuffer = [];
myFinalBuffer.push.apply(myFinalBuffer, myBuffer1);
myFinalBuffer.push.apply(myFinalBuffer, myBuffer2); 
var myFinalB64 = 'data:audio/x-wav;base64,' + arrayBufferToBase64(myFinalBuffer); 
console.log( myFinalB64 );

它由控制台返回下一个:"data:audio/x-wav;base64,AA==">

我的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.buffer;
}
function arrayBufferToBase64( buffer ) {
var binary = '';
var bytes = new Uint8Array( buffer );
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode( bytes[ i ] );
}
return window.btoa( binary );
}

我解决了!(两天后的艰苦和疯狂的工作,并通过复制答案从转换AudioBuffer到ArrayBuffer/Blob WAV下载)我希望它能帮助您节省我为此开发的所有工作;)

var myB64Data  = myB64WavString.split(',');
var myB64Chunk = myB64Data[1];
var myBuffer1 =  base64ToArrayBuffer(myB64Chunk);
var myBuffer2 = ""; //Same process
var myFinalBuffer = appendBuffer (myBuffer1, myBuffer2);
var myFinalBuffer = getWavBytes( arrBytesFinal, {
isFloat: false,       // floating point or 16-bit integer
numChannels: 2,     //1 for mono recordings
sampleRate: 48000, //Depends on your file audio bitrate !! 32000
})              

var myFinalB64 = 'data:audio/x-wav;base64,' + arrayBufferToBase64(myFinalBuffer); 
console.log( myFinalB64 );
//Then you can asign to an audio HTML control
myAudioControl.src = myFinalB64;

附加功能:

function appendBuffer(buffer1, buffer2) {
var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);
tmp.set(new Uint8Array(buffer1), 0);
tmp.set(new Uint8Array(buffer2), buffer1.byteLength);
return tmp;
};

function getWavBytes(buffer, options) {
const type = options.isFloat ? Float32Array : Uint16Array
const numFrames = buffer.byteLength / type.BYTES_PER_ELEMENT
const headerBytes = getWavHeader(Object.assign({}, options, { numFrames }))
const wavBytes = new Uint8Array(headerBytes.length + buffer.byteLength);
// prepend header, then add pcmBytes
wavBytes.set(headerBytes, 0)
wavBytes.set(new Uint8Array(buffer), headerBytes.length)
return wavBytes
}
// adapted from https://gist.github.com/also/900023
// returns Uint8Array of WAV header bytes
function getWavHeader(options) {
const numFrames =      options.numFrames
const numChannels =    options.numChannels || 2
const sampleRate =     options.sampleRate || 44100
const bytesPerSample = options.isFloat? 4 : 2
const format =         options.isFloat? 3 : 1
const blockAlign = numChannels * bytesPerSample
const byteRate = sampleRate * blockAlign
const dataSize = numFrames * blockAlign
const buffer = new ArrayBuffer(44)
const dv = new DataView(buffer)
let p = 0
function writeString(s) {
for (let i = 0; i < s.length; i++) {
dv.setUint8(p + i, s.charCodeAt(i))
}
p += s.length
}
function writeUint32(d) {
dv.setUint32(p, d, true)
p += 4
}
function writeUint16(d) {
dv.setUint16(p, d, true)
p += 2
}
writeString('RIFF')              // ChunkID
writeUint32(dataSize + 36)       // ChunkSize
writeString('WAVE')              // Format
writeString('fmt ')              // Subchunk1ID
writeUint32(16)                  // Subchunk1Size
writeUint16(format)              // AudioFormat
writeUint16(numChannels)         // NumChannels
writeUint32(sampleRate)          // SampleRate
writeUint32(byteRate)            // ByteRate
writeUint16(blockAlign)          // BlockAlign
writeUint16(bytesPerSample * 8)  // BitsPerSample
writeString('data')              // Subchunk2ID
writeUint32(dataSize)            // Subchunk2Size
return new Uint8Array(buffer)
}

详细说明上面的答案,下面是如何处理一个由编码字符串组成的数组,而不仅仅是两个字符串。

function joinBuffers(buffers) {
const byteLength = buffers
.map((buffer) => buffer.byteLength)
.reduce((prev, curr) => prev + curr);
var tmp = new Uint8Array(byteLength);
var length = 0;
for (let i = 0; i < buffers.length; i++) {
const buffer = buffers[i];
tmp.set(new Uint8Array(buffer), length);
length += buffer.byteLength;
}
return tmp;
}

上面的答案对我不起作用,但是这个简单的答案起作用了:

只需解码每个B64字符串

// Decode the String
var decodedString0 = atob(encodedString0);
var decodedString1 = atob(encodedString1);

将它们合并在一起,然后再进行编码,

var decodedStringMerge = decodedString0 + decodedString1 
var ecodedStringMergeB64 = btoa(decodedStringMerge)
console.log(ecodedStringMergeB64);

播放合并后的音频…

最新更新