Czytaj strony internetowe i wyróżniaj treści za pomocą Amazon Polly PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Czytaj strony internetowe i wyróżniaj treści za pomocą Amazon Polly

W tym poście pokazujemy, jak używać Amazon Polly— wiodąca usługa w chmurze, która przekształca tekst na realistyczną mowę — do odczytywania zawartości strony internetowej i wyróżniania jej w trakcie czytania. Dodanie odtwarzania dźwięku do strony internetowej poprawia dostępność i wrażenia odwiedzających stronę. Treści wzmocnione dźwiękiem mają większy wpływ i zapadają w pamięć, przyciągają większy ruch na stronę i wykorzystują siłę nabywczą odwiedzających. Poprawia również markę firmy lub organizacji, która publikuje stronę. Technologia przetwarzania tekstu na mowę umożliwia osiągnięcie tych korzyści biznesowych. Przyspieszamy tę podróż, pokazując, jak osiągnąć ten cel za pomocą Amazon Polly.

Ta funkcja poprawia dostępność dla osób niepełnosprawnych i może zostać przyjęta jako część strategii ułatwień dostępu Twojej organizacji. Co równie ważne, poprawia wrażenia ze strony dla osób bez niepełnosprawności. Obie grupy mają znaczną siłę nabywczą i swobodniej wydają na stronach, które wykorzystują ulepszenia dźwięku, aby przyciągnąć ich uwagę.

Przegląd rozwiązania

PollyReadsThePage (PRTP) — jak mówimy o rozwiązaniu — umożliwia wydawcy strony internetowej upuszczenie kontrolki dźwięku na swojej stronie internetowej. Kiedy gość wybierze Grać w kontrolce, kontrolka odczytuje stronę i podświetla zawartość. PRTP wykorzystuje ogólne możliwości Amazon Polly do syntezy mowy z tekstu. Wywołuje Amazon Polly, aby wygenerować dwa artefakty dla każdej strony:

  • Zawartość audio w formacie odtwarzanym przez przeglądarkę: MP3
  • Plik znaków mowy, który wskazuje dla każdego zdania tekstu:
    • Czas podczas odtwarzania, w którym czytane jest zdanie
    • Lokalizacja na stronie, w której pojawia się zdanie

Kiedy gość wybierze Graćprzeglądarka odtworzy plik MP3. Gdy dźwięk jest odczytywany, przeglądarka sprawdza godzinę, znajduje w pliku znaczników, które zdanie należy w danym momencie przeczytać, lokalizuje je na stronie i podświetla.

PRTP umożliwia odwiedzającemu czytanie w różnych głosach i językach. Każdy głos wymaga własnej pary plików. PRTP wykorzystuje głosy neuronowe. Aby uzyskać listę obsługiwanych głosów neuronowych i języków, zobacz Głosy neuronowe. Aby zobaczyć pełną listę standardowych i neuronowych głosów w Amazon Polly, zobacz Głosy w Amazon Polly.

Rozważamy dwa rodzaje stron internetowych: strony statyczne i strony dynamiczne. W statyczny strona, treść jest zawarta na stronie i zmienia się dopiero po opublikowaniu nowej wersji strony. Firma może aktualizować stronę codziennie lub co tydzień w ramach procesu budowania strony internetowej. W przypadku tego typu strony możliwe jest wstępne wygenerowanie plików audio w czasie kompilacji i umieszczenie ich na serwerze sieciowym w celu odtworzenia. Jak pokazuje poniższy rysunek, skrypt PRTP Pre-Gen wywołuje Amazon Polly, aby wygenerować dźwięk. Jako dane wejściowe przyjmuje samą stronę HTML i, opcjonalnie, plik konfiguracyjny, który określa, który tekst ze strony wyodrębnić (Text Extract Config). Jeśli konfiguracja ekstrakcji zostanie pominięta, skrypt pre-gen dokonuje rozsądnego wyboru tekstu do wyodrębnienia z treści strony. Amazon Polly wyprowadza pliki w Usługa Amazon Simple Storage (Amazon S3) łyżka; skrypt kopiuje je na twój serwer WWW. Gdy odwiedzający odtwarza dźwięk, przeglądarka pobiera plik MP3 bezpośrednio z serwera WWW. W przypadku najciekawszych miejsc biblioteka rozwijana, PRTP.js, używa pliku znaczników do podświetlenia czytanego tekstu.

