Lees webpagina's en markeer inhoud met Amazon Polly PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

Lees webpagina's en markeer inhoud met Amazon Polly

In dit bericht laten we zien hoe te gebruiken Amazon Pollyโ€” een toonaangevende cloudservice die tekst omzet in levensechte spraak โ€” om de inhoud van een webpagina te lezen en de inhoud te markeren terwijl deze wordt gelezen. Het toevoegen van audioweergave aan een webpagina verbetert de toegankelijkheid en bezoekerservaring van de pagina. Audio-verbeterde inhoud is effectiever en gedenkwaardiger, trekt meer verkeer naar de pagina en maakt gebruik van de koopkracht van bezoekers. Het verbetert ook het merk van het bedrijf of de organisatie die de pagina publiceert. Tekst-naar-spraaktechnologie maakt deze zakelijke voordelen haalbaar. We versnellen die reis door te laten zien hoe we dit doel kunnen bereiken met Amazon Polly.

Deze mogelijkheid verbetert de toegankelijkheid voor bezoekers met een handicap en kan worden toegepast als onderdeel van de toegankelijkheidsstrategie van uw organisatie. Net zo belangrijk is dat het de pagina-ervaring verbetert voor bezoekers zonder handicap. Beide groepen hebben aanzienlijke koopkracht en besteden vrijer aan pagina's die audioverbetering gebruiken om hun aandacht te trekken.

Overzicht van de oplossing

PollyReadsThePage (PRTP), zoals we naar de oplossing verwijzen, stelt een uitgever van een webpagina in staat om een โ€‹โ€‹audiobediening op hun webpagina te plaatsen. Wanneer de bezoeker kiest Spelen op de besturing leest de besturing de pagina en markeert de inhoud. PRTP gebruikt de algemene mogelijkheden van Amazon Polly om spraak uit tekst te synthetiseren. Het roept Amazon Polly aan om twee artefacten voor elke pagina te genereren:

  • De audio-inhoud in een formaat dat door de browser kan worden afgespeeld: MP3
  • Een bestand met spraakmarkeringen dat voor elke tekstzin aangeeft:
    • De tijd tijdens het afspelen dat de zin wordt voorgelezen
    • De locatie op de pagina waar de zin verschijnt

Wanneer de bezoeker kiest Spelen, speelt de browser het MP3-bestand af. Terwijl de audio wordt gelezen, controleert de browser de tijd, zoekt in het markeerbestand welke zin op dat moment moet worden gelezen, lokaliseert deze op de pagina en markeert deze.

PRTP stelt de bezoeker in staat om in verschillende stemmen en talen te lezen. Elke stem heeft zijn eigen paar bestanden nodig. PRTP maakt gebruik van neurale stemmen. Voor een lijst met ondersteunde neurale stemmen en talen, zie Neurale stemmen. Voor een volledige lijst met standaard- en neurale stemmen in Amazon Polly, zie Stemmen in Amazon Polly.

We beschouwen twee soorten webpagina's: statische en dynamische pagina's. In een statisch pagina, de inhoud is opgenomen in de pagina en verandert alleen wanneer een nieuwe versie van de pagina wordt gepubliceerd. Het bedrijf kan de pagina dagelijks of wekelijks bijwerken als onderdeel van het webbouwproces. Voor dit type pagina is het mogelijk om de audiobestanden tijdens het bouwen vooraf te genereren en ze op de webserver te plaatsen om ze af te spelen. Zoals de volgende afbeelding laat zien, is het script PRTP Pre-Gen roept Amazon Polly op om de audio te genereren. Het heeft als invoer de HTML-pagina zelf en, optioneel, een configuratiebestand dat specificeert welke tekst van de pagina moet worden uitgepakt (Text Extract Config). Als de extractconfiguratie wordt weggelaten, maakt het pre-gen-script een verstandige keuze van de tekst om uit de hoofdtekst van de pagina te extraheren. Amazon Polly voert de bestanden uit in een Amazon eenvoudige opslagservice (Amazon S3) emmer; het script kopieert ze naar uw webserver. Wanneer de bezoeker de audio afspeelt, downloadt de browser de MP3 rechtstreeks van de webserver. Voor hoogtepunten, een drop-in bibliotheek, PRTP.js, gebruikt het marks-bestand om de gelezen tekst te markeren.

