Como uno de esos proyectos raros que nos gusta compartir aquí en Our Code World, te traemos hoy una de esas funciones que probablemente no usarás en tu escena Laboral sino en proyectos personales o simplemente para ampliar tus conocimientos de Javascript. Estamos hablando de un útil "Volume Meter" que viene muy bien para visualizarlo gráficamente para advertir al que usa el sistema con la famosa barra verde y roja, que debe hablar en voz baja.
Empecemos !
1. Descarga Volume Meter
Volume Meter no es un complemento, sino una colección de 2 funciones útiles que lo ayudarán a recuperar el nivel de entrada del micrófono a través de la API de WebAudio. Si estás trabajando en algún tipo de proyecto científico sobre cómo recuperar el nivel de sonido del micrófono a través del navegador, probablemente esto no sea lo que estás buscando. Pero si el objetivo es tener una idea general de una medida del nivel de sonido para su usuario, entonces podría ser bastante útil.
Descargue el script del medidor de volumen en el repositorio de Github aquí . Este script fue escrito por Chris Wilson en Google, visite el repositorio oficial en Github para obtener más información.
2. Uso del medidor de volumen
Como se mencionó anteriormente, el "complemento" son 2 funciones, puede decidir por su cuenta si desea declararlas en la ventana o simplemente agregarlas como un nuevo script en su documento. El punto es que las 2 funciones del complemento están disponibles: createAudioMeter
y volumeAudioProcess
.
Con esas funciones, ahora puede recuperar el nivel de sonido del micrófono y puede realizar cualquiera de las siguientes tareas:
Importante
Vale la pena decir que los scripts ( getUserMedia
) deben ejecutarse una vez que se cargue la ventana, de lo contrario fallará por razones obvias.
Nivel de visualización en Canvas
Para mostrar la barra conocida que se vuelve verde y roja según el nivel de entrada del micrófono, puede usar el siguiente código. Intentará acceder al User Media API y a través del flujo recibido como primer argumento en la devolución de llamada onMicrophoneGranted, se podrá recuperar el nivel de entrada del micrófono gracias a las funciones del plugin createAudioMeter
y volumeAudioProcess:
<!-- El lienzo que se utilizará para representar el nivel de entrada. -->
<canvas id="meter" width="500" height="50"></canvas>
<script>
/*
The MIT License (MIT)
Copyright (c) 2014 Chris Wilson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
var audioContext = null;
var meter = null;
var canvasContext = null;
var WIDTH=500;
var HEIGHT=50;
var rafID = null;
window.onload = function() {
// tomar el canvas
canvasContext = document.getElementById( "meter" ).getContext("2d");
// monkeypatch Web Audio
window.AudioContext = window.AudioContext || window.webkitAudioContext;
// tomar un contexto de audio
audioContext = new AudioContext();
// Intenta obtener entrada de audio
try {
// monkeypatch getUserMedia
navigator.getUserMedia =
navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia;
// pide una entrada de audio
navigator.getUserMedia(
{
"audio": {
"mandatory": {
"googEchoCancellation": "false",
"googAutoGainControl": "false",
"googNoiseSuppression": "false",
"googHighpassFilter": "false"
},
"optional": []
},
}, onMicrophoneGranted, onMicrophoneDenied);
} catch (e) {
alert('getUserMedia threw exception :' + e);
}
}
function onMicrophoneDenied() {
alert('Stream generation failed.');
}
var mediaStreamSource = null;
function onMicrophoneGranted(stream) {
// Cree un AudioNode a partir de la transmisión.
mediaStreamSource = audioContext.createMediaStreamSource(stream);
// Cree un nuevo medidor de volumen y conéctelo.
meter = createAudioMeter(audioContext);
mediaStreamSource.connect(meter);
// iniciar la actualización visual
onLevelChange();
}
function onLevelChange( time ) {
// limpiar el fondo
canvasContext.clearRect(0,0,WIDTH,HEIGHT);
// compruebe si actualmente estamos recortando
if (meter.checkClipping())
canvasContext.fillStyle = "red";
else
canvasContext.fillStyle = "green";
console.log(meter.volume);
// dibuja una barra basada en el volumen actual
canvasContext.fillRect(0, 0, meter.volume * WIDTH * 1.4, HEIGHT);
// configurar la siguiente devolución de llamada visual
rafID = window.requestAnimationFrame( onLevelChange );
}
</script>
El código anterior debería mostrar un lienzo simple en forma de barra que cambia cuando usa el micrófono:
Puede consultar el script de trabajo que muestra una implementación básica del Medidor de volumen en su navegador aquí (y lo muestra en un lienzo).
Standalone
En caso de que desee mostrar un medidor de volumen personalizado con su propio estilo, solo necesitará los valores del medidor de volumen en lugar de mostrarlos en un lienzo. Para recuperar solo los valores, simplemente puede eliminar todo el código relacionado con el elemento canvas del script anterior.
El siguiente fragmento mostrará, una vez iniciado, el valor de volumen del objeto medidor (de 0,00 a 1,00) en la consola (respectivamente con console.log
si el nivel es "normal" o con console.warn
si el volumen está "recortado") con la onLevelChange
función:
/**
* Cree variables accesibles globales que se modificarán más adelante
*/
var audioContext = null;
var meter = null;
var rafID = null;
var mediaStreamSource = null;
// Recuperar AudioContext con todos los prefijos de los navegadores
window.AudioContext = window.AudioContext || window.webkitAudioContext;
// Obtenga un contexto de audio
audioContext = new AudioContext();
/**
* Devolución de llamada activada si se deniega el permiso del micrófono
*/
function onMicrophoneDenied() {
alert('Stream generation failed.');
}
/**
* Devolución de llamada activada si se concede el acceso al micrófono
*/
function onMicrophoneGranted(stream) {
// Cree un AudioNode a partir de la transmisión.
mediaStreamSource = audioContext.createMediaStreamSource(stream);
// Cree un nuevo medidor de volumen y conéctelo.
meter = createAudioMeter(audioContext);
mediaStreamSource.connect(meter);
// Activar devolución de llamada que muestra el nivel del "Medidor de volumen"
onLevelChange();
}
/**
* Esta función se ejecuta repetidamente
*/
function onLevelChange(time) {
// compruebe si actualmente estamos recortando
if (meter.checkClipping()) {
console.warn(meter.volume);
} else {
console.log(meter.volume);
}
// configurar la siguiente devolución de llamada
rafID = window.requestAnimationFrame(onLevelChange);
}
// Intenta acceder al micrófono
try {
// Recuperar la API getUserMedia con todos los prefijos de los navegadores
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
// Solicita una entrada de audio
navigator.getUserMedia(
{
"audio": {
"mandatory": {
"googEchoCancellation": "false",
"googAutoGainControl": "false",
"googNoiseSuppression": "false",
"googHighpassFilter": "false"
},
"optional": []
},
},
onMicrophoneGranted,
onMicrophoneDenied
);
} catch (e) {
alert('getUserMedia threw exception :' + e);
}
La función onLevelChange
es la función a la que debe prestar atención.
Crea tu wrapper personalizado
Como la implementación del código será un poco complicada, puede crear un script personalizado para facilitar su uso con solo ejecutar una función. Mira el siguiente ejemplo, creará la microphoneLevel
función en la ventana y espera 2 devoluciones de llamada ( onResult
y onError
):
(function(){
function wrapperAudioMeter(OPTIONS){
var audioContext = null;
var meter = null;
var rafID = null;
var mediaStreamSource = null;
// Recuperar AudioContext con todos los prefijos de los navegadores
window.AudioContext = window.AudioContext || window.webkitAudioContext;
// Obtenga un contexto de audio
audioContext = new AudioContext();
function onMicrophoneDenied() {
if(typeof(OPTIONS["onError"]) == "function"){
OPTIONS.onError('Stream generation failed.');
}
}
function onMicrophoneGranted(stream) {
// Cree un AudioNode a partir de la transmisión.
mediaStreamSource = audioContext.createMediaStreamSource(stream);
// Cree un nuevo medidor de volumen y conéctelo
meter = createAudioMeter(audioContext);
mediaStreamSource.connect(meter);
// Activar devolución de llamada que
onLevelChange();
}
function onLevelChange(time) {
if(typeof(OPTIONS["onResult"]) == "function"){
OPTIONS.onResult(meter, time);
}
// configurar la siguiente devolución de llamada
rafID = window.requestAnimationFrame(onLevelChange);
}
// Intenta acceder al micrófono
try {
// Recuperar la API getUserMedia con todos los prefijos de los navegadores
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
// Solicita una entrada de audio
navigator.getUserMedia(
{
"audio": {
"mandatory": {
"googEchoCancellation": "false",
"googAutoGainControl": "false",
"googNoiseSuppression": "false",
"googHighpassFilter": "false"
},
"optional": []
},
},
onMicrophoneGranted,
onMicrophoneDenied
);
} catch (e) {
if(typeof(OPTIONS["onError"]) == "function"){
OPTIONS.onError(e);
}
}
}
window["microphoneLevel"] = wrapperAudioMeter;
})();
Este script se puede utilizar de la siguiente manera:
/**
* Ejecute el script una vez que se cargue la ventana
**/
window.onload = function(){
// Solicitar micrófono para mostrar el nivel
window.microphoneLevel({
onResult: function(meter , time){
if (meter.checkClipping()) {
console.warn(meter.volume);
} else {
console.log(meter.volume);
}
},
onError: function(err){
console.error(err);
}
});
};
La onResult
devolución de llamada se activa repetidamente y recibe el objeto del medidor con la información y los métodos del AudioContext
. Es fácil de leer y trabajar, ¿no?
Que te diviertas ❤️!
Conviertete en un programador más sociable