• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com专业计算机教程网站
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • html/xhtml
  • html5
  • CSS
  • XML/XSLT
  • Dreamweaver教程
  • Frontpage教程
  • 心得技巧
  • bootstrap
  • vue
  • AngularJS
  • HBuilder教程
  • css3
  • 浏览器兼容
  • div/css
  • 网页编辑器
  • axure
您的位置:首页 > 网页设计 >html5 > 详解HTML5网页录音和压缩的示例代码

详解HTML5网页录音和压缩的示例代码

作者:匿名 字体:[增加 减小] 来源:互联网 时间:2018-12-03

本文主要包含HTML5,网页录音,压缩等相关知识,匿名希望在学习及工作中可以帮助到您
最近公司需要用到web录音的功能

讲的都差不多

问题1:怎么上传

下载来的栗子也比较简单,可以直接运行

问题1:怎么上传

栗子中最后返回的是Blob数据

return new Blob([dataview], { type: type })

因为对html5不熟,所以又查了一些数据

原来HTML5中使用FormData这个对象好方便

var fd = new FormData();
fd.append("audioData", blob);var xhr = new XMLHttpRequest();
xhr.open("POST", url);
xhr.send(fd);

在C#服务器端 如下代码就可以接收了

public void ProcessRequest(HttpContext context)
{    if (context.Request.Files.Count > 0)
    {
        context.Request.Files[0].SaveAs("d:\\1.wav");
    }
}

问题2:文件体积太大

是的,使用上面的栗子,直接录音保存后基本上2秒就需要400K,一段20秒的录音就达到了的4M

这样的数据根本无法使用,必须想办法压缩数据

我开始尝试读每一段代码

function encodeWAV(samples){  
var buffer = new ArrayBuffer(44 + samples.length * 2); 
 var view = new DataView(buffer); 
  /* RIFF identifier */
  writeString(view, 0, 'RIFF');  /* file length */
  view.setUint32(4, 32 + samples.length * 2, true);  /* RIFF type */
  writeString(view, 8, 'WAVE');  /* format chunk identifier */
  writeString(view, 12, 'fmt ');  /* format chunk length */
  view.setUint32(16, 16, true);  /* sample format (raw) */
  view.setUint16(20, 1, true);  /* channel count */
  view.setUint16(22, 2, true);  /* sample rate */
  view.setUint32(24, sampleRate, true);  /* byte rate (sample rate * block align) */
  view.setUint32(28, sampleRate * 4, true);  /* block align (channel count * bytes per sample) */
  view.setUint16(32, 4, true);  /* bits per sample */
  view.setUint16(34, 16, true);  /* data chunk identifier */
  writeString(view, 36, 'data');  /* data chunk length */
  view.setUint32(40, samples.length * 2, true);
 
  floatTo16BitPCM(view, 44, samples); 
  return view;
}

上面的代码,就是把字节数据格式化成wav的格式的过程

所以我又去查了wav的头文件

要压缩,就要从上面三个红圈的地方入手

最简单的就是把双声道改成单声道的,

在录音的时候只需要记录一个声道就可以了

// 创建声音的缓存节点,createJavaScriptNode方法的
    // 第二个和第三个参数指的是输入和输出都是双声道。
    //recorder = context.createJavaScriptNode(bufferSize, 2, 2);
    recorder = context.createJavaScriptNode(bufferSize, 1, 1);//这里改成1

    this.node.onaudioprocess = function(e){
      if (!recording) return;
      worker.postMessage({
        command: 'record',
        buffer: [
          e.inputBuffer.getChannelData(0)//,
          //e.inputBuffer.getChannelData(1)// 这里只需要保存一个
        ]
      });
    }

function exportWAV(type){
  var bufferL = mergeBuffers(recBuffersL, recLength);
  //var bufferR = mergeBuffers(recBuffersR, recLength);
  var interleaved = interleave(bufferL);//, bufferR); //合并数据的时候去到对右声道的处理
  var dataview = encodeWAV(interleaved);
  var audioBlob = new Blob([dataview], { type: type });
 
  this.postMessage(audioBlob);
}

function interleave(inputL){//, inputR){//混合声道的时候去掉对右声道的处理
  var length = inputL.length ;//+ inputR.length;
  var result = new Float32Array(length);
 
  var index = 0,
    inputIndex = 0;
 
  while (index < length){
    result[index++] = inputL[inputIndex];
    //result[index++] = inputR[inputIndex];
    inputIndex++;
  }
  return result;
}

然后修改一下注释,我不喜欢英文的....

function encodeWAV(samples) {
    var dataLength = samples.length * 2;
    var buffer = new ArrayBuffer(44 + dataLength);
    var view = new DataView(buffer);

    var sampleRateTmp = sampleRate;
    var sampleBits = 16;
    var channelCount = 1;
    var offset = 0;
    /* 资源交换文件标识符 */
    writeString(view, offset, 'RIFF'); offset += 4;
    /* 下个地址开始到文件尾总字节数,即文件大小-8 */
    view.setUint32(offset, /*32这里地方栗子中的值错了,但是不知道为什么依然可以运行成功*/ 36 + dataLength, true); offset += 4;
    /* WAV文件标志 */
    writeString(view, offset, 'WAVE'); offset += 4;
    /* 波形格式标志 */
    writeString(view, offset, 'fmt '); offset += 4;
    /* 过滤字节,一般为 0x10 = 16 */
    view.setUint32(offset, 16, true); offset += 4;
    /* 格式类别 (PCM形式采样数据) */
    view.setUint16(offset, 1, true); offset += 2;
    /* 通道数 */
    view.setUint16(offset, channelCount, true); offset += 2;
    /* 采样率,每秒样本数,表示每个通道的播放速度 */
    view.setUint32(offset, sampleRateTmp, true); offset += 4;
    /* 波形数据传输率 (每秒平均字节数) 通道数×每秒数据位数×每样本数据位/8 */
    view.setUint32(offset, sampleRateTmp * channelCount * (sampleBits / 8), true); offset += 4;
    /* 快数据调整数 采样一次占用字节数 通道数×每样本的数据位数/8 */
    view.setUint16(offset, channelCount * (sampleBits / 8), true); offset += 2;
    /* 每样本数据位数 */
    view.setUint16(offset, sampleBits, true); offset += 2;
    /* 数据标识符 */
    writeString(view, offset, 'data'); offset += 4;
    /* 采样数据总数,即数据总大小-44 */
    view.setUint32(offset, dataLength, true); offset += 4;
    /* 采样数据 */
    floatTo16BitPCM(view, 44, samples);

    return view;
}