De inhoud van een dynamisch pagina verandert als reactie op de interactie van de bezoeker, dus audio kan niet vooraf worden gegenereerd, maar moet dynamisch worden gesynthetiseerd. Zoals de volgende afbeelding laat zien, gebruikt de pagina wanneer de bezoeker de audio afspeelt PRTP.js om de audio in Amazon Polly te genereren, en het benadrukt de gesynthetiseerde audio met dezelfde aanpak als bij statische pagina's. Om toegang te krijgen tot AWS-services vanuit de browser, heeft de bezoeker een AWS-identiteit nodig. We laten zien hoe u een kunt gebruiken Amazon Cognito identiteitspool om de bezoeker net genoeg toegang te geven tot Amazon Polly en de S3-bucket om de audio weer te geven.

Dynamische Content

Voor het genereren van zowel mp3-audio als spraakmarkeringen moet de Polly-service dezelfde invoer twee keer synthetiseren. Verwijs naar de Amazon Polly-prijspagina kostenimplicaties te begrijpen. Pre-generatie bespaart kosten omdat de synthese tijdens de build wordt uitgevoerd in plaats van on-demand voor elke interactie van de bezoeker.

De code bij dit bericht is beschikbaar als een open-source repository op GitHub.

Om de oplossing te verkennen, volgen we deze stappen:

  1. Stel de bronnen in, waaronder de pre-gen build-server, S3-bucket, webserver en Amazon Cognito-identiteit.
  2. Voer de statische pre-gen build uit en test statische pagina's.
  3. Test dynamische pagina's.

Voorwaarden

Om dit voorbeeld uit te voeren, hebt u een AWS-account met toestemming om Amazon Polly, Amazon S3, Amazon Cognito en (voor demo-doeleinden) te gebruiken AWS-Cloud9.

Voorzieningsbronnen

We delen een AWS CloudFormatie sjabloon om in uw account een op zichzelf staande demo-omgeving te maken om u te helpen het bericht te volgen. Als u PRTP liever in uw eigen omgeving instelt, raadpleegt u de instructies in README.md.

Om de demo-omgeving in te richten met CloudFormation, downloadt u eerst een kopie van de CloudFormation-sjabloon. Voer vervolgens de volgende stappen uit:

  1. Kies op de AWS CloudFormation-console Maak een stapel.
  2. Kies Met nieuwe middelen (standaard).
  3. kies Upload een sjabloonbestand.
  4. Kies Kies bestand om de lokale kopie van de sjabloon die u hebt gedownload te uploaden. De naam van het bestand is prtp.yml.
  5. Kies Volgende.
  6. Voer een stapelnaam naar keuze in. Later vul je dit nog een keer in als vervanging voor .
  7. U kunt de standaardwaarden behouden in de parameters pagina.
  8. Kies Volgende.
  9. Ga door met de resterende secties.
  10. Lees en selecteer de selectievakjes in de Mogelijkheden pagina.
  11. Kies Maak een stapel.
  12. Als de stapel compleet is, zoek je de waarde voor BucketName in de stapeluitgangen.

We raden u aan de stack met uw beveiligingsteam te bekijken voordat u deze in een productieomgeving gebruikt.

Stel de webserver en pre-gen server in een AWS Cloud9 IDE in

Zoek vervolgens op de AWS Cloud9-console de omgeving PRTPDemoCloud9 gemaakt door de CloudFormation-stack. Kiezen IDE openen om de AWS Cloud9-omgeving te openen. Open een terminalvenster en voer de volgende opdrachten uit, waarmee de PRTP-code wordt gekloond, pre-gen-afhankelijkheden worden ingesteld en een webserver wordt gestart om mee te testen:

#Obtain PRTP code
cd /home/ec2-user/environment
git clone https://github.com/aws-samples/amazon-polly-reads-the-page.git

# Navigate to that code
cd amazon-polly-reads-the-page/setup

# Install Saxon and html5 Python lib. For pre-gen.
sh ./setup.sh <StackName>

# Run Python simple HTTP server
cd ..
./runwebserver.sh <IngressCIDR> 

Voor , gebruik de naam die u aan de CloudFormation-stack hebt gegeven. Voor , geef een reeks IP-adressen op die toegang hebben tot de webserver. Om de toegang tot de browser op uw lokale computer te beperken, zoekt u uw IP-adres op met https://whatismyipaddress.com/ en voeg toe /32 om het bereik te specificeren. Als uw IP bijvoorbeeld is: 10.2.3.4, use 10.2.3.4/32. De server luistert op poort 8080. Het openbare IP-adres waarop de server luistert, wordt gegeven in de uitvoer. Bijvoorbeeld:

