bugfix
This commit is contained in:
parent
8462fdfe8d
commit
536adc7887
@ -26,7 +26,7 @@ bricks.AudioPlayer = class extends bricks.JsWidget {
|
||||
this.audio = this._create('audio');
|
||||
this.audio.controls = true;
|
||||
if (this.opts.autoplay){
|
||||
this.audio.addEventListener('canplay', this.play_audio.bind(this));
|
||||
this.audio.addEventListener('canplay', this.play.bind(this));
|
||||
}
|
||||
this.audio.style.width = "100%"
|
||||
this.dom_element.appendChild(this.audio);
|
||||
@ -34,6 +34,58 @@ bricks.AudioPlayer = class extends bricks.JsWidget {
|
||||
this.set_source(this.url);
|
||||
}
|
||||
}
|
||||
|
||||
set_stream_urls(response){
|
||||
async function* dyn_urls(response) {
|
||||
const reader = response.body.getReader();
|
||||
var value;
|
||||
var done;
|
||||
while (true){
|
||||
done, value = await reader.read();
|
||||
if (value.done){
|
||||
console.log('done=', done, 'value=', value);
|
||||
break;
|
||||
}
|
||||
let result = '';
|
||||
for (let i = 0; i < value.value.length; i++) {
|
||||
result += String.fromCharCode(value.value[i]);
|
||||
}
|
||||
console.log('audio set url=', result);
|
||||
yield result;
|
||||
}
|
||||
}
|
||||
this.url_generator = dyn_urls(response);
|
||||
this.srcList = [];
|
||||
schedule_once(this.load_queue_url.bind(this), 0.1);
|
||||
}
|
||||
async load_queue_url(){
|
||||
while (true){
|
||||
var d = await this.url_generator.next();
|
||||
if (d.done){
|
||||
return;
|
||||
}
|
||||
this.srcList.push({played:false, url:d.value});
|
||||
if (this.srcList.length < 2 ){
|
||||
await this.play_srclist();
|
||||
this.audio.addEventListener('ended',
|
||||
this.play_srclist.bind(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
async play_srclist(evnet){
|
||||
if (event && ! this.audio.ended){
|
||||
return;
|
||||
}
|
||||
for (var i=0;i<this.srcList.length;i++){
|
||||
if (!this.srcList[i].played){
|
||||
console.log('playit', i, this.srcList[i]);
|
||||
this.set_url(this.srcList[i].url);
|
||||
this.srcList[i].played = true;
|
||||
await this.play();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
set_source(url){
|
||||
if (! this.source){
|
||||
this.source = this._create('source');
|
||||
@ -49,14 +101,14 @@ bricks.AudioPlayer = class extends bricks.JsWidget {
|
||||
// 播放音频
|
||||
this.audio.play();
|
||||
}
|
||||
play(){
|
||||
this.audio.play();
|
||||
async play(){
|
||||
await this.audio.play();
|
||||
}
|
||||
toggle_play(){
|
||||
async toggle_play(){
|
||||
if (this.audio.paused){
|
||||
this.audio.play();
|
||||
await this.audio.play();
|
||||
} else {
|
||||
this.audio.pause();
|
||||
await this.audio.pause();
|
||||
}
|
||||
}
|
||||
set_url(url){
|
||||
@ -81,6 +133,7 @@ bricks.AudioRecorder = class extends bricks.HBox {
|
||||
*/
|
||||
constructor(opts){
|
||||
super(opts);
|
||||
this.set_css('clickable');
|
||||
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({
|
||||
@ -97,7 +150,7 @@ bricks.AudioRecorder = class extends bricks.HBox {
|
||||
width:'120px'
|
||||
});
|
||||
this.upload_url = opts.upload_url;
|
||||
this.rec_btn.bind('click', this.rec_btn_pressed.bind(this))
|
||||
this.bind('click', this.rec_btn_pressed.bind(this))
|
||||
this.URL = window.URL||webkitURL;
|
||||
this.rec = null;
|
||||
this.wave = null;
|
||||
|
@ -32,3 +32,25 @@ bricks.UpStreaming = class extends bricks.JsWidget {
|
||||
this.stream_ctlr = controller;
|
||||
}
|
||||
}
|
||||
|
||||
bricks.down_streaming = async function*(response) {
|
||||
if (! response){
|
||||
return;
|
||||
}
|
||||
const reader = response.body.getReader();
|
||||
var value;
|
||||
var t = 0;
|
||||
while (true){
|
||||
done, value = await reader.read();
|
||||
if (value.done){
|
||||
break;
|
||||
}
|
||||
let result = '';
|
||||
for (let i = 0; i < value.value.length; i++) {
|
||||
result += String.fromCharCode(value.value[i]);
|
||||
}
|
||||
console.log('audio set url=', result);
|
||||
yield result;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,4 +38,5 @@ cp -a ../examples/* ../dist/examples
|
||||
cp -a ../3parties/* ../dist/3parties
|
||||
cp -a ../docs/* ../dist/docs
|
||||
cp *.tmpl ../dist
|
||||
cp -a ../dist /tmp
|
||||
echo "Finished ..."
|
||||
|
@ -41,7 +41,7 @@ hr {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
.clickable {
|
||||
color: #80ff88;
|
||||
color: #40cc40;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
@ -4,11 +4,11 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="stylesheet" href="/bricks/3parties/xterm.css" />
|
||||
<link rel="stylesheet" href="{{entire_url('/bricks/3parties/xterm.css')}}" />
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/js-docx-viewer/dist/css/docxviewer.min.css">
|
||||
<link href="/bricks/3parties/video-js.css" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="/bricks/css/bricks.css">
|
||||
<link rel="stylesheet", href="/css/myapp.css">
|
||||
<link href="{{entire_url('/bricks/3parties/video-js.css')}}" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="{{entire_url('/bricks/css/bricks.css')}}">
|
||||
<link rel="stylesheet", href="{{entire_url('/css/myapp.css')}}">
|
||||
</head>
|
||||
<body>
|
||||
<!--
|
||||
@ -23,17 +23,17 @@
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/mammoth/1.4.2/mammoth.browser.min.js"></script>
|
||||
<script type="text/javascript" src="https://registry.npmmirror.com/echarts/5.5.1/files/dist/echarts.min.js"></script>
|
||||
|
||||
<script src="/bricks/3parties/marked.min.js"></script>
|
||||
<script src="/bricks/3parties/xterm.js"></script>
|
||||
<script src="/bricks/3parties/video.min.js"></script>
|
||||
<script src="{{entire_url('/bricks/3parties/marked.min.js')}}"></script>
|
||||
<script src="{{entire_url('/bricks/3parties/xterm.js')}}"></script>
|
||||
<script src="{{entire_url('/bricks/3parties/video.min.js')}}"></script>
|
||||
<!---
|
||||
<link href="https://unpkg.com/video.js@6/dist/video-js.css" rel="stylesheet">
|
||||
<script src="https://unpkg.com/video.js@6/dist/video.js"></script></head>
|
||||
--->
|
||||
|
||||
<script src="/bricks/3parties/recorder.wav.min.js"></script>
|
||||
<script src="/bricks/bricks.js"></script>
|
||||
<script src="/js/myapp.js"></script>
|
||||
<script src="{{entire_url('/bricks/3parties/recorder.wav.min.js')}}"></script>
|
||||
<script src="{{entire_url('/bricks/bricks.js')}}"></script>
|
||||
<script src="{{entire_url('/js/myapp.js')}}"></script>
|
||||
<script>
|
||||
const opts = {
|
||||
"widget":
|
||||
|
@ -49,6 +49,47 @@ bricks.UiType =class extends bricks.Layout {
|
||||
}
|
||||
}
|
||||
|
||||
bricks.UiAudioRecorder = class extends bricks.AudioRecorder {
|
||||
constructor(opts){
|
||||
super(opts);
|
||||
this.uitype = 'audiorecorder';
|
||||
this.name = this.opts.name;
|
||||
this.required = opts.required || false;
|
||||
this.value = opts.value || opts.defaultvalue||'';
|
||||
this.bind('record_ended', this.getValue.bind(this));
|
||||
}
|
||||
|
||||
getValue(){
|
||||
var o = {}
|
||||
this.value = this.recordData.data;
|
||||
o[this.name] = this.value;
|
||||
return o;
|
||||
}
|
||||
set_formdata(formdata){
|
||||
formdata.append(this.name, this.value, 'record.wav');
|
||||
}
|
||||
resultValue(){
|
||||
return this.value;
|
||||
}
|
||||
focus(){
|
||||
this.dom_element.focus();
|
||||
}
|
||||
reset(){
|
||||
}
|
||||
setValue(v){
|
||||
return;
|
||||
}
|
||||
set_disabled(f){
|
||||
this.dom_element.disabled = f;
|
||||
}
|
||||
set_readonly(f){
|
||||
this.dom_element.readOnly = f;
|
||||
}
|
||||
set_required(f){
|
||||
this.dom_element.required = f;
|
||||
this.required = f;
|
||||
}
|
||||
}
|
||||
bricks.UiAudioText = class extends bricks.UiType {
|
||||
/*
|
||||
{
|
||||
@ -337,7 +378,7 @@ bricks.UiFile =class extends bricks.UiStr {
|
||||
return this.dom_element.files;
|
||||
}
|
||||
resultValue(){
|
||||
return this.get_files();
|
||||
return this.get_files()[0];
|
||||
}
|
||||
setValue(v){
|
||||
return;
|
||||
@ -910,6 +951,7 @@ bricks.UiVideo =class extends bricks.UiStr {
|
||||
}
|
||||
}
|
||||
var Input = new bricks._Input();
|
||||
Input.register('UiAudioRecorder', 'audiorecorder', bricks.UiAudioRecorder);
|
||||
Input.register('UiStr', 'str', bricks.UiStr);
|
||||
Input.register('UiHide', 'hide', bricks.UiHide);
|
||||
Input.register('UiTel', 'tel', bricks.UiTel);
|
||||
|
@ -102,7 +102,7 @@ bricks.HttpText = class {
|
||||
}
|
||||
return Object.assign(this.headers, headers);
|
||||
}
|
||||
async httpcall(url, {method='GET', headers=null, params=null}={}){
|
||||
async bricks_fetch(url, {method='GET', headers=null, params=null}={}){
|
||||
url = this.url_parse(url);
|
||||
var data = this.add_own_params(params);
|
||||
var header = this.add_own_headers(headers);
|
||||
@ -120,8 +120,13 @@ bricks.HttpText = class {
|
||||
_params.body = JSON.stringify(data);
|
||||
}
|
||||
}
|
||||
const fetchResult = await fetch(url, _params);
|
||||
// console.log('fetchResult.status=', fetchResult.status, url, 'login url=', bricks.app.login_url);
|
||||
return await fetch(url, _params);
|
||||
}
|
||||
async httpcall(url, opts){
|
||||
const fetchResult = await this.bricks_fetch(url, {
|
||||
method: opts.method,
|
||||
headers: opts.headers,
|
||||
params: opts.params});
|
||||
if (fetchResult.status == 401 && bricks.app.login_url){
|
||||
console.log('go to login')
|
||||
return await this.withLoginInfo(url, _params);
|
||||
|
204
bricks/utils.js
204
bricks/utils.js
@ -16,12 +16,12 @@ var inputdata2dic = function(data){
|
||||
}
|
||||
}
|
||||
bricks.delete_null_values = function(obj) {
|
||||
for (let key in obj) {
|
||||
if (obj[key] === null) {
|
||||
delete obj[key];
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
for (let key in obj) {
|
||||
if (obj[key] === null) {
|
||||
delete obj[key];
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
bricks.is_empty = function(obj){
|
||||
@ -59,7 +59,7 @@ bricks.debug = function(...args){
|
||||
}
|
||||
|
||||
bricks.is_mobile = function(){
|
||||
var userAgent = navigator.userAgent;
|
||||
var userAgent = navigator.userAgent;
|
||||
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent)) {
|
||||
return true;
|
||||
}
|
||||
@ -105,9 +105,9 @@ var currentScriptPath = function () {
|
||||
}
|
||||
currentScript = scripts[ scripts.length - 1 ].src;
|
||||
}
|
||||
var currentScriptChunks = currentScript.split( '/' );
|
||||
var currentScriptFile = currentScriptChunks[ currentScriptChunks.length - 1 ];
|
||||
return currentScript.replace( currentScriptFile, '' );
|
||||
var currentScriptChunks = currentScript.split( '/' );
|
||||
var currentScriptFile = currentScriptChunks[ currentScriptChunks.length - 1 ];
|
||||
return currentScript.replace( currentScriptFile, '' );
|
||||
}
|
||||
|
||||
bricks.path = currentScriptPath();
|
||||
@ -122,17 +122,17 @@ var bricks_resource = function(name){
|
||||
* @see https://stackoverflow.com/a/71692555/2228771
|
||||
*/
|
||||
function querySelectorAllShadows(selector, el = document.body) {
|
||||
// recurse on childShadows
|
||||
const childShadows = Array.from(el.querySelectorAll('*')).
|
||||
map(el => el.shadowRoot).filter(Boolean);
|
||||
// recurse on childShadows
|
||||
const childShadows = Array.from(el.querySelectorAll('*')).
|
||||
map(el => el.shadowRoot).filter(Boolean);
|
||||
|
||||
bricks.debug('[querySelectorAllShadows]', selector, el, `(${childShadows.length} shadowRoots)`);
|
||||
bricks.debug('[querySelectorAllShadows]', selector, el, `(${childShadows.length} shadowRoots)`);
|
||||
|
||||
const childResults = childShadows.map(child => querySelectorAllShadows(selector, child));
|
||||
|
||||
// fuse all results into singular, flat array
|
||||
const result = Array.from(el.querySelectorAll(selector));
|
||||
return result.concat(childResults).flat();
|
||||
const childResults = childShadows.map(child => querySelectorAllShadows(selector, child));
|
||||
|
||||
// fuse all results into singular, flat array
|
||||
const result = Array.from(el.querySelectorAll(selector));
|
||||
return result.concat(childResults).flat();
|
||||
}
|
||||
|
||||
var schedule_once = function(f, t){
|
||||
@ -210,7 +210,7 @@ bricks.obj_fmtstr = function(obj, fmt){
|
||||
'${name:}, ${age=}'
|
||||
*/
|
||||
var s = fmt;
|
||||
s = s.replace(/\${(\w+)([:=]*)}/g, (k, key, op) => {
|
||||
s = s.replace(/\${(\w+)([:=]*)}/g, (k, key, op) => {
|
||||
if (obj.hasOwnProperty(key)){
|
||||
if (op == ''){
|
||||
return obj[key];
|
||||
@ -285,7 +285,7 @@ var archorize = function(ele,archor){
|
||||
}
|
||||
|
||||
Array.prototype.insert = function ( index, ...items ) {
|
||||
this.splice( index, 0, ...items );
|
||||
this.splice( index, 0, ...items );
|
||||
};
|
||||
|
||||
Array.prototype.remove = function(item){
|
||||
@ -325,26 +325,26 @@ var convert2int = function(s){
|
||||
}
|
||||
|
||||
function setCookie(name,value,days) {
|
||||
var expires = "";
|
||||
if (days) {
|
||||
var date = new Date();
|
||||
date.setTime(date.getTime() + (days*24*60*60*1000));
|
||||
expires = "; expires=" + date.toUTCString();
|
||||
}
|
||||
document.cookie = name + "=" + (value || "") + expires + "; path=/";
|
||||
var expires = "";
|
||||
if (days) {
|
||||
var date = new Date();
|
||||
date.setTime(date.getTime() + (days*24*60*60*1000));
|
||||
expires = "; expires=" + date.toUTCString();
|
||||
}
|
||||
document.cookie = name + "=" + (value || "") + expires + "; path=/";
|
||||
}
|
||||
function getCookie(name) {
|
||||
var nameEQ = name + "=";
|
||||
var ca = document.cookie.split(';');
|
||||
for(var i=0;i < ca.length;i++) {
|
||||
var c = ca[i];
|
||||
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
||||
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
|
||||
}
|
||||
return null;
|
||||
var nameEQ = name + "=";
|
||||
var ca = document.cookie.split(';');
|
||||
for(var i=0;i < ca.length;i++) {
|
||||
var c = ca[i];
|
||||
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
||||
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function eraseCookie(name) {
|
||||
document.cookie = name +'=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
|
||||
function eraseCookie(name) {
|
||||
document.cookie = name +'=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
|
||||
}
|
||||
|
||||
var set_max_height = function(w1, w2){
|
||||
@ -358,13 +358,53 @@ var set_max_height = function(w1, w2){
|
||||
}
|
||||
}
|
||||
var objcopy = function(obj){
|
||||
var o = {}
|
||||
for ( k in obj){
|
||||
if (obj.hasOwnProperty(k)){
|
||||
o[k] = obj[k];
|
||||
}
|
||||
}
|
||||
return o;
|
||||
var o = {}
|
||||
for ( k in obj){
|
||||
if (obj.hasOwnProperty(k)){
|
||||
o[k] = obj[k];
|
||||
}
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
bricks.set_stream_source = async function(target, url, params){
|
||||
var widget;
|
||||
if (typeof target == typeof ''){
|
||||
widget = bricks.getWidgetById(target);
|
||||
} else if (target instanceof bricks.JsWidget){
|
||||
widget = target;
|
||||
} else {
|
||||
widget = await bricks.widgetBuild(target);
|
||||
}
|
||||
if (! widget){
|
||||
bricks.debug('playResponseAudio():', target, 'can not found or build a widget');
|
||||
return;
|
||||
}
|
||||
const mediaSource = new MediaSource();
|
||||
mediaSource.addEventListener('sourceopen', handleSourceOpen);
|
||||
widget.set_url(URL.createObjectURL(mediaSource));
|
||||
function handleSourceOpen(){
|
||||
const sourceBuffer = mediaSource.addSourceBuffer('audio/wav; codecs=1');
|
||||
var ht = new bricks.HttpText();
|
||||
ht.bricks_fetch(url, {params:params})
|
||||
.then(response => response.body)
|
||||
.then(body => {
|
||||
const reader = body.getReader();
|
||||
const read = () => {
|
||||
reader.read().then(({ done, value }) => {
|
||||
if (done) {
|
||||
mediaSource.endOfStream();
|
||||
return;
|
||||
}
|
||||
sourceBuffer.appendBuffer(value);
|
||||
read();
|
||||
}).catch(error => {
|
||||
console.error('Error reading audio stream:', error);
|
||||
});
|
||||
};
|
||||
read();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
bricks.playResponseAudio = async function(response, target){
|
||||
@ -382,8 +422,8 @@ bricks.playResponseAudio = async function(response, target){
|
||||
bricks.debug('playResponseAudio():', target, 'can not found or build a widget');
|
||||
return;
|
||||
}
|
||||
const blob = await response.blob();
|
||||
const url = URL.createObjectURL(blob);
|
||||
const blob = await response.blob();
|
||||
const url = URL.createObjectURL(blob);
|
||||
widget.set_url(url);
|
||||
widget.play();
|
||||
}
|
||||
@ -410,12 +450,78 @@ bricks.Observable = class {
|
||||
this.value = v;
|
||||
}
|
||||
set(v){
|
||||
if (this.value != v){
|
||||
var ov = this.value;
|
||||
this.value = v;
|
||||
if (this.value != ov){
|
||||
this.owner.dispatch(this.name, v);
|
||||
}
|
||||
this.value = v;
|
||||
}
|
||||
get(){
|
||||
return this.v;
|
||||
}
|
||||
}
|
||||
|
||||
bricks.Queue = class {
|
||||
constructor() {
|
||||
this.items = [];
|
||||
this._done = false;
|
||||
}
|
||||
|
||||
// 添加元素到队列尾部
|
||||
enqueue(element) {
|
||||
this.items.push(element);
|
||||
}
|
||||
done(){
|
||||
this._done = true;
|
||||
}
|
||||
is_done(){
|
||||
return this._done;
|
||||
}
|
||||
|
||||
// 移除队列的第一个元素并返回
|
||||
dequeue() {
|
||||
if (this.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return this.items.shift();
|
||||
}
|
||||
|
||||
// 查看队列的第一个元素
|
||||
peek() {
|
||||
if (this.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return this.items[0];
|
||||
}
|
||||
|
||||
// 检查队列是否为空
|
||||
isEmpty() {
|
||||
return this.items.length === 0;
|
||||
}
|
||||
|
||||
// 获取队列的大小
|
||||
size() {
|
||||
return this.items.length;
|
||||
}
|
||||
|
||||
// 清空队列
|
||||
clear() {
|
||||
this.items = [];
|
||||
}
|
||||
|
||||
// 打印队列元素
|
||||
print() {
|
||||
console.log(this.items.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// 使用队列
|
||||
const queue = new Queue();
|
||||
queue.enqueue(1);
|
||||
queue.enqueue(2);
|
||||
queue.enqueue(3);
|
||||
queue.print(); // 输出: 1,2,3
|
||||
console.log(queue.dequeue()); // 输出: 1
|
||||
queue.print(); // 输出: 2,3
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user