h5 如何录音保存上传_H5进行录音,播放,上传

本文介绍了如何在H5中实现录音、播放、保存并上传的功能。通过利用webkitAudioContext和getUserMedia API,创建HZRecorder类来处理录音过程,包括采样率、采样数位的设置,并将录音数据转换为WAV格式的Blob对象,便于文件上传。
摘要由CSDN通过智能技术生成

(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 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

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= newFloat32Array(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= newArrayBuffer(44 + dataLength);

var data= newDataView(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('RIFF'); offset += 4;// 下个地址开始到文件尾总字节数,即文件大小-8

data.setUint32(offset, 36 + dataLength, true); offset += 4;// WAV文件标志

writeString('WAVE'); offset += 4;// 波形格式标志

writeString('fmt '); offset += 4;// 过滤字节,一般为 0x10= 16data.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('data'); 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: 'audio/wav' });

}

};

//开始录音

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= newFormData();

fd.append("audioData", this.getBlob());

var xhr= newXMLHttpRequest();

if (callback) {

xhr.upload.addEventListener("progress", function (e) {

callback('uploading', e);

}, false);

xhr.addEventListener("load", function (e) {

callback('ok', e);

}, false);

xhr.addEventListener("error", function (e) {

callback('error', e);

}, false);

xhr.addEventListener("abort", function (e) {

callback('cancel', 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= newHZRecorder(stream, config);

callback(rec);

}

, function (error) {

switch (error.code || error.name) {

case 'PERMISSION_DENIED':

case 'PermissionDeniedError':

HZRecorder.throwError('用户拒绝提供信息。');

break;

case 'NOT_SUPPORTED_ERROR':

case 'NotSupportedError':

HZRecorder.throwError('浏览器不支持硬件设备。');

break;

case 'MANDATORY_UNSATISFIED_ERROR':

case 'MandatoryUnsatisfiedError':

HZRecorder.throwError('无法发现指定的硬件设备。');

break;

default:

HZRecorder.throwError('无法打开麦克风。异常信息:' + (error.code || error.name));

break;

}

});

} else {

HZRecorder.throwErr('当前浏览器不支持录音功能。'); return;

}

}

}

window.HZRecorder= HZRecorder;})(window);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值