Commit 0257a219 authored by Sylvain Coulange's avatar Sylvain Coulange
Browse files

Ajout fonctionnalité text2speech AWS

parent be8be992
import base64
import boto3
import os
from contextlib import closing
# Source : http://ipa-reader.xyz/
def lambda_handler(ipa, loc):
# init polly
polly = boto3.client("polly")
# get submitted text string and selected voice
text = ipa
voice = loc
# strip out slashes if submitted with text string
if "/" in text:
text = text.replace("/", "")
# generate phoneme tag for polly to read
phoneme = f"<prosody rate='85%'><phoneme alphabet='ipa' ph='{text}'></phoneme></prosody>" #<prosody rate='85%'></prosody>
# send to polly, requesting mp3 back
response = polly.synthesize_speech(
OutputFormat="mp3",
TextType="ssml",
Text=phoneme,
VoiceId=voice
)
print(response)
# encode polly's returned audio stream as base64 and return
if "AudioStream" in response:
with closing(response["AudioStream"]) as stream:
audio = base64.encodebytes(stream.read())
return audio.decode("ascii")
\ No newline at end of file
......@@ -4,6 +4,7 @@ from .models import Serie
from django.forms.models import model_to_dict
from django.views.generic import ListView, DetailView
import subprocess, json, os, tempfile
from .text2speech import lambda_handler
### Chargement de la base de données
dbFile = '../db/db_phonographe.json'
......@@ -120,4 +121,14 @@ def openPlayerPhono(request, pk):
serieContent = Serie.objects.filter(id=pk).first()
print(serieContent)
print("Demande ouverture série", serieContent.nom, ' (', pk, ')')
return render(request, 'playerPhono.html', {'updateTime': updateTimeStr, 'serieContent':serieContent})
\ No newline at end of file
return render(request, 'playerPhono.html', {'updateTime': updateTimeStr, 'serieContent':serieContent})
def playIpa(request):
colis = json.loads(request.body)
ipa = colis['ipa']
print("Lecture de ["+ipa+"]")
data = {
"audio": lambda_handler(ipa,"Celine")
}
return JsonResponse(data)
\ No newline at end of file
......@@ -47,6 +47,7 @@ urlpatterns = [
path('player/serie-<int:pk>/play', clavier_views.openPlayerPhono, name='serie-play'),
path('_saveTrace/', csrf_exempt(user_views.saveTrace)),
path('_playIpa/', csrf_exempt(clavier_views.playIpa)),
# path('getActivity/', csrf_exempt(clavier_views.getActivity)),
......
......@@ -577,3 +577,52 @@ function openInNewTab() {
var URL = document.getElementById("pLienSave").value;
window.open(URL, '_blank');
}
var currentIpa = "";
async function playIpa() {
if (thisPageLang == 'fr'){
if (document.getElementsByClassName('text').length > 0) {
// PRÉPARATION COLIS
var phonEllist = document.getElementsByClassName('text');
var ipa = "";
for (e=0; e<phonEllist.length; e++){
var phon = phonEllist[e].classList[1];
if (phon.match(/phon_.*/)) {
ipa += phon2api[phon];
}
}
if (ipa != currentIpa){
console.log("lecture de ", ipa);
currentIpa = ipa;
// ON EMBALLE TOUT ÇA
var colis = {
'ipa': ipa
};
// Paramètres d'envoi
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(colis)
};
// ENVOI
const response = await fetch('_playIpa/', options)
const data = await response.json();
readResponse(data["audio"]);
} else {
document.getElementsByTagName("audio")[0].play();
}
}
} else window.alert("Cette fonctionnalité n'est pas encore disponible pour l'anglais !");
}
function readResponse(response) {
var source = '<source src="data:audio/mpeg;base64,' + response + '" type="audio/mpeg"></source>';
var audio = '<audio autoplay="true" controls>' + source + '</audio>';
document.getElementById('audio').innerHTML = audio;
}
var phon2api = {
"phon_1":"ɨ",
"phon_2":"ø",
"phon_3":"ɜ",
"phon_3_slash":"ɞ",
"phon_3_long":"ɜː",
"phon_3_rho":"ɝ",
"phon_4":"ɾ",
"phon_5":"ɫ",
"phon_5":"",
"phon_6":"ɐ",
"phon_7":"ɤ",
"phon_8":"ɵ",
"phon_9":"œ",
"phon_9_maj":"ɶ",
"phon_9_nas":"œ̃",
"phon_a":"a",
"phon_a_centr":"ä",
"phon_a_maj":"ɑ",
"phon_a_maj_long":"ɑː",
"phon_a_maj_nas":"ɑ̃",
"phon_arobase":"ə",
"phon_arobase_rho":"ɚ",
"phon_arho":"",
"phon_7rho":"ɤ˞",
"phon_arobase_slash":"ɘ",
"phon_b":"b",
"phon_b_chev":"ɓ",
"phon_b_maj":"β",
"phon_b_maj_slash":"ʙ",
"phon_c":"c",
"phon_c_maj":"ç",
"phon_cbrack":"æ",
"phon_cbrack2":"ʉ",
"phon_chevron_slash":"ʢ",
"phon_chevron2_slash":"ʡ",
"phon_d":"d",
"phon_d_chev":"ɗ",
"phon_d_maj":"ð",
"phon_d_retr":"ɖ",
"phon_e":"e",
"phon_e_maj":"ɛ",
"phon_e_maj_nas":"ɛ̃",
"phon_egal_slash":"ǂ",
"phon_exclam_slash":"ǃ",
"phon_f":"f",
"phon_f_maj":"ɱ",
"phon_g":"ɡ",
"phon_g_chev":"ɠ",
"phon_g_maj":"ɣ",
"phon_g_maj_slash":"ɢ",
"phon_g_maj_slash_chev":"ʛ",
"phon_glottstop":"ʔ",
"phon_glottstop_slash":"ʕ",
"phon_h":"h",
"phon_h_maj":"ɥ",
"phon_h_maj_slash":"ʜ",
"phon_h_slash":"ɦ",
"phon_i":"i",
"phon_i_long":"",
"phon_i_maj":"ɪ",
"phon_j":"j",
"phon_j_slash":"ʝ",
"phon_j_maj_slash":"ɟ",
"phon_j_maj_slash_chev":"ʄ",
"phon_k":"k",
"phon_k_chev2":"",
"phon_k_h":"",
"phon_k_maj":"ɬ",
"phon_k_maj_slash":"ɮ",
"phon_l":"l",
"phon_l_maj":"ʎ",
"phon_l_maj_slash":"ʟ",
"phon_l_retr":"ɭ",
"phon_m":"m",
"phon_m_maj":"ɯ",
"phon_m_maj_slash":"ɰ",
"phon_n":"n",
"phon_n_maj":"ŋ",
"phon_n_maj_slash":"ɴ",
"phon_n_retr":"ɳ",
"phon_o":"o",
"phon_o_maj":"ɔ",
"phon_o_maj_long":"ɔː",
"phon_o_maj_nas":"ɔ̃",
"phon_o_maj_slash":"ʘ",
"phon_p":"p",
"phon_p_chev2":"",
"phon_p_d":"",
"phon_p_h":"",
"phon_p_maj":"ʋ",
"phon_p_slash":"ɸ",
"phon_pipe_slash":"ǀ",
"phon_pipe_slashpipe_slash":"ǁ",
"phon_q":"q",
"phon_q_chev2":"",
"phon_q_maj":"ɒ",
"phon_r":"r",
"phon_r_0":"",
"phon_r_maj":"ʁ",
"phon_r_maj_slash":"ʀ",
"phon_r_retr":"ɽ",
"phon_r_slash":"ɹ",
"phon_r_slash_retr":"ɻ",
"phon_s":"s",
"phon_s_chev2":"",
"phon_s_maj":"ʃ",
"phon_s_maj_chev2":"ʃʼ",
"phon_s_retr":"ʂ",
"phon_s_slash":"ɕ",
"phon_t":"t",
"phon_t_chev2":"",
"phon_t_h":"",
"phon_t_maj":"θ",
"phon_t_retr":"ʈ",
"phon_t_retr_chev2":"ʈʼ",
"phon_u":"u",
"phon_u_long":"",
"phon_u_maj":"ʊ",
"phon_v":"v",
"phon_v_flap":"",
"phon_v_maj":"ʌ",
"phon_w":"w",
"phon_w_maj":"ʍ",
"phon_x":"x",
"phon_x_chev2":"",
"phon_x_maj":"χ",
"phon_x_maj_slash":"ħ",
"phon_x_slash":"ɧ",
"phon_y":"y",
"phon_y_maj":"ʏ",
"phon_z":"z",
"phon_z_maj":"ʒ",
"phon_z_retr":"ʐ",
"phon_z_slash":"ʑ",
"phon_schwi":"pour l'anglais i/ɪ",
"phon_schwa":"pour l'anglais ə",
"phon_schwu":"pour l'anglais u/ʊ",
"phon_a_majr":"ɑɹ",
"phon_ai_maj":"",
"phon_ai_majarobase":"aɪə",
"phon_au_maj":"",
"phon_au_majwarobase":"aʊwə",
"phon_arobasel":"əl",
"phon_arobasem":"əm",
"phon_arobasen":"ən",
"phon_arobaseu_maj":"əʊ",
"phon_dz":"d͡z",
"phon_dz":"dz",
"phon_dz_maj":"d͡ʒ",
"phon_dz_maj":"",
"phon_dz_retr":"d͡ʐ",
"phon_dz_retr":"",
"phon_dz_slash":"d͡ʑ",
"phon_dz_slash":"",
"phon_ef":"ef",
"phon_ei_maj":"",
"phon_earobase":"",
"phon_er":"",
"phon_i_majarobase":"ɪə",
"phon_ju_majarobase":"jʊə",
"phon_gb":"ɡ͡b",
"phon_gb":"ɡb",
"phon_gz":"ɡz",
"phon_gz_maj":"ɡʒ",
"phon_h_maj_i":"ɥi",
"phon_ij":"ij",
"phon_i_majr":"ɪɹ",
"phon_j_maj":"ɲ",
"phon_jarobase":"",
"phon_ju_long":"juː",
"phon_ju_majr":"jʊɹ",
"phon_kp":"k͡p",
"phon_kp":"kp",
"phon_ks":"k͡s",
"phon_ks":"ks",
"phon_ks_maj":"",
"phon_kx":"k͡x",
"phon_kx":"kx",
"phon_kw":"",
"phon_kw":"kw",
"phon_lj":"lj",
"phon_nj":"nj",
"phon_ou_maj":"",
"phon_o_maji_maj":"ɔɪ",
"phon_o_majr":"ɔɹ",
"phon_pf":"p͡f",
"phon_pf":"pf",
"phon_sz":"sz",
"phon_t_hs":"t͡sʰ",
"phon_t_hs":"tsʰ",
"phon_t_hs_retr":"t͡ʂʰ",
"phon_t_hs_retr":"tʂʰ",
"phon_t_hs_slash":"t͡ɕʰ",
"phon_t_hs_slash":"tɕʰ",
"phon_tk_maj":"t͡ɬ",
"phon_tk_maj":"",
"phon_tk_maj_slash":"d͡ɮ",
"phon_tk_maj_slash":"",
"phon_ts":"t͡s",
"phon_ts":"ts",
"phon_ts_chev2":"t͡sʼ",
"phon_ts_chev2":"tsʼ",
"phon_ts_maj":"t͡ʃ",
"phon_ts_maj":"",
"phon_ts_maj_chev2":"t͡ʃʼ",
"phon_ts_maj_chev2":"tʃʼ",
"phon_ts_retr":"t͡ʂ",
"phon_ts_retr":"",
"phon_ts_slash":"t͡ɕ",
"phon_ts_slash":"",
"phon_tt_maj":"t͡θ",
"phon_tt_maj":"",
"phon_u_majarobase":"ʊə",
"phon_u_majr":"ʊɹ",
"phon_wa":"wa",
"phon_war":"waɹ",
"phon_wa_maj":"",
"phon_wa_maj_long":"wɑː",
"phon_wai_maj":"waɪ",
"phon_we_maj_nas":"wɛ̃",
"phon_wv_maj":"",
"phon_schwju":"ju/jʊ",
"phon_schwiz":"iz/ɪz",
"phon_schwaz":"əz",
"phon_mp":"m͡p",
"phon_mb":"m͡b",
"phon_nt_d":"n͡t̪",
"phon_nd_d":"n͡d̪",
"phon_nt":"n͡t",
"phon_nd":"n͡d",
"phon_n_retrt":"ɳ͡ʈ",
"phon_n_retrd_retr":"ɳ͡ɖ",
"phon_j_majc":"ɲ͡c",
"phon_j_majj_maj_slash":"ɲ͡ɟ",
"phon_n_majk":"ŋ͡k",
"phon_n_majg":"ŋ͡ɡ",
"phon_n_maj_slashq":"ɴ͡q",
"phon_n_maj_slashg_maj_slash":"ɴ͡ɢ",
"phon_n_majm":"ŋ͡m",
"phon_pp_slash":"p͡ɸ",
"phon_bb_maj":"b͡β",
"phon_bv":"b͡v",
"phon_dd_maj":"d͡ð",
"phon_t_slashs_retr":"ʈ͡ʂ",
"phon_d_slashz_retr":"ɖ͡ʐ",
"phon_cc_maj":"c͡ç",
"phon_j_maj_slashj_slash":"ɟ͡ʝ",
"phon_gg_maj":"ɡ͡ɣ",
"phon_qx_maj":"q͡χ",
"phon_g_maj_slashr_maj":"ɢ͡ʁ",
"phon_glottstoph":"ʔ͡h",
"phon_mp_slash":"m͡ɸ",
"phon_mb_maj":"m͡β",
"phon_nt_maj":"n͡θ",
"phon_nd_maj":"n͡ð",
"phon_ns":"n͡s",
"phon_nz":"n͡z",
"phon_ns_maj":"n͡ʃ",
"phon_nz_maj":"n͡ʒ",
"phon_mp":"mp",
"phon_mb":"mb",
"phon_nt_d":"nt̪",
"phon_nd_d":"nd̪",
"phon_nt":"nt",
"phon_nd":"nd",
"phon_n_retrt":"ɳʈ",
"phon_n_retrd_retr":"ɳɖ",
"phon_j_majc":"ɲc",
"phon_j_majj_maj_slash":"ɲɟ",
"phon_n_majk":"ŋk",
"phon_n_majg":"ŋɡ",
"phon_n_maj_slashq":"ɴq",
"phon_n_maj_slashg_maj_slash":"ɴɢ",
"phon_n_majm":"ŋm",
"phon_pp_slash":"",
"phon_bb_maj":"",
"phon_bv":"bv",
"phon_dd_maj":"",
"phon_t_slashs_retr":"ʈʂ",
"phon_d_slashz_retr":"ɖʐ",
"phon_cc_maj":"",
"phon_j_maj_slashj_slash":"ɟʝ",
"phon_gg_maj":"ɡɣ",
"phon_qx_maj":"",
"phon_g_maj_slashr_maj":"ɢʁ",
"phon_glottstoph":"ʔh",
"phon_mp_slash":"",
"phon_mb_maj":"",
"phon_nt_maj":"",
"phon_nd_maj":"",
"phon_ns":"ns",
"phon_nz":"nz",
"phon_ns_maj":"",
"phon_nz_maj":"",
"phon_n_majw":"ŋʷ",
"phon_gw":"ɡʷ",
"phon_xw":"",
"phon_g_majw":"ɣʷ",
"phon_n_majw":"ŋw",
"phon_gw":"ɡw",
"phon_xw":"xw",
"phon_g_majw":"ɣw",
"phon_j3_rho":"",
"phon_schwar":"əɹ",
"phon_schwiz":"ɪz",
"phon_schwju":"",
"ju":"phon_schwju"
}
\ No newline at end of file
......@@ -84,7 +84,6 @@
display: inline-table;
background-color: black;
color: gray;
height: 80px;
width: 98%;
text-align: left;
padding: 10px;
......
......@@ -30,11 +30,17 @@
</div>
</div>
<div class="fenetre textSide textZone" id="textZoneBack">
<div class="d-flex justify-content-between fenetre textSide textZone" id="textZoneBack">
<div id="textZone" contenteditable="false" spellcheck="true"></div>
<div class="pe-3" onclick="playIpa();" style="cursor: pointer;" title="Prononcer !">
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" fill="currentColor" class="bi bi-play-circle nobg" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/>
<path d="M6.271 5.055a.5.5 0 0 1 .52.038l3.5 2.5a.5.5 0 0 1 0 .814l-3.5 2.5A.5.5 0 0 1 6 10.5v-5a.5.5 0 0 1 .271-.445z"/>
</svg>
</div>
</div>
<div id="audio"></div>
<div class="boutons">
<button type="button" class="btn btn-secondary" onclick="writeGraph('. ','punct')">.</button>
......@@ -65,7 +71,12 @@
<embed id="svgClick" src="../static/svg/00-click.svg" class="superpose">
<img src="" class="popUpProfile" id="popDiv"/>
<div class="doAide" style="right:0px">
<span id="aidbtn" onclick="toggleAides()" class="glyphicon glyphicon-question-sign" aria-hidden="true" title="Afficher/masquer les popups d'aide"></span>
<div id="aidbtn" onclick="toggleAides()" title="Afficher/masquer les popups d'aide">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-info-circle nobg" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/>
<path d="M8.93 6.588l-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/>
</svg>
</div>
</div>
<!-- EN Clavier PronSci UK -->
......@@ -159,7 +170,7 @@
</div>
<script type="text/javascript" src="{% static 'js/phon2api.js' %}"></script>
{% endblock %}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment