Home Web Front-end H5 Tutorial Implementation of HTML5 sound recording and playback functions

Implementation of HTML5 sound recording and playback functions

Jul 02, 2018 am 11:53 AM
h5

This article introduces the HTML5 sound recording/playback function to everyone through example code. It is very good and has reference value. Friends who need it can follow the editor of Script House to learn together

html code:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>火星黑洞</title>
    </head>
    <body>
        <p>
            <audio autoplay></audio>
            <input onclick="startRecording()" type="button" value="录音" />
            <input onclick="stopRecording()" type="button" value="停止" />
            <input onclick="playRecording()" type="button" value="播放" />
            <input onclick="uploadAudio()" type="button" value="提交" />
            <br />
            <p id="recordingslist"></p>
        </p>
        <script type="text/javascript" src="js/HZRecorder.js"></script>
        <script>
            var recorder;
            var audio = document.querySelector(&#39;audio&#39;);
            function startRecording() {
                HZRecorder.get(function(rec) {
                    recorder = rec;
                    recorder.start();
                }, {
                    sampleBits: 16,
                    sampleRate: 16000
                });
            }
            function stopRecording() {
                recorder.stop();
                var blob = recorder.getBlob();
                var url = URL.createObjectURL(blob);
                var p = document.createElement(&#39;p&#39;);
                var au = document.createElement(&#39;audio&#39;);
                var hf = document.createElement(&#39;a&#39;);
                au.controls = true;
                au.src = url;
                hf.href = url;
                hf.download = new Date().toISOString() + &#39;.wav&#39;;
                hf.innerHTML = hf.download;
                p.appendChild(au);
                p.appendChild(hf);
                recordingslist.appendChild(p);
            }
            function playRecording() {
                recorder.play(audio);
            }
            function uploadAudio() {
                recorder.upload("Handler1.ashx", function(state, e) {
                    switch(state) {
                        case &#39;uploading&#39;:
                            //var percentComplete = Math.round(e.loaded * 100 / e.total) + &#39;%&#39;;
                            break;
                        case &#39;ok&#39;:
                            //alert(e.target.responseText);
                            alert("上传成功");
                            break;
                        case &#39;error&#39;:
                            alert("上传失败");
                            break;
                        case &#39;cancel&#39;:
                            alert("上传被取消");
                            break;
                    }
                });
            }
        </script>
    </body>
</html>
Copy after login

HZRecorder.js

(function (window) {
    //兼容
    window.URL = window.URL || window.webkitURL;
    navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
    var HZRecorder = function (stream, config) {
        config = config || {};
        config.sampleBits = config.sampleBits || 8      //采样数位 8, 16
        config.sampleRate = config.sampleRate || (44100 / 6);   //采样率(1/6 44100)
        var context = new (window.webkitAudioContext || window.AudioContext)();
        var audioInput = context.createMediaStreamSource(stream);
        var createScript = context.createScriptProcessor || context.createJavaScriptNode;
        var recorder = createScript.apply(context, [4096, 1, 1]);
        var mp3ReceiveSuccess, currentErrorCallback;
        var audioData = {
            size: 0          //录音文件长度
            , buffer: []     //录音缓存
            , inputSampleRate: context.sampleRate    //输入采样率
            , inputSampleBits: 16       //输入采样数位 8, 16
            , outputSampleRate: config.sampleRate    //输出采样率
            , oututSampleBits: config.sampleBits       //输出采样数位 8, 16
            , input: function (data) {
                this.buffer.push(new Float32Array(data));
                this.size += data.length;
            }
            , compress: function () { //合并压缩
                //合并
                var data = new Float32Array(this.size);
                var offset = 0;
                for (var i = 0; i < this.buffer.length; i++) {
                    data.set(this.buffer[i], offset);
                    offset += this.buffer[i].length;
                }
                //压缩
                var compression = parseInt(this.inputSampleRate / this.outputSampleRate);
                var length = data.length / compression;
                var result = new Float32Array(length);
                var index = 0, j = 0;
                while (index < length) {
                    result[index] = data[j];
                    j += compression;
                    index++;
                }
                return result;
            }
            , encodeWAV: function () {
                var sampleRate = Math.min(this.inputSampleRate, this.outputSampleRate);
                var sampleBits = Math.min(this.inputSampleBits, this.oututSampleBits);
                var bytes = this.compress();
                var dataLength = bytes.length * (sampleBits / 8);
                var buffer = new ArrayBuffer(44 + dataLength);
                var data = new DataView(buffer);
                var channelCount = 1;//单声道
                var offset = 0;
                var writeString = function (str) {
                    for (var i = 0; i < str.length; i++) {
                        data.setUint8(offset + i, str.charCodeAt(i));
                    }
                }
                // 资源交换文件标识符 
                writeString(&#39;RIFF&#39;); offset += 4;
                // 下个地址开始到文件尾总字节数,即文件大小-8 
                data.setUint32(offset, 36 + dataLength, true); offset += 4;
                // WAV文件标志
                writeString(&#39;WAVE&#39;); offset += 4;
                // 波形格式标志 
                writeString(&#39;fmt &#39;); offset += 4;
                // 过滤字节,一般为 0x10 = 16 
                data.setUint32(offset, 16, true); offset += 4;
                // 格式类别 (PCM形式采样数据) 
                data.setUint16(offset, 1, true); offset += 2;
                // 通道数 
                data.setUint16(offset, channelCount, true); offset += 2;
                // 采样率,每秒样本数,表示每个通道的播放速度 
                data.setUint32(offset, sampleRate, true); offset += 4;
                // 波形数据传输率 (每秒平均字节数) 单声道×每秒数据位数×每样本数据位/8 
                data.setUint32(offset, channelCount * sampleRate * (sampleBits / 8), true); offset += 4;
                // 快数据调整数 采样一次占用字节数 单声道×每样本的数据位数/8 
                data.setUint16(offset, channelCount * (sampleBits / 8), true); offset += 2;
                // 每样本数据位数 
                data.setUint16(offset, sampleBits, true); offset += 2;
                // 数据标识符 
                writeString(&#39;data&#39;); offset += 4;
                // 采样数据总数,即数据总大小-44 
                data.setUint32(offset, dataLength, true); offset += 4;
                // 写入采样数据 
                if (sampleBits === 8) {
                    for (var i = 0; i < bytes.length; i++, offset++) {
                        var s = Math.max(-1, Math.min(1, bytes[i]));
                        var val = s < 0 ? s * 0x8000 : s * 0x7FFF;
                        val = parseInt(255 / (65535 / (val + 32768)));
                        data.setInt8(offset, val, true);
                    }
                } else {
                    for (var i = 0; i < bytes.length; i++, offset += 2) {
                        var s = Math.max(-1, Math.min(1, bytes[i]));
                        data.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
                    }
                }
                return new Blob([data], { type: &#39;audio/wav&#39; });
            }
        };
        //开始录音
        this.start = function () {
            audioInput.connect(recorder);
            recorder.connect(context.destination);
        }
        //停止
        this.stop = function () {
            recorder.disconnect();
        }
        //获取音频文件
        this.getBlob = function () {
            this.stop();
            return audioData.encodeWAV();
        }
        //回放
        this.play = function (audio) {
            audio.src = window.URL.createObjectURL(this.getBlob());
        }
        //上传
        this.upload = function (url, callback) {
            var fd = new FormData();
            fd.append("audioData", this.getBlob());
            var xhr = new XMLHttpRequest();
            if (callback) {
                xhr.upload.addEventListener("progress", function (e) {
                    callback(&#39;uploading&#39;, e);
                }, false);
                xhr.addEventListener("load", function (e) {
                    callback(&#39;ok&#39;, e);
                }, false);
                xhr.addEventListener("error", function (e) {
                    callback(&#39;error&#39;, e);
                }, false);
                xhr.addEventListener("abort", function (e) {
                    callback(&#39;cancel&#39;, e);
                }, false);
            }
            xhr.open("POST", url);
            xhr.send(fd);
        }
        //音频采集
        recorder.onaudioprocess = function (e) {
            audioData.input(e.inputBuffer.getChannelData(0));
            //record(e.inputBuffer.getChannelData(0));
        }
    };
    //抛出异常
    HZRecorder.throwError = function (message) {
        alert(message);
        throw new function () { this.toString = function () { return message; } }
    }
    //是否支持录音
    HZRecorder.canRecording = (navigator.getUserMedia != null);
    //获取录音机
    HZRecorder.get = function (callback, config) {
        if (callback) {
            if (navigator.getUserMedia) {
                navigator.getUserMedia(
                    { audio: true } //只启用音频
                    , function (stream) {
                        var rec = new HZRecorder(stream, config);
                        callback(rec);
                    }
                    , function (error) {
                        switch (error.code || error.name) {
                            case &#39;PERMISSION_DENIED&#39;:
                            case &#39;PermissionDeniedError&#39;:
                                HZRecorder.throwError(&#39;用户拒绝提供信息。&#39;);
                                break;
                            case &#39;NOT_SUPPORTED_ERROR&#39;:
                            case &#39;NotSupportedError&#39;:
                                HZRecorder.throwError(&#39;浏览器不支持硬件设备。&#39;);
                                break;
                            case &#39;MANDATORY_UNSATISFIED_ERROR&#39;:
                            case &#39;MandatoryUnsatisfiedError&#39;:
                                HZRecorder.throwError(&#39;无法发现指定的硬件设备。&#39;);
                                break;
                            default:
                                HZRecorder.throwError(&#39;无法打开麦克风。异常信息:&#39; + (error.code || error.name));
                                break;
                        }
                    });
            } else {
                HZRecorder.throwErr(&#39;当前浏览器不支持录音功能。&#39;); return;
            }
        }
    }
    window.HZRecorder = HZRecorder;
})(window);
Copy after login

The above is the entire content of this article, I hope it will help everyone learn Helpful, please pay attention to the PHP Chinese website for more related content!

Related recommendations:

How to solve the problem of HTML5 virtual keyboard blocking the input box

About HTML5 and CSS3 implementation machines Cat code

The above is the detailed content of Implementation of HTML5 sound recording and playback functions. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

What does h5 mean? What does h5 mean? Aug 02, 2023 pm 01:52 PM

H5 refers to HTML5, the latest version of HTML. H5 is a powerful markup language that provides developers with more choices and creative space. Its emergence promotes the development of Web technology, making the interaction and effect of web pages more Excellent, as H5 technology gradually matures and becomes popular, I believe it will play an increasingly important role in the Internet world.

How to distinguish between H5, WEB front-end, big front-end, and WEB full stack? How to distinguish between H5, WEB front-end, big front-end, and WEB full stack? Aug 03, 2022 pm 04:00 PM

This article will help you quickly distinguish between H5, WEB front-end, large front-end, and WEB full stack. I hope it will be helpful to friends in need!

How to use position in h5 How to use position in h5 Dec 26, 2023 pm 01:39 PM

In H5, you can use the position attribute to control the positioning of elements through CSS: 1. Relative positioning, the syntax is "style="position: relative;"; 2. Absolute positioning, the syntax is "style="position: absolute;" "; 3. Fixed positioning, the syntax is "style="position: fixed;" and so on.

How to implement h5 to slide up on the web side to load the next page How to implement h5 to slide up on the web side to load the next page Mar 11, 2024 am 10:26 AM

Implementation steps: 1. Monitor the scroll event of the page; 2. Determine whether the page has scrolled to the bottom; 3. Load the next page of data; 4. Update the page scroll position.

How to implement H5 form validation component in vue3 How to implement H5 form validation component in vue3 Jun 03, 2023 pm 02:09 PM

The rendering description is based on vue.js and does not rely on other plug-ins or libraries; the basic functions remain consistent with element-ui, and some adjustments have been made to the internal implementation for mobile terminal differences. The current construction platform is built using the uni-app official scaffolding. Because most mobile terminals currently have two types: h6 and WeChat mini-programs, it is very suitable for technology selection to run one set of code on multiple terminals. Implementation idea core api: use provide and inject, corresponding to and. In the component, a variable (array) is used internally to store all instances, and the data to be transferred is exposed through provide; the component uses inject internally to receive the data provided by the parent component, and finally combines its own attributes with method submission

What Does H5 Refer To? Exploring the Context What Does H5 Refer To? Exploring the Context Apr 12, 2025 am 12:03 AM

H5referstoHTML5,apivotaltechnologyinwebdevelopment.1)HTML5introducesnewelementsandAPIsforrich,dynamicwebapplications.2)Itsupportsmultimediawithoutplugins,enhancinguserexperienceacrossdevices.3)SemanticelementsimprovecontentstructureandSEO.4)H5'srespo

Summary and introduction to the new H5 promotion tag (with examples) Summary and introduction to the new H5 promotion tag (with examples) Aug 03, 2022 pm 05:10 PM

​This article will give you an introduction to the new H5 promotion tags. I hope it will be helpful to friends in need!

Is h5 same as HTML5? Is h5 same as HTML5? Apr 08, 2025 am 12:16 AM

"h5" and "HTML5" are the same in most cases, but they may have different meanings in certain specific scenarios. 1. "HTML5" is a W3C-defined standard that contains new tags and APIs. 2. "h5" is usually the abbreviation of HTML5, but in mobile development, it may refer to a framework based on HTML5. Understanding these differences helps to use these terms accurately in your project.

See all articles