javascript - insertar - HTML5 grabar audio en un archivo
reproductor audio html5 playlist (7)
Aquí hay un proyecto de gitHub que hace precisamente eso.
Graba el audio del navegador en formato mp3 y lo guarda automáticamente en el servidor web. https://github.com/nusofthq/Recordmp3js
También puede ver una explicación detallada de la implementación: http://nusofthq.com/blog/recording-mp3-using-only-html5-and-javascript-recordmp3-js/
Lo que en última instancia quiero hacer es grabar desde el micrófono del usuario y subir el archivo al servidor cuando hayan terminado. Hasta ahora, he logrado hacer una transmisión a un elemento con el siguiente código:
var audio = document.getElementById("audio_preview");
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
navigator.getUserMedia({video: false, audio: true}, function(stream) {
audio.src = window.URL.createObjectURL(stream);
}, onRecordFail);
var onRecordFail = function (e) {
console.log(e);
}
¿Cómo paso de eso a grabar en un archivo?
El código que se muestra a continuación tiene copyright de Matt Diamond y está disponible para su uso bajo la licencia de MIT. Los archivos originales están aquí:
- http://webaudiodemos.appspot.com/AudioRecorder/index.html
- http://webaudiodemos.appspot.com/AudioRecorder/js/recorderjs/recorderWorker.js
Guarde estos archivos y use
(function(window){
var WORKER_PATH = ''recorderWorker.js'';
var Recorder = function(source, cfg){
var config = cfg || {};
var bufferLen = config.bufferLen || 4096;
this.context = source.context;
this.node = this.context.createJavaScriptNode(bufferLen, 2, 2);
var worker = new Worker(config.workerPath || WORKER_PATH);
worker.postMessage({
command: ''init'',
config: {
sampleRate: this.context.sampleRate
}
});
var recording = false,
currCallback;
this.node.onaudioprocess = function(e){
if (!recording) return;
worker.postMessage({
command: ''record'',
buffer: [
e.inputBuffer.getChannelData(0),
e.inputBuffer.getChannelData(1)
]
});
}
this.configure = function(cfg){
for (var prop in cfg){
if (cfg.hasOwnProperty(prop)){
config[prop] = cfg[prop];
}
}
}
this.record = function(){
recording = true;
}
this.stop = function(){
recording = false;
}
this.clear = function(){
worker.postMessage({ command: ''clear'' });
}
this.getBuffer = function(cb) {
currCallback = cb || config.callback;
worker.postMessage({ command: ''getBuffer'' })
}
this.exportWAV = function(cb, type){
currCallback = cb || config.callback;
type = type || config.type || ''audio/wav'';
if (!currCallback) throw new Error(''Callback not set'');
worker.postMessage({
command: ''exportWAV'',
type: type
});
}
worker.onmessage = function(e){
var blob = e.data;
currCallback(blob);
}
source.connect(this.node);
this.node.connect(this.context.destination); //this should not be necessary
};
Recorder.forceDownload = function(blob, filename){
var url = (window.URL || window.webkitURL).createObjectURL(blob);
var link = window.document.createElement(''a'');
link.href = url;
link.download = filename || ''output.wav'';
var click = document.createEvent("Event");
click.initEvent("click", true, true);
link.dispatchEvent(click);
}
window.Recorder = Recorder;
})(window);
//ADDITIONAL JS recorderWorker.js
var recLength = 0,
recBuffersL = [],
recBuffersR = [],
sampleRate;
this.onmessage = function(e){
switch(e.data.command){
case ''init'':
init(e.data.config);
break;
case ''record'':
record(e.data.buffer);
break;
case ''exportWAV'':
exportWAV(e.data.type);
break;
case ''getBuffer'':
getBuffer();
break;
case ''clear'':
clear();
break;
}
};
function init(config){
sampleRate = config.sampleRate;
}
function record(inputBuffer){
recBuffersL.push(inputBuffer[0]);
recBuffersR.push(inputBuffer[1]);
recLength += inputBuffer[0].length;
}
function exportWAV(type){
var bufferL = mergeBuffers(recBuffersL, recLength);
var bufferR = mergeBuffers(recBuffersR, recLength);
var interleaved = interleave(bufferL, bufferR);
var dataview = encodeWAV(interleaved);
var audioBlob = new Blob([dataview], { type: type });
this.postMessage(audioBlob);
}
function getBuffer() {
var buffers = [];
buffers.push( mergeBuffers(recBuffersL, recLength) );
buffers.push( mergeBuffers(recBuffersR, recLength) );
this.postMessage(buffers);
}
function clear(){
recLength = 0;
recBuffersL = [];
recBuffersR = [];
}
function mergeBuffers(recBuffers, recLength){
var result = new Float32Array(recLength);
var offset = 0;
for (var i = 0; i < recBuffers.length; i++){
result.set(recBuffers[i], offset);
offset += recBuffers[i].length;
}
return result;
}
function interleave(inputL, inputR){
var length = inputL.length + inputR.length;
var result = new Float32Array(length);
var index = 0,
inputIndex = 0;
while (index < length){
result[index++] = inputL[inputIndex];
result[index++] = inputR[inputIndex];
inputIndex++;
}
return result;
}
function floatTo16BitPCM(output, offset, input){
for (var i = 0; i < input.length; i++, offset+=2){
var s = Math.max(-1, Math.min(1, input[i]));
output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
}
}
function writeString(view, offset, string){
for (var i = 0; i < string.length; i++){
view.setUint8(offset + i, string.charCodeAt(i));
}
}
function encodeWAV(samples){
var buffer = new ArrayBuffer(44 + samples.length * 2);
var view = new DataView(buffer);
/* RIFF identifier */
writeString(view, 0, ''RIFF'');
/* file length */
view.setUint32(4, 32 + samples.length * 2, true);
/* RIFF type */
writeString(view, 8, ''WAVE'');
/* format chunk identifier */
writeString(view, 12, ''fmt '');
/* format chunk length */
view.setUint32(16, 16, true);
/* sample format (raw) */
view.setUint16(20, 1, true);
/* channel count */
view.setUint16(22, 2, true);
/* sample rate */
view.setUint32(24, sampleRate, true);
/* byte rate (sample rate * block align) */
view.setUint32(28, sampleRate * 4, true);
/* block align (channel count * bytes per sample) */
view.setUint16(32, 4, true);
/* bits per sample */
view.setUint16(34, 16, true);
/* data chunk identifier */
writeString(view, 36, ''data'');
/* data chunk length */
view.setUint32(40, samples.length * 2, true);
floatTo16BitPCM(view, 44, samples);
return view;
}
<html>
<body>
<audio controls autoplay></audio>
<script type="text/javascript" src="recorder.js"> </script>
<fieldset><legend>RECORD AUDIO</legend>
<input onclick="startRecording()" type="button" value="start recording" />
<input onclick="stopRecording()" type="button" value="stop recording and play" />
</fieldset>
<script>
var onFail = function(e) {
console.log(''Rejected!'', e);
};
var onSuccess = function(s) {
var context = new webkitAudioContext();
var mediaStreamSource = context.createMediaStreamSource(s);
recorder = new Recorder(mediaStreamSource);
recorder.record();
// audio loopback
// mediaStreamSource.connect(context.destination);
}
window.URL = window.URL || window.webkitURL;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
var recorder;
var audio = document.querySelector(''audio'');
function startRecording() {
if (navigator.getUserMedia) {
navigator.getUserMedia({audio: true}, onSuccess, onFail);
} else {
console.log(''navigator.getUserMedia not present'');
}
}
function stopRecording() {
recorder.stop();
recorder.exportWAV(function(s) {
audio.src = window.URL.createObjectURL(s);
});
}
</script>
</body>
</html>
Este es un grabador y editor de sonido JavaScript simple. Puedes probarlo.
https://www.danieldemmel.me/JSSoundRecorder/
Puede descargar desde aquí
Hay una demo de grabación bastante completa disponible en: http://webaudiodemos.appspot.com/AudioRecorder/index.html
Le permite grabar audio en el navegador, luego le da la opción de exportar y descargar lo que ha grabado.
Puede ver el origen de esa página para encontrar enlaces al javascript, pero para resumir, hay un objeto Recorder
que contiene un método exportWAV
y un método forceDownload
.
Puede usar Recordmp3js desde GitHub para cumplir sus requisitos. Puede grabar desde el micrófono del usuario y luego obtener el archivo como un mp3. Por último, cárguelo en su servidor.
Usé esto en mi demo. Ya hay una muestra disponible con el código fuente por el autor en esta ubicación: https://github.com/nusofthq/Recordmp3js
La demostración está aquí: http://audior.ec/recordmp3js/
Pero actualmente solo funciona en Chrome y Firefox.
Parece que funciona bien y es bastante simple. Espero que esto ayude.
Transmita audio en tiempo real sin esperar a que finalice la grabación: https://github.com/noamtcohen/AudioStreamer
Esto transmite datos PCM, pero puede modificar el código para transmitir mp3 o Speex
Actualizar ahora Chrome también es compatible con MediaRecorder API desde v47. Lo más sensato sería usarlo (supongo que el método de grabación nativo es más rápido que la solución), la API es realmente fácil de usar, y encontrarás muchísimas respuestas sobre cómo cargar una burbuja para el servidor .
Demo : funcionaría en Chrome y Firefox, se omitió intencionalmente empujar blob al servidor ...
Actualmente, hay tres formas de hacerlo:
- como
wav
[código completo del lado del cliente, grabación sin comprimir], puede consultar -> Recorderjs . Problema: el tamaño del archivo es bastante grande, se requiere más ancho de banda de carga. - como
mp3
[código completo del lado del cliente, grabación comprimida], puede consultar -> mp3Recorder . Problema: personalmente, considero que la calidad es mala, también existe este problema de licencia. como código
ogg
[cliente + servidor (node.js
), grabación comprimida, horas infinitas de grabación sin bloqueo del navegador], puede consultar -> recordOpus , ya sea solo la grabación del lado del cliente o agrupación cliente-servidor, la elección es suya .Ejemplo de grabación ogg (solo Firefox):
var mediaRecorder = new MediaRecorder(stream); mediaRecorder.start(); // to start recording. ... mediaRecorder.stop(); // to stop recording. mediaRecorder.ondataavailable = function(e) { // do something with the data. }
Fiddle Demo para la grabación ogg.