Public IP is

3.92.33.223

Statische pagina's testen

Navigeer in uw browser naar: PRTPStaticDefault.html. (Als je de demo gebruikt, is de URL http://<cloud9host>:8080/web/PRTPStaticDefault.html, Waar is het openbare IP-adres dat u hebt ontdekt bij het instellen van de IDE.) Kies Spelen op de audiobediening bovenaan. Luister naar de audio en bekijk de hoogtepunten. Verken de besturing door snelheden te wijzigen, stemmen te wijzigen, te pauzeren, vooruit te spoelen en terug te spoelen. De volgende schermafbeelding toont de pagina; de tekst "Sla verborgen alinea over" is gemarkeerd omdat deze momenteel wordt gelezen.

Lees webpagina's en markeer inhoud met Amazon Polly PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

Probeer hetzelfde voor PRTPStaticConfig.html en PRTPStaticCustom.html. De resultaten zijn vergelijkbaar. Ze lazen bijvoorbeeld alle drie de alt-tekst voor de foto van de kat (โ€œWillekeurige afbeelding van een katโ€). Alle drie lezen NE, NW, SE en SW als volledige woorden ("noordoost", "noordwest", "zuidoost", "zuidwest"), gebruikmakend van Amazon Polly-lexicons.

Let op de belangrijkste verschillen in audio:

  • PRTPStaticDefault.html leest alle tekst in de hoofdtekst van de pagina, inclusief het afsluitende gedeelte onderaan met 'Uw gedachten in รฉรฉn woord', 'Query indienen', 'Laatst bijgewerkt op 1 april 2020' en 'Vragen voor het ontwikkelteam'. PRTPStaticConfig.html en PRTPStaticCustom.html lees deze niet omdat ze de wrap-up expliciet uitsluiten van spraaksynthese.
  • PRTPStaticCustom.html leest de QB-bestsellers tafel anders dan de anderen. Het leest alleen de eerste drie rijen en leest het rijnummer voor elke rij. Het herhaalt de kolommen voor elke rij. PRTPStaticCustom.html gebruikt een aangepaste transformatie om de uitlezing van de tabel aan te passen. De andere pagina's gebruiken standaard tabelweergave.
  • PRTPStaticCustom.html leest "Tom Brady" op een luider volume dan de rest van de tekst. Het maakt gebruik van de spraaksynthese opmaaktaal (SSML) prosody tag om de lezing van Tom Brady aan te passen. De andere pagina's passen niet op deze manier.
  • PRTPStaticCustom.html, dankzij een aangepaste transformatie, leest de hoofdtegels in NW, SW, NE, SE volgorde; dat wil zeggen, er staat "Artikelen van vandaag", "Citaat van de dag", "Foto van de dag", "Grappen van de dag". De andere pagina's worden gelezen in de volgorde waarin de tegels verschijnen in de natuurlijke NW, NE, SW, SE volgorde waarin ze in de HTML verschijnen: 'Artikelen van vandaag', 'Foto van de dag', 'Quote of the Day', 'Grappen van de Dag."

Laten we dieper ingaan op hoe de audio wordt gegenereerd en hoe de pagina de tekst benadrukt.

Statische voorgenerator

Onze GitHub-repo bevat vooraf gegenereerde audiobestanden voor de PRPTStatic pagina's, maar als u ze zelf wilt genereren, voert u vanuit de bash-shell in de AWS Cloud9 IDE de volgende opdrachten uit:

# navigate to examples
cd /home/ec2-user/environment/amazon-polly-reads-the-page-blog/pregen/examples

# Set env var for my S3 bucket. Example, I called mine prtp-output
S3_BUCKET=prtp-output # Use output BucketName from CloudFormation

#Add lexicon for pronuniciation of NE NW SE NW
#Script invokes aws polly put-lexicon
./addlexicon.sh.

#Gen each variant
./gen_default.sh
./gen_config.sh
./gen_custom.sh

Laten we nu eens kijken hoe die scripts werken.

Standaardgeval

We beginnen met gen_default.sh:

cd ..
python FixHTML.py ../web/PRTPStaticDefault.html  
   example/tmp_wff.html
./gen_ssml.sh example/tmp_wff.html generic.xslt example/tmp.ssml
./run_polly.sh example/tmp.ssml en-US Joanna 
   ../web/polly/PRTPStaticDefault compass
./run_polly.sh example/tmp.ssml en-US Matthew 
   ../web/polly/PRTPStaticDefault compass

Het script begint met het uitvoeren van het Python-programma FixHTML.py om het HTML-bronbestand te maken PRTPStaticDefault.html goed gevormd. Het schrijft de goed gevormde versie van het bestand naar example/tmp_wff.html. Deze stap is cruciaal om twee redenen:

  • De meeste bron-HTML is niet goed gevormd. Deze stap herstelt de bron-HTML om goed gevormd te zijn. Veel HTML-pagina's sluiten bijvoorbeeld niet P elementen. Deze stap sluit ze.
  • We houden bij waar in de HTML-pagina we tekst vinden. We moeten locaties volgen met behulp van dezelfde documentobjectmodel (DOM) -structuur die de browser gebruikt. De browser voegt bijvoorbeeld automatisch een TBODY een TABLE. Het Python-programma volgt dezelfde goedgevormde reparaties als de browser.

gen_ssml.sh neemt de goed gevormde HTML als invoer, past er een XML-stylesheettransformatie (XSLT)-transformatie op toe en voert een SSML-bestand uit. (SSML is de taal in Amazon Polly om te bepalen hoe audio uit tekst wordt weergegeven.) In het huidige voorbeeld is de invoer example/tmp_wff.html. De uitvoer is: example/tmp.ssml. De taak van de transformatie is om te beslissen welke tekst uit de HTML moet worden gehaald en naar Amazon Polly moet worden gestuurd. generic.xslt is een verstandige standaard XSLT-transformatie voor de meeste webpagina's. In het volgende voorbeeldcodefragment zijn de audiobesturing, de HTML-header en HTML-elementen zoals: script en form. Het sluit ook elementen met het verborgen attribuut uit. Het bevat elementen die doorgaans tekst bevatten, zoals: P, H1 en SPAN. Hiervoor wordt zowel een markering weergegeven, inclusief de volledige XPath-expressie van het element, als de waarde van het element.

<!-- skip the header -->
<xsl:template match="html/head">
</xsl:template>

<!-- skip the audio itself -->
<xsl:template match="html/body/table[@id='prtp-audio']">
</xsl:template>

<!-- For the body, work through it by applying its templates. This is the default. -->
<xsl:template match="html/body">
<speak>
      <xsl:apply-templates />
</speak>
</xsl:template>

<!-- skip these -->
<xsl:template match="audio|option|script|form|input|*[@hidden='']">
</xsl:template>

<!-- include these -->
<xsl:template match="p|h1|h2|h3|h4|li|pre|span|a|th/text()|td/text()">
<xsl:for-each select=".">
<p>
      <mark>
          <xsl:attribute name="name">
          <xsl:value-of select="prtp:getMark(.)"/>
          </xsl:attribute>
      </mark>
      <xsl:value-of select="normalize-space(.)"/>
</p>
</xsl:for-each>
</xsl:template>

Het volgende is een fragment van de SSML die wordt weergegeven. Dit wordt ingevoerd als input voor Amazon Polly. Merk bijvoorbeeld op dat de tekst "Verborgen alinea overslaan" moet worden gelezen in de audio, en we associรซren deze met een markering, die ons vertelt dat deze tekst voorkomt op de locatie op de pagina die wordt gegeven door de XPath-expressie /html/body[1]/div[2]/ul[1]/li[1].

<speak>
<p><mark name="/html/body[1]/div[1]/h1[1]"/>PollyReadsThePage Normal Test Page</p>
<p><mark name="/html/body[1]/div[2]/p[1]"/>PollyReadsThePage is a test page for audio readout with highlights.</p>
<p><mark name="/html/body[1]/div[2]/p[2]"/>Here are some features:</p>
<p><mark name="/html/body[1]/div[2]/ul[1]/li[1]"/>Skips hidden paragraph</p>
<p><mark name="/html/body[1]/div[2]/ul[1]/li[2]"/>Speaks but does not highlight collapsed content</p>
โ€ฆ
</speak>

Om audio te genereren in Amazon Polly, noemen we het script run_polly.sh. Het loopt de AWS-opdrachtregelinterface (AWS CLI)-opdracht aws polly start-speech-synthesis-task tweemaal: eenmaal om MP3-audio te genereren en nogmaals om het marks-bestand te genereren. Omdat de generatie asynchroon is, pollt het script totdat het de uitvoer in de opgegeven S3-bucket vindt. Wanneer het de uitvoer vindt, downloadt het naar de buildserver en kopieert het de bestanden naar de web/polly map. Het volgende is een lijst van de webmappen:

  • PRTPStaticDefault.html
  • PRTPStaticConfig.html
  • PRTPStaticCustom.html
  • PRTP.js
  • polly/PRTPStaticDefault/Joanna.mp3, Joanna.marks, Matthew.mp3, Matthew.marks
  • polly/PRTPStaticConfig/Joanna.mp3, Joanna.marks, Matthew.mp3, Matthew.marks
  • polly/PRTPStaticCustom/Joanna.mp3, Joanna.marks, Matthew.mp3, Matthew.marks

Elke pagina heeft zijn eigen set spraakspecifieke MP3- en markeerbestanden. Deze bestanden zijn de vooraf gegenereerde bestanden. De pagina hoeft Amazon Polly tijdens runtime niet aan te roepen; de bestanden maken deel uit van de webbuild.

Configuratiegestuurde case

Denk vervolgens na gen_config.sh:

cd ..
python FixHTML.py ../web/PRTPStaticConfig.html 
  example/tmp_wff.html
python ModGenericXSLT.py example/transform_config.json 
  example/tmp.xslt
./gen_ssml.sh example/tmp_wff.html example/tmp.xslt 
  example/tmp.ssml
./run_polly.sh example/tmp.ssml en-US Joanna 
  ../web/polly/PRTPStaticConfig compass
./run_polly.sh example/tmp.ssml en-US Matthew 
  ../web/polly/PRTPStaticConfig compass

Het script is vergelijkbaar met het script in het standaardgeval, maar de vetgedrukte regels geven het belangrijkste verschil aan. Onze aanpak is config-gedreven. We passen de inhoud aan die van de pagina moet worden geรซxtraheerd door te specificeren wat moet worden geรซxtraheerd via configuratie, niet via code. In het bijzonder gebruiken we het JSON-bestand transform_config.json, die aangeeft dat de op te nemen inhoud de elementen met ID's zijn title, main, maintable en qbtable. Het element met ID wrapup moet worden uitgesloten. Zie de volgende code:

{
 "inclusions": [ 
 	{"id" : "title"} , 
 	{"id": "main"}, 
 	{"id": "maintable"}, 
 	{"id": "qbtable" }
 ],
 "exclusions": [
 	{"id": "wrapup"}
 ]
}

We voeren het Python-programma uit ModGenericXSLT.py aanpassen generic.xslt, gebruikt in het standaardgeval, om de insluitsels en uitsluitingen te gebruiken die we specificeren in transform_config.json. Het programma schrijft de resultaten naar een tijdelijk bestand (example/tmp.xslt), waarnaar het gaat gen_ssml.sh als zijn XSLT-transformatie.

Dit is een low-code optie. De webuitgever hoeft niet te weten hoe hij XSLT moet schrijven. Maar ze moeten wel de structuur van de HTML-pagina begrijpen en de ID's die worden gebruikt in de belangrijkste organiserende elementen.

Aanpassing geval:

Overweeg ten slotte gen_custom.sh:

cd ..
python FixHTML.py ../web/PRTPStaticCustom.html 
   example/tmp_wff.html
./gen_ssml.sh example/tmp_wff.html example/custom.xslt  
   example/tmp.ssml
./run_polly.sh example/tmp.ssml en-US Joanna 
   ../web/polly/PRTPStaticCustom compass
./run_polly.sh example/tmp.ssml en-US Matthew 
   ../web/polly/PRTPStaticCustom compass

Dit script is bijna identiek aan het standaardscript, behalve dat het zijn eigen XSLT gebruiktโ€”example/custom.xslt-in plaats van de generieke XSLT. Het volgende is een fragment van de XSLT:

<!-- Use NW, SW, NE, SE order for main tiles! -->
<xsl:template match="*[@id='maintable']">
    <mark>
        <xsl:attribute name="name">
        <xsl:value-of select="stats:getMark(.)"/>
        </xsl:attribute>
    </mark>
    <xsl:variable name="tiles" select="./tbody"/>
    <xsl:variable name="tiles-nw" select="$tiles/tr[1]/td[1]"/>
    <xsl:variable name="tiles-ne" select="$tiles/tr[1]/td[2]"/>
    <xsl:variable name="tiles-sw" select="$tiles/tr[2]/td[1]"/>
    <xsl:variable name="tiles-se" select="$tiles/tr[2]/td[2]"/>
    <xsl:variable name="tiles-seq" select="($tiles-nw,  $tiles-sw, $tiles-ne, $tiles-se)"/>
    <xsl:for-each select="$tiles-seq">
         <xsl:apply-templates />  
    </xsl:for-each>
</xsl:template>   

<!-- Say Tom Brady load! -->
<xsl:template match="span[@style = 'color:blue']" >
<p>
      <mark>
          <xsl:attribute name="name">
          <xsl:value-of select="prtp:getMark(.)"/>
          </xsl:attribute>
      </mark>
      <prosody volume="x-loud">Tom Brady</prosody>
</p>
</xsl:template>

Als je de code in detail wilt bestuderen, raadpleeg dan de scripts en programma's in de GitHub-repo.

Browserconfiguratie en hoogtepunten

De statische pagina's bevatten een HTML5-audiobesturing, die als audiobron het MP3-bestand gebruikt dat is gegenereerd door Amazon Polly en dat zich op de webserver bevindt:

<audio id="audio" controls>
  <source src="polly/PRTPStaticDefault/en/Joanna.mp3" type="audio/mpeg">
</audio>

Tijdens het laden laadt de pagina ook het door Amazon Polly gegenereerde markeringenbestand. Dit gebeurt in de PRTP.js bestand, dat de HTML-pagina bevat. Het volgende is een fragment van het tekenbestand voor: PRTPStaticDefault:

{โ€œtimeโ€:11747,โ€œtypeโ€:โ€œsentenceโ€,โ€œstartโ€:289,โ€œendโ€:356,โ€œvalueโ€:โ€œPollyReadsThePage is a test page for audio readout with highlights.โ€œ}
{โ€œtimeโ€:15784,โ€œtypeโ€:โ€œssmlโ€,โ€œstartโ€:363,โ€œendโ€:403,โ€œvalueโ€:โ€œ/html/body[1]/div[2]/p[2]โ€œ}
{โ€œtimeโ€:16427,โ€œtypeโ€:โ€œsentenceโ€,โ€œstartโ€:403,โ€œendโ€:426,โ€œvalueโ€:โ€œHere are some features:โ€œ}
{โ€œtimeโ€:17677,โ€œtypeโ€:โ€œssmlโ€,โ€œstartโ€:433,โ€œendโ€:480,โ€œvalueโ€:โ€œ/html/body[1]/div[2]/ul[1]/li[1]โ€œ}
{โ€œtimeโ€:18344,โ€œtypeโ€:โ€œsentenceโ€,โ€œstartโ€:480,โ€œendโ€:502,โ€œvalueโ€:โ€œSkips hidden paragraphโ€}
{โ€œtimeโ€:19894,โ€œtypeโ€:โ€œssmlโ€,โ€œstartโ€:509,โ€œendโ€:556,โ€œvalueโ€:โ€œ/html/body[1]/div[2]/ul[1]/li[2]โ€œ}
{โ€œtimeโ€:20537,โ€œtypeโ€:โ€œsentenceโ€,โ€œstartโ€:556,โ€œendโ€:603,โ€œvalueโ€:โ€œSpeaks but does not highlight collapsed contentโ€}

Tijdens het afspelen van audio is er een gebeurtenishandler voor de audiotimer PRTP.js die de huidige tijd van de audio controleert, de tekst vindt die moet worden gemarkeerd, de locatie op de pagina vindt en deze markeert. De tekst die moet worden gemarkeerd, is een invoer van het type sentence in het tekenbestand. De locatie is de XPath-expressie in het naamattribuut van de invoer van het type SSML die aan de zin voorafgaat. Als de tijd bijvoorbeeld 18400 is, volgens het marks-bestand, is de zin die moet worden gemarkeerd 'Verborgen alinea overslaan', die begint bij 18334. De locatie is het SSML-item op tijd 17667: /html/body[1]/div[2]/ul[1]/li[1].

Dynamische pagina's testen

De pagina PRTPDynamic.html demonstreert het dynamisch teruglezen van audio met behulp van standaard, configuratiegestuurde en aangepaste benaderingen voor audio-extractie.

Standaardgeval

Navigeer in uw browser naar: PRTPDynamic.html. De pagina heeft รฉรฉn queryparameter, dynOption, die waarden accepteert default, config en custom. Het staat standaard op default, dus u kunt het in dit geval weglaten. De pagina heeft twee secties met dynamische inhoud:

  • Laatste artikels โ€“ Verandert regelmatig gedurende de dag
  • Griekse filosofen zoeken op datum โ€“ Laat de bezoeker zoeken naar Griekse filosofen op datum en toont de resultaten in een tabel

Lees webpagina's en markeer inhoud met Amazon Polly PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

Maak wat inhoud in de Griekse filosoof sectie door een datumbereik van -800 tot 0 in te voeren, zoals weergegeven in het voorbeeld. Kies dan VIND DE PLEK DIE PERFECT VOOR JOU IS.

Speel nu de audio af door te kiezen voor Spelen in de audiobediening.

Achter de schermen voert de pagina de volgende code uit om de audio weer te geven en af โ€‹โ€‹te spelen:

   buildSSMLFromDefault();
   chooseRenderAudio();
   setVoice();

Eerst roept het de functie aan buildSSMLFromDefault in PRTP.js om de meeste tekst uit de hoofdtekst van de HTML-pagina te extraheren. Die functie loopt door de DOM-boom, op zoek naar tekst in gemeenschappelijke elementen zoals p, h1, pre, span en td. Het negeert tekst in elementen die normaal gesproken geen tekst bevatten die hardop moet worden voorgelezen, zoals: audio, option en script. Het bouwt SSML-opmaak om te worden ingevoerd in Amazon Polly. Het volgende is een fragment dat de extractie van de eerste rij uit de philosopher tafel:

<speak>
...
  <p><mark name="/HTML[1]/BODY[1]/DIV[3]/DIV[1]/DIV[1]/TABLE[1]/TBODY[1]/TR[2]/TD[1]"/>Thales</p>
  <p><mark name="/HTML[1]/BODY[1]/DIV[3]/DIV[1]/DIV[1]/TABLE[1]/TBODY[1]/TR[2]/TD[2]"/>-624 to -546</p>
  <p><mark name="/HTML[1]/BODY[1]/DIV[3]/DIV[1]/DIV[1]/TABLE[1]/TBODY[1]/TR[2]/TD[3]"/>Miletus</p>
  <p><mark name="/HTML[1]/BODY[1]/DIV[3]/DIV[1]/DIV[1]/TABLE[1]/TBODY[1]/TR[2]/TD[4]"/>presocratic</p>
...
</speak>

De chooseRenderAudio functie in PRTP.js begint met het initialiseren van de AWS SDK voor Amazon Cognito, Amazon S3 en Amazon Polly. Deze initialisatie vindt slechts รฉรฉn keer plaats. Als chooseRenderAudio opnieuw wordt aangeroepen omdat de inhoud van de pagina is gewijzigd, wordt de initialisatie overgeslagen. Zie de volgende code:

AWS.config.region = env.REGION
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
            IdentityPoolId: env.IDP});