一旦把双声道变为单声道,数据直接缩小一半了

但是还不够

继续缩小体积

除了声道以外,还有一个可以缩减的地方就是采样位数 默认是16位的,我们改成8位 又可以减少一半了

function encodeWAV(samples) {
    var sampleBits = 8;//16;//这里改成8位
    var dataLength = samples.length * (sampleBits / 8);
    var buffer = new ArrayBuffer(44 + dataLength);
    var view = new DataView(buffer);

    var sampleRateTmp = sampleRate;

    var channelCount = 1;
    var offset = 0;
    /* 资源交换文件标识符 */
    writeString(view, offset, 'RIFF'); offset += 4;
    /* 下个地址开始到文件尾总字节数,即文件大小-8 */
    view.setUint32(offset, /*32这里地方栗子中的值错了,但是不知道为什么依然可以运行成功*/ 36 + dataLength, true); offset += 4;
    /* WAV文件标志 */
    writeString(view, offset, 'WAVE'); offset += 4;
    /* 波形格式标志 */
    writeString(view, offset, 'fmt '); offset += 4;
    /* 过滤字节,一般为 0x10 = 16 */
    view.setUint32(offset, 16, true); offset += 4;
    /* 格式类别 (PCM形式采样数据) */
    view.setUint16(offset, 1, true); offset += 2;
    /* 通道数 */
    view.setUint16(offset, channelCount, true); offset += 2;
    /* 采样率,每秒样本数,表示每个通道的播放速度 */
    view.setUint32(offset, sampleRateTmp, true); offset += 4;
    /* 波形数据传输率 (每秒平均字节数) 通道数×每秒数据位数×每样本数据位/8 */
    view.setUint32(offset, sampleRateTmp * channelCount * (sampleBits / 8), true); offset += 4;
    /* 快数据调整数 采样一次占用字节数 通道数×每样本的数据位数/8 */
    view.setUint16(offset, channelCount * (sampleBits / 8), true); offset += 2;
    /* 每样本数据位数 */
    view.setUint16(offset, sampleBits, true); offset += 2;
    /* 数据标识符 */
    writeString(view, offset, 'data'); offset += 4;
    /* 采样数据总数,即数据总大小-44 */
    view.setUint32(offset, dataLength, true); offset += 4;
    /* 采样数据 */
    //floatTo16BitPCM(view, 44, samples);
    floatTo8BitPCM(view, 44, samples);//这里改
  


 

您可能想查找下面的文章:

  • HTML5知识点总结
  • HTML5的本地存储
  • HTML5本地存储之IndexedDB
  • Html5实现文件异步上传功能
  • Html5新标签datalist实现输入框与后台数据库数据的动态匹配
  • 详解HTML5 window.postMessage与跨域
  • HTML5拖放API实现拖放排序的实例代码
  • 解决html5中video标签无法播放mp4问题的办法
  • HTML5新特性 多线程(Worker SharedWorker)
  • Html5新增标签有哪些

相关文章

  • 2017-08-06使用phonegap获取设备的一些信息方法
  • 2018-12-03有关射击的文章推荐10篇
  • 2017-08-06HTML5 Web Database 数据库的SQL语句的使用方法
  • 2018-12-03小强的HTML5移动开发之路(53)——jQueryMobile页面间参数传递
  • 2018-12-03html5定位获取当前位置并在百度地图上显示_html5教程技巧
  • 2018-12-03html5实现的便签特效(实战分享)_html5教程技巧
  • 2017-08-06HTML5实践-图片设置成灰度图
  • 2018-12-03HTML5 WebApp part4:使用 Web Workers 来加速您的移动 Web 应用程序(上) ...
  • 2018-12-03JS代码实现瀑布流插件
  • 2018-12-03React Router中的核心history库的详细分析

文章分类

  • html/xhtml
  • html5
  • CSS
  • XML/XSLT
  • Dreamweaver教程
  • Frontpage教程
  • 心得技巧
  • bootstrap
  • vue
  • AngularJS
  • HBuilder教程
  • css3
  • 浏览器兼容
  • div/css
  • 网页编辑器
  • axure

最近更新的内容

    • 如何自动获取HTML5的data-*属性示例代码详解
    • html5 实现如何将两个矩形相互叠加
    • 关于印刷的10篇文章推荐
    • 前端未来页面布局发展方向是 Flexbox 还是 Grid?
    • 值得收藏的HTML5资源(学习html5的朋友可以收藏下)
    • 用HTML5制作一个简单的弹力球游戏_html5教程技巧
    • HTML5 对各个标签的定义与规定:body的介绍_html5教程技巧
    • Html5游戏开发之乒乓Ping Pong游戏示例(一)_html5教程技巧
    • 让IE下支持Html5的placeholder属性的插件_html5教程技巧
    • HTML5 中的新数组

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有