我正在尝试将我用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
Run Code Online (Sandbox Code Playgroud)
我怎么在JS中这样做?我可以使用dataURI从字节中产生声音,但这是否允许我在这里控制其他信息(即采样率等)?换句话说:在JS中执行此操作的最简单,最准确的方法是什么?
更新
我一直试图复制我在这个答案中找到的东西.这是我的代码的相关部分:
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 …Run Code Online (Sandbox Code Playgroud) 背景
我正在编写一个服务来以块的形式提供静态音频文件,以支持带宽较低的用户的流畅体验。一旦文件完全流式传输(块序列是线性的,用户将无法“跳转”范围),我想将文件保存到本地缓存中(使用 localforage,但这不是这个问题的一部分)到稍后从那里加载缓存文件并节省带宽。
问题
根据我目前的知识/代码/工具状态,只能执行以下操作之一:
A) 使用HTMLAudioElement流式传输音频
const audio = new Audio()
audio.src = url
audio.preload = 'auto'
audio.load()
Run Code Online (Sandbox Code Playgroud)
HTML5 音频在内部处理部分响应,本身工作正常,但一旦完全加载,我就无法访问底层缓冲区来保存文件。因此,如果不单独下载(在另一个请求中),我将无法在本地缓存文件。
B) 下载/获取整个文件,然后播放
fetch(url, options) // set content header to array buffer
.then((response) => {
var blob = new Blob([response.value], { type: 'audio/mp3' })
var url = window.URL.createObjectURL(blob)
const audio = new Audio()
audio.src = url
audio.play()
})
Run Code Online (Sandbox Code Playgroud)
这使我可以访问数据,以便我可以缓存它以供离线重用。但是我放弃了流媒体选项,这使得几乎不可能在没有长时间等待的情况下播放更大的文件。
C) 使用自定义加载器并使用 WebAudio API 播放每个块
由于 A 和 B 不够用,我编写了一个自定义 loader,它加载块(工作正常),并使用当前块(作为 ArrayBuffer)作为数据分派事件。它还在结束时调度另一个事件,该事件返回所有块,因此我可以从中创建一个 blob:
const chunkSize …Run Code Online (Sandbox Code Playgroud)