javascript - Trim or cut audio recorded with mediarecorder JS -
requested knowledge
how shorten (from front) array of audio blobs , still have playable audio.
goal
i trying record continuous 45 second loop of audio using js mediarecorder api. user able push button , last 45s of audio saved. can record, playback, , download single recording fine.
issue
when have array called chunks
of 1000 blobs mediarecorder , use chunks.slice(500, 1000)
resulting blob array can't used playback or download audio.
oddly enough chunks.slice(0,500)
still works fine.
code
let chunks = []; navigator.mediadevices.getusermedia({ audio: true }) .then((stream) => { const mediarecorder = new mediarecorder(stream); mediarecorder.ondataavailable = (e) => chunks.push(e.data); } // @ later time, attempt trim const trimmedaudio = chunks.slice(500, 1000) const blob = new blob(chunks, { 'type' : 'audio/ogg; codecs=opus' }); const audiourl = url.createobjecturl(blob); // audio audio dom element audio.src = audiourl; // @ point audio won't play
attempted solutions
because slicing beginning middle works, tried reversing, slicing, , reversing original direction. failed.
i tried leaving 16 blobs @ beginning , removing of middle. failed.
hunch
my hunch blobs don't uniformly contain data , require conversion arraybuffer or specific typedarray. have tried number of these conversions, still have not found solution. guidance appreciated can find documentation @ editing recorded blob arrays.
update 2017-02-11
based on kaiido's advice concatenate chunks, convert arraybuffer, , pass web audio api, tried following.
const blob = new blob(chunksfrommediarecorder, { 'type' : 'audio/ogg codecs=opus' }) // blob blob size: 32714, type: "audio/ogg codecs=opus"} function playfromblob(blob) { const actx = new (window.audiocontext || window.webkitaudiocontext)() const source = actx.createbuffersource() const filereader = new filereader() let arraybuffer filereader.onload = function() { arraybuffer = this.result console.log('arraybuffer', arraybuffer) // arraybuffer {} byte length 32714 actx.decodeaudiodata(arraybuffer) // throws: uncaught (in promise) domexception: unable decode audio data .then(decodeddata => { // use decoded data here source.buffer = decodeddata source.connect(audioctx.destination) }) } filereader.readasarraybuffer(blob); }
the above successful @ creating arraybuffer same size blob, when pass decodeaudiodata
function, throws unable decode audio data
error. there step missing in conversion process?
update 2017-02-18
kaiido pointed out there known bug chrome prevent me shifting array of audio data. far can tell makes sort of audio trimming or cutting currently impossible in chrome (firefox audio array trimming works, see kaiido's comment fiddle).
in order achieve ultimate goal of continuous 45s of retroactive recording, instantiating 2 mediarecorders
offset 45s , swapping them out. when 1 @ 45s , other @ 90s start new recording , rid of 90s mediarecorder
. suboptimal, best solution can presently find.
Comments
Post a Comment