bricks/bricks/audio.js
2024-03-21 18:12:24 +08:00

262 lines
6.3 KiB
JavaScript
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

var bricks = window.bricks || {};
bricks.formatMs=function(ms,all){
var ss=ms%1000;ms=(ms-ss)/1000;
var s=ms%60;ms=(ms-s)/60;
var m=ms%60;ms=(ms-m)/60;
var h=ms;
var t=(h?h+":":"")
+(all||h+m?("0"+m).substr(-2)+":":"")
+(all||h+m+s?("0"+s).substr(-2)+"″":"")
+("00"+ss).substr(-3);
return t;
};
bricks.AudioPlayer = class extends bricks.JsWidget {
/*
{
url:
autoplay:
}
*/
constructor(options){
super(options);
this.url = options.url;
this.audio = this._create('audio');
this.audio.controls = true;
if (this.opts.autoplay){
this.audio.addEventListener('canplay', this.play_audio.bind(this));
}
this.audio.style.width = "100%"
this.source = this._create('source');
this.source.src = this.opts.url;
this.audio.appendChild(this.source);
this.dom_element.appendChild(this.audio);
}
set_source(url){
this.audio.src = url;
bricks.debug(this.audio.src,' new src seted');
}
play(){
this.audio.play();
}
toggle_play(){
if (this.audio.paused){
this.audio.play();
} else {
this.audio.pause();
}
}
set_url(url){
this.set_source(url);
}
}
bricks.AudioRecorder = class extends bricks.HBox {
/*
{
"upload_url":
"icon_rate":
}
we need this module:
https://gitee.com/xiangyuecn/Recorder
events:
record_started
record_ended
realtime record wave show need a another package
we only use the wav file format
*/
constructor(opts){
super(opts);
this.start_icon = opts.start_icon || bricks_resource('imgs/start_recording.png');
this.stop_icon = opts.stop_icon || bricks_resource('imgs/stop_recording.png');
this.rec_btn = new bricks.Icon({
dynsize:true,
url:this.start_icon,
rate:this.icon_rate
});
// this.player = new bricks.AudioPlayer({url:"",width:'80px'});
this.rec_time = new bricks.Text({
text:" record time",
i18n:false,
dynsize:true,
wrap:false,
width:'120px'
});
this.upload_url = opts.upload_url;
this.rec_btn.bind('click', this.rec_btn_pressed.bind(this))
this.URL = window.URL||webkitURL;
this.rec = null;
this.wave = null;
this.mic_opened = false;
this.add_widget(this.rec_btn);
this.add_widget(this.rec_time);
this.recordData = null;
this.bind('record_ended', this.upload.bind(this));
}
rec_btn_pressed(){
bricks.debug(this.rec_btn.url, ':url:', this.start_icon, this.stop_icon);
if(this.rec_btn.url == this.start_icon){
this.rec_btn.set_url(this.stop_icon);
this.start_recording();
} else {
this.rec_btn.set_url(this.start_icon);
this.stop_recording();
}
}
on_process(buffers,powerLevel,
bufferDuration,bufferSampleRate,
newBufferIdx,asyncEnd){
//录音实时回调大约1秒调用12次本回调
// document.querySelector(".recpowerx").style.width=powerLevel+"%";
//可视化图形绘制
// wave.input(buffers[buffers.length-1],powerLevel,bufferSampleRate);
this.rec_time.set_text(' ' + bricks.formatMs(bufferDuration,1));
}
recOpen(){
this.rec=null;
this.wave=null;
var newRec = Recorder({
type:"wav",sampleRate:16000,bitRate:16
,onProcess:this.on_process.bind(this)
});
newRec.open(function(){//打开麦克风授权获得相关资源
this.mic_opened = true;
this.rec=newRec;
this.rec.start();
this.dispatch('record_started');
//此处创建这些音频可视化图形绘制浏览器支持妥妥的
//this.wave=Recorder.FrequencyHistogramView({elem:".recwave"});
}.bind(this),function(msg,isUserNotAllow){//用户拒绝未授权或不支持
bricks.debug('open recorder failed');
});
}
recClose(){
if(this.rec){
this.rec.close();
this.rec = null;
this.mic_opened = false;
}else{
bricks.debug('close recorder error');
};
}
start_recording(){
this.recordData = null;
if( this.recordData ){
this.URL.revokeObjectURL(this.recordData.url);
}
if (this.mic_opened){
this.rec.start();
this.dispatch('record_started');
}
this.recOpen();
}
pause_recording(){
if(this.rec&&Recorder.IsOpen()){
this.rec.pause();
}else{
bricks.debug("gCAR::未打开录音");
};
}
resume_recording(){
if(this.rec&&Recorder.IsOpen()){
this.rec.resume();
}else{
bricks.debug("Ob6S::未打开录音");
};
}
stop_recording(){
if(!(this.rec&&Recorder.IsOpen())){
bricks.debug("5JuL::未打开录音");
return;
};
this.rec.stop(function(blob,duration){
var localURL = this.URL.createObjectURL(blob);
var d = {
data:blob,
url:localURL,
duration:duration
}
this.recordData = d;
this.dispatch('record_ended', d);
}.bind(this),function(msg){
bricks.debug("kGZO::录音失败:");
});
this.recClose();
}
upload = async function(){
var running = new bricks.Running({target:this});
if(!this.recordData){
bricks.debug("DUTn::请先录音,然后停止后再上传");
return;
};
if(!this.upload_url){
return;
}
var blob=this.recordData.data;
bricks.debug('blob=', blob, this.recordData);
var form=new FormData();
form.append("audiofile",blob,"recorder.wav");
var jpost = bricks.jpost
var ret = await jpost(this.upload_url,{
params:form
});
bricks.debug('ret=', ret);
this.dispatch('uploaded', ret)
running.dismiss();
}
download(){
if(!this.recordData){
bricks.debug('recorder not opened');
return;
};
var fileName="recorder-"+Date.now()+".wav";
var downA=document.createElement("A");
downA.innerHTML="下载"+fileName;
downA.href=this.recordData.url;
downA.download=fileName;
// document.querySelector("."+cls).appendChild(downA);
if(/mobile/i.test(navigator.userAgent)){
bricks.debug('mobile device');
}
downA.click();
//不用了时需要revokeObjectURL否则霸占内存
(window.URL||webkitURL).revokeObjectURL(downA.href);
}
}
bricks.SttClient = class extends bricks.VBox {
/*
{
"upload_url"
}
*/
constructor(opts){
super(opts);
this.recorder = new bricks.AudioRecorder({
icon_rate:2,
upload_url:opts.upload_url,
upload_resp:'json'
});
this.add_widget(this.recorder);
this.result_text = new bricks.Text({
text:'',
dynsize:true
});
this.add_widget(this.result_text);
this.recorder.bind('uploaded', this.set_result_text.bind(this));
}
set_result_text(event){
var txt = event.params.text;
this.result_text.set_text(txt);
}
}
bricks.Factory.register('AudioPlayer', bricks.AudioPlayer);
bricks.Factory.register('AudioRecorder', bricks.AudioRecorder);
bricks.Factory.register('SttClient', bricks.SttClient);