Mary TTS with HTML/JavaScript and PHP - text-to-speech

I installed Mary TTS (version 5.1.2) on my Windows (and Linux computers).
I started the Mary TTS server and the Mary TTS client, and I did some trials with text to audio conversion in the GUI window (its great).
I would like to use Mary TTS on my website to read text aloud, where a user can add a text into the input field and generate the output like in the GUI window, without using the java client.
For example:
<input type="text" id="text">
<button onclick="play('text');">Speak it</button>
<script>
function play(id){
var text = document.getElementById(id).value;
var a = new Audio(text);
a.play();
}
</script>
Just to get started.. I can't realize how to do that in HTML/JavaScript and PHP?

Step 1. Host MaryTTS on a server
I wrote marytts-http to wraps MaryTTS so it's easy to deploy to Heroku, though you could deploy it to other servers as well.
First you'll need an account with Heroku, then install their toolbelt and run heroku login.
After that you can deploy marytts-http to Heroku like this:
git clone https://github.com/draffensperger/marytts-http
cd marytts-http
heroku create
git push heroku master
Step 2. Use your hosted MaryTTS instance in your website
Heroku will give a name to your marytts-http instance that you created above which you can change later on the Heroku dashboard. Let's say the name of your instance is my-marytts, then the URL to get a text-to-speech audio file would be my-marytts.herokuapp.com/?text=Hello (just specify the text query parameter).
To embed the audio on your website you should use an <audio> tag, e.g.:
<audio src="my-marytts.herokuapp.com/?text=Hello" autoplay></audio>
The autoplay makes it start the audio when the element is loaded. So in your case, what you could do is dynamically add an <audio> element after the user clicks the button, e.g.:
<input type="text" id="text">
<button onclick="play('text');">Speak it</button>
<span id="audio-container" style="display:none;"></span>
<script>
function play(id) {
var maryttsHost = 'https://example-mary-tts.herokuapp.com'
var text = document.getElementById(id).value;
var container = document.getElementById("audio-container");
var audioSrc = maryttsHost + '/?text=' + encodeURIComponent(text);
container.innerHTML = '<audio src="' + audioSrc + '" autoplay></audio>';
}
</script>
You would need to change maryttsHost above to match the actual URL of your marytts-http instance on Heroku.

Related

How to pick an element from .XML file in MS edge browser

I am trying to get a value(Identifier in my case) from XML to pull some logic rules for a web app. I have managed to get my JavaScript to work on Firefox & Chrome but for Edge, instead of picking an element(Identifier) it's picking an element description from Developers tool.
Test case is:
1. Get an identifier from .XML
2. Go to an application and search using that identifier
For example: .XML
<Application Type="ABCD">
<Identifier>18753</Identifier>
<SalesChannel SalesChannelType="PQRS" SalesChannelSegment="XYZ">
<Identifier>AB1234</Identifier>
My code for this:
driver.get("URL for .XML");
Assert.assertTrue(driver.getPageSource().contains("Identifier"));
String xml = driver.getPageSource();
String appID = xml.split("<Identifier>")[1].split("</Identifier>")[0];
**Code to navigate to web app **
driver.findElement(By.id("oData")).sendKeys(appID);
--It uses appID and proceed with an application.
But instead of picking an identifier which is "18753" in this case, it's picking below value and putting in Search :
{{a xmlns="http://www.w3.org/1999/xhtml" tabindex="-1" role="treeitem" aria-expanded="true" aria-posinset="1" aria-setsize="20" aria-level="2" style="color: blue; margin-left: -2em;"><Identifier>18754</Identifier>
After investigation i found this value is coming from developer tool:
Try replacing
String appID = xml.split("<Identifier>")[1].split("</Identifier>")[0];
With
String appID = xml.split("<Identifier>")[0];

Cannot refresh content in browser using http-server with Aurelia

I'm using Aurelia with http-server, as it is described in Aurelia getting started docs. I'm unable to see changes, because any browser seems to cache entire page at first load. When I use F5, ctrl+F5 or ctrl+r, page refreshes but nothing changes, none of my modifications are visible. Then I can use another browser and at first visit changes are visible, but any subsequent visit shows always the first one. It occurs in every browser I use (Chrome and Firefox, ever in private mode). I'm certain that it is not bug in Aurelia itself.
I tried to change port and use http-server with -c parameter. Nothing changed. Any ideas?
If you want to force your Aurelia app to be constantly refreshed after you modify it, you can have a look at the following thread:
https://github.com/aurelia/framework/issues/94
Aaike commented on 8 May 2015:
change your index.html to add the extension right before you import
the aurelia-bootstrapper
<script>
var systemLocate = System.locate;
System.locate = function(load) {
var System = this;
return Promise.resolve(systemLocate.call(this, load)).then(function(address) {
if(address.lastIndexOf("html.js") > -1) return address;
if(address.lastIndexOf("css.js") > -1) return address;
return address + System.cacheBust;
});
};
System.cacheBust = '?bust=' + Date.now();
System.import('aurelia-bootstrapper');
</script>
This is a caching issue that pops up sometimes with http-server. I don't know exactly what causes it but I believe the -c modifier changes the length of cache-control so I would set that as 0 or 1 instead of assigning a port that way.

Balanced Payments doesn't seem to work with Phonegap

We are not able to call balanced.card.create from a Phonegap application. This is reproduced in a stock Phonegap application here: https://github.com/kevg/phonegap-balanced. Full details are in the README.md on github, but the basic summary is:
For those not familiar with phonegap, the main page that loads is
index.html. This initializes phonegap in index.js. When the device is
ready, we will show a hidden DIV with a button named "Execute
Balanced." When you click this button, app.executeBalanced in index.js
will be called which prompts for the balanced marketplace URI, loads
balanced.js with $.getScript, and then calls balanced.card.create with
a test credit card.
The expected result is that callbackHandler is called or an exception
is caught. Instead, it seems the execution of the Javascript thread
disappears into balanced.card.create, never to return and without any
error.
Alrighty, I found the bug in balanced.js. So, in Phonegap, window.location.href returns something like file:///.../index.html. Balanced.js creates an iframe to something like https://js.balancedpayments.com/proxy#file
var src = proxy + "#" + encodeURIComponent(window.location.href);
https://github.com/balanced/balanced-js/blob/master/src/utils.js#L48
In the script returned in proxy.html (which I can't find on github), it does:
c.parentURL=decodeURIComponent(
window.location.hash.replace(/^#/,"")
).replace(/#.*$/,"")
c.parentDomain=c.parentURL.replace(/([^:]+:\/\/[^\/]+).*/,"$1")
The regex doesn't match because file: has three slashes. Now, at first, I thought I could just convert the regex to:
/([^:]+:\/+[^\/]+).*/
However, then there's another problem, because balanced does a security origin check on the match:
if (d.origin.toLowerCase() !== c.toLowerCase()) return !1;
However, the regex returns file:///firstcomponent, whereas event.origin does not include a host name for the file scheme, so these won't match even with a fixed regex.
I can't change anything in the script returned in the proxy response because if I load that from a domain other than balancedpayments.com, then the AJAX POST fails (return code 0 with a blank body). Therefore, the only thing I can control is the hash passed to the iframe.
However, since this regex is a replace, we can simply pass exactly what we know we need (we don't care that the regex is a no-op).
Therefore, the solution is to change L48 above to:
var src = proxy + "#" + encodeURIComponent("file://");
This works.

IntelliJ and xDebug - xdebug.file_link_format

I've searched much time about IntelliJ IDEA 12 and the xdebug.file_link_format configuration value.
I found nothing which works...
Using protocols like "idea", "intellij", "txmt", or other protocols doesn't work.
I found nothing about a plugin which register the IntelliJ protocol...
Is it possible to use the xdebug file links with IntelliJ IDEA or PhpStorm?
Yes and No.
No -- there is no proper built-in support for this. Watch this ticket for details: http://youtrack.jetbrains.com/issue/IDEA-65879
Yes -- you may find some workaround, at very least the aforementioned ticket has recipes for Mac OS (using AppleScript) or via Remote Call etc.
Update: as of PhpStorm 8 you may use:
xdebug.file_link_format = "phpstorm://open?file=%f&line=%l"
Not out of the box, but it is possible to get the links to work. I have this working with Windows 7, Firefox and PhpStorm 10 - in this example, I'm using the protocol phpstorm://, but this will work regardless of the name.
create a custom protocol handler: Any executable will do, here I have modified a WScript from https://pla.nette.org/en/how-open-files-in-ide-from-debugger . Save as run-editor.js :
// note: edit the path, with backslashes escaped
var editor = '"c:\\Program Files (x86)\\JetBrains\\PhpStorm 143.434\\bin\\PhpStorm.exe" nosplash --line %line% "%file%"';
var url = WScript.Arguments(0);
var match = /^phpstorm:\/\/open\/\?file=(.+)&line=(\d+)$/.exec(url);
if (match) {
var file = decodeURIComponent(match[1]).replace(/\+/g, ' ');
var command = editor.replace(/%line%/g, match[2]).replace(/%file%/g, file);
var shell = new ActiveXObject("WScript.Shell");
shell.Exec(command.replace(/\\/g, '\\\\'));
}
create the protocol in registry: create the following as editor.reg and import to Registry. Note that you again need to double-escape the path to the above file, and set it to wherever yours is saved:
REGEDIT4
[HKEY_CLASSES_ROOT\phpstorm]
#="URL:phpstorm Protocol"
"URL Protocol"=""
[HKEY_CLASSES_ROOT\phpstorm\shell\open\command]
#="wscript \"C:\\path\\to\\run-editor.js\" \"%1\""
enable the protocol in Firefox:
in about:config, create a "logical value" named
network.protocol-handler.expose.phpstorm and set it to false
open one such link in Firefox, e.g. phpstorm://open?file=somefile.html&line=123 - it should open in PhpStorm.
Per the comment from #gapple, this will make Xdebug link to the file/link in PhpStorm:
xdebug.file_link_format = "phpstorm://open?file=%f&line=%l"
I tested this in PhpStorm 10 on Mac and it works great.
You need to ad to the php.ini file in the [xdebug] section the following line:
xdebug.file_link_format = "phpstorm://open?file=%f&line=%l"
Then restart your web server (Apache for me on Mac)
The REST API is probably the best option now:
http://localhost:63342/api/file%f:%l
Wrapping in a javascript protocol and AJAX request allows the permission approval to be saved so you don't have to approve every time you click:
javascript: var r = new XMLHttpRequest; r.open('get', 'http://localhost:63342/api/file%f:%l');r.send()
API specs:
https://www.develar.org/idea-rest-api/

How to link a PDF Document to a Record using Visual Studio LightSwitch 2011?

I'm Stuck the following problem: How can I link a PDF Document to a Record in a Data Grid using Visual Studio LightSwitch 2011 and Visual Basic?
Any help would be awesome, thanks!
Here's the simplest way to do this: add a custom command to the Command Bar of the Data Grid Row for your Data Grid. In this example I'm calling the command Open PDF File. Then add this code to Execute code for the command:
partial void OpenPDFFile_Execute()
{
const string LOCAL_SERVER_PDF_DIR = #"\\MyServer\PDFs\";
const string WEB_SERVER_PDF_DIR = "http://myweb.server/PDFs/";
const string PDF_SUFFIX = ".pdf"; //assumes you do not include the extension in the db field value
if (AutomationFactory.IsAvailable)
{
//if the AutomationFactory is available, this is a desktop deployment
//use the shell to open a PDF file from the local network
dynamic shell = AutomationFactory.CreateObject("Shell.Application");
string filePath = LOCAL_SERVER_PDF_DIR + this.PDFFiles.SelectedItem.FileName + PDF_SUFFIX;
shell.ShellExecute(filePath);
}
else
{
//otherwise this must be a web deployment
//in order to make this work you must add a reference to System.Windows.Browser
//to the Client project of your LS solution
var uri = new Uri(WEB_SERVER_PDF_DIR + this.PDFFiles.SelectedItem.FileName + PDF_SUFFIX);
HtmlPage.Window.Navigate(uri, "_blank");
}
}
You will need to add the following imports to the top of your user code file to make this code compile:
using System.Runtime.InteropServices.Automation;
using System.Windows.Browser;
I should mention that you need a directory to server the PDFs up from. This example is flexible with respect to deployment, because it handles both desktop and web configurations. Since you'll need to set up the PDF directoy, you may want to just handle one configuration option to simply things (or you could expose the same PDF directory over http and as a local network share).
You may also want to present this as a true link instead of a button. In order to do this, you'll need a custom SilverLight control. In any case, I would recommend implementing the PDF link using a button first. You can then move this same code to a link event handler as a separate project if that is worth spending time on.