HTML5 Web Audio Api 声音登陆

2023-11-13

之前最早时候给过一个识别hz的demo 今天讲那个demo结合上一篇说的振荡器,做了个声音登录的小demo

原理就是2w+hz人听不见。(其实1w9左右就很轻微了)

直接上代码

识别器(限电脑)

<span style="font-size:18px;"><!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width">
    <meta name="full-screen" content="yes"/>
    <meta content="telephone=no" name="format-detection" />
    <meta name="screen-orientation" content="portrait"/>
    <meta name="x5-fullscreen" content="true"/>
    <meta name="360-fullscreen" content="true"/>
    <title>动态加载</title>
    <script src="js/get-float-time-domain-data.min.js"></script>
    <style type="text/css">
        .center {
            margin-right: auto;margin-left: auto;
        }
        #button {
            width: 30%;height: 50px;background-color: cornflowerblue;text-align: center;font-size: 18px;border-radius: 10px;line-height: 50px
        }
        #canvas {
            margin-top: 10px;
        }
    </style>
</head>
<body style="text-align: center">
<h1>动态加载</h1>
<br>
<h2 id="hz">点击开始</h2>
<div οnclick="buttonClicked()" id="button" class="center">开始</div>
<iframe style="margin-left: auto;margin-right: auto;margin-top: 30px;display: none" frameborder="0" width="640" height="498" src="" allowfullscreen></iframe>
<script type="application/javascript">
    var body = document.body,