Treść dynamiczny strona zmienia się w odpowiedzi na interakcję użytkownika, więc dźwięk nie może być wstępnie generowany, ale musi być dynamicznie syntetyzowany. Jak pokazuje poniższy rysunek, gdy odwiedzający odtwarza dźwięk, strona używa PRTP.js aby wygenerować dźwięk w Amazon Polly i podświetla zsyntetyzowany dźwięk przy użyciu tego samego podejścia, co w przypadku stron statycznych. Aby uzyskać dostęp do usług AWS z przeglądarki, odwiedzający wymaga tożsamości AWS. Pokazujemy, jak używać an Amazon Cognito pula tożsamości, aby umożliwić odwiedzającym dostęp tylko do Amazon Polly i zasobnika S3 w celu renderowania dźwięku.

Treść dynamiczna

Generowanie znaczników audio i mowy w formacie MP3 wymaga, aby usługa Polly dwukrotnie zsyntetyzowała to samo wejście. Zapoznaj się z Strona cenowa Amazon Polly zrozumieć konsekwencje kosztów. Wstępne generowanie oszczędza koszty, ponieważ synteza jest wykonywana w czasie budowy, a nie na żądanie dla każdej interakcji z odwiedzającym.

Kod towarzyszący temu poście jest dostępny jako repozytorium open-source na GitHub.

Aby zbadać rozwiązanie, wykonaj następujące kroki:

  1. Skonfiguruj zasoby, w tym serwer kompilacji przed generacją, zasobnik S3, serwer sieciowy i tożsamość Amazon Cognito.
  2. Uruchom statyczną kompilację przed generacją i przetestuj strony statyczne.
  3. Testuj strony dynamiczne.

Wymagania wstępne

Aby uruchomić ten przykład, potrzebujesz Konto AWS z pozwoleniem na korzystanie z Amazon Polly, Amazon S3, Amazon Cognito oraz (w celach demonstracyjnych) Chmura AWS9.

Zasoby zaopatrzenia

Dzielimy się Tworzenie chmury AWS szablon, aby utworzyć na swoim koncie samodzielne środowisko demonstracyjne, które pomoże Ci śledzić wraz z postem. Jeśli wolisz skonfigurować PRTP we własnym środowisku, zapoznaj się z instrukcjami w README.md.

Aby udostępnić środowisko demonstracyjne przy użyciu CloudFormation, najpierw pobierz kopię Szablon CloudFormation. Następnie wykonaj następujące czynności:

  1. W konsoli AWS CloudFormation wybierz Utwórz stos.
  2. Dodaj Z nowymi zasobami (standard).
  3. Wybierz Prześlij plik szablonu.
  4. Dodaj Wybierz plik aby przesłać lokalną kopię pobranego szablonu. Nazwa pliku to prtp.yml.
  5. Dodaj Następna.
  6. Wprowadź wybraną nazwę stosu. Później wpisujesz to ponownie jako zamiennik dla .
  7. Możesz zachować wartości domyślne w parametry
  8. Dodaj Następna.
  9. Przejdź przez pozostałe sekcje.
  10. Przeczytaj i zaznacz pola wyboru w Nasze możliwości
  11. Dodaj Utwórz stos.
  12. Gdy stos jest kompletny, znajdź wartość dla BucketName w wyjściach stosu.

Zachęcamy do przejrzenia stosu z zespołem ds. bezpieczeństwa przed użyciem go w środowisku produkcyjnym.

Skonfiguruj serwer WWW i serwer przed generacją w IDE AWS Cloud9

Następnie w konsoli AWS Cloud9 zlokalizuj środowisko PRTPDemoCloud9 utworzony przez stos CloudFormation. Wybierać Otwórz IDE aby otworzyć środowisko AWS Cloud9. Otwórz okno terminala i uruchom następujące polecenia, które klonują kod PRTP, konfigurują zależności przed generacją i uruchamiają serwer WWW do testowania:

#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> 

