bugfix
This commit is contained in:
parent
76abe0935f
commit
a47d155bf9
186
bricks/audio.js
186
bricks/audio.js
@ -1,4 +1,16 @@
|
|||||||
|
|
||||||
|
var 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;
|
||||||
|
};
|
||||||
|
|
||||||
class AudioPlayer extends JsWidget {
|
class AudioPlayer extends JsWidget {
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
@ -35,6 +47,7 @@ class AudioPlayer extends JsWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.player.source.src = url;
|
||||||
//webkitURL is deprecated but nevertheless
|
//webkitURL is deprecated but nevertheless
|
||||||
var URL = window.URL || window.webkitURL;
|
var URL = window.URL || window.webkitURL;
|
||||||
var AudioContext = window.AudioContext || window.webkitAudioContext;
|
var AudioContext = window.AudioContext || window.webkitAudioContext;
|
||||||
@ -44,66 +57,135 @@ class AudioRecorder extends HBox {
|
|||||||
super(opts);
|
super(opts);
|
||||||
this.start_icon = opts.start_icon || bricks_resource('imgs/start_recording.png');
|
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.stop_icon = opts.stop_icon || bricks_resource('imgs/stop_recording.png');
|
||||||
console.log('this.start_icon=', this.start_icon, this.stop_icon);
|
this.rec = null;
|
||||||
this.gumStream = null; //stream from getUserMedia()
|
this.wave = null;
|
||||||
this.recorder = null;
|
this.recBlob = null;
|
||||||
// shim for AudioContext when it's not avb.
|
this.recOpen();
|
||||||
this.img = new Image({height:'100%', url:this.start_icon});
|
}
|
||||||
this.player = new AudioPlayer({});
|
on_process(buffers,powerLevel,
|
||||||
this.player.disabled(true);
|
bufferDuration,bufferSampleRate,
|
||||||
this.add_widget(this.img);
|
newBufferIdx,asyncEnd){
|
||||||
this.add_widget(this.player);
|
//录音实时回调,大约1秒调用12次本回调
|
||||||
this.img.bind('click', this.btn_clicked.bind(this));
|
document.querySelector(".recpowerx").style.width=powerLevel+"%";
|
||||||
this.audioContext = null;
|
document.querySelector(".recpowert").innerText=formatMs(bufferDuration,1)+" / "+powerLevel;
|
||||||
this.stream = null;
|
|
||||||
this.chunks = [];
|
//可视化图形绘制
|
||||||
|
wave.input(buffers[buffers.length-1],powerLevel,bufferSampleRate);
|
||||||
|
}
|
||||||
|
recOpen(){
|
||||||
|
this.rec=null;
|
||||||
|
this.wave=null;
|
||||||
|
this.recBlob=null;
|
||||||
|
var newRec=Recorder({
|
||||||
|
type:"wav",sampleRate:16000,bitRate:16
|
||||||
|
,onProcess:this.on_process.bind(this)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
newRec.open(function(){//打开麦克风授权获得相关资源
|
||||||
|
this.rec=newRec;
|
||||||
|
//此处创建这些音频可视化图形绘制浏览器支持妥妥的
|
||||||
|
this.wave=Recorder.FrequencyHistogramView({elem:".recwave"});
|
||||||
|
}.bind(this),function(msg,isUserNotAllow){//用户拒绝未授权或不支持
|
||||||
|
console.log('open recorder failed');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
recClose(){
|
||||||
|
if(this.rec){
|
||||||
|
this.rec.close();
|
||||||
|
}else{
|
||||||
|
console.log('close recorder error');
|
||||||
|
};
|
||||||
}
|
}
|
||||||
start_recording(){
|
start_recording(){
|
||||||
console.log("recordButton clicked", this);
|
if(this.rec&&Recorder.IsOpen()){
|
||||||
var constraints = { audio: true, video:false }
|
this.recBlob=null;
|
||||||
navigator.mediaDevices.getUserMedia(constraints)
|
this.rec.start();
|
||||||
.then(function(stream) {
|
}else{
|
||||||
console.log("getUserMedia() success, stream created, initializing Recorder.js ...", this);
|
console.log("ajKR::未打开录音");
|
||||||
this.img.set_url(this.stop_icon);
|
};
|
||||||
this.audioContext = new AudioContext();
|
|
||||||
this.gumStream = stream;
|
|
||||||
/* use the stream */
|
|
||||||
try {
|
|
||||||
var input = this.audioContext.createMediaStreamSource(stream);
|
|
||||||
} catch(e){
|
|
||||||
console.log('e====', e);
|
|
||||||
}
|
}
|
||||||
this.recorder = new Recorder(input,{numChannels:1})
|
pause_recording(){
|
||||||
this.recorder.record()
|
if(this.rec&&Recorder.IsOpen()){
|
||||||
console.log("Recording started");
|
this.rec.pause();
|
||||||
}.bind(this)).catch(function(err) {
|
}else{
|
||||||
//enable the record button if getUserMedia() fails
|
console.log("gCAR::未打开录音");
|
||||||
this.img.set_url(this.start_icon);
|
};
|
||||||
}.bind(this));
|
}
|
||||||
|
resume_recording(){
|
||||||
|
if(this.rec&&Recorder.IsOpen()){
|
||||||
|
this.rec.resume();
|
||||||
|
}else{
|
||||||
|
console.log("Ob6S::未打开录音");
|
||||||
|
};
|
||||||
}
|
}
|
||||||
stop_recording(){
|
stop_recording(){
|
||||||
this.img.set_url(this.start_icon);
|
if(!(this.rec&&Recorder.IsOpen())){
|
||||||
this.recorder.stop();
|
console.log("5JuL::未打开录音");
|
||||||
this.gumStream.getAudioTracks()[0].stop();
|
return;
|
||||||
this.recorder.exportWAV(this.createWAV.bind(this));
|
};
|
||||||
|
this.rec.stop(function(blob,duration){
|
||||||
|
console.log(blob,(window.URL||webkitURL).createObjectURL(blob),Html_xT(Html_$T("gOix::时长:{1}ms",0,duration)));
|
||||||
|
|
||||||
|
this.recBlob=blob;
|
||||||
|
console.log("0LHf::已录制mp3:{1}ms {2}字节,可以点击播放、上传、本地下载了",0,formatMs(duration),blob.size);
|
||||||
|
}.bind(this),function(msg){
|
||||||
|
console.log("kGZO::录音失败:");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
createWAV(blob){
|
play_record(){
|
||||||
console.log('reord stoped .....', this);
|
if(!this.recBlob){
|
||||||
var url = URL.createObjectURL(blob);
|
console.log("tIke::请先录音,然后停止后再播放");
|
||||||
this.player.set_source(url);
|
return;
|
||||||
this.player.disabled(false);
|
};
|
||||||
console.log('---------done------------', url);
|
var cls=("a"+Math.random()).replace(".","");
|
||||||
|
var audio=document.createElement("audio");
|
||||||
|
audio.controls=true;
|
||||||
|
document.querySelector("."+cls).appendChild(audio);
|
||||||
|
//简单利用URL生成播放地址,注意不用了时需要revokeObjectURL,否则霸占内存
|
||||||
|
audio.src=(window.URL||webkitURL).createObjectURL(recBlob);
|
||||||
|
audio.play();
|
||||||
|
|
||||||
|
setTimeout(function(){
|
||||||
|
(window.URL||webkitURL).revokeObjectURL(audio.src);
|
||||||
|
},5000);
|
||||||
}
|
}
|
||||||
btn_clicked(){
|
upload(){
|
||||||
if (!this.isRecording){
|
var blob=this.recBlob;
|
||||||
this.img.src = this.stop_icon;
|
if(!blob){
|
||||||
this.isRecording = true;
|
console.log("DUTn::请先录音,然后停止后再上传");
|
||||||
this.start_recording();
|
return;
|
||||||
} else {
|
};
|
||||||
this.img.src = this.start_icon;
|
var form=new FormData();
|
||||||
this.isRecording = false;
|
form.append("audiofile",blob,"recorder.wav");
|
||||||
this.stop_recording();
|
const data = new URLSearchParams();
|
||||||
|
for (const pair of form)) {
|
||||||
|
data.append(pair[0], pair[1]);
|
||||||
}
|
}
|
||||||
|
hj = HttpJson()
|
||||||
|
ret = await hj.post(this.upload_url,{
|
||||||
|
params:data
|
||||||
|
});
|
||||||
|
console.log('ret=', ret);
|
||||||
|
this.dispatch('updated', ret)
|
||||||
|
}
|
||||||
|
download(){
|
||||||
|
if(!this.recBlob){
|
||||||
|
console.log('recorder not opened');
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
var fileName="recorder-"+Date.now()+".wav";
|
||||||
|
var downA=document.createElement("A");
|
||||||
|
downA.innerHTML="下载")+fileName;
|
||||||
|
downA.href=(window.URL||webkitURL).createObjectURL(this.recBlob);
|
||||||
|
downA.download=fileName;
|
||||||
|
# document.querySelector("."+cls).appendChild(downA);
|
||||||
|
if(/mobile/i.test(navigator.userAgent)){
|
||||||
|
;
|
||||||
|
}
|
||||||
|
downA.click();
|
||||||
|
//不用了时需要revokeObjectURL,否则霸占内存
|
||||||
|
(window.URL||webkitURL).revokeObjectURL(downA.href);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
<link rel="stylesheet" href="/bricks/css/bricks.css">
|
<link rel="stylesheet" href="/bricks/css/bricks.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<script src="/3parties/recorder.wav.min.js"></script>
|
||||||
<script src="/bricks/bricks.js"></script>
|
<script src="/bricks/bricks.js"></script>
|
||||||
<script>
|
<script>
|
||||||
const opts = {
|
const opts = {
|
||||||
|
BIN
bricks/imgs/download.png
Normal file
BIN
bricks/imgs/download.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
BIN
bricks/imgs/resume-record.png
Normal file
BIN
bricks/imgs/resume-record.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
bricks/imgs/stop.png
Normal file
BIN
bricks/imgs/stop.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
bricks/imgs/upload.png
Normal file
BIN
bricks/imgs/upload.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
@ -40,15 +40,17 @@ class HttpText {
|
|||||||
add_own_params(params){
|
add_own_params(params){
|
||||||
if (! params)
|
if (! params)
|
||||||
params = {};
|
params = {};
|
||||||
|
var session = bricks_app.get_session();
|
||||||
if (params instanceof FormData){
|
if (params instanceof FormData){
|
||||||
for ( const [key, value] of Object.entries(this.params)){
|
for ( const [key, value] of Object.entries(this.params)){
|
||||||
params.append(key, value);
|
params.append(key, value);
|
||||||
}
|
}
|
||||||
|
if(session){
|
||||||
|
params.append('session', session);
|
||||||
|
}
|
||||||
|
return params;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
params = Object.assign(this.params, params);
|
params = Object.assign(this.params, params);
|
||||||
}
|
|
||||||
var session = bricks_app.get_session();
|
|
||||||
if (session){
|
if (session){
|
||||||
extend(params,{session:session});
|
extend(params,{session:session});
|
||||||
}
|
}
|
||||||
@ -60,7 +62,6 @@ class HttpText {
|
|||||||
}
|
}
|
||||||
return Object.assign(this.headers, headers);
|
return Object.assign(this.headers, headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
async httpcall(url, {method='GET', headers=null, params=null}={}){
|
async httpcall(url, {method='GET', headers=null, params=null}={}){
|
||||||
url = this.url_parse(url);
|
url = this.url_parse(url);
|
||||||
var data = this.add_own_params(params);
|
var data = this.add_own_params(params);
|
||||||
@ -93,8 +94,6 @@ class HttpText {
|
|||||||
if (fetchResult.status == 401 && bricks_app.login_url){
|
if (fetchResult.status == 401 && bricks_app.login_url){
|
||||||
return await this.withLoginInfo(url, _params);
|
return await this.withLoginInfo(url, _params);
|
||||||
}
|
}
|
||||||
console.log('method=', method, 'url=', url, 'params=', params);
|
|
||||||
console.log('jsoncall error:');
|
|
||||||
const resp_error = {
|
const resp_error = {
|
||||||
"type":"Error",
|
"type":"Error",
|
||||||
"message":result.message || 'Something went wrong',
|
"message":result.message || 'Something went wrong',
|
||||||
|
Loading…
Reference in New Issue
Block a user