Как создать аудио WAV-файл из байтового массива - PullRequest
0 голосов
/ 31 января 2019

Я создаю приложение, в котором пользователь может просматривать стенограмму и воспроизводить аудио.И в любое время он может выбрать часть транскрипции и сгенерировать аудиофайл, возможно, 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++];
  }
}
...