W razie zamówieenia projektu , użyj nazwy, którą nadałeś stosowi CloudFormation. Do , określ zakres adresów IP, które mogą uzyskiwać dostęp do serwera WWW. Aby ograniczyć dostęp do przeglądarki na komputerze lokalnym, znajdź swój adres IP za pomocą https://whatismyipaddress.com/ i dołącz /32 aby określić zakres. Na przykład, jeśli Twój adres IP to 10.2.3.4, use 10.2.3.4/32. Serwer nasłuchuje na porcie 8080. W danych wyjściowych podawany jest publiczny adres IP, na którym nasłuchuje serwer. Na przykład:

Public IP is

3.92.33.223

Testuj strony statyczne

W przeglądarce przejdź do PRTPStaticDefault.html. (Jeśli korzystasz z wersji demonstracyjnej, adres URL to http://<cloud9host>:8080/web/PRTPStaticDefault.html, Gdzie to publiczny adres IP, który odkryłeś podczas konfigurowania IDE). Wybierz Grać na kontrolce audio u góry. Posłuchaj dźwięku i obejrzyj najciekawsze momenty. Eksploruj sterowanie, zmieniając prędkości, zmieniając głosy, wstrzymując, przewijając do przodu i do tyłu. Poniższy zrzut ekranu przedstawia stronę; tekst „Pomija ukryty akapit” jest podświetlony, ponieważ jest właśnie czytany.

Czytaj strony internetowe i wyróżniaj treści za pomocą Amazon Polly PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Spróbuj tego samego dla PRTPStaticConfig.html i PRTPStaticCustom.html. Wyniki są podobne. Na przykład wszyscy trzej czytają tekst alternatywny dla zdjęcia kota („Losowe zdjęcie kota”). Wszystkie trzy brzmią NE, NW, SE i SW jako pełne słowa („północny wschód”, „północny zachód”, „południowy wschód”, „południowy zachód”), korzystając z leksykonów Amazon Polly.

Zwróć uwagę na główne różnice w dźwięku:

  • PRTPStaticDefault.html odczytuje cały tekst w treści strony, w tym część podsumowującą na dole z „Twoje przemyślenia w jednym słowie”, „Prześlij zapytanie”, „Ostatnia aktualizacja 1 kwietnia 2020 r.” i „Pytania do zespołu programistów”. PRTPStaticConfig.html i PRTPStaticCustom.html nie czytaj ich, ponieważ wyraźnie wykluczają podsumowanie z syntezy mowy.
  • PRTPStaticCustom.html czyta Bestsellery QB stół inaczej niż pozostałe. Odczytuje tylko pierwsze trzy wiersze i odczytuje numer wiersza dla każdego wiersza. Powtarza kolumny dla każdego wiersza. PRTPStaticCustom.html używa niestandardowej transformacji, aby dostosować odczyt tabeli. Pozostałe strony używają domyślnego renderowania tabeli.
  • PRTPStaticCustom.html brzmi „Tom Brady” głośniej niż reszta tekstu. Używa języka znaczników syntezy mowy (SSML) prosody tag, aby dostosować czytanie Toma Brady'ego. Inne strony nie są dostosowywane w ten sposób.
  • PRTPStaticCustom.html, dzięki niestandardowej transformacji odczytuje główne kafelki w kolejności NW, SW, NE, SE; czyli „Dzisiejsze artykuły”, „Cytat dnia”, „Zdjęcie dnia”, „Dowcipy dnia”. Inne strony czytają w kolejności, w jakiej kafelki pojawiają się w naturalnej kolejności NW, NE, SW, SE, w jakiej pojawiają się w kodzie HTML: „Dzisiejsze artykuły”, „Zdjęcie dnia”, „Cytat dnia”, „Dowcipy z Dzień."

Przyjrzyjmy się dokładniej, jak generowany jest dźwięk i jak strona wyróżnia tekst.

Pregenerator statyczny

Nasze repozytorium GitHub zawiera wstępnie wygenerowane pliki audio dla PRPTStatic strony, ale jeśli chcesz je wygenerować samodzielnie, z powłoki bash w IDE AWS Cloud9, uruchom następujące polecenia:

# 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

Przyjrzyjmy się teraz, jak działają te skrypty.

Domyślny przypadek

Zaczynamy od 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

Skrypt zaczyna się od uruchomienia programu Python FixHTML.py aby utworzyć źródłowy plik HTML PRTPStaticDefault.html dobrze uformowane. Zapisuje dobrze sformatowaną wersję pliku do example/tmp_wff.html. Ten krok jest kluczowy z dwóch powodów:

  • Większość kodu źródłowego HTML nie jest dobrze sformatowana. Ten krok naprawia źródłowy kod HTML, aby był dobrze sformatowany. Na przykład wiele stron HTML się nie zamyka P elementy. Ten krok je zamyka.
  • Śledzimy, gdzie na stronie HTML znajdujemy tekst. Musimy śledzić lokalizacje przy użyciu tej samej struktury obiektowego modelu dokumentu (DOM), z której korzysta przeglądarka. Na przykład przeglądarka automatycznie dodaje a TBODY do TABLE. Program w Pythonie wykonuje te same dobrze sformułowane naprawy, co przeglądarka.

gen_ssml.sh przyjmuje dobrze sformatowany HTML jako dane wejściowe, stosuje do niego transformację arkusza stylów XML (XSLT) i wyprowadza plik SSML. (SSML to język w Amazon Polly do kontrolowania sposobu renderowania dźwięku z tekstu). W bieżącym przykładzie dane wejściowe to example/tmp_wff.html. Wyjście to example/tmp.ssml. Zadaniem przekształcenia jest podjęcie decyzji, jaki tekst wyodrębnić z kodu HTML i przekazać do Amazon Polly. generic.xslt jest rozsądną domyślną transformacją XSLT dla większości stron internetowych. W poniższym przykładowym fragmencie kodu wykluczono kontrolkę audio, nagłówek HTML, a także elementy HTML, takie jak script i form. Wyklucza również elementy z ukrytym atrybutem. Zawiera elementy, które zazwyczaj zawierają tekst, takie jak P, H1, SPAN. W tym przypadku renderuje zarówno znak, w tym pełne wyrażenie XPath elementu, jak i wartość elementu.

<!-- 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>

Poniżej znajduje się fragment kodu SSML, który jest renderowany. Jest to podawane jako dane wejściowe do Amazon Polly. Zauważ na przykład, że tekst „Pomija ukryty akapit” ma być odczytany w audio i kojarzymy go ze znacznikiem, który mówi nam, że ten tekst występuje w miejscu na stronie podanym przez wyrażenie XPath /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>

Aby wygenerować dźwięk w Amazon Polly, nazywamy skrypt run_polly.sh. Prowadzi Interfejs wiersza poleceń AWS (AWS CLI), polecenie aws polly start-speech-synthesis-task dwa razy: raz, aby wygenerować dźwięk MP3 i ponownie, aby wygenerować plik znaczników. Ponieważ generowanie jest asynchroniczne, skrypt sonduje, dopóki nie znajdzie danych wyjściowych w określonym zasobniku S3. Gdy znajdzie dane wyjściowe, pobiera je na serwer kompilacji i kopiuje pliki do web/polly teczka. Poniżej znajduje się lista folderów internetowych:

  • 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

Każda strona ma swój własny zestaw plików MP3 specyficznych dla głosu i zaznacza pliki. Te pliki są wstępnie wygenerowanymi plikami. Strona nie musi wywoływać Amazon Polly w czasie wykonywania; pliki są częścią kompilacji internetowej.

Sprawa oparta na konfiguracji

Następnie rozważ 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

Skrypt jest podobny do skryptu w przypadku domyślnym, ale pogrubione linie wskazują główną różnicę. Nasze podejście opiera się na konfiguracji. Dopasowujemy zawartość do wyodrębnienia ze strony, określając, co ma zostać wyodrębnione poprzez konfigurację, a nie kod. W szczególności korzystamy z pliku JSON transform_config.json, który określa, że ​​treścią, która ma zostać uwzględniona, są elementy z identyfikatorami title, main, maintable, qbtable. Element z ID wrapup należy wykluczyć. Zobacz następujący kod:

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

Uruchamiamy program Python ModGenericXSLT.py modyfikować generic.xslt, używane w przypadku domyślnym, aby korzystać z włączeń i wykluczeń, które określamy w transform_config.json. Program zapisuje wyniki do pliku tymczasowego (example/tmp.xslt), które przekazuje gen_ssml.sh jako jego transformację XSLT.

To jest opcja o niskim kodzie. Wydawca internetowy nie musi wiedzieć, jak pisać XSLT. Ale muszą zrozumieć strukturę strony HTML i identyfikatory używane w jej głównych elementach organizacyjnych.

Przypadek dostosowywania

Wreszcie rozważ 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

Ten skrypt jest prawie identyczny ze skryptem domyślnym, z wyjątkiem tego, że używa własnego XSLT—example/custom.xslt—zamiast ogólnego XSLT. Poniżej znajduje się fragment kodu 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>

Jeśli chcesz szczegółowo przestudiować kod, zapoznaj się ze skryptami i programami w repozytorium GitHub.

Konfiguracja przeglądarki i najważniejsze informacje

Strony statyczne zawierają kontrolkę audio HTML5, która jako źródło dźwięku przyjmuje plik MP3 wygenerowany przez Amazon Polly i znajdujący się na serwerze WWW:

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

W czasie ładowania strona ładuje również plik znaczników wygenerowany przez Amazon Polly. Dzieje się tak w PRTP.js plik, który zawiera strona HTML. Poniżej znajduje się fragment pliku znaków dla 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”}

