个性化阅读
专注于IT技术分析

如何使用JavaScript在浏览器中创建音量计(测量音量)

本文概述

作为我们想在《代码世界》中分享的那些怪异项目之一, 我们今天为你带来了你可能不会在Laboral场景中使用的那些功能之一, 而是在个人项目中或只是用来扩展Java知识的那些功能。我们正在谈论一种有用的”音量计”, 它可以方便地以图形方式显示它, 以警告使用该系统的人带有著名的绿色和红色条, 他应该安静地讲话。

让我们开始吧 !

1.下载音量计

音量表不是插件, 而是2个有用功能的集合, 这些功能将帮助你通过WebAudio API检索麦克风的输入电平。如果你正在从事某种有关如何通过浏览器检索麦克风声级的科学项目, 那么这可能不是你想要的。但是, 如果目标是让你对用户的声音水平进行总体了解, 那么它可能会非常有用。

在此处下载Github存储库中的体积计脚本。该脚本由Google的Chris Wilson编写, 有关更多信息, 请访问Github的官方存储库。

2.使用音量计

如前所述, “插件”是2个函数, 你可以自行决定是要在窗口中声明它们还是将其作为新脚本添加到文档中。关键是, 该插件的两个功能可用:createAudioMeter和volumeAudioProcess。

使用这些功能, 你现在可以获取麦克风的声音电平, 并且可以执行以下任何任务:

重要

值得一提的是, 一旦加载窗口, 就需要执行脚本(getUserMedia), 否则, 由于明显的原因, 它将失败。

画布中的显示级别

要显示根据麦克风的输入电平而变为绿色和红色的已知条, 可以使用以下代码。它将尝试访问User Media API, 并通过在onMicrophoneGranted回调中作为第一个参数接收的流来访问, 由于插件createAudioMeter和volumeAudioProcess的功能, 可以检索麦克风的输入电平:

<!-- The canvas that will be used to render the input level -->
<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() {

    // grab our canvas
	canvasContext = document.getElementById( "meter" ).getContext("2d");
	
    // monkeypatch Web Audio
    window.AudioContext = window.AudioContext || window.webkitAudioContext;
	
    // grab an audio context
    audioContext = new AudioContext();

    // Attempt to get audio input
    try {
        // monkeypatch getUserMedia
        navigator.getUserMedia = 
        	navigator.getUserMedia ||
        	navigator.webkitGetUserMedia ||
        	navigator.mozGetUserMedia;

        // ask for an audio input
        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) {
    // Create an AudioNode from the stream.
    mediaStreamSource = audioContext.createMediaStreamSource(stream);

    // Create a new volume meter and connect it.
    meter = createAudioMeter(audioContext);
    mediaStreamSource.connect(meter);

    // kick off the visual updating
    onLevelChange();
}

function onLevelChange( time ) {
    // clear the background
    canvasContext.clearRect(0, 0, WIDTH, HEIGHT);

    // check if we're currently clipping
    if (meter.checkClipping())
        canvasContext.fillStyle = "red";
    else
        canvasContext.fillStyle = "green";

    console.log(meter.volume);

    // draw a bar based on the current volume
    canvasContext.fillRect(0, 0, meter.volume * WIDTH * 1.4, HEIGHT);

    // set up the next visual callback
    rafID = window.requestAnimationFrame( onLevelChange );
}
</script>

前面的代码应该以条形显示一个简单的画布, 当你使用麦克风时该画布会发生变化:

麦克风输入电平

你可以在此处查看在浏览器中显示音量计基本实现的工作脚本(并将其显示在画布上)。

单机版

如果要显示自己的样式的自定义体积计, 则只需要体积计的值即可, 而不是在画布上显示它们。要仅检索值, 你可以简单地从上一个脚本中删除与canvas元素相关的所有代码。

以下代码段将在启动后显示控制台中仪表对象的音量值(从0.00到1.00)(如果级别为”正常”, 则分别与console.log一起显示;如果音量为”剪切”, 则分别与console.warn一起显示)。 )与onLevelChange函数:

