javascript - 将 Java 代码重写为 JS - 从字节创建音频?

标签 javascript java android html audio

我正在尝试将我发现用 Java 编写的一些(非常简单的)android 代码重写为静态 HTML5 应用程序(我不需要服务器来执行任何操作,我希望保持这种状态)。我有广泛的Web开发背景,但对Java有基本的了解,对Android开发的了解就​​更少了。

该应用程序的唯一功能是获取一些数字并将它们从字节转换为音频。我完全没有问题将数学逻辑翻译成 JS。我遇到麻烦的地方是实际发出声音的时候。这是原始代码的相关部分:

import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;

// later in the code:

AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STATIC);

// some math, and then:

track.write(sound, 0, sound.length); // sound is an array of bytes

我如何在 JS 中执行此操作?我可以使用 dataURI to produce the sound from the bytes ,但这是否允许我控制此处的其他信息(即采样率等)?换句话说:在 JS 中什么是最简单、最准确的方法

更新

我一直在尝试复制我在 this answer 中找到的内容.这是我的代码的相关部分:

window.onload = init;
var context;    // Audio context
var buf;        // Audio buffer

function init() {
if (!window.AudioContext) {
    if (!window.webkitAudioContext) {
        alert("Your browser does not support any AudioContext and cannot play back this audio.");
        return;
    }
        window.AudioContext = window.webkitAudioContext;
    }

    context = new AudioContext();
}

function playByteArray( bytes ) {
    var buffer = new Uint8Array( bytes.length );
    buffer.set( new Uint8Array(bytes), 0 );

    context.decodeAudioData(buffer.buffer, play);
}

function play( audioBuffer ) {
    var source    = context.createBufferSource();
    source.buffer = audioBuffer;
    source.connect( context.destination );
    source.start(0);
}

但是,当我运行它时,出现了这个错误:

Uncaught (in promise) DOMException: Unable to decode audio data

我觉得这很不寻常,因为它是一个如此普遍的错误,它设法漂亮地告诉我到底哪里出了问题。更令人惊讶的是,当我一步一步调试时,即使错误链(预期)以 context.decodeAudioData(buffer.buffer, play); 行开始,它实际上遇到了一些jQuery 文件 ( 3.2.1, uncompressed ) 中的更多行,在出错之前经过第 5208、5195、5191、5219、5223 行和最后的 5015 行。我不知道为什么 jQuery 与它有任何关系,而且错误让我不知道该尝试什么。有什么想法吗?

最佳答案

如果bytes是一个 ArrayBuffer没有必要创建 Uint8Array .你可以通过ArrayBuffer bytes作为 AudioContext.decodeAudioData() 的参数返回 Promise , 链条 .then().decodeAudioData() , 调用 play函数作为参数。

javascript在 stacksnippets,<input type="file">元素用于接受音频文件的上传,FileReader.prototype.readAsArrayBuffer()创建 ArrayBuffer来自 File对象,传递给 playByteArray .

window.onload = init;
var context; // Audio context
var buf; // Audio buffer
var reader = new FileReader(); // to create `ArrayBuffer` from `File`

function init() {
  if (!window.AudioContext) {
    if (!window.webkitAudioContext) {
      alert("Your browser does not support any AudioContext and cannot play back this audio.");
      return;
    }
    window.AudioContext = window.webkitAudioContext;
  }

  context = new AudioContext();
}

function handleFile(file) {
  console.log(file);
  reader.onload = function() {
    console.log(reader.result instanceof ArrayBuffer);
    playByteArray(reader.result); // pass `ArrayBuffer` to `playByteArray`
  }
  reader.readAsArrayBuffer(file);
};

function playByteArray(bytes) {
  context.decodeAudioData(bytes)
  .then(play)
  .catch(function(err) {
    console.error(err);
  });
}

function play(audioBuffer) {
  var source = context.createBufferSource();
  source.buffer = audioBuffer;
  source.connect(context.destination);
  source.start(0);
}
<input type="file" accepts="audio/*" onchange="handleFile(this.files[0])" />

关于javascript - 将 Java 代码重写为 JS - 从字节创建音频?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43126476/

相关文章:

javascript - 射击 focusin 和 focusout 无法正常工作

javascript - 有没有更干净的方法来切换表单验证类?

java - Mongos 限制查询速度

android - 如何在 Android 的 Twitter 集成中获取用户个人资料图片?

android - 了解退出/重新进入共享元素转换

java - 从 Activity 调用 finish()

javascript - 我如何使用以前的方法让 CSS 类显示在我的 javascript 中?

javascript - 如何将 match() 用于字符白名单?

java - 如何使用 Spring Data 从 Mongo 文档的数组字段中仅获取匹配结果

java - 英文数字的可扩展正则表达式