Podczas odtwarzania dźwięku w urządzeniu znajduje się procedura obsługi zdarzeń zegara audio PRTP.js który sprawdza aktualny czas dźwięku, znajduje tekst do podświetlenia, znajduje jego lokalizację na stronie i podświetla go. Podświetlany tekst to wpis typu sentence w pliku znaków. Lokalizacja jest wyrażeniem XPath w atrybucie name wpisu typu SSML, który poprzedza zdanie. Na przykład, jeśli godzina to 18400, zgodnie z plikiem znaczników, zdanie do podświetlenia to „Pomija ukryty akapit”, które zaczyna się od 18334. Lokalizacja to wpis SSML w czasie 17667: /html/body[1]/div[2]/ul[1]/li[1].

Testuj strony dynamiczne

Strona PRTPDynamic.html demonstruje dynamiczny odczyt dźwięku przy użyciu domyślnego, opartego na konfiguracji i niestandardowego podejścia do ekstrakcji dźwięku.

Domyślny przypadek

W przeglądarce przejdź do PRTPDynamic.html. Strona ma jeden parametr zapytania, dynOption, który akceptuje wartości default, config, custom. Domyślnie: default, więc możesz go w tym przypadku pominąć. Strona posiada dwie sekcje z dynamiczną zawartością:

  • Najnowsze artykuły – Zmienia się często w ciągu dnia
  • Greccy filozofowie szukają według daty – Umożliwia odwiedzającemu wyszukiwanie greckich filozofów według daty i pokazuje wyniki w tabeli

Czytaj strony internetowe i wyróżniaj treści za pomocą Amazon Polly PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Utwórz jakieś treści w filozof grecki sekcji, wprowadzając zakres dat od -800 do 0, jak pokazano w przykładzie. Następnie wybierz Znajdź.

Teraz odtwórz dźwięk, wybierając Grać w sterowaniu dźwiękiem.

Za kulisami strona uruchamia następujący kod do renderowania i odtwarzania dźwięku:

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

Najpierw wywołuje funkcję buildSSMLFromDefault in PRTP.js aby wyodrębnić większość tekstu z treści strony HTML. Ta funkcja przechodzi przez drzewo DOM, szukając tekstu we wspólnych elementach, takich jak p, h1, pre, span, td. Ignoruje tekst w elementach, które zwykle nie zawierają tekstu do odczytania na głos, takich jak audio, option, script. Tworzy znaczniki SSML do wprowadzenia do Amazon Polly. Poniżej znajduje się fragment pokazujący wyodrębnienie pierwszego wiersza z philosopher stół:

<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>

Połączenia chooseRenderAudio funkcja w PRTP.js zaczyna się od zainicjowania AWS SDK dla Amazon Cognito, Amazon S3 i Amazon Polly. Ta inicjalizacja następuje tylko raz. Jeśli chooseRenderAudio jest wywoływana ponownie, ponieważ zawartość strony uległa zmianie, inicjalizacja jest pomijana. Zobacz następujący kod:

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()
};

Generuje dźwięk MP3 z Amazon Polly. Generowanie jest synchroniczne dla małych wejść SSML i asynchroniczne (z danymi wyjściowymi wysyłanymi do zasobnika S3) dla dużych wejść SSML (większych niż 6,000 znaków). W przypadku synchronicznym prosimy Amazon Polly o dostarczenie pliku MP3 za pomocą wcześniej podpisanego adresu URL. Gdy zsyntetyzowane wyjście jest gotowe, ustawiamy src atrybut kontrolki audio do tego adresu URL i załaduj kontrolkę. Następnie żądamy pliku ze znakami i ładujemy go w taki sam sposób, jak w przypadku statycznym. Zobacz następujący kod:

// 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);
  });
});

Sprawa oparta na konfiguracji

W przeglądarce przejdź do PRTPDynamic.html?dynOption=config. Odtwórz dźwięk. Odtwarzanie dźwięku jest podobne do przypadku domyślnego, ale istnieją niewielkie różnice. W szczególności niektóre treści są pomijane.

Za kulisami, podczas korzystania z config opcja, strona wyodrębnia zawartość inaczej niż w przypadku domyślnym. W przypadku domyślnym strona używa buildSSMLFromDefault. W przypadku config-driven strona określa sekcje, które chce uwzględnić i wykluczyć:

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

Połączenia buildSSMLFromConfig funkcja, zdefiniowana w PRTP.js, przechodzi drzewo DOM w każdej sekcji, której identyfikator jest podany w inclusions. Wyodrębnia treść z każdego i łączy je razem, w określonej kolejności, tworząc dokument SSML. Nie obejmuje sekcji określonych w exclusions. Wyodrębnia zawartość z każdej sekcji w ten sam sposób buildSSMLFromDefault wyodrębnia zawartość z treści strony.

Przypadek dostosowywania

W przeglądarce przejdź do PRTPDynamic.html?dynOption=custom. Odtwórz dźwięk. Istnieją trzy zauważalne różnice. Zwróćmy na to uwagę i rozważmy niestandardowy kod, który działa za kulisami:

  • Odczytuje główne kafelki w kolejności NW, SW, NE, SE. Kod niestandardowy pobiera każdy z tych bloków komórek z maintable i dodaje je do SSML w kolejności NW, SW, NE, SE:
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” jest wypowiadany głośno. Niestandardowy kod umieszcza tekst „Tom Brady” w SSML prosody etykietka:
if (cellText == "Tom Brady") {
   addSSMLMark(getXpathOfNode( node.childNodes[tdi]));
   startSSMLParagraph();
   startSSMLTag("prosody", {"volume": "x-loud"});
   addSSMLText(cellText);
   endSSMLTag();
   endSSMLParagraph();
}

  • Czyta tylko pierwsze trzy rzędy tabeli rozgrywającego. Odczytuje nagłówki kolumn dla każdego wiersza. Sprawdź kod w repozytorium GitHub, aby dowiedzieć się, jak to jest zaimplementowane.

Sprzątać

Aby uniknąć ponoszenia przyszłych opłat, usuń stos CloudFormation.

Wnioski

W tym poście zademonstrowaliśmy techniczne rozwiązanie problemu biznesowego o dużej wartości: jak używać Amazon Polly do odczytywania treści strony internetowej i wyróżniania jej podczas czytania. Pokazaliśmy to za pomocą zarówno statycznych, jak i dynamicznych stron. Do wyodrębnienia treści ze strony wykorzystaliśmy przechodzenie DOM i XSLT. Aby ułatwić wyróżnianie, użyliśmy funkcji znaków mowy w Amazon Polly.

Dowiedz się więcej o Amazon Polly, odwiedzając jego strona usługi.

Zapraszam do zadawania pytań w komentarzach.


O autorach

Czytaj strony internetowe i wyróżniaj treści za pomocą Amazon Polly PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.Mike'a Havey'a jest architektem rozwiązań dla AWS z ponad 25-letnim doświadczeniem w tworzeniu aplikacji dla przedsiębiorstw. Mike jest autorem dwóch książek i licznych artykułów. Odwiedź jego Amazonkę strona autora aby przeczytać więcej.

Czytaj strony internetowe i wyróżniaj treści za pomocą Amazon Polly PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.Vineeta Kachhawahy jest architektem rozwiązań w AWS z doświadczeniem w uczeniu maszynowym. Jest odpowiedzialny za pomaganie klientom w architekturze skalowalnych, bezpiecznych i opłacalnych obciążeń w AWS.

Znak czasu:

Więcej z Uczenie maszynowe AWS