javascript - 如何从字节数组创建音频 wav 文件
问题描述
我正在构建一个应用程序,用户可以在其中查看成绩单以及播放音频。他可以随时选择转录的一部分并生成音频文件,可能是 wav 或 mp3,然后让他下载或保存到服务器。
我正在计算这样的字节缓冲区并发送到服务器并保存为 .wav 文件,但它没有播放任何内容:
var getMsFromSecs = function (sel) {
var from = sel.baseNode.parentElement.getAttribute('starttime').split('.');
var to = sel.focusNode.parentElement.getAttribute('endtime').split('.');
return {
from : Number(from[0]) * 1000 + Number(from[1]),
to : Number(to[0]) * 1000 + Number(to[1])
}
};
var trimAudio = function () {
var sel=window.getSelection();
if (!sel.baseNode.parentElement.getAttribute('starttime')) {
alert('Please select a text range and try again');
return;
}
$('#shareArea').val('Please Wait...');
var timesObj = getMsFromSecs(sel);
var fromTimeInMs = timesObj.from;
var toTimeInMs = timesObj.to;
var totalTimeInMs = audio.duration * 1000;
var totalBufferSize = audioBuffer.byteLength;
var bytesPerMs = totalBufferSize/totalTimeInMs;
var u8a = new Uint8Array(audioBuffer);
var selDurationBytes = u8a.subarray(bytesPerMs * fromTimeInMs, bytesPerMs * toTimeInMs);
var xhr = new XMLHttpRequest();
xhr.open('POST', './trimAudioFile');
xhr.setRequestHeader('Content-Type', 'application/octet-stream');
xhr.send(selDurationBytes);
xhr.onload = function (res) {
$('#shareArea').val(res);
}
};
和服务器端:
app.use(bodyParser.raw({type: '/trimAudioFile'}));
var body, i = 0;
router.post('/trimAudioFile', async (req, res, next) => {
if (!body) {
i = 0;
body = new Buffer(parseInt(req.headers['content-length']));
console.log('bodylength ', body.length);
}
req.on('data', function(data) {
var tempBuffer = new Buffer(data);
for (var j = 0; j < data.length; j++) {
body[i++] = tempBuffer[j];
}
});
req.on('end', function () {
fs.appendFile('test.wav', body, function() {
body = null;
res.end();
});
});
});
添加适当的元数据后更新代码:
var audioArray = new Uint8Array(audioBuffer);
var partFileLength = Math.floor((bytesPerMs * toTimeInMs) - (bytesPerMs * fromTimeInMs));
var u8a = new Uint8Array(44 + partFileLength);
for (var idx = 0, idxx = Math.floor(bytesPerMs * fromTimeInMs); idx < partFileLength + 44; idx++) {
if (idx < 44) {
if (idx > 3 && idx < 8) {
var fileSize = u8a.byteLength - 8;
u8a[idx] = (fileSize>>0)&0xFF;
u8a[idx + 1] = (fileSize>>8)&0xFF;
u8a[idx + 2] = (fileSize>>16)&0xFF;
u8a[idx + 3] = (fileSize>>24)&0xFF;
idx = idx + 4;
} else if (idx > 39 && idx < 44) {
var fileData = u8a.byteLength - 44;
u8a[idx] = (fileData>>0)&0xFF;
u8a[idx + 1] = (fileData>>8)&0xFF;
u8a[idx + 2] = (fileData>>16)&0xFF;
u8a[idx + 3] = (fileData>>24)&0xFF;
idx = idx + 4;
} else {
u8a[idx] = audioArray[idx];
}
} else {
u8a[idx] = audioArray[idxx++];
}
}
解决方案
推荐阅读
- python - 如果循环需要继续运行,如何停止 for 循环中的打印语句重复打印?
- r - R process$new 将标准输出和标准错误写入同一个文件
- python - 将配置文件加载到脚本中
- javascript - NgOnInit [Angular] 内部函数的顺序执行
- java - 如何解决这些错误和任何其他建议?
- c++ - 许多内核上令人尴尬的并行工作扩展性差
- php - TCPDF HTML 表格拉伸行高
- r - 基于R中列中的多个值组合/合并Dataframe
- sockets - 如何使用 ffi 存储 luasocket 数据?
- android - Android 给定的最终块未正确填充。如果在解密期间使用了错误的密钥,则可能会出现此类问题