Hace algún tiempo, un proyecto fue desarrollar un material educativo de audio. Básicamente, después de importar documentos, imágenes y otros recursos, la página se convierte en un diseño similar a PPT y luego, al seleccionar una imagen, se puede insertar audio. y modelo de edición global. Hay dos formas de importar audio, una es importar desde la biblioteca de recursos y la otra es mencionar la grabación.
Para ser honesto, nunca estuve expuesto a la API de audio de HTML5 al principio, y tenemos que optimizarla en función del código antes de tomar el control. Por supuesto, también hay muchos obstáculos involucrados. Esta vez también hablaré sobre mis sentimientos en torno a estos obstáculos (la inicialización y adquisición de algunos objetos básicos se omitirá porque estos contenidos no son el enfoque de este tiempo. Los estudiantes interesados pueden buscar en MDN. por sí mismos documentación sobre):
Antes de comenzar a grabar, primero debe averiguar si el dispositivo actual admite Audio API. El método anterior navigator.getUserMedia ha sido reemplazado por navigator.mediaDevices.getUserMedia. Normalmente, la mayoría de los navegadores modernos ahora admiten el uso de navigator.mediaDevices.getUserMedia. Por supuesto, MDN también proporciona información de compatibilidad.
const promisifiedOldGUM = function(constraints) { // Primero póngase en contacto con getUserMedia, si está presente const getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || Algunos navegadores simplemente no lo implementan: devuelven una promesa rechazada; con un error // para mantener una interfaz consistente if (!getUserMedia) { return Promise.reject( new Error('getUserMedia no está implementado en este navegador') } // De lo contrario, envuelve la llamada al antiguo navigator.getUserMedia con una promesa return new Promise(function(resolve, rechazar) { getUserMedia.call (navegador, restricciones, resolución, rechazo); });}; // Es posible que los navegadores más antiguos no implementen mediaDevices, por lo que primero configuramos un objeto vacío. (navigator.mediaDevices === undefinido) { navigator.mediaDevices = {};} // Algunos navegadores implementan parcialmente mediaDevices. No podemos simplemente asignar un objeto// con getUserMedia ya que sobrescribiría las propiedades existentes.// Aquí, nosotros simplemente agregará la propiedad getUserMedia si falta.if (navigator.mediaDevices.getUserMedia === undefinido) { navigator.mediaDevices.getUserMedia = promisifiedOldGUM;}
Debido a que este método es asincrónico, podemos proporcionar indicaciones amigables para dispositivos incompatibles.
navigator.mediaDevices.getUserMedia(constraints).then( function(mediaStream) { // Éxito }, function(error) { // Fallo const { nombre } = error; let errorMessage; switch (nombre) { // El usuario rechaza mayúsculas y minúsculas ' NotAllowedError': case 'PermissionDeniedError': errorMessage = 'El usuario ha prohibido a la página web llamar al dispositivo de grabación' // El dispositivo de grabación no está conectado case 'NotFoundError': case; 'DevicesNotFoundError': errorMessage = 'Dispositivo de grabación no encontrado'; break; // Otros casos de error 'NotSupportedError': errorMessage = 'La función de grabación no es compatible'; default: errorMessage = 'Error de llamada de grabación'; iniciar sesión (error); devolver mensaje de error });
Si todo va bien, podremos pasar al siguiente paso.
(El método para obtener contexto se omite aquí porque esta vez no es el enfoque)
Iniciar grabación, pausar grabaciónHay un punto especial aquí, es decir, es necesario agregar una variable intermedia para identificar si se está realizando la grabación actualmente. Porque en el navegador Firefox encontramos un problema. El proceso de grabación fue normal, pero cuando hicimos clic para pausar, descubrimos que no se podía pausar. Usamos el método de desconexión en ese momento. Este método no es posible. Este método requiere desconectar todas las conexiones. Más tarde, descubrí que se debe agregar una variable intermedia this.isRecording para determinar si la grabación se está realizando actualmente. Cuando se hace clic en iniciar, configúrelo en verdadero y cuando esté en pausa, configúrelo en falso.
Cuando comenzamos a grabar, habrá un evento de escucha de grabación en el proceso de audio. Si se devuelve verdadero, se escribirá la transmisión. Si se devuelve falso, no se escribirá. Por lo tanto, juzgue this.isRecording y, si es falso, regrese directamente
// Alguna inicialización const audioContext = new AudioContext(); const sourceNode = audioContext.createMediaStreamSource(mediaStream); const scriptNode = audioContext.createScriptProcessor( BUFFER_SIZE, INPUT_CHANNELS_NUM, OUPUT_CHANNELS_NUM);sourceNode.connect(this.scriptNode);scriptNode.connect(this.audioContext.destination); // Monitorear el proceso de grabación scriptNode.onaudioprocess = event => { if (!this.isRecording) // Determinar si Grabación periódica this.buffers.push(event.inputBuffer.getChannelData(0)); Obtenga los datos del canal actual y escríbalos en la matriz};
Por supuesto, habrá un problema aquí, es decir, ya no se puede usar. Viene con un método para obtener la duración de la grabación actual, porque en realidad no es una pausa real, pero la transmisión no se escribe. Por lo tanto, también necesitamos obtener la duración de la grabación actual, que debe obtenerse mediante una fórmula.
const getDuration = () => { return (4096 * this.buffers.length) / this.audioContext.sampleRate // 4096 es la longitud de una transmisión, sampleRate es la frecuencia de muestreo}
De esta manera puede obtener la duración de grabación correcta.
finalizar la grabaciónPara finalizar la grabación, primero la pausa, luego realizo escucha u otras operaciones si es necesario, y luego configuro la longitud de la matriz del flujo de almacenamiento en 0.
Obtener frecuenciagetVoiceSize = analizador => { const dataArray = new Uint8Array(analyser.frequencyBinCount); analyser.getByteFrequencyData(dataArray); const data = dataArray.slice(100, 1000); a + b); suma de retorno;};
Para obtener más información, consulte https://developer.mozilla.org/zh-CN/docs/Web/API/AnalyserNode/frequencyBinCount
otro
La mayoría de los problemas que encontré esta vez fueron problemas de compatibilidad, por lo que me encontré con muchos problemas, especialmente en el lado móvil. Al principio, hubo un problema en el que la duración de la grabación se escribió incorrectamente, lo que provocó que se congelara directamente. Esta experiencia también ha compensado algunas lagunas en la API HTML5. Por supuesto, lo más importante es recordarles a todos que este tipo de documentación de API nativa se obtiene de manera simple y sencilla mirando directamente MDN.
Lo anterior es el contenido completo de este artículo. Espero que sea útil para el estudio de todos. También espero que todos apoyen VeVb Wulin Network.