Несколько вещей здесь.
Относительно части MediaRecorder, событие dataavailable может сработать в любое время, когда браузер сочтет это необходимым, оно может сработать даже без данных вообще. ,
Если вы хотите записать фиксированный промежуток времени, прослушайте событие stop , чтобы создать ссылку для скачивания, и используйте dataavailable one только для pu sh порции данных, которые браузер будет выводить в течение этого времени:
Что касается части AudioContext, представьте себе соединение ссылки как [гитара - педаль (ы) - предусилитель - усилитель] настроить. Каждый connect
прокладывает новый провод между двумя узлами.
В вашей настройке вы создали gainNode и подключили к нему свой генератор, теперь вам нужно подключить gainNode (g
) к MediaStreamDestinationNode (stream
) если хочешь записать. В противном случае ничто не будет передано в устройство записи, так как узел stream-dest не будет подключен ни к чему.
const context = new AudioContext();
const stream = context.createMediaStreamDestination();
document.getElementById('btn').onclick = play;
function play(){
const o = context.createOscillator();
const g = context.createGain();
const r = new MediaRecorder(stream.stream);
o.type = "sine";
g.gain.value = 0.5;
o.connect(g);
// you want to connect the gainNode to the stream-dest
g.connect(stream);
// and to the context's dest (speakers)
g.connect(context.destination);
o.start(0);
// we need an Array to store all the chunks
const chunks = [];
// in datavailable we only push the new chunks
r.ondataavailable = function(e) {
chunks.push(e.data);
};
// we wait until the recoder has been stopped to build the final media
r.onstop = function(e) {
// concatenate all the chunks in a single Blob
const blob = new Blob(chunks);
const url = window.URL.createObjectURL(blob);
const li = document.createElement('li');
const au = document.createElement('audio');
const hf = document.createElement('a');
au.controls = true;
au.src = url;
hf.href = url;
// setting the filename's extension won't make it a wav file
// what you have here is an ogg-vorbis audio file.
hf.download = new Date().toISOString() + '.oga';
hf.innerHTML = hf.download;
li.appendChild(au);
li.appendChild(hf);
document.getElementById('recordingslist').appendChild(li);
o.stop();
};
r.start();
// stop the recording in 3s
setTimeout(() => { r.stop(); }, 3000);
}
<button id="btn">start</button>
<ul id="recordingslist"></ul>