/**
 * Create global accessible variables that will be modified later
 */
var audioContext = null;
var meter = null;
var rafID = null;
var mediaStreamSource = null;

// Retrieve AudioContext with all the prefixes of the browsers
window.AudioContext = window.AudioContext || window.webkitAudioContext;

// Get an audio context
audioContext = new AudioContext();

/**
 * Callback triggered if the microphone permission is denied
 */
function onMicrophoneDenied() {
    alert('Stream generation failed.');
}

/**
 * Callback triggered if the access to the microphone is granted
 */
function onMicrophoneGranted(stream) {
    // Create an AudioNode from the stream.
    mediaStreamSource = audioContext.createMediaStreamSource(stream);
    // Create a new volume meter and connect it.
    meter = createAudioMeter(audioContext);
    mediaStreamSource.connect(meter);

    // Trigger callback that shows the level of the "Volume Meter"
    onLevelChange();
}

/**
 * This function is executed repeatedly
 */
function onLevelChange(time) {
    // check if we're currently clipping

    if (meter.checkClipping()) {
        console.warn(meter.volume);
    } else {
        console.log(meter.volume);
    }

    // set up the next callback
    rafID = window.requestAnimationFrame(onLevelChange);
}


// Try to get access to the microphone
try {

    // Retrieve getUserMedia API with all the prefixes of the browsers
    navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

    // Ask for an audio input
    navigator.getUserMedia(
        {
            "audio": {
                "mandatory": {
                    "googEchoCancellation": "false", "googAutoGainControl": "false", "googNoiseSuppression": "false", "googHighpassFilter": "false"
                }, "optional": []
            }, }, onMicrophoneGranted, onMicrophoneDenied
    );
} catch (e) {
    alert('getUserMedia threw exception :' + e);
}

onLevelChange是你需要注意的功能。

创建自定义包装

由于代码的实现会有些混乱, 因此你可以创建一个自定义脚本, 只需执行一个函数就可以轻松使用该脚本。看看下面的示例, 它将在窗口中创建麦克风级别函数, 并且需要2个回调(onResult和onError):

(function(){
    function wrapperAudioMeter(OPTIONS){
        var audioContext = null;
        var meter = null;
        var rafID = null;
        var mediaStreamSource = null;

        // Retrieve AudioContext with all the prefixes of the browsers
        window.AudioContext = window.AudioContext || window.webkitAudioContext;

        // Get an audio context
        audioContext = new AudioContext();

        function onMicrophoneDenied() {
            if(typeof(OPTIONS["onError"]) == "function"){
                OPTIONS.onError('Stream generation failed.');
            }
        }

        function onMicrophoneGranted(stream) {
            // Create an AudioNode from the stream.
            mediaStreamSource = audioContext.createMediaStreamSource(stream);
            // Create a new volume meter and connect it.
            meter = createAudioMeter(audioContext);
            mediaStreamSource.connect(meter);

            // Trigger callback that 
            onLevelChange();
        }

        function onLevelChange(time) {
            if(typeof(OPTIONS["onResult"]) == "function"){
                OPTIONS.onResult(meter, time);
            }

            // set up the next callback
            rafID = window.requestAnimationFrame(onLevelChange);
        }

        // Try to get access to the microphone
        try {

            // Retrieve getUserMedia API with all the prefixes of the browsers
            navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

            // Ask for an audio input
            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;
})();

可以通过以下方式使用此脚本:

/**
 * Execute the script once the window loads 
 **/
window.onload = function(){

    // Request microphone to display level
    window.microphoneLevel({
        onResult: function(meter , time){
            if (meter.checkClipping()) {
                console.warn(meter.volume);
            } else {
                console.log(meter.volume);
            }
        }, onError: function(err){
            console.error(err);
        }
    });
};

重复触发onResult回调, 并接收带有AudioContext的信息和方法的仪表对象。它易于阅读和使用, 不是吗?

编码愉快!

赞(0)
未经允许不得转载:srcmini » 如何使用JavaScript在浏览器中创建音量计(测量音量)

评论 抢沙发

评论前必须登录!