audioTracker.sdk.connection = {
   polly: new AWS.Polly({apiVersion: '2016-06-10'}),
   s3: new AWS.S3()
};

Het genereert MP3-audio van Amazon Polly. De generatie is synchroon voor kleine SSML-invoer en asynchroon (met uitvoer naar de S3-bucket) voor grote SSML-invoer (meer dan 6,000 tekens). In het synchrone geval vragen we Amazon Polly om het MP3-bestand te verstrekken met behulp van een vooraf ondertekende URL. Wanneer de gesynthetiseerde uitvoer gereed is, stellen we de src attribuut van het audiobesturingselement naar die URL en laad het besturingselement. We vragen dan het marks-bestand op en laden het op dezelfde manier als in het statische geval. Zie de volgende code:

// create signed URL
const signer = new AWS.Polly.Presigner(pollyAudioInput, audioTracker.sdk.connection.polly);

// call Polly to get MP3 into signed URL
signer.getSynthesizeSpeechUrl(pollyAudioInput, function(error, url) {
  // Audio control uses signed URL
  audioTracker.audioControl.src =
    audioTracker.sdk.audio[audioTracker.voice];
  audioTracker.audioControl.load();

  // call Polly to get marks
  audioTracker.sdk.connection.polly.synthesizeSpeech(
    pollyMarksInput, function(markError, markData) {
    const marksStr = new
      TextDecoder().decode(markData.AudioStream);
    // load marks into page the same as with static
    doLoadMarks(marksStr);
  });
});

Configuratiegestuurde case

Navigeer in uw browser naar: PRTPDynamic.html?dynOption=config. Speel het geluid af. Het afspelen van audio is vergelijkbaar met het standaardgeval, maar er zijn kleine verschillen. Met name wordt bepaalde inhoud overgeslagen.

Achter de schermen, bij het gebruik van de config optie, extraheert de pagina inhoud anders dan in het standaard geval. In het standaard geval gebruikt de pagina buildSSMLFromDefault. In het configuratiegestuurde geval specificeert de pagina de secties die hij wil opnemen en uitsluiten:

const ssml = buildSSMLFromConfig({
	 "inclusions": [ 
	 	{"id": "title"}, 
	 	{"id": "main"}, 
	 	{"id": "maintable"}, 
	 	{"id": "phil-result"},
	 	{"id": "qbtable"}, 
	 ],
	 "exclusions": [
	 	{"id": "wrapup"}
	 ]
	});

De buildSSMLFromConfig functie, gedefinieerd in PRTP.js, loopt door de DOM-boomstructuur in elk van de secties waarvan de ID is opgegeven onder inclusions. Het extraheert de inhoud van elk en combineert ze samen, in de aangegeven volgorde, om een โ€‹โ€‹SSML-document te vormen. Het sluit de secties uit die zijn gespecificeerd onder exclusions. Het haalt op dezelfde manier inhoud uit elke sectie buildSSMLFromDefault haalt inhoud uit de hoofdtekst van de pagina.

Aanpassing geval:

Navigeer in uw browser naar: PRTPDynamic.html?dynOption=custom. Speel het geluid af. Er zijn drie opvallende verschillen. Laten we deze noteren en de aangepaste code bekijken die achter de schermen wordt uitgevoerd:

  • Het leest de belangrijkste tegels in NW, SW, NE, SE volgorde. De aangepaste code haalt elk van deze celblokken van maintable en voegt ze toe aan de SSML in NW, SW, NE, SE volgorde:
const nw = getElementByXpath("//*[@id='maintable']//tr[1]/td[1]");
const sw = getElementByXpath("//*[@id='maintable']//tr[2]/td[1]");
const ne = getElementByXpath("//*[@id='maintable']//tr[1]/td[2]");
const se = getElementByXpath("//*[@id='maintable']//tr[2]/td[2]");
[nw, sw, ne, se].forEach(dir => buildSSMLSection(dir, []));

  • "Tom Brady" wordt luid gesproken. De aangepaste code plaatst de tekst "Tom Brady" in een SSML prosody label:
if (cellText == "Tom Brady") {
   addSSMLMark(getXpathOfNode( node.childNodes[tdi]));
   startSSMLParagraph();
   startSSMLTag("prosody", {"volume": "x-loud"});
   addSSMLText(cellText);
   endSSMLTag();
   endSSMLParagraph();
}

  • Het leest alleen de eerste drie rijen van de quarterback-tabel. Het leest de kolomkoppen voor elke rij. Controleer de code in de GitHub-repo om te ontdekken hoe dit is geรฏmplementeerd.

Opruimen

Verwijder de CloudFormation-stack om toekomstige kosten te voorkomen.

Conclusie

In dit bericht hebben we een technische oplossing voor een hoogwaardig zakelijk probleem gedemonstreerd: hoe Amazon Polly te gebruiken om de inhoud van een webpagina te lezen en de inhoud te markeren terwijl deze wordt gelezen. We lieten dit zien met zowel statische als dynamische pagina's. Om inhoud van de pagina te extraheren, hebben we DOM traversal en XSLT gebruikt. Om het markeren te vergemakkelijken, hebben we de mogelijkheid voor spraakmarkeringen in Amazon Polly gebruikt.

Kom meer te weten over Amazon Polly door zijn . te bezoeken servicepagina.

Stel gerust vragen in de comments.


Over de auteurs

Lees webpagina's en markeer inhoud met Amazon Polly PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.Mike Havey is een Solutions Architect voor AWS met meer dan 25 jaar ervaring in het bouwen van bedrijfsapplicaties. Mike is de auteur van twee boeken en talloze artikelen. Bezoek zijn Amazon auteurspagina om meer te lezen.

Lees webpagina's en markeer inhoud met Amazon Polly PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.Vineet Kachhawaha is Solutions Architect bij AWS met expertise in machine learning. Hij is verantwoordelijk voor het helpen van klanten bij het ontwerpen van schaalbare, veilige en kosteneffectieve workloads op AWS.

Tijdstempel:

Meer van AWS-machine learning