//        canvas = document.getElementById("canvas"),
//        ctx = canvas.getContext("2d"),
        hz = document.getElementById("hz"),
        width = 0,
        height = 0,
        src = "http://v.qq.com/iframe/player.html?vid=z01978vcjoa&tiny=0&auto=0",
        button = document.getElementById("button");

    var onRecord = false,//是否在录音
        currentHz = 0, //当前频率
        historyHz = [];//用来记录历史hz (为了canvas)

    //这个是主角 WebAudio
    window.AudioContext = window.AudioContext || window.webkitAudioContext;
    var audioContext = null,
        sourceNode = null,
        analyser = null,
        theBuffer = null,
        mediaStreamSource = null;

    window.onload = function(){
//        canvas.width = body.clientWidth*0.5;
//        canvas.height = body.clientWidth*0.5;
        width = body.clientWidth*0.5;
        height = body.clientWidth*0.5;
//        ctx.fillStyle = "#B0E2FF"
//        ctx.fillRect(0,0,canvas.width,canvas.height);
        initWebAudioApi();
    }

    function initWebAudioApi(){
        try {
            audioContext = new AudioContext();
        }catch(e) {
            alert("您的设备不支持Web Audi Api");
        }
    }

    function error() {
        alert('Stream generation failed.');
    }

    function initMovie(){
        var iframe = document.getElementsByTagName("iframe")[0];
        iframe.src = src;
        iframe.style.display = "block";
    }

    function buttonClicked(){
        if (!onRecord){
            onRecord = true;
            button.innerText = "停止";
            hz.innerText = "";
            getUserMedia(
                    {
                        "audio": {
                            "mandatory": {
                                "googEchoCancellation": "false",
                                "googAutoGainControl": "false",
                                "googNoiseSuppression": "false",
                                "googHighpassFilter": "false"
                            },
                            "optional": []
                        },
                    }, gotStream);
        }else{
            onRecord = false;
            button.innerText = "开始";
            hz.innerText = "点击开始";
        }
    }

    function getUserMedia(dictionary, callback) {
        try {
            navigator.getUserMedia =
                    navigator.getUserMedia ||
                    navigator.webkitGetUserMedia ||
                    navigator.mozGetUserMedia;
            navigator.getUserMedia(dictionary, callback, error);
        } catch (e) {
            //常见错误原因是因为使用了http协议 (这个接口需要https)
            console.log(e)
            alert("抱歉GetUserMedia调用失败");
        }
    }

    function gotStream(stream) {
        mediaStreamSource = audioContext.createMediaStreamSource(stream);
        analyser = audioContext.createAnalyser();
        analyser.fftSize = 2048;
        mediaStreamSource.connect( analyser );
        updatePitch();
    }

    function autoCorrelate( buf, sampleRate ) {
        var SIZE = buf.length;
        var MAX_SAMPLES = Math.floor(SIZE/2);
        var best_offset = -1;
        var best_correlation = 0;
        var rms = 0;
        var foundGoodCorrelation = false;
        var correlations = new Array(MAX_SAMPLES);
        for (var i=0;i<SIZE;i++) {
            var val = buf[i];
            rms += val*val;
        }
        rms = Math.sqrt(rms/SIZE);
        if (rms<0.01)
            return -1;
        var lastCorrelation=1;
        for (var offset = 0; offset < MAX_SAMPLES; offset++) {
            var correlation = 0;
            for (var i=0; i<MAX_SAMPLES; i++) {
                correlation += Math.abs((buf[i])-(buf[i+offset]));
            }
            correlation = 1 - (correlation/MAX_SAMPLES);
            correlations[offset] = correlation; // store it, for the tweaking we need to do below.
            if ((correlation>0.9) && (correlation > lastCorrelation)) {
                foundGoodCorrelation = true;
                if (correlation > best_correlation) {
                    best_correlation = correlation;
                    best_offset = offset;
                }
            } else if (foundGoodCorrelation) {
                var shift = (correlations[best_offset+1] - correlations[best_offset-1])/correlations[best_offset];
                return sampleRate/(best_offset+(8*shift));
            }
            lastCorrelation = correlation;
        }
        if (best_correlation > 0.01) {
            return sampleRate/best_offset;
        }
        return -1;
    }

    var buflen = 1024,
        startDetect = false,
        canChange = true;
        frequency = 0;
    var buf = new Float32Array(buflen);

    function updatePitch(){
        frequency++;
        analyser.getFloatTimeDomainData(buf);
        var ac = autoCorrelate(buf,audioContext.sampleRate);
        var current_hz = 0;
        if (ac != -1){
            pitch = ac;
            current_hz = (Math.round( pitch ));
        }
        if (current_hz>20000){
            startDetect = true;
        }
//        if (startDetect){
//            if (historyHz.length<50){
//                historyHz
//            }
//        }
//
//        if (historyHz.length>100){
//            if (historyHz.indexOf(20000)==0){
//                console.log(historyHz);
//            }
//            historyHz.length = 0;
//        }
//        currentHz = current_hz;
        if (current_hz>20000){
            hz.innerText = "识别到你啦";
            initMovie();
            canChange = false;
        }
        historyHz.push((current_hz>20000)?20000:current_hz);
        animate()
        if (canChange){
           // hz.innerText = current_hz+"Hz";
            loop = window.requestAnimationFrame(updatePitch);
        }
    }
</script>
</body>
</html></span>

基本就是在demo上进行了一点点修改


下面是发声器 可以是手机也可以是电脑

<span style="font-size:18px;"><!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        .button {
            margin-left: auto;margin-right: auto;width: 40%;height: 50px;background-color: aqua;border-radius: 5px;text-align: center;line-height: 50px;
        }
    </style>
</head>
<body>
<div οnclick="makeNoise()" class="button">点击发声</div>
<script type="application/javascript">
    var AudioContext=AudioContext||webkitAudioContext,
            context=new AudioContext,
            canClick = true,
            timeOut;
    function makeNoise(){
        var oscillator = context.createOscillator();
        oscillator.connect(context.destination);
        oscillator.frequency.value = 18500;
        oscillator.start(0);
    }
</script>

</body>
</html></span>


特别注意的是识别完成后请关闭这个网页


 



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HTML5 Web Audio Api 声音登陆 的相关文章

  • C语言初学:比较两个数的大小

    比较两数大小 1 利用if else输出较大值 include
  • Java设计模式-解释器模式

    解释器模式 在软件开发中 会遇到有些问题多次重复出现 而且有一定的相似性和规律性 如果将它们归纳成一种简单的语言 那么这些问题实例将是该语言的一些句子 这样就可以用 编译原理 中的解释器模式来实现了 虽然使用解释器模式的实例不是很多 但对于
  • element 表格嵌套 switch 踩坑

    因为项目需求 需要在表格中插入开关 当前的组件并不支持 手写了个简易demo 记录一下踩坑历程
  • 网站架构演变过程之微服务概念描述

    传统架构 传统的SSH架构 分为三层架构 web控制层 业务逻辑层 数据库访问层 传统架构也就是单点应用 就是大家在刚开始初学JavaEE技术的时候SSH架构或者SSM架构 业务没有进行拆分 都写同一个项目工程里面 一般是适合于个人或者是小
  • 企业使用VMware vSphere进行服务器虚拟化的经验分享

    企业使用VMware vSphere进行服务器虚拟化的经验分享 对于很多中小企业来说 虚拟化已经成为节省IT开支的一种重要手段 下面就根据公司Vmware虚拟化产品部署案例 同大家来详细分享一下在使用vSphere产品组建虚拟化数据中心的一
  • python中列表数据类型_python基础数据类型一(列表)

    列表 表是python的基础数据类型之一 其他编程语言也有类似的数据类型 比如JS中的数 组 java中的数组等等 它是以 括起来 每个元素用 隔开而且可以存放各种数据类型 列表是python中的基础数据类型之一 其他语言中也有类似于列表的
  • Python的PyYAML模块详解

    文章目录 简介 安装 简单安装 从源码安装 最常被问到的问题 使用详解 加载YAML 转储YAML 构造 表示和解析 YAML语法 文档 块序列 块映射 流集合 标量 别名 标签 YAML标签和Python3 对象 字符串转换 名称和模块
  • LaTeX Error: File `tabu.sty‘ not found.

    虽然Miktex可以自动下载和安装没有的库 但有些时候也有可能会直接报错 LaTeX Error File tabu sty not found 解决方法就是打开控制台 然后手动下载
  • linux切换用户su自动输入密码,Linux切换用户出现【su:命令鉴定故障】问题&修改的密码位数必须大于8位的问题...

    一 切换到普通用户出现 su 命令鉴定故障 创建用户设置好密码后 从root用户进入普通用户是不需要输入密码的 但是我切换到另一个普通用户 进行普通用户之间的切换的时候 出现了 su 命令鉴定故障 最开始我以为是我密码错误 后来改 也怎么都
  • 互联网小拼,这一生的故事,你要看看吗

    前言 谁也不知道 今天竟然是我的最后一天加班 我叫小拼 我来自农村 一个国家级贫困县 原以为会在老家种田一辈子 谁曾想 考上了一所大学 学了计算机专业改变了我的一生 大学毕业以前都没什么好说的 九年义务教育 再加高中三年 大学四年 毕业后
  • 引领高并发直播场景进入毫秒时代,阿里云发布超低延时直播服务

    近日 阿里云上线超低延时直播服务RTS Real time Streaming 该服务在视频直播产品的基础上 进行全链路延时监控 传输协议改造等底层技术优化 支持千万级并发场景下的毫秒级延迟直播能力 保障低延时 低卡顿 高清流畅的极致直播观
  • C++文件读取

    简介 最近在复习C 在写一个停车场管理系统项目的时候突然遇到了关于文件的处理 感觉忘记的差不多了 重新复习了一下 也顺便写一下笔记 当然在一个文章中有很多细节都没有进行深入的研究 只是知道一些基本的用法 主要感觉在学完数据库后再用文件系统进
  • java基础之内存机制详解

    今天有看到一篇好的关于java内存机制的文章 果断转载过来 哈哈哈哈哈哈 堆区 1 存储的全部是对象 每个对象都包含一个与之对应的class的信息 class的目的是得到操作指令 2 jvm只有一个堆区 heap 被所有线程共享 堆中不存放
  • 有符号数和无符号数详解

    有符号数和无符号数详解 1 通过例子看问题 2 有符号数和无符号数 2 1 什么是无符号数 2 2 什么是有符号数 2 3 有符号数和无符号数的区别 3 原码 反码 补码 3 1 背景 3 2 原码 反码 补码 3 2 1 什么是机器数 3
  • vue2 ant datepicker 日期选择框 点击此刻时间多8小时不正确解决方案

    点击 此刻 后 可以看到在DatePicker上时间是正确的 但是打印出来的dateString时间却多了8小时 原因 因为点击 此刻 那个按钮时 moment 对象会经过 getTodayTime 设置了 utcOffset utcOff
  • cd命令行 python_cd命令

    cd命令行 python Once you have a folder you can move into it using the cd command cd means change directory You invoke it sp
  • jdbc大数据量时处理速度的比较

    在预编译空间够的情况下 使用预编译 addBatch gt 纯预编译 gt 原生sql语句
  • vue移动端无法使用string.replaceAll,报错显示空白

    开发vue时 使用了replaceAll函数 在pc端调试没问题 但是打包部署到移动端端测试时 发现部分页面显示空白 控制台只显示Error 经过排查是replaceAll函数报错了 替换成replace解决
  • 如何将彩图.png转换成灰度图.png(python)

    1 安装所需要的包 使用PIL库需要先安装Pillow包 Pillow是PIL库的一个Fork 分支 它提供了与PIL兼容的API 并进行了一些功能扩展和改进 因此 在使用PIL之前 需要确保已经正确安装了Pillow包 可以使用pip命令

随机推荐

  • Python实现照片右上角添加红色数字

    Python实现照片右上角添加红色数字 在许多图像处理应用程序中 我们经常需要在图像上添加一些标记或注释 本文将介绍如何使用Python编程语言在照片的右上角添加一个红色的数字 我们将使用Python的Pillow库来处理图像 并利用该库提
  • android.intent.extra,Android Intent的几种用法详细解析

    Intent应该算是Android中特有的东西 你可以在Intent中指定程序要执行的动作 比如 view edit dial 以及程序执行到该动作时所需要的资料 都指定好后 只要调用startActivity Android系统会自动寻找
  • C语言预处理条件语句的 与或运算

    C语言预处理条件语句的 与或运算 1 ifdef 与或运算 ifdef MIN MAX 错误使用 if defined MIN defined MAX 正确使用 ifdef MIN MAX 错误使用 if defined MIN defin
  • 汇编语言 第3版 王爽 检测点答案及详细解析

    第一章 基础知识 检测点1 1 1 1个CPU的寻址能力为8KB 那么它的地址总线的宽度为 13位 2 1KB的存储器有 1024 个存储单元 存储单元的编号从 0 到 1023 3 1KB的存储器可以存储 8192 2 13 个bit 1
  • HTML 一文读懂

    目录 1 认识HTML 2 HTML 网页构成 HTML基本结构 网页头部信息 3 HTML 基本标签 4 图像标签 5 链接标签 6 行内元素和块元素 7 列表 8 表格 9 媒体元素 10 页面结构分析 11 HTML 内联框架 ifr
  • 本地搭建web服务器、个人博客并发布公网访问

    文章目录 前言 1 安装套件软件 2 创建网页运行环境 指定网页输出的端口号 3 让WordPress在所需环境中安装并运行 生成网页 4 装修 个人网站 5 将位于本地电脑上的网页发布到公共互联网上 前言 在现代社会 网络已经成为我们生活
  • Spring Boot + Vue的网上商城之登陆认证

    Spring Boot Vue的网上商城之登陆认证 本篇博客介绍了如何使用Spring Boot和Vue来实现网上商城的登陆认证功能 下面是本文的主要内容总结 后端实现 创建Spring Boot项目 并添加Spring Security和
  • 为什么spring单例模式可以支持多线程并发访问

    为什么spring单例模式可以支持多线程并发访问 1 spring单例模式是指 在内存中只实例化一个类的对象 2 类的变量有线程安全的问题 就是有get和set方法的类成员属性 执行单例对象的方法不会有线程安全的问题 因为方法是磁盘上的一段
  • Vulnhub靶机-BLACKLIGHT

    项目地址 http download vulnhub com blacklight BLACKLIGHT ova 靶机渗透 网络选择桥接模式 使用命令 arp scan l nmap 192 168 0 130 使用dirb遍历网站目录结构
  • Linux自学笔记

    Linux自学笔记 06 常用命令 文件目录类 Linux自学笔记 01 文件系统和目录结构 Linux自学笔记 02 VIM编辑器的安装与使用 Linux自学笔记 03 Linux网络配置 Linux自学笔记 04 远程登录 Linux自
  • 高速模数转换器(ADC)的INL/DNL测量

    摘要 尽管积分非线性和微分非线性不是高速 高动态性能数据转换器最重要的参数 但在高分辨率成像应用中却具有重要意义 本文简要回顾了这两个参数的定义 并给出了两种不同但常用的测量高速模数转换器 ADC 的INL DNL的方法 近期 许多厂商推出
  • 微信小程序 ---- 【invalid credential, access_token is invalid】

    报错返回 errcode 40001 errmsg invalid credential access token is invalid or not latest rid 6004f3da 1529ba72 5c345f67 报错原因 a
  • oled拼接屏有哪些安装方法?

    嘉峪关是一个历史悠久的城市 也是一个旅游胜地 为了更好地展示城市的文化和旅游资源 嘉峪关市政府决定在市区的重要场所安装oled拼接屏 oled拼接屏是一种高清晰度的显示屏 具有高亮度 高对比度 高色彩饱和度等优点 它可以将图像和视频以更清晰
  • qtp的基本使用方法(1)

    1 action qtp为每一个action生成相应的测试文件和目录 对象库也是和action绑定的 用action 来划分和组织测试流程 编辑action 修改action的名字 action properties 增加action in
  • StartSSL CA证书签名 和 Tomcat Https访问 全过程说明

    第1章 准备工作 IP地址 外网服务器的IP 如X X 47 xx 作用 1 解析域名 2 部署Tomcat7 域 名 将域名 如samuscasting cn 解析 映射到外网IP 注 1 记住购买域名所使用的邮箱 原因 认证机构对域名做
  • QGIS编译(跨平台编译)之五十一:MacOS环境下安装Python、pyqt5、pyqt5-tools等

    目录 1 安装背景 2 卸载Python 3 下载Python3 9 4 安装Python3 9 5 安装pyqt5 6 安装pyqt5 tools
  • 微信小程序 分享图片大小处理

    1 在分享的page 添加 canvas 标签
  • c++单链表的创建、输出、插入、删除操作

    混子来了 单链表的创建 首先单链表的定义就不再赘述了 本文利用带头节点 尾插法的方法进行创建 同时注意头节点在此的重要性 即所有操作都要通过头节点来实现 头节点的值绝对不能被改变 结点的定义 struct ListNode 定义节点 int
  • 最小的前端开发框架 Vanilla JS

    刚刚在看前端文章的时候看到了Vanilla JS 这是什么高端框架 打开了谷鸽google搜索 果然是发现了不得了的技术 VanillaJS是库 框架免费javascript的术语 它有时具有讽刺意味地被称为库 这是为那些可能会盲目使用不同
  • HTML5 Web Audio Api 声音登陆

    之前最早时候给过一个识别hz的demo 今天讲那个demo结合上一篇说的振荡器 做了个声音登录的小demo 原理就是2w hz人听不见 其实1w9左右就很轻微了 直接上代码 识别器 限电脑 span style font size 18px