Comments (12)
This might not be very helpful. This takes a OGG blob and converts it into audio buffers:
var worker = new Worker('./oggopusDecoder.js')
worker.postMessage(recorder.config); // uses same config as for recording
worker.addEventListener("error", function(e) {
console.log(e);
});
worker.addEventListener("message", function(e) {
console.log(e.data);
});
///
var reader = new FileReader();
reader.onload = function(event) {
worker.postMessage({
command: "decode",
pages: new Uint8Array(this.result)
});
};
reader.readAsArrayBuffer(blob);
from opus-recorder.
Thanks for the snippet. I have started an example in a seperate repo, but it's not complete.
from opus-recorder.
@super-coder I've removed comments unrelated to this issue. Please open a new issue if you have an issue or questions about the lib.
from opus-recorder.
Hi,
Would it be possible to outline how to go from encoded blob to playing back via a AudioContext destination? I would like to connect to a gain node and playback through there.
I have tried getting this example working as well as the other repo. I see the output from the decoder is a Float32Array is returned, what is the next step to get this actually playing though?
Thank you
from opus-recorder.
@brancusi: The decoder returns an array of buffers (one for each channel)
- Configure the decoder to decode at your context sample rate using config option
{ outputBufferSampleRate : audioContext.sampleRate }
- Store each buffer as it is decoded (it will send a message with
null
payload when it is finished) - Create an audioContext buffer with appropriate length (number of decoded buffers * decoded buffer length)
- Fill audioContext buffer with decoded data
- Playback audioContext buffer
- Sample code at MDN
from opus-recorder.
Thanks @chris-rudmin, got it working!
This returns a promise and resolves with a source that can be started. A little lengthy but works for now. Does anything pop out at you as being a potential problem?
Thanks again for the great library!
/**
* Create a buffer source from an ogg blob
* @param {Blob} The ogg blob created by recorderjs
* @param {AudioContext} An instance of an AudioContext to create the bufferSource with
* @param {Integer} Numbers of channels, defaults to 2
* @returns {Promise} A promise that will resolve with an AudioBufferSourceNode prefilled with the ogg blob data, ready for playback
*/
createBufferSource ( blob, audioContext, channels = 2 ) {
return new Promise((res, rej) => {
const decoder = new OpusDecoderWorker();
const buffers = [];
const config = {
outputBufferSampleRate : audioContext.sampleRate,
bufferLength : 4096
}
decoder.onmessage = e => {
if (e.data === null) {
var frameCount = buffers.length * config.bufferLength;
var audioBuffer = audioContext.createBuffer(channels, frameCount, audioContext.sampleRate);
// Fill the channel data
for (let channel = 0; channel < channels; channel++) {
var channgelBuffer = audioBuffer.getChannelData(channel);
buffers
.map((buffer, i) => {
(buffer[channel] || buffer[0])
.forEach((frame, j) => {
channgelBuffer[(i*config.bufferLength)+j] = frame;
});
});
}
const source = audioContext.createBufferSource();
source.buffer = audioBuffer;
source.connect(audioContext.destination);
// Resolve the promise
res(source);
} else {
buffers.push(e.data);
}
};
// Initialize the decoder
decoder.postMessage({ command: "init", config: config });
// Load blob
const reader = new FileReader();
reader.onload = e => {
decoder.postMessage({ command: "decode", pages: new Uint8Array(reader.result)});
decoder.postMessage({ command: 'done' });
};
reader.readAsArrayBuffer(blob);
});
}
P.S. This is working in a react app using the worker-loader to wrap the worker scripts in case anyone wonders about that new worker line.
from opus-recorder.
@brancusi Looks good. Is this pure ECMASCript 6 code? I'm unfamiliar with =>
syntax. Does defining a value as const make it immutable? Seems strange to make an array which you push to a constant.
from opus-recorder.
@chris-rudmin ok cool. Yes this is es6 syntax. The =>
is a new way to declare an anonymous function that will bind any this
references to current outer scope. Gets us away from having to do, var self = this;
As for Const, it just makes the reference read-only but you can still mutate the underlying array in our case. I think it adds some clarity of intend mostly, none of the refs will be redeclared inside that promise.
Under the hood right now this all gets compiled to es5 any way, so const become var. Babel
from opus-recorder.
@brancusi One thing I might add, you could get better performance and higher fidelity playback (at the expense of more memory) if you can create the buffer source at with a sample rate of 48000. This is the native decoder rate of opus and it will avoid you using my lo-fi resampler.
from opus-recorder.
Thanks @chris-rudmin, I will definitely swap that out. Will it matter if the audioContext's rate is different? Or should that be set (can it be set?) before hand to 48000 as well?
from opus-recorder.
My understanding is that it will use the browsers internal resampling algorithm which should be faster and of higher quality than a resampler implemented in js. However I have not tested this.
from opus-recorder.
Added a decoder example in the examples folder!
from opus-recorder.
Related Issues (20)
- How to use with Vite? HOT 6
- The first recording is not saved in Safari on IOS 15.1 HOT 1
- Robotic, torn audio on IOS 15.1 HOT 3
- Issue while using decoder with React application HOT 11
- Recorder output file size too small - Vue.js HOT 4
- building and running on windows 10 HOT 4
- Error running waveRecorder.html example HOT 3
- using waveform-playlist with opus-recorder HOT 1
- Uncaught TypeError: Cannot read properties of undefined (reading 'length')
- Not working with Vite + Vue 3
- wasm streaming compile failed: TypeError: Could not download wasm module falling back to ArrayBuffer instantiation how can i resolve this issue ? HOT 3
- Convert 16 bit signed int to 32 bit float HOT 8
- Audio distorted after 30 seconds HOT 6
- few seconds of recording are missing at the beginning (especially on IOS) HOT 1
- Play pages real-time HOT 2
- ondataavailable not fired with waveWorker
- TypeScript definitions HOT 1
- Opus Player
- Is it possible to Decode two audio sources HOT 4
- Error webassembly.compile HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from opus-recorder.