diff --git a/CHANGES.txt b/CHANGES.txt index 8c02b319..cc706eb1 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -5,6 +5,7 @@ Version 3.1.28 (Build 2020040500) -added singapore and mumbai regions for cloudpoodll -fixed cloudpoodlltoken to be callable from template JS -replaced interactivetranscriptaudio and interactivetranscriptvideo with superinteractiveaudio and superinteractivevideo +-replaced TTS templates with cloud poodll ones for new users Version 3.1.25 (Build 2019121200) -fixed lightbox2 template and popover template on classic theme (M3.8) diff --git a/db/install.php b/db/install.php index a87dbd93..f89576e2 100644 --- a/db/install.php +++ b/db/install.php @@ -32,8 +32,8 @@ function xmldb_filter_poodll_install() { $forinstall = array('fff', 'flowplayer', 'mediaelementvideo', 'videojs', 'nativevideo', 'audiojs_shim', 'mediaelementaudio', 'nativeaudio', 'youtubeplayer', 'youtube','onceplayer', 'twiceaudioplayer','superinteractiveaudio','superinteractivevideo', 'tabs', 'tabitem', 'accordian', 'accordianitem', - 'Button-Maker','countdown','dice','flipclock','icontoggle','lightbox2','poodllcalc','popover','popuprecorder','speechcards','tapwordtohear', - 'textblockreader','tta','soundboard'); + 'Button-Maker','countdown','dice','flipclock','icontoggle','lightbox2','poodllcalc','popover','popuprecorder','speechcards','tapwordtohearcloud', + 'textblockreadercloud','ttacloud','soundboardcloud'); $templateindex = 0; foreach ($presets as $preset) { if (in_array($preset['key'], $forinstall)) { diff --git a/presets/dictation.txt b/presets/dictation.txt deleted file mode 100644 index d35869c3..00000000 --- a/presets/dictation.txt +++ /dev/null @@ -1 +0,0 @@ -{"name":"Dictation","key":"dictation","version":"1.0.3","instructions":"Add an html list (bullets) of statements/words to be read, between the dictation tags. Users must listen to the audio and type what they hear ","showatto":"1","showplayers":"0","requirecss":"","requirejs":"","shim":"","defaults":"language=\"English(US)|English(GB)|English(AU)|English(In)|English(Welsh)|Danish|Dutch|French(FR)|French(CA)|German|Icelandic|Italian|Japanese|Korean|Norwegian|Polish|Portugese(BR)|Portugese(PT)|Romanian|Russian|Spanish(ES)|Spanish(US)|Swedish|Turkish|Welsh\",\nspeaker=\"Male|Female\"","amd":"1","body":"
\n\n
\n","bodyend":"
","script":"//remove any HTML editor artifacts\n$('#' + @@AUTOID@@ + ' p').remove();\n$('#' + @@AUTOID@@ + ' span').remove();\n\n//fetch the controls we inserted in \"body\"\nvar theplayer = $('#' + @@AUTOID@@ + '_player');\nvar theulcontainer = $('#' + @@AUTOID@@); \nvar theitemscontainer = $('#' + @@AUTOID@@ + '_container'); \n\ntheitemscontainer.on('click','.dictationtrigger', function(e){\n theplayer.attr('src',$(this).attr('data-src'));\n theplayer[0].play();\n});\n\n\n//determine voice\nvar mf=@@speaker@@\nswitch(@@language@@){\ncase \"English(US)\": voice = mf=='Male'?'Joey':'Kendra';break;\ncase \"English(GB)\": voice = mf=='Male'?'Brian':'Amy';break;\ncase \"English(AU)\": voice = mf=='Male'?'Russell':'Nicole';break;\ncase \"English(IN)\": voice = mf=='Male'?'Aditi':'Raveena';break;\ncase \"English(WELSH)\": voice = mf=='Male'? 'Geraint':'Geraint';break;\ncase \"Danish\": voice = mf=='Male'?'Mads':'Naja';break;\ncase \"Dutch\": voice = mf=='Male'?'Ruben':'Lotte';break;\ncase \"French(FR)\": voice = mf=='Male'?'Mathieu':'Celine';break;\ncase \"French(CA)\": voice = mf=='Male'?'Chantal':'Chantal';break;\ncase \"German\": voice = mf=='Male'?'Hans':'Marlene';break;\ncase \"Icelandic\": voice = mf=='Male'?'Karl':'Dora';break;\ncase \"Italian\": voice = mf=='Male'?'Carla':'Giorgio';break;\ncase \"Japanese\": voice = mf=='Male'?'Takumi':'Mizuki';break;\ncase \"Korean\": voice = mf=='Male'?'Seoyan':'Seoyan';break;\ncase \"Norwegian\": voice = mf=='Male'?'Liv':'Liv';break;\ncase \"Polish\": voice = mf=='Male'?'Jacek':'Ewa';break;\ncase \"Portugese(BR)\": voice = mf=='Male'?'Ricardo':'Vitoria';break;\ncase \"Portugese(PT)\": voice = mf=='Male'?'Cristiano':'Ines';break;\ncase \"Romanian\": voice = mf=='Male'?'Carmen':'Carmen';break;\ncase \"Russian\": voice = mf=='Male'?'Maxim':'Tatyana';break;\ncase \"Spanish(ES)\": voice = mf=='Male'?'Enrique':'Conchita';break;\ncase \"Spanish(US)\": voice = mf=='Male'?'Miguel':'Penelope';break;\ncase \"Swedish\": voice = mf=='Male'?'Astrid':'Astrid';break;\ncase \"Turkish\": voice = mf=='Male'?'Filiz':'Filiz';break;\ncase \"Welsh\": voice = mf=='Male'?'Gwyneth':'Gwyneth';break;\ndefault: voice = mf=='Male'?'Brian':'Amy';\n}\n\n\n\n//Build audio url components\nvar poodllfilelib = M.cfg.wwwroot + '/filter/poodll/poodllfilelib.php?datatype=speaktext¶mone=';\nvar format = 'text';\n\n//build template for one dictation item\nvar template ='
';\ntemplate += '
';\ntemplate += '
';\ntemplate += '
';\ntemplate += '
';\ntemplate +='
';\n\nvar container = \n\n$('#' + @@AUTOID@@ + \" li\" ).each(function(index) {\n var usetext = $(this).text();\n var datastring= 'text' + '|' + voice + '|' + usetext;\n var src = poodllfilelib+encodeURIComponent(datastring);\n var usetemplate = template.replace('@AUDIO@',src); \n usetemplate = usetemplate.replace(/@ID@/g, index);\n theitemscontainer.append(usetemplate);\n \n //add events\n var theinput= $('#dictationinput_' + index + ' input');\n var thestatus= $('#dictationstatus_' + index);\n var theaudio= $('#dictationplayer_' + index + ' audio');\n theinput.on('keyup',function(){\n if($(this).val()==usetext){\n thestatus.addClass('dictationcorrect');\n }else{\n thestatus.removeClass('dictationcorrect');\n }\n });//end of change event\n \n\n });//end of each loop","style":"div.poodlldictationstatus {\n padding: 3px;\n border: black 1px solid;\n border-width: 2px;\n border-radius: 10px;\n width: 30px;\n text-align: center;\n}\ndiv.dictationcorrect{\n color: white;\nbackground-color: green;\n}\ndiv.row.dictationrow{\n max-width: 600px;\n min-height: 50px;\ndisplay: flex;\n}\ndiv.dictationrow input {\n width: 100%;\n}","dataset":"","datasetvars":"","alternate":"","alternateend":""} \ No newline at end of file diff --git a/presets/dictationcloud.txt b/presets/dictationcloud.txt new file mode 100644 index 00000000..fdbc143a --- /dev/null +++ b/presets/dictationcloud.txt @@ -0,0 +1 @@ +{"name":"Dictation (Cloud)","key":"dictationcloud","version":"1.0.0","instructions":"Add an html list (bullets) of statements/words to be read, between the dictation tags. Users must listen to the audio and type what they hear. (Uses Cloud Poodll) ","showatto":"1","showplayers":"0","requirecss":"","requirejs":"","shim":"","defaults":"language=\"English(US)|English(GB)|English(AU)|English(In)|English(Welsh)|Danish|Dutch|French(FR)|French(CA)|German|Icelandic|Italian|Japanese|Korean|Norwegian|Polish|Portugese(BR)|Portugese(PT)|Romanian|Russian|Spanish(ES)|Spanish(US)|Swedish|Turkish|Welsh\",\nspeaker=\"Male|Female\"","amd":"1","body":"
\n\n\n
\n","bodyend":"
","script":"//FUNCTION fetch polly url\n var fetch_polly_url = function(speaktext, voice, callback) {\n\n //The REST API we are calling\n var functionname = 'local_cpapi_fetch_polly_url';\n\n //fetch the Posturl. We need this.\n //set up our ajax request\n var xhr = new XMLHttpRequest();\n var that = this;\n\n //set up our handler for the response\n xhr.onreadystatechange = function (e) {\n if (this.readyState === 4) {\n if (xhr.status == 200) {\n\n //get a yes or forgetit or tryagain\n var payload = xhr.responseText;\n var payloadobject = JSON.parse(payload);\n if (payloadobject) {\n //returnCode > 0 indicates an error\n if (payloadobject.returnCode > 0) {\n console.log(payloadobject.returnMessage);\n return false;\n //if all good, then lets do the embed\n } else if (payloadobject.returnCode === 0){\n var pollyurl = payloadobject.returnMessage;\n callback(pollyurl);\n } else {\n console.log('Polly Signed URL Request failed:');\n console.log(payloadobject);\n }\n } else {\n console.log('Polly Signed URL Request something bad happened');\n }\n } else {\n console.log('Polly Signed URL Request Not 200 response:' + xhr.status);\n }\n }\n };\n\n //make our request\n var xhrparams = \"wstoken=\" + @@CLOUDPOODLLTOKEN@@\n + \"&wsfunction=\" + functionname\n + \"&moodlewsrestformat=\" + 'json'\n + \"&text=\" + encodeURIComponent(speaktext)\n + '&texttype=text'\n + '&voice=' + voice\n + '&appid=' + 'filter_poodll'\n + '&owner=poodll'\n + '®ion=useast1';\n\n var serverurl = 'https://cloud.poodll.com' + \"/webservice/rest/server.php\";\n xhr.open(\"POST\", serverurl, true);\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n xhr.send(xhrparams);\n };\n\n//remove any HTML editor artifacts\n$('#' + @@AUTOID@@ + ' p').remove();\n$('#' + @@AUTOID@@ + ' span').remove();\n\n//fetch the controls we inserted in \"body\"\nvar theplayer = $('#' + @@AUTOID@@ + '_player');\nvar theulcontainer = $('#' + @@AUTOID@@); \nvar theitemscontainer = $('#' + @@AUTOID@@ + '_container'); \n\ntheitemscontainer.on('click','.dictationtrigger', function(e){\n theplayer.attr('src',$(this).attr('data-src'));\n theplayer[0].play();\n});\n\n\n//determine voice\nvar mf=@@speaker@@\nswitch(@@language@@){\ncase \"English(US)\": voice = mf=='Male'?'Joey':'Kendra';break;\ncase \"English(GB)\": voice = mf=='Male'?'Brian':'Amy';break;\ncase \"English(AU)\": voice = mf=='Male'?'Russell':'Nicole';break;\ncase \"English(IN)\": voice = mf=='Male'?'Aditi':'Raveena';break;\ncase \"English(WELSH)\": voice = mf=='Male'? 'Geraint':'Geraint';break;\ncase \"Danish\": voice = mf=='Male'?'Mads':'Naja';break;\ncase \"Dutch\": voice = mf=='Male'?'Ruben':'Lotte';break;\ncase \"French(FR)\": voice = mf=='Male'?'Mathieu':'Celine';break;\ncase \"French(CA)\": voice = mf=='Male'?'Chantal':'Chantal';break;\ncase \"German\": voice = mf=='Male'?'Hans':'Marlene';break;\ncase \"Icelandic\": voice = mf=='Male'?'Karl':'Dora';break;\ncase \"Italian\": voice = mf=='Male'?'Carla':'Giorgio';break;\ncase \"Japanese\": voice = mf=='Male'?'Takumi':'Mizuki';break;\ncase \"Korean\": voice = mf=='Male'?'Seoyan':'Seoyan';break;\ncase \"Norwegian\": voice = mf=='Male'?'Liv':'Liv';break;\ncase \"Polish\": voice = mf=='Male'?'Jacek':'Ewa';break;\ncase \"Portugese(BR)\": voice = mf=='Male'?'Ricardo':'Vitoria';break;\ncase \"Portugese(PT)\": voice = mf=='Male'?'Cristiano':'Ines';break;\ncase \"Romanian\": voice = mf=='Male'?'Carmen':'Carmen';break;\ncase \"Russian\": voice = mf=='Male'?'Maxim':'Tatyana';break;\ncase \"Spanish(ES)\": voice = mf=='Male'?'Enrique':'Conchita';break;\ncase \"Spanish(US)\": voice = mf=='Male'?'Miguel':'Penelope';break;\ncase \"Swedish\": voice = mf=='Male'?'Astrid':'Astrid';break;\ncase \"Turkish\": voice = mf=='Male'?'Filiz':'Filiz';break;\ncase \"Welsh\": voice = mf=='Male'?'Gwyneth':'Gwyneth';break;\ndefault: voice = mf=='Male'?'Brian':'Amy';\n}\n\n\n\n//build template for one dictation item\nvar template ='
';\ntemplate += '
';\ntemplate += '
';\ntemplate += '
';\ntemplate += '
';\ntemplate +='
';\n\nvar container = \n\n$('#' + @@AUTOID@@ + \" li\" ).each(function(index) {\n var usetext = $(this).text();\n fetch_polly_url(usetext,voice,\n function(bulletindex){return function(pollyurl){\n\n //create the item and get the TTS audio\n var usetemplate = template.replace('@AUDIO@',pollyurl); \n usetemplate = usetemplate.replace(/@ID@/g, bulletindex);\n theitemscontainer.append(usetemplate);\n\n //add events\n var theinput= $('#dictationinput_' + bulletindex + ' input');\n var thestatus= $('#dictationstatus_' + bulletindex);\n var theaudio= $('#dictationplayer_' + bulletindex + ' audio');\n theinput.on('keyup',function(){\n if($(this).val()==usetext){\n thestatus.addClass('dictationcorrect');\n }else{\n thestatus.removeClass('dictationcorrect');\n }\n });//end of change event\n //we use function inside function so that: index = bullet index. (index value changing before callback called)\n }}(index)\n );\n\n });//end of each loop","style":"div.poodlldictationstatus {\n padding: 3px;\n border: black 1px solid;\n border-width: 2px;\n border-radius: 10px;\n width: 30px;\n text-align: center;\n}\ndiv.dictationcorrect{\n color: white;\nbackground-color: green;\n}\ndiv.row.dictationrow{\n max-width: 600px;\n min-height: 50px;\ndisplay: flex;\n}\ndiv.dictationrow input {\n width: 100%;\n}","dataset":"","datasetvars":"","alternate":"","alternateend":""} \ No newline at end of file diff --git a/presets/soundboard.txt b/presets/soundboard.txt deleted file mode 100644 index 668cdf82..00000000 --- a/presets/soundboard.txt +++ /dev/null @@ -1 +0,0 @@ -{"name":"Sound Board","key":"soundboard","version":"1.0.0","instructions":"Add an html list (bullets) of phrases to be read, between the tags. They will become buttons that speak when tapped.","showatto":"1","showplayers":"0","requirecss":"","requirejs":"","shim":"","defaults":"language=\"English(US)|English(GB)|English(AU)|English(In)|English(Welsh)|Danish|Dutch|French(FR)|French(CA)|German|Icelandic|Italian|Japanese|Korean|Norwegian|Polish|Portugese(BR)|Portugese(PT)|Romanian|Russian|Spanish(ES)|Spanish(US)|Swedish|Turkish|Welsh\",\nspeaker=\"Male|Female\"","amd":"1","body":"
\n\n
\n","bodyend":"
","script":"//remove any HTML editor artifacts\n$('#' + @@AUTOID@@ + ' p').remove();\n$('#' + @@AUTOID@@ + ' span').remove();\n\n//fetch the controls we inserted in \"body\"\nvar theplayer = $('#' + @@AUTOID@@ + '_player');\nvar theulcontainer = $('#' + @@AUTOID@@); \nvar theitemscontainer = $('#' + @@AUTOID@@ + '_container'); \n\ntheitemscontainer.on('click','.fp_soundboard_player_trigger', function(e){\n theplayer.attr('src',$(this).attr('data-src'));\n theplayer[0].play();\n});\n\n\n//determine voice\nvar mf=@@speaker@@\nswitch(@@language@@){\ncase \"English(US)\": voice = mf=='Male'?'Joey':'Kendra';break;\ncase \"English(GB)\": voice = mf=='Male'?'Brian':'Amy';break;\ncase \"English(AU)\": voice = mf=='Male'?'Russell':'Nicole';break;\ncase \"English(IN)\": voice = mf=='Male'?'Aditi':'Raveena';break;\ncase \"English(WELSH)\": voice = mf=='Male'? 'Geraint':'Geraint';break;\ncase \"Danish\": voice = mf=='Male'?'Mads':'Naja';break;\ncase \"Dutch\": voice = mf=='Male'?'Ruben':'Lotte';break;\ncase \"French(FR)\": voice = mf=='Male'?'Mathieu':'Celine';break;\ncase \"French(CA)\": voice = mf=='Male'?'Chantal':'Chantal';break;\ncase \"German\": voice = mf=='Male'?'Hans':'Marlene';break;\ncase \"Icelandic\": voice = mf=='Male'?'Karl':'Dora';break;\ncase \"Italian\": voice = mf=='Male'?'Carla':'Giorgio';break;\ncase \"Japanese\": voice = mf=='Male'?'Takumi':'Mizuki';break;\ncase \"Korean\": voice = mf=='Male'?'Seoyan':'Seoyan';break;\ncase \"Norwegian\": voice = mf=='Male'?'Liv':'Liv';break;\ncase \"Polish\": voice = mf=='Male'?'Jacek':'Ewa';break;\ncase \"Portugese(BR)\": voice = mf=='Male'?'Ricardo':'Vitoria';break;\ncase \"Portugese(PT)\": voice = mf=='Male'?'Cristiano':'Ines';break;\ncase \"Romanian\": voice = mf=='Male'?'Carmen':'Carmen';break;\ncase \"Russian\": voice = mf=='Male'?'Maxim':'Tatyana';break;\ncase \"Spanish(ES)\": voice = mf=='Male'?'Enrique':'Conchita';break;\ncase \"Spanish(US)\": voice = mf=='Male'?'Miguel':'Penelope';break;\ncase \"Swedish\": voice = mf=='Male'?'Astrid':'Astrid';break;\ncase \"Turkish\": voice = mf=='Male'?'Filiz':'Filiz';break;\ncase \"Welsh\": voice = mf=='Male'?'Gwyneth':'Gwyneth';break;\ndefault: voice = mf=='Male'?'Brian':'Amy';\n}\n\n\n\n//Build audio url components\nvar poodllfilelib = M.cfg.wwwroot + '/filter/poodll/poodllfilelib.php?datatype=speaktext¶mone=';\nvar format = 'text';\n\n//build template for one dictation item\nvar template ='
';\ntemplate += '
';\ntemplate += '@TEXT@';\ntemplate += '
';\n\n\nvar container = \n\n$('#' + @@AUTOID@@ + \" li\" ).each(function(index) {\n var usetext = $(this).text();\n var datastring= 'text' + '|' + voice + '|' + usetext;\n var src = poodllfilelib+encodeURIComponent(datastring);\n var usetemplate = template.replace('@AUDIO@',src); \n usetemplate = usetemplate.replace('@TEXT@',usetext); \n usetemplate = usetemplate.replace(/@ID@/g, index);\n theitemscontainer.append(usetemplate);\n \n //add events\n var theaudio= $('#fp_soundboard_player_' + index + ' audio');\n\n });//end of each loop","style":"","dataset":"","datasetvars":"","alternate":"","alternateend":""} \ No newline at end of file diff --git a/presets/soundboardcloud.txt b/presets/soundboardcloud.txt new file mode 100644 index 00000000..fed8ad75 --- /dev/null +++ b/presets/soundboardcloud.txt @@ -0,0 +1 @@ +{"name":"Sound Board (Cloud)","key":"soundboardcloud","version":"1.0.0","instructions":"Add an html list (bullets) of phrases to be read, between the tags. They will become buttons that speak when tapped.","showatto":"1","showplayers":"0","requirecss":"","requirejs":"","shim":"","defaults":"language=\"English(US)|English(GB)|English(AU)|English(In)|English(Welsh)|Danish|Dutch|French(FR)|French(CA)|German|Icelandic|Italian|Japanese|Korean|Norwegian|Polish|Portugese(BR)|Portugese(PT)|Romanian|Russian|Spanish(ES)|Spanish(US)|Swedish|Turkish|Welsh\",\nspeaker=\"Male|Female\"","amd":"1","body":"
\n\n\n
\n","bodyend":"
","script":"//FUNCTION fetch polly url\n var fetch_polly_url = function(speaktext, voice, callback) {\n\n //The REST API we are calling\n var functionname = 'local_cpapi_fetch_polly_url';\n\n //fetch the Posturl. We need this.\n //set up our ajax request\n var xhr = new XMLHttpRequest();\n var that = this;\n\n //set up our handler for the response\n xhr.onreadystatechange = function (e) {\n if (this.readyState === 4) {\n if (xhr.status == 200) {\n\n //get a yes or forgetit or tryagain\n var payload = xhr.responseText;\n var payloadobject = JSON.parse(payload);\n if (payloadobject) {\n //returnCode > 0 indicates an error\n if (payloadobject.returnCode > 0) {\n console.log(payloadobject.returnMessage);\n return false;\n //if all good, then lets do the embed\n } else if (payloadobject.returnCode === 0){\n var pollyurl = payloadobject.returnMessage;\n callback(pollyurl);\n } else {\n console.log('Polly Signed URL Request failed:');\n console.log(payloadobject);\n }\n } else {\n console.log('Polly Signed URL Request something bad happened');\n }\n } else {\n console.log('Polly Signed URL Request Not 200 response:' + xhr.status);\n }\n }\n };\n\n //make our request\n var xhrparams = \"wstoken=\" + @@CLOUDPOODLLTOKEN@@\n + \"&wsfunction=\" + functionname\n + \"&moodlewsrestformat=\" + 'json'\n + \"&text=\" + encodeURIComponent(speaktext)\n + '&texttype=text'\n + '&voice=' + voice\n + '&appid=' + 'filter_poodll'\n + '&owner=poodll'\n + '®ion=useast1';\n\n var serverurl = 'https://cloud.poodll.com' + \"/webservice/rest/server.php\";\n xhr.open(\"POST\", serverurl, true);\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n xhr.send(xhrparams);\n };\n\n//remove any HTML editor artifacts\n$('#' + @@AUTOID@@ + ' p').remove();\n$('#' + @@AUTOID@@ + ' span').remove();\n\n//fetch the controls we inserted in \"body\"\nvar theplayer = $('#' + @@AUTOID@@ + '_player');\nvar theulcontainer = $('#' + @@AUTOID@@); \nvar theitemscontainer = $('#' + @@AUTOID@@ + '_container'); \n\ntheitemscontainer.on('click','.fp_soundboard_player_trigger', function(e){\n theplayer.attr('src',$(this).attr('data-src'));\n theplayer[0].play();\n});\n\n\n//determine voice\nvar mf=@@speaker@@\nswitch(@@language@@){\ncase \"English(US)\": voice = mf=='Male'?'Joey':'Kendra';break;\ncase \"English(GB)\": voice = mf=='Male'?'Brian':'Amy';break;\ncase \"English(AU)\": voice = mf=='Male'?'Russell':'Nicole';break;\ncase \"English(IN)\": voice = mf=='Male'?'Aditi':'Raveena';break;\ncase \"English(WELSH)\": voice = mf=='Male'? 'Geraint':'Geraint';break;\ncase \"Danish\": voice = mf=='Male'?'Mads':'Naja';break;\ncase \"Dutch\": voice = mf=='Male'?'Ruben':'Lotte';break;\ncase \"French(FR)\": voice = mf=='Male'?'Mathieu':'Celine';break;\ncase \"French(CA)\": voice = mf=='Male'?'Chantal':'Chantal';break;\ncase \"German\": voice = mf=='Male'?'Hans':'Marlene';break;\ncase \"Icelandic\": voice = mf=='Male'?'Karl':'Dora';break;\ncase \"Italian\": voice = mf=='Male'?'Carla':'Giorgio';break;\ncase \"Japanese\": voice = mf=='Male'?'Takumi':'Mizuki';break;\ncase \"Korean\": voice = mf=='Male'?'Seoyan':'Seoyan';break;\ncase \"Norwegian\": voice = mf=='Male'?'Liv':'Liv';break;\ncase \"Polish\": voice = mf=='Male'?'Jacek':'Ewa';break;\ncase \"Portugese(BR)\": voice = mf=='Male'?'Ricardo':'Vitoria';break;\ncase \"Portugese(PT)\": voice = mf=='Male'?'Cristiano':'Ines';break;\ncase \"Romanian\": voice = mf=='Male'?'Carmen':'Carmen';break;\ncase \"Russian\": voice = mf=='Male'?'Maxim':'Tatyana';break;\ncase \"Spanish(ES)\": voice = mf=='Male'?'Enrique':'Conchita';break;\ncase \"Spanish(US)\": voice = mf=='Male'?'Miguel':'Penelope';break;\ncase \"Swedish\": voice = mf=='Male'?'Astrid':'Astrid';break;\ncase \"Turkish\": voice = mf=='Male'?'Filiz':'Filiz';break;\ncase \"Welsh\": voice = mf=='Male'?'Gwyneth':'Gwyneth';break;\ndefault: voice = mf=='Male'?'Brian':'Amy';\n}\n\n\n\n//build template for one dictation item\nvar template ='
';\ntemplate += '
';\ntemplate += '@TEXT@';\ntemplate += '
';\n\n\n$('#' + @@AUTOID@@ + \" li\" ).each(function(index) {\n var usetext = $(this).text();\n\n fetch_polly_url(usetext,voice,\n function(itemindex,itemusetext){\n return function(pollyurl){\n var usetemplate = template.replace('@AUDIO@',pollyurl); \n usetemplate = usetemplate.replace('@TEXT@',itemusetext); \n usetemplate = usetemplate.replace(/@ID@/g, itemindex);\n theitemscontainer.append(usetemplate);\n \n //add events\n var theaudio= $('#fp_soundboard_player_' + itemindex + ' audio');\n };\n \n }(index,usetext));\n\n \n\n });//end of each loop","style":"","dataset":"","datasetvars":"","alternate":"","alternateend":""} \ No newline at end of file diff --git a/presets/tapwordtohear.txt b/presets/tapwordtohear.txt deleted file mode 100644 index 148bc51c..00000000 --- a/presets/tapwordtohear.txt +++ /dev/null @@ -1 +0,0 @@ -{"name":"Tap Word to Hear","key":"tapwordtohear","version":"1.0.1","instructions":"This will read aloud words in the enclosed text block when tapped. Currently does not support \"sentence\" mode.","showatto":"1","showplayers":"0","requirecss":"","requirejs":"","shim":"","defaults":"playmode=\"word|sentence\",speaker=\"Male|Female\",language=\"English(US)|English(GB)|English(AU)|English(In)|English(Welsh)|Danish|Dutch|French(FR)|French(CA)|German|Icelandic|Italian|Japanese|Korean|Norwegian|Polish|Portugese(BR)|Portugese(PT)|Romanian|Russian|Spanish(ES)|Spanish(US)|Swedish|Turkish|Welsh\"","amd":"1","body":"\n
","bodyend":"
","script":"//DECLARATIONS and INITs ...........................\nvar thesentence_number =0;\nvar lettered= false;\n\n//audio player declarations\nvar aplayer = $('#' + @@AUTOID@@ + '_audio');\n\n//text to audio preparation\nvar poodllfilelib = M.cfg.wwwroot + '/filter/poodll/poodllfilelib.php?datatype=speaktext¶mone=';\nvar format = \"text\";\n\n//determine the voice\nvar mf=@@speaker@@\nswitch(@@language@@){\ncase \"English(US)\": voice = mf=='Male'?'Joey':'Kendra';break;\ncase \"English(GB)\": voice = mf=='Male'?'Brian':'Amy';break;\ncase \"English(AU)\": voice = mf=='Male'?'Russell':'Nicole';break;\ncase \"English(IN)\": voice = mf=='Male'?'Aditi':'Raveena';break;\ncase \"English(WELSH)\": voice = mf=='Male'? 'Geraint':'Geraint';break;\ncase \"Danish\": voice = mf=='Male'?'Mads':'Naja';break;\ncase \"Dutch\": voice = mf=='Male'?'Ruben':'Lotte';break;\ncase \"French(FR)\": voice = mf=='Male'?'Mathieu':'Celine';break;\ncase \"French(CA)\": voice = mf=='Male'?'Chantal':'Chantal';break;\ncase \"German\": voice = mf=='Male'?'Hans':'Marlene';break;\ncase \"Icelandic\": voice = mf=='Male'?'Karl':'Dora';break;\ncase \"Italian\": voice = mf=='Male'?'Carla':'Giorgio';break;\ncase \"Japanese\": voice = mf=='Male'?'Takumi':'Mizuki';break;\ncase \"Korean\": voice = mf=='Male'?'Seoyan':'Seoyan';break;\ncase \"Norwegian\": voice = mf=='Male'?'Liv':'Liv';break;\ncase \"Polish\": voice = mf=='Male'?'Jacek':'Ewa';break;\ncase \"Portugese(BR)\": voice = mf=='Male'?'Ricardo':'Vitoria';break;\ncase \"Portugese(PT)\": voice = mf=='Male'?'Cristiano':'Ines';break;\ncase \"Romanian\": voice = mf=='Male'?'Carmen':'Carmen';break;\ncase \"Russian\": voice = mf=='Male'?'Maxim':'Tatyana';break;\ncase \"Spanish(ES)\": voice = mf=='Male'?'Enrique':'Conchita';break;\ncase \"Spanish(US)\": voice = mf=='Male'?'Miguel':'Penelope';break;\ncase \"Swedish\": voice = mf=='Male'?'Astrid':'Astrid';break;\ncase \"Turkish\": voice = mf=='Male'?'Filiz':'Filiz';break;\ncase \"Welsh\": voice = mf=='Male'?'Gwyneth':'Gwyneth';break;\ndefault: voice = mf=='Male'?'Brian':'Amy';\n}\n\n\n//fetch the text to read\nvar useblock = $('#' + @@AUTOID@@ + '_textblock');\nvar usetext = useblock.text();\n//we replace tags with markers to survive going into a URL and out again\nusetext = usetext.replace(//gi, \"dddd\");\n\n//some common selectors\nvar wordselector = '#' + @@AUTOID@@+ '_textblock span.tbr_word';\nvar sentenceselector = '#' + @@AUTOID@@+ '_textblock span.tbr_sentence';\n\n//FUNCTIONS ...........................\n//FUNCTION: determine if the string is text or HTML\nvar isHTML = function (testString) {\n var htmlRegex = new RegExp(\"<([A-Za-z][A-Za-z0-9]*)\\\\b[^>]*>(.*?)\");\n return htmlRegex.test(testString);\n};\n\n//FUNCTION: split a text passage into words\nvar split_into_words= function(thetext){\n thetext = thetext.replace(/\\s+/g,' ').trim();\n if(thetext==''){return[]};\n return thetext.split(' '); \n};\n\n//FUNCTION: split a text passage into sentences\nvar split_into_sentences = function(thetext){\n thetext = thetext.replace(/\\s+/g,' ').trim();\n if(thetext ==''){return[]};\n return thetext.match(/([^\\.!\\?]+[\\.!\\?\"']+)|([^\\.!\\?\"']+$)/g); \n};\n\n//FUNCTION: break a text passage into words/sentences, and surround the words with marker tags\nvar spanify_text_passage = function(){\n //the itemcount er\n var itemcount = -1;\n\n //get all the text nodes in the useblock\n var textnodes = useblock.find('*').contents().filter(function(){ return this.nodeType == 3; });\n //wrap sentence or words in text block with spans\n textnodes.each(function(){\n var retpieces = ''; \n if(@@playmode@@=='word'){\n //for words\n var thewords = split_into_words($(this).text());\n for (var theword=0; theword < thewords.length; theword++){\n itemcount++;\n retpieces = retpieces + '' + thewords[theword] + ' ';\n }//end of for loop\n }else{\n //for sentences\n //something is wrong in sentence mode. For now, just use word mode.\n var thesentences = split_into_sentences($(this).text());\n for (var thesentence=0; thesentence < thesentences.length; thesentence++){\n itemcount++;\n retpieces = retpieces + '' + thesentences[thesentence] + ' ';\n }//end of for loop\n }\n $(this).replaceWith(retpieces);\n });//end of textnodes each\n};\n\n//FUNCTION: unhighlight a sentence as active\nvar dehighlight_all = function(){\n switch(@@playmode@@){\n case 'word':\n $(wordselector).removeClass('activesentence');\n break;\n case 'sentence':\n $(sentenceselector).removeClass('activesentence');\n case 'none':\n default:\n //do nothing\n }\n};\n\n//FUNCTION: highlight a word as active\nvar highlight_word = function(theword){\n $(wordselector).removeClass('activesentence');\n theword.addClass('activesentence');\n};\n\n//FUNCTION: highlight a sentence as active\nvar highlight_sentence = function(thesentence){\n $(sentenceselector).removeClass('activesentence');\n $(sentenceselector + '[data-sentenceindex=' + thesentence + ']').addClass('activesentence');\n};\n\n//FUNCTION: play a single sentence and mark it active for display purposes\nvar doplaysentence = function(thesentence){\n highlight_sentence(thesentence);\n aplayer.attr('src', instancedata[@@AUTOID@@].sentenceURLs[thesentence]);\n aplayer[0].play();\n};\n\nvar doplayword = function(theword){\n highlight_word(theword);\n var datastring= format + '|' + voice + '|' + theword.text();\n var src = poodllfilelib+encodeURIComponent(datastring);\n aplayer.attr('src', src);\n aplayer[0].play();\n};\n\n//AUDIO PLAYER events\naplayer[0].addEventListener('ended', function(){\n dehighlight_all();\n aplayer[0].pause();\n});\n\n//handle sentence or word clicks\n$('#' + @@AUTOID@@ + '_textblock .tbr_innerdiv').on('click', '.tbr_sentence, .tbr_word',function(){\n var clickeditem= $(this);\n var startnewplay = function(){ switch(@@playmode@@){\n case 'sentence':\n var index = clickeditem.attr('data-sentenceindex');\n doplaysentence(index);\n break;\n case 'word':\n default:\n //var index = clickeditem.attr('data-wordindex');\n doplayword(clickeditem);\n }//end of switch\n \n };//end of startnewplay function\n\n if(aplayer[0].playing){\n console.log('was playing but then got iterrupted');\n aplayer[0].pause().then(startnewplay);\n }else{ \n startnewplay();\n }//end of if\n});//end of on click handler\n\n//PROCEDURAL stuff ...........................\n//break it into sentences, and fetch data + TTS URL for each sentence\nvar sentences = split_into_sentences(usetext);\nwordstarts=[];\nwordcounts=[];\nsentenceURLs=[];\nvar previousend=0;\nfor (var currentsentence=0;currentsentence\n\n
","bodyend":"
","script":"//DECLARATIONS and INITs ...........................\nvar thesentence_number =0;\nvar lettered= false;\n\n//audio player declarations\nvar aplayer = $('#' + @@AUTOID@@ + '_audio');\n\n//determine the voice\nvar mf=@@speaker@@\nswitch(@@language@@){\ncase \"English(US)\": voice = mf=='Male'?'Joey':'Kendra';break;\ncase \"English(GB)\": voice = mf=='Male'?'Brian':'Amy';break;\ncase \"English(AU)\": voice = mf=='Male'?'Russell':'Nicole';break;\ncase \"English(IN)\": voice = mf=='Male'?'Aditi':'Raveena';break;\ncase \"English(WELSH)\": voice = mf=='Male'? 'Geraint':'Geraint';break;\ncase \"Danish\": voice = mf=='Male'?'Mads':'Naja';break;\ncase \"Dutch\": voice = mf=='Male'?'Ruben':'Lotte';break;\ncase \"French(FR)\": voice = mf=='Male'?'Mathieu':'Celine';break;\ncase \"French(CA)\": voice = mf=='Male'?'Chantal':'Chantal';break;\ncase \"German\": voice = mf=='Male'?'Hans':'Marlene';break;\ncase \"Icelandic\": voice = mf=='Male'?'Karl':'Dora';break;\ncase \"Italian\": voice = mf=='Male'?'Carla':'Giorgio';break;\ncase \"Japanese\": voice = mf=='Male'?'Takumi':'Mizuki';break;\ncase \"Korean\": voice = mf=='Male'?'Seoyan':'Seoyan';break;\ncase \"Norwegian\": voice = mf=='Male'?'Liv':'Liv';break;\ncase \"Polish\": voice = mf=='Male'?'Jacek':'Ewa';break;\ncase \"Portugese(BR)\": voice = mf=='Male'?'Ricardo':'Vitoria';break;\ncase \"Portugese(PT)\": voice = mf=='Male'?'Cristiano':'Ines';break;\ncase \"Romanian\": voice = mf=='Male'?'Carmen':'Carmen';break;\ncase \"Russian\": voice = mf=='Male'?'Maxim':'Tatyana';break;\ncase \"Spanish(ES)\": voice = mf=='Male'?'Enrique':'Conchita';break;\ncase \"Spanish(US)\": voice = mf=='Male'?'Miguel':'Penelope';break;\ncase \"Swedish\": voice = mf=='Male'?'Astrid':'Astrid';break;\ncase \"Turkish\": voice = mf=='Male'?'Filiz':'Filiz';break;\ncase \"Welsh\": voice = mf=='Male'?'Gwyneth':'Gwyneth';break;\ndefault: voice = mf=='Male'?'Brian':'Amy';\n}\n\n\n//fetch the text to read\nvar useblock = $('#' + @@AUTOID@@ + '_textblock');\nvar usetext = useblock.text();\n\n//some common selectors\nvar wordselector = '#' + @@AUTOID@@+ '_textblock span.tbr_word';\nvar sentenceselector = '#' + @@AUTOID@@+ '_textblock span.tbr_sentence';\n\n//FUNCTIONS ...........................\n\n\n//FUNCTION fetch polly url\n var fetch_polly_url = function(speaktext, voice, callback) {\n\n //The REST API we are calling\n var functionname = 'local_cpapi_fetch_polly_url';\n\n //fetch the Posturl. We need this.\n //set up our ajax request\n var xhr = new XMLHttpRequest();\n var that = this;\n\n //set up our handler for the response\n xhr.onreadystatechange = function (e) {\n if (this.readyState === 4) {\n if (xhr.status == 200) {\n\n //get a yes or forgetit or tryagain\n var payload = xhr.responseText;\n var payloadobject = JSON.parse(payload);\n if (payloadobject) {\n //returnCode > 0 indicates an error\n if (payloadobject.returnCode > 0) {\n console.log(payloadobject.returnMessage);\n return false;\n //if all good, then lets do the embed\n } else if (payloadobject.returnCode === 0){\n var pollyurl = payloadobject.returnMessage;\n callback(pollyurl);\n } else {\n console.log('Polly Signed URL Request failed:');\n console.log(payloadobject);\n }\n } else {\n console.log('Polly Signed URL Request something bad happened');\n }\n } else {\n console.log('Polly Signed URL Request Not 200 response:' + xhr.status);\n }\n }\n };\n\n //make our request\n var xhrparams = \"wstoken=\" + @@CLOUDPOODLLTOKEN@@\n + \"&wsfunction=\" + functionname\n + \"&moodlewsrestformat=\" + 'json'\n + \"&text=\" + encodeURIComponent(speaktext)\n + '&texttype=text'\n + '&voice=' + voice\n + '&appid=' + 'filter_poodll'\n + '&owner=poodll'\n + '®ion=useast1';\n\n var serverurl = 'https://cloud.poodll.com' + \"/webservice/rest/server.php\";\n xhr.open(\"POST\", serverurl, true);\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n xhr.send(xhrparams);\n };\n\n//FUNCTION: determine if the string is text or HTML\nvar isHTML = function (testString) {\n var htmlRegex = new RegExp(\"<([A-Za-z][A-Za-z0-9]*)\\\\b[^>]*>(.*?)\");\n return htmlRegex.test(testString);\n};\n\n//FUNCTION: split a text passage into words\nvar split_into_words= function(thetext){\n thetext = thetext.replace(/\\s+/g,' ').trim();\n if(thetext==''){return[]};\n return thetext.split(' '); \n};\n\n//FUNCTION: split a text passage into sentences\nvar split_into_sentences = function(thetext){\n thetext = thetext.replace(/\\s+/g,' ').trim();\n if(thetext ==''){return[]};\n return thetext.match(/([^\\.!\\?]+[\\.!\\?\"']+)|([^\\.!\\?\"']+$)/g); \n};\n\n//FUNCTION: break a text passage into words/sentences, and surround the words with marker tags\nvar spanify_text_passage = function(){\n //the itemcount er\n var itemcount = -1;\n\n //get all the text nodes in the useblock\n var textnodes = useblock.find('*').contents().filter(function(){ return this.nodeType == 3; });\n //wrap sentence or words in text block with spans\n textnodes.each(function(){\n var retpieces = ''; \n if(@@playmode@@=='word'){\n //for words\n var thewords = split_into_words($(this).text());\n for (var theword=0; theword < thewords.length; theword++){\n itemcount++;\n retpieces = retpieces + '' + thewords[theword] + ' ';\n }//end of for loop\n }else{\n //for sentences\n //something is wrong in sentence mode. For now, just use word mode.\n var thesentences = split_into_sentences($(this).text());\n for (var thesentence=0; thesentence < thesentences.length; thesentence++){\n itemcount++;\n retpieces = retpieces + '' + thesentences[thesentence] + ' ';\n }//end of for loop\n }\n $(this).replaceWith(retpieces);\n });//end of textnodes each\n};\n\n//FUNCTION: unhighlight a sentence as active\nvar dehighlight_all = function(){\n switch(@@playmode@@){\n case 'word':\n $(wordselector).removeClass('activesentence');\n break;\n case 'sentence':\n $(sentenceselector).removeClass('activesentence');\n case 'none':\n default:\n //do nothing\n }\n};\n\n//FUNCTION: highlight a word as active\nvar highlight_word = function(theword){\n $(wordselector).removeClass('activesentence');\n theword.addClass('activesentence');\n};\n\n//FUNCTION: highlight a sentence as active\nvar highlight_sentence = function(thesentence){\n $(sentenceselector).removeClass('activesentence');\n $(sentenceselector + '[data-sentenceindex=' + thesentence + ']').addClass('activesentence');\n};\n\n//FUNCTION: play a single sentence and mark it active for display purposes\nvar doplaysentence = function(thesentence){\n highlight_sentence(thesentence);\n aplayer.attr('src', instancedata[@@AUTOID@@].sentenceURLs[thesentence]);\n aplayer[0].play();\n};\n\nvar doplayword = function(theword){\n highlight_word(theword);\n fetch_polly_url(theword.text(),voice,function(pollyurl){\n aplayer.attr('src', pollyurl);\n aplayer[0].play();\n });\n \n};\n\n//AUDIO PLAYER events\naplayer[0].addEventListener('ended', function(){\n dehighlight_all();\n aplayer[0].pause();\n});\n\n//handle sentence or word clicks\n$('#' + @@AUTOID@@ + '_textblock .tbr_innerdiv').on('click', '.tbr_sentence, .tbr_word',function(){\n var clickeditem= $(this);\n var startnewplay = function(){ switch(@@playmode@@){\n case 'sentence':\n var index = clickeditem.attr('data-sentenceindex');\n doplaysentence(index);\n break;\n case 'word':\n default:\n //var index = clickeditem.attr('data-wordindex');\n doplayword(clickeditem);\n }//end of switch\n \n };//end of startnewplay function\n\n if(aplayer[0].playing){\n console.log('was playing but then got iterrupted');\n aplayer[0].pause().then(startnewplay);\n }else{ \n startnewplay();\n }//end of if\n});//end of on click handler\n\n//PROCEDURAL stuff ...........................\n//break it into sentences, and fetch data + TTS URL for each sentence\nvar sentences = split_into_sentences(usetext);\nwordstarts=[];\nwordcounts=[];\nsentenceURLs=[];\nvar previousend=0;\n\nfor (var currentsentence=0;currentsentence\n\t\n\t\n\n
\n
","bodyend":"
\n
","script":"//DECLARATIONS and INITs ...........................\nvar thesentence_number =0;\nvar lettered= false;\n\n//audio player declarations\nvar aplayer = $('#' + @@AUTOID@@).children().first();\nvar fa = $('#' + @@AUTOID@@ + ' .fa');\n\n//text to audio preparation\nvar poodllfilelib = M.cfg.wwwroot + '/filter/poodll/poodllfilelib.php?datatype=speaktext¶mone=';\nvar format = \"text\";\n\n//determine the voice\nvar mf=@@speaker@@\nswitch(@@language@@){\ncase \"English(US)\": voice = mf=='Male'?'Joey':'Kendra';break;\ncase \"English(GB)\": voice = mf=='Male'?'Brian':'Amy';break;\ncase \"English(AU)\": voice = mf=='Male'?'Russell':'Nicole';break;\ncase \"English(IN)\": voice = mf=='Male'?'Aditi':'Raveena';break;\ncase \"English(WELSH)\": voice = mf=='Male'? 'Geraint':'Geraint';break;\ncase \"Danish\": voice = mf=='Male'?'Mads':'Naja';break;\ncase \"Dutch\": voice = mf=='Male'?'Ruben':'Lotte';break;\ncase \"French(FR)\": voice = mf=='Male'?'Mathieu':'Celine';break;\ncase \"French(CA)\": voice = mf=='Male'?'Chantal':'Chantal';break;\ncase \"German\": voice = mf=='Male'?'Hans':'Marlene';break;\ncase \"Icelandic\": voice = mf=='Male'?'Karl':'Dora';break;\ncase \"Italian\": voice = mf=='Male'?'Carla':'Giorgio';break;\ncase \"Japanese\": voice = mf=='Male'?'Takumi':'Mizuki';break;\ncase \"Korean\": voice = mf=='Male'?'Seoyan':'Seoyan';break;\ncase \"Norwegian\": voice = mf=='Male'?'Liv':'Liv';break;\ncase \"Polish\": voice = mf=='Male'?'Jacek':'Ewa';break;\ncase \"Portugese(BR)\": voice = mf=='Male'?'Ricardo':'Vitoria';break;\ncase \"Portugese(PT)\": voice = mf=='Male'?'Cristiano':'Ines';break;\ncase \"Romanian\": voice = mf=='Male'?'Carmen':'Carmen';break;\ncase \"Russian\": voice = mf=='Male'?'Maxim':'Tatyana';break;\ncase \"Spanish(ES)\": voice = mf=='Male'?'Enrique':'Conchita';break;\ncase \"Spanish(US)\": voice = mf=='Male'?'Miguel':'Penelope';break;\ncase \"Swedish\": voice = mf=='Male'?'Astrid':'Astrid';break;\ncase \"Turkish\": voice = mf=='Male'?'Filiz':'Filiz';break;\ncase \"Welsh\": voice = mf=='Male'?'Gwyneth':'Gwyneth';break;\ndefault: voice = mf=='Male'?'Brian':'Amy';\n}\n\n\n//fetch the text to read\nvar useblock = $('#' + @@AUTOID@@ + '_textblock');\nvar usetext = useblock.text();\n//we replace tags with markers to survive going into a URL and out again\nusetext = usetext.replace(//gi, \"dddd\");\n\n//some common selectors\nvar wordselector = '#' + @@AUTOID@@+ '_textblock span.tbr_word';\nvar sentenceselector = '#' + @@AUTOID@@+ '_textblock span.tbr_sentence';\n\n//FUNCTIONS ...........................\n//FUNCTION: determine if the string is text or HTML\nvar isHTML = function (testString) {\n var htmlRegex = new RegExp(\"<([A-Za-z][A-Za-z0-9]*)\\\\b[^>]*>(.*?)\");\n return htmlRegex.test(testString);\n};\n\n//FUNCTION: split a text passage into words\nvar split_into_words= function(thetext){\n thetext = thetext.replace(/\\s+/g,' ').trim();\n if(thetext==''){return[]};\n return thetext.split(' '); \n};\n\n//FUNCTION: split a text passage into sentences\nvar split_into_sentences = function(thetext){\n thetext = thetext.replace(/\\s+/g,' ').trim();\n if(thetext ==''){return[]};\n return thetext.match(/([^\\.!\\?]+[\\.!\\?\"']+)|([^\\.!\\?\"']+$)/g); \n};\n\n//FUNCTION: break a text passage into words/sentences, and surround the words with marker tags\nvar spanify_text_passage = function(){\n //the itemcount er\n var itemcount = -1;\n\n //get all the text nodes in the useblock\n var textnodes = useblock.find('*').contents().filter(function(){ return this.nodeType == 3; });\n //wrap sentence or words in text block with spans\n textnodes.each(function(){\n var retpieces = ''; \n if(@@highlightmode@@=='word'){\n //for words\n var thewords = split_into_words($(this).text());\n for (var theword=0; theword < thewords.length; theword++){\n itemcount++;\n retpieces = retpieces + '' + thewords[theword] + ' ';\n }//end of for loop\n }else{\n //for sentences\n var thesentences = split_into_sentences($(this).text());\n for (var thesentence=0; thesentence < thesentences.length; thesentence++){\n itemcount++;\n retpieces = retpieces + '' + thesentences[thesentence] + ' ';\n }//end of for loop\n }\n $(this).replaceWith(retpieces);\n });//end of textnodes each\n};\n\n//FUNCTION: unhighlight a sentence as active\nvar dehighlight_all = function(){\n switch(@@highlightmode@@){\n case 'word':\n $(wordselector,useblock).removeClass('activesentence');\n break;\n case 'sentence':\n $(sentenceselector,useblock).removeClass('activesentence');\n break;\n case 'none':\n default:\n //do nothing\n }\n}\n\n//FUNCTION: highlight a sentence as active\nvar highlight_sentence = function(thesentence){\n switch(@@highlightmode@@){\n case 'word':\n $(wordselector,useblock).removeClass('activesentence');\n $(wordselector,useblock).slice(instancedata[@@AUTOID@@].wordstarts[thesentence],\n instancedata[@@AUTOID@@].wordstarts[thesentence] + \n instancedata[@@AUTOID@@].wordcounts[thesentence]).addClass('activesentence');\n break;\n case 'sentence':\n $(sentenceselector).removeClass('activesentence');\n $(sentenceselector + '[data-sentenceindex=' + thesentence + ']').addClass('activesentence');\n break;\n case 'none':\n default:\n //do nothing\n }\n}\n\n//FUNCTION: play a single sentence and mark it active for display purposes\nvar doplayaudio = function(thesentence){\n highlight_sentence(thesentence);\n aplayer.attr('src', instancedata[@@AUTOID@@].sentenceURLs[thesentence]);\n aplayer[0].play();\n};\n\n//AUDIO PLAYER events\naplayer[0].addEventListener('ended', function(){\n if(thesentence_number< sentences.length -1){\n thesentence_number++;\n doplayaudio(thesentence_number);\n }else{\n dehighlight_all();\n $(fa).removeClass(@@pause@@);\n $(fa).addClass(@@play@@);\n aplayer[0].pause();\n }\n});\n\n//handle audio player button clicks\n$('#' + @@AUTOID@@).click(function(){\n if(!aplayer[0].paused && !aplayer[0].ended){\n aplayer[0].pause();\n if(@@stoporpause@@=='stop'){\n aplayer[0].load();\n thesentence_number=0;\n }\n $(fa).removeClass(@@pause@@);\n $(fa).addClass(@@play@@);\n\n //if paused and in limbo no src state\n }else if(aplayer[0].paused && aplayer.attr('src')){\n aplayer[0].play();\n $(fa).removeClass(@@play@@);\n $(fa).addClass(@@pause@@);\n//play \n}else{\n if(!lettered){\n spanify_text_passage();\n lettered=true;\n };//end of if lettered\n if(@@stoporpause@@=='stop'){\n thesentence_number=0;\n } \n doplayaudio(thesentence_number);\n $(fa).removeClass(@@play@@);\n $(fa).addClass(@@pause@@);\n }//end of if paused ended\n});\n\n//handle sentence clicks\n$('#' + @@AUTOID@@ + '_textblock .tbr_innerdiv').on('click', '.tbr_sentence',function(){\naplayer[0].pause();\n var sentenceindex = $(this).attr('data-sentenceindex');\n $(fa).removeClass(@@play@@);\n $(fa).addClass(@@pause@@);\n thesentence_number = sentenceindex; \n doplayaudio(sentenceindex );\n});\n\n//PROCEDURAL stuff ...........................\n//break it into sentences, and fetch data + TTS URL for each sentence\nvar sentences = split_into_sentences(usetext);\nwordstarts=[];\nwordcounts=[];\nsentenceURLs=[];\nvar previousend=0;\nfor (var currentsentence=0;currentsentence\n\t\n\t\n\n
\n\n
","bodyend":"
\n
","script":"//DECLARATIONS and INITs ...........................\nvar thesentence_number =0;\nvar lettered= false;\n\n//audio player declarations\nvar aplayer = $('#' + @@AUTOID@@).children().first();\nvar fa = $('#' + @@AUTOID@@ + ' .fa');\n\n//text to audio preparation\nvar poodllfilelib = M.cfg.wwwroot + '/filter/poodll/poodllfilelib.php?datatype=speaktext¶mone=';\nvar format = \"text\";\n\n//determine the voice\nvar mf=@@speaker@@\nswitch(@@language@@){\ncase \"English(US)\": voice = mf=='Male'?'Joey':'Kendra';break;\ncase \"English(GB)\": voice = mf=='Male'?'Brian':'Amy';break;\ncase \"English(AU)\": voice = mf=='Male'?'Russell':'Nicole';break;\ncase \"English(IN)\": voice = mf=='Male'?'Aditi':'Raveena';break;\ncase \"English(WELSH)\": voice = mf=='Male'? 'Geraint':'Geraint';break;\ncase \"Danish\": voice = mf=='Male'?'Mads':'Naja';break;\ncase \"Dutch\": voice = mf=='Male'?'Ruben':'Lotte';break;\ncase \"French(FR)\": voice = mf=='Male'?'Mathieu':'Celine';break;\ncase \"French(CA)\": voice = mf=='Male'?'Chantal':'Chantal';break;\ncase \"German\": voice = mf=='Male'?'Hans':'Marlene';break;\ncase \"Icelandic\": voice = mf=='Male'?'Karl':'Dora';break;\ncase \"Italian\": voice = mf=='Male'?'Carla':'Giorgio';break;\ncase \"Japanese\": voice = mf=='Male'?'Takumi':'Mizuki';break;\ncase \"Korean\": voice = mf=='Male'?'Seoyan':'Seoyan';break;\ncase \"Norwegian\": voice = mf=='Male'?'Liv':'Liv';break;\ncase \"Polish\": voice = mf=='Male'?'Jacek':'Ewa';break;\ncase \"Portugese(BR)\": voice = mf=='Male'?'Ricardo':'Vitoria';break;\ncase \"Portugese(PT)\": voice = mf=='Male'?'Cristiano':'Ines';break;\ncase \"Romanian\": voice = mf=='Male'?'Carmen':'Carmen';break;\ncase \"Russian\": voice = mf=='Male'?'Maxim':'Tatyana';break;\ncase \"Spanish(ES)\": voice = mf=='Male'?'Enrique':'Conchita';break;\ncase \"Spanish(US)\": voice = mf=='Male'?'Miguel':'Penelope';break;\ncase \"Swedish\": voice = mf=='Male'?'Astrid':'Astrid';break;\ncase \"Turkish\": voice = mf=='Male'?'Filiz':'Filiz';break;\ncase \"Welsh\": voice = mf=='Male'?'Gwyneth':'Gwyneth';break;\ndefault: voice = mf=='Male'?'Brian':'Amy';\n}\n\n\n//fetch the text to read\nvar useblock = $('#' + @@AUTOID@@ + '_textblock');\nvar usetext = useblock.text();\n//we replace tags with markers to survive going into a URL and out again\nusetext = usetext.replace(//gi, \"dddd\");\n\n//some common selectors\nvar wordselector = '#' + @@AUTOID@@+ '_textblock span.tbr_word';\nvar sentenceselector = '#' + @@AUTOID@@+ '_textblock span.tbr_sentence';\n\n//FUNCTIONS ...........................\n//FUNCTION fetch polly url\n var fetch_polly_url = function(speaktext, voice, callback) {\n\n //The REST API we are calling\n var functionname = 'local_cpapi_fetch_polly_url';\n\n //fetch the Posturl. We need this.\n //set up our ajax request\n var xhr = new XMLHttpRequest();\n var that = this;\n\n //set up our handler for the response\n xhr.onreadystatechange = function (e) {\n if (this.readyState === 4) {\n if (xhr.status == 200) {\n\n //get a yes or forgetit or tryagain\n var payload = xhr.responseText;\n var payloadobject = JSON.parse(payload);\n if (payloadobject) {\n //returnCode > 0 indicates an error\n if (payloadobject.returnCode > 0) {\n console.log(payloadobject.returnMessage);\n return false;\n //if all good, then lets do the embed\n } else if (payloadobject.returnCode === 0){\n var pollyurl = payloadobject.returnMessage;\n callback(pollyurl);\n } else {\n console.log('Polly Signed URL Request failed:');\n console.log(payloadobject);\n }\n } else {\n console.log('Polly Signed URL Request something bad happened');\n }\n } else {\n console.log('Polly Signed URL Request Not 200 response:' + xhr.status);\n }\n }\n };\n\n //make our request\n var xhrparams = \"wstoken=\" + @@CLOUDPOODLLTOKEN@@\n + \"&wsfunction=\" + functionname\n + \"&moodlewsrestformat=\" + 'json'\n + \"&text=\" + encodeURIComponent(speaktext)\n + '&texttype=text'\n + '&voice=' + voice\n + '&appid=' + 'filter_poodll'\n + '&owner=poodll'\n + '®ion=useast1';\n\n var serverurl = 'https://cloud.poodll.com' + \"/webservice/rest/server.php\";\n xhr.open(\"POST\", serverurl, true);\n xhr.setRequestHeader(\"Cache-Control\", \"no-cache\");\n xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n xhr.send(xhrparams);\n };\n\n//FUNCTION: determine if the string is text or HTML\nvar isHTML = function (testString) {\n var htmlRegex = new RegExp(\"<([A-Za-z][A-Za-z0-9]*)\\\\b[^>]*>(.*?)\");\n return htmlRegex.test(testString);\n};\n\n//FUNCTION: split a text passage into words\nvar split_into_words= function(thetext){\n thetext = thetext.replace(/\\s+/g,' ').trim();\n if(thetext==''){return[]};\n return thetext.split(' '); \n};\n\n//FUNCTION: split a text passage into sentences\nvar split_into_sentences = function(thetext){\n thetext = thetext.replace(/\\s+/g,' ').trim();\n if(thetext ==''){return[]};\n return thetext.match(/([^\\.!\\?]+[\\.!\\?\"']+)|([^\\.!\\?\"']+$)/g); \n};\n\n//FUNCTION: break a text passage into words/sentences, and surround the words with marker tags\nvar spanify_text_passage = function(){\n //the itemcount er\n var itemcount = -1;\n\n //get all the text nodes in the useblock\n var textnodes = useblock.find('*').contents().filter(function(){ return this.nodeType == 3; });\n //wrap sentence or words in text block with spans\n textnodes.each(function(){\n var retpieces = ''; \n if(@@highlightmode@@=='word'){\n //for words\n var thewords = split_into_words($(this).text());\n for (var theword=0; theword < thewords.length; theword++){\n itemcount++;\n retpieces = retpieces + '' + thewords[theword] + ' ';\n }//end of for loop\n }else{\n //for sentences\n var thesentences = split_into_sentences($(this).text());\n for (var thesentence=0; thesentence < thesentences.length; thesentence++){\n itemcount++;\n retpieces = retpieces + '' + thesentences[thesentence] + ' ';\n }//end of for loop\n }\n $(this).replaceWith(retpieces);\n });//end of textnodes each\n};\n\n//FUNCTION: unhighlight a sentence as active\nvar dehighlight_all = function(){\n switch(@@highlightmode@@){\n case 'word':\n $(wordselector,useblock).removeClass('activesentence');\n break;\n case 'sentence':\n $(sentenceselector,useblock).removeClass('activesentence');\n break;\n case 'none':\n default:\n //do nothing\n }\n}\n\n//FUNCTION: highlight a sentence as active\nvar highlight_sentence = function(thesentence){\n switch(@@highlightmode@@){\n case 'word':\n $(wordselector,useblock).removeClass('activesentence');\n $(wordselector,useblock).slice(instancedata[@@AUTOID@@].wordstarts[thesentence],\n instancedata[@@AUTOID@@].wordstarts[thesentence] + \n instancedata[@@AUTOID@@].wordcounts[thesentence]).addClass('activesentence');\n break;\n case 'sentence':\n $(sentenceselector).removeClass('activesentence');\n $(sentenceselector + '[data-sentenceindex=' + thesentence + ']').addClass('activesentence');\n break;\n case 'none':\n default:\n //do nothing\n }\n}\n\n//FUNCTION: play a single sentence and mark it active for display purposes\nvar doplayaudio = function(thesentence){\n highlight_sentence(thesentence);\n aplayer.attr('src', instancedata[@@AUTOID@@].sentenceURLs[thesentence]);\n aplayer[0].play();\n};\n\n//AUDIO PLAYER events\naplayer[0].addEventListener('ended', function(){\n if(thesentence_number< sentences.length -1){\n thesentence_number++;\n doplayaudio(thesentence_number);\n }else{\n dehighlight_all();\n $(fa).removeClass(@@pause@@);\n $(fa).addClass(@@play@@);\n aplayer[0].pause();\n }\n});\n\n//handle audio player button clicks\n$('#' + @@AUTOID@@).click(function(){\n if(!aplayer[0].paused && !aplayer[0].ended){\n aplayer[0].pause();\n if(@@stoporpause@@=='stop'){\n aplayer[0].load();\n thesentence_number=0;\n }\n $(fa).removeClass(@@pause@@);\n $(fa).addClass(@@play@@);\n\n //if paused and in limbo no src state\n }else if(aplayer[0].paused && aplayer.attr('src')){\n aplayer[0].play();\n $(fa).removeClass(@@play@@);\n $(fa).addClass(@@pause@@);\n//play \n}else{\n if(!lettered){\n spanify_text_passage();\n lettered=true;\n };//end of if lettered\n if(@@stoporpause@@=='stop'){\n thesentence_number=0;\n } \n doplayaudio(thesentence_number);\n $(fa).removeClass(@@play@@);\n $(fa).addClass(@@pause@@);\n }//end of if paused ended\n});\n\n//handle sentence clicks\n$('#' + @@AUTOID@@ + '_textblock .tbr_innerdiv').on('click', '.tbr_sentence',function(){\naplayer[0].pause();\n var sentenceindex = $(this).attr('data-sentenceindex');\n $(fa).removeClass(@@play@@);\n $(fa).addClass(@@pause@@);\n thesentence_number = sentenceindex; \n doplayaudio(sentenceindex );\n});\n\n//PROCEDURAL stuff ...........................\n//break it into sentences, and fetch data + TTS URL for each sentence\nvar sentences = split_into_sentences(usetext);\nwordstarts=[];\nwordcounts=[];\nsentenceURLs=[];\nvar previousend=0;\nfor (var currentsentence=0;currentsentence\n
","bodyend":"
","script":"var poodllfilelib = M.cfg.wwwroot + '/filter/poodll/poodllfilelib.php?datatype=speaktext¶mone=';\nvar usetext = $('#' + @@AUTOID@@).text();\nvar theplayer = $('#' + @@AUTOID@@ + '_audioplayer');\nvar mf=@@speaker@@\n\nswitch(@@language@@){\ncase \"English(US)\": voice = mf=='Male'?'Joey':'Kendra';break;\ncase \"English(GB)\": voice = mf=='Male'?'Brian':'Amy';break;\ncase \"English(AU)\": voice = mf=='Male'?'Russell':'Nicole';break;\ncase \"English(IN)\": voice = mf=='Male'?'Aditi':'Raveena';break;\ncase \"English(WELSH)\": voice = mf=='Male'? 'Geraint':'Geraint';break;\ncase \"Danish\": voice = mf=='Male'?'Mads':'Naja';break;\ncase \"Dutch\": voice = mf=='Male'?'Ruben':'Lotte';break;\ncase \"French(FR)\": voice = mf=='Male'?'Mathieu':'Celine';break;\ncase \"French(CA)\": voice = mf=='Male'?'Chantal':'Chantal';break;\ncase \"German\": voice = mf=='Male'?'Hans':'Marlene';break;\ncase \"Icelandic\": voice = mf=='Male'?'Karl':'Dora';break;\ncase \"Italian\": voice = mf=='Male'?'Carla':'Giorgio';break;\ncase \"Japanese\": voice = mf=='Male'?'Takumi':'Mizuki';break;\ncase \"Korean\": voice = mf=='Male'?'Seoyan':'Seoyan';break;\ncase \"Norwegian\": voice = mf=='Male'?'Liv':'Liv';break;\ncase \"Polish\": voice = mf=='Male'?'Jacek':'Ewa';break;\ncase \"Portugese(BR)\": voice = mf=='Male'?'Ricardo':'Vitoria';break;\ncase \"Portugese(PT)\": voice = mf=='Male'?'Cristiano':'Ines';break;\ncase \"Romanian\": voice = mf=='Male'?'Carmen':'Carmen';break;\ncase \"Russian\": voice = mf=='Male'?'Maxim':'Tatyana';break;\ncase \"Spanish(ES)\": voice = mf=='Male'?'Enrique':'Conchita';break;\ncase \"Spanish(US)\": voice = mf=='Male'?'Miguel':'Penelope';break;\ncase \"Swedish\": voice = mf=='Male'?'Astrid':'Astrid';break;\ncase \"Turkish\": voice = mf=='Male'?'Filiz':'Filiz';break;\ncase \"Welsh\": voice = mf=='Male'?'Gwyneth':'Gwyneth';break;\ndefault: voice = mf=='Male'?'Brian':'Amy';\n}\n\n\n//we replace tags with markers to survive going into a URL and out again\nusetext = usetext.replace(//gi, \"dddd\");\n\nvar datastring= @@format@@ + '|' + voice + '|' + usetext;\nvar src = poodllfilelib+encodeURIComponent(datastring);\ntheplayer.attr('src',src);","style":"","dataset":"","datasetvars":"","alternate":"","alternateend":""} \ No newline at end of file diff --git a/presets/ttacloud.txt b/presets/ttacloud.txt new file mode 100644 index 00000000..62a42630 --- /dev/null +++ b/presets/ttacloud.txt @@ -0,0 +1 @@ +{"name":"Text to Audio (Cloud)","key":"ttacloud","version":"1.0.2","instructions":"Enter the text to be read between the 'tta' tags after they are inserted on the page. (Uses Cloud Poodll) ","showatto":"1","showplayers":"0","requirecss":"","requirejs":"","shim":"","defaults":"format=\"text|ssml\",language=\"English(US)|English(GB)|English(AU)|English(In)|English(Welsh)|Danish|Dutch|French(FR)|French(CA)|German|Icelandic|Italian|Japanese|Korean|Norwegian|Polish|Portugese(BR)|Portugese(PT)|Romanian|Russian|Spanish(ES)|Spanish(US)|Swedish|Turkish|Welsh\",\nspeaker=\"Male|Female\"","amd":"1","body":"