Initial commit

This commit is contained in:
Marcelo
2025-11-20 15:27:34 -06:00
commit cc72c9fc5d
3221 changed files with 737477 additions and 0 deletions

View File

@@ -0,0 +1,140 @@
<!DOCTYPE html>
<!--
Copyright 2015 Lorentz Lasson
Copyright 2015-2019 Lorentz Lasson, Dave Conway-Jones
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<script type="text/javascript">
(function() {
var voices;
var sources = [];
RED.nodes.registerType('play audio',{
category: 'output',
color: '#DAAFF7',
defaults: {
name: {value:""},
voice: {value:""}
},
inputs:1,
outputs:0,
icon: "feed.png",
align: "right",
label: function() {
return this.name||"play audio";
},
onpaletteadd: function() {
this.handleAudio = function(t,o) {
var context = new AudioContext();
var byteArray = (o.hasOwnProperty("data")) ? o.data : o;
( function () {
return new Promise(function resolver(resolve, reject) {
if (context.state && 'running' !== context.state && context.resume) {
context.resume().then(() => {
resolve();
})
} else {
resolve();
}
});
}()).then(() => {
try {
var source = context.createBufferSource();
var buffer = new Uint8Array(byteArray.length);
buffer.set(new Uint8Array(byteArray), 0);
source.addEventListener('ended', () => { context.close(); context = undefined; }, {capture:false, once:true});
context.decodeAudioData(buffer.buffer, function(buffer) {
source.buffer = buffer;
source.onended = function() {
$.getJSON('playaudio',function() { });
sources = sources.filter(function(s) {
if (source === s) { return false; }
else { return true; }
});
}
source.connect(context.destination);
source.start(0);
sources.push(source);
});
}
catch(e) {
alert("Error playing audio: "+e);
}
}).catch((e)=> {
alert("Audio context error: "+e);
});
};
this.handleTTS = function(t,o) {
var v = o.split('#',2);
if ('speechSynthesis' in window) {
voices = window.speechSynthesis.getVoices();
var words = new SpeechSynthesisUtterance(v[1]);
words.voice = voices[parseInt(v[0])];
window.speechSynthesis.speak(words);
words.onend = function(event) {
$.getJSON('playaudio',function() { });
}
}
else {
alert("Your Browser does not support Text-to-Speech");
}
};
RED.comms.subscribe("playaudio", this.handleAudio);
RED.comms.subscribe("playtts", this.handleTTS);
},
oneditprepare: function() {
if ('speechSynthesis' in window) {
voices = window.speechSynthesis.getVoices();
for (i = 0; i < voices.length ; i++) {
//console.log(i,voices[i].name,voices[i].lang,voices[i].voiceURI,voices[i].default);
var option = document.createElement('option');
option.textContent = voices[i].name + ' (' + voices[i].lang + ')';
if (voices[i].default) { option.textContent += ' -- DEFAULT'; }
option.setAttribute('value', i);
document.getElementById("node-input-voice").appendChild(option);
}
$('#node-input-voice').val(this.voice || 0);
}
else {
$('#voice-input-row').hide();
}
},
button : {
enabled : true,
onclick : function() {
sources = sources.filter(function(source) {
source.stop(0);
return false;
});
}
}
});
})();
</script>
<script type="text/html" data-template-name="play audio">
<div class="form-row" id="voice-input-row">
<label for="node-input-voice"><i class="fa fa-language"></i> <span data-i18n="playAudio.label.ttsVoice"></label>
<select id="node-input-voice"></select>
</div>
<div class="form-row">
<label for="node-input-name"><i class="icon-tag"></i> <span data-i18n="node-red:common.label.name"></label>
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
</div>
</script>