mirror of
https://github.com/element-hq/element-web.git
synced 2024-12-05 05:38:41 +03:00
79 lines
2.9 KiB
TypeScript
79 lines
2.9 KiB
TypeScript
|
/*
|
||
|
Copyright 2021 The Matrix.org Foundation C.I.C.
|
||
|
|
||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
you may not use this file except in compliance with the License.
|
||
|
You may obtain a copy of the License at
|
||
|
|
||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
||
|
Unless required by applicable law or agreed to in writing, software
|
||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
See the License for the specific language governing permissions and
|
||
|
limitations under the License.
|
||
|
*/
|
||
|
|
||
|
import wavEncoderPath from 'opus-recorder/dist/waveWorker.min.js';
|
||
|
import decoderPath from 'opus-recorder/dist/decoderWorker.min.js';
|
||
|
import {SAMPLE_RATE} from "./VoiceRecording";
|
||
|
// @ts-ignore - we know that this is not a module. We're looking for a path.
|
||
|
import decoderWasmPath from 'opus-recorder/dist/decoderWorker.min.wasm';
|
||
|
|
||
|
export function createAudioContext(opts?: AudioContextOptions): AudioContext {
|
||
|
if (window.AudioContext) {
|
||
|
return new AudioContext(opts);
|
||
|
} else if (window.webkitAudioContext) {
|
||
|
return new window.webkitAudioContext(opts);
|
||
|
} else {
|
||
|
throw new Error("Unsupported browser");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
export function decodeOgg(audioBuffer: ArrayBuffer): Promise<ArrayBuffer> {
|
||
|
// Condensed version of decoder example, using a promise:
|
||
|
// https://github.com/chris-rudmin/opus-recorder/blob/master/example/decoder.html
|
||
|
return new Promise((resolve) => { // no reject because the workers don't seem to have a fail path
|
||
|
console.log("Decoder WASM path: " + decoderWasmPath); // so we use the variable (avoid tree shake)
|
||
|
const typedArray = new Uint8Array(audioBuffer);
|
||
|
const decoderWorker = new Worker(decoderPath);
|
||
|
const wavWorker = new Worker(wavEncoderPath);
|
||
|
|
||
|
decoderWorker.postMessage({
|
||
|
command: 'init',
|
||
|
decoderSampleRate: SAMPLE_RATE,
|
||
|
outputBufferSampleRate: SAMPLE_RATE,
|
||
|
});
|
||
|
|
||
|
wavWorker.postMessage({
|
||
|
command: 'init',
|
||
|
wavBitDepth: 24, // standard for 48khz (SAMPLE_RATE)
|
||
|
wavSampleRate: SAMPLE_RATE,
|
||
|
});
|
||
|
|
||
|
decoderWorker.onmessage = (ev) => {
|
||
|
if (ev.data === null) { // null == done
|
||
|
wavWorker.postMessage({command: 'done'});
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
wavWorker.postMessage({
|
||
|
command: 'encode',
|
||
|
buffers: ev.data,
|
||
|
}, ev.data.map(b => b.buffer));
|
||
|
};
|
||
|
|
||
|
wavWorker.onmessage = (ev) => {
|
||
|
if (ev.data.message === 'page') {
|
||
|
// The encoding comes through as a single page
|
||
|
resolve(new Blob([ev.data.page], {type: "audio/wav"}).arrayBuffer());
|
||
|
}
|
||
|
};
|
||
|
|
||
|
decoderWorker.postMessage({
|
||
|
command: 'decode',
|
||
|
pages: typedArray,
|
||
|
}, [typedArray.buffer]);
|
||
|
});
|
||
|
}
|