Leia páginas da Web e destaque o conteúdo usando o Amazon Polly PlatoBlockchain Data Intelligence. Pesquisa Vertical. Ai.

Leia páginas da web e destaque o conteúdo usando o Amazon Polly

Neste post, mostramos como usar Amazon Polly—um serviço de nuvem líder que converte texto em fala realista—para ler o conteúdo de uma página da Web e destacar o conteúdo à medida que está sendo lido. Adicionar reprodução de áudio a uma página da Web melhora a acessibilidade e a experiência do visitante da página. O conteúdo com áudio aprimorado é mais impactante e memorável, atrai mais tráfego para a página e aproveita o poder de compra dos visitantes. Também melhora a marca da empresa ou organização que publica a página. A tecnologia de conversão de texto em voz torna esses benefícios comerciais atingíveis. Aceleramos essa jornada demonstrando como atingir esse objetivo usando o Amazon Polly.

Esse recurso melhora a acessibilidade para visitantes com deficiência e pode ser adotado como parte da estratégia de acessibilidade de sua organização. Tão importante quanto isso, melhora a experiência da página para visitantes sem deficiências. Ambos os grupos têm um poder de compra significativo e gastam mais livremente em páginas que usam aprimoramento de áudio para chamar sua atenção.

Visão geral da solução

PollyReadsThePage (PRTP)—como nos referimos à solução—permite que um editor de página da web solte um controle de áudio em sua página da web. Quando o visitante escolhe Jogar no controle, o controle lê a página e destaca o conteúdo. O PRTP usa o recurso geral do Amazon Polly para sintetizar fala a partir de texto. Ele invoca o Amazon Polly para gerar dois artefatos para cada página:

  • O conteúdo de áudio em um formato reproduzível pelo navegador: MP3
  • Um arquivo de marcas de fala que indica para cada frase do texto:
    • O tempo durante a reprodução em que a frase é lida
    • A localização na página em que a frase aparece

Quando o visitante escolhe Jogar, o navegador reproduz o arquivo MP3. À medida que o áudio é lido, o navegador verifica a hora, encontra no arquivo de marcas qual frase ler naquele momento, localiza-a na página e a destaca.

O PRTP permite que o visitante leia em diferentes vozes e idiomas. Cada voz requer seu próprio par de arquivos. O PRTP usa vozes neurais. Para obter uma lista de vozes e idiomas neurais compatíveis, consulte Vozes Neurais. Para obter uma lista completa de vozes padrão e neurais no Amazon Polly, consulte Vozes na Amazon Polly.

Consideramos dois tipos de páginas da web: páginas estáticas e dinâmicas. Em um estático página, o conteúdo está contido na página e muda apenas quando uma nova versão da página é publicada. A empresa pode atualizar a página diariamente ou semanalmente como parte de seu processo de criação da web. Para este tipo de página, é possível pré-gerar os arquivos de áudio em tempo de compilação e colocá-los no servidor web para reprodução. Como mostra a figura a seguir, o script PRTP Pre-Gen invoca o Amazon Polly para gerar o áudio. Toma como entrada a própria página HTML e, opcionalmente, um arquivo de configuração que especifica qual texto da página extrair (Text Extract Config). Se a configuração de extração for omitida, o script de pré-geração fará uma escolha sensata de texto para extrair do corpo da página. O Amazon Polly gera os arquivos em um Serviço de armazenamento simples da Amazon (Amazon S3) balde; o script os copia para o seu servidor web. Quando o visitante reproduz o áudio, o navegador baixa o MP3 diretamente do servidor web. Para destaques, uma biblioteca drop-in, PRTP.js, usa o arquivo de marcas para destacar o texto que está sendo lido.

O conteúdo de um dinâmico a página muda em resposta à interação do visitante, portanto, o áudio não pode ser pré-gerado, mas deve ser sintetizado dinamicamente. Como mostra a figura a seguir, quando o visitante reproduz o áudio, a página usa PRTP.js para gerar o áudio no Amazon Polly e destaca o áudio sintetizado usando a mesma abordagem das páginas estáticas. Para acessar os serviços da AWS a partir do navegador, o visitante precisa de uma identidade da AWS. Mostramos como usar um Amazon Cognito grupo de identidades para permitir que o visitante tenha acesso suficiente ao Amazon Polly e ao bucket do S3 para renderizar o áudio.

Conteúdo Dinâmico

A geração de áudio Mp3 e marcas de fala requer que o serviço Polly sintetize a mesma entrada duas vezes. Consulte o Página de preços do Amazon Polly para entender as implicações de custo. A pré-geração economiza custos porque a síntese é realizada no momento da construção e não sob demanda para cada interação do visitante.

O código que acompanha este post está disponível como um repositório de código aberto em GitHub.

Para explorar a solução, seguimos os seguintes passos:

  1. Configure os recursos, incluindo o servidor de compilação pré-geração, bucket do S3, servidor web e identidade do Amazon Cognito.
  2. Execute a compilação estática de pré-geração e teste as páginas estáticas.
  3. Teste páginas dinâmicas.

Pré-requisitos

Para executar este exemplo, você precisa de um Conta da AWS com permissão para usar Amazon Polly, Amazon S3, Amazon Cognito e (para fins de demonstração) Nuvem AWS9.

Recursos de provisionamento

Nós compartilhamos um Formação da Nuvem AWS template para criar em sua conta um ambiente de demonstração independente para ajudá-lo a acompanhar a postagem. Se você preferir configurar o PRTP em seu próprio ambiente, consulte as instruções em README.md.

Para provisionar o ambiente de demonstração usando o CloudFormation, primeiro baixe uma cópia do Modelo CloudFormation. Em seguida, conclua as seguintes etapas:

  1. No console do AWS CloudFormation, escolha Crie uma pilha.
  2. Escolha Com novos recursos (padrão).
  3. Selecionar Carregue um arquivo de modelo.
  4. Escolha Escolha o arquivo para carregar a cópia local do modelo que você baixou. O nome do arquivo é prtp.yml.
  5. Escolha Próximo.
  6. Insira um nome de pilha de sua escolha. Mais tarde, você entra novamente como um substituto para .
  7. Você pode manter os valores padrão no parâmetros seção.
  8. Escolha Próximo.
  9. Continue pelas seções restantes.
  10. Leia e marque as caixas de seleção na Empresa seção.
  11. Escolha Criar pilha.
  12. Quando a pilha estiver completa, encontre o valor de BucketName nas saídas da pilha.

Recomendamos que você revise a pilha com sua equipe de segurança antes de usá-la em um ambiente de produção.

Configure o servidor web e o servidor de pré-geração em um AWS Cloud9 IDE

Em seguida, no console do AWS Cloud9, localize o ambiente PRTPDemoCloud9 criado pela pilha do CloudFormation. Escolher Abrir IDE para abrir o ambiente AWS Cloud9. Abra uma janela de terminal e execute os seguintes comandos, que clonam o código PRTP, configuram dependências de pré-geração e iniciam um servidor web para testar:

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

Escolha , use o nome que você deu à pilha do CloudFormation. Por , especifique um intervalo de endereços IP com permissão para acessar o servidor web. Para restringir o acesso ao navegador em sua máquina local, encontre seu endereço IP usando https://whatismyipaddress.com/ e anexar /32 para especificar o intervalo. Por exemplo, se o seu IP for 10.2.3.4, use 10.2.3.4/32. O servidor atende na porta 8080. O endereço IP público no qual o servidor atende é fornecido na saída. Por exemplo:

Public IP is

3.92.33.223

Testar páginas estáticas

No seu navegador, navegue até PRTPStaticDefault.html. (Se você estiver usando a demonstração, o URL é http://<cloud9host>:8080/web/PRTPStaticDefault.html, Onde é o endereço IP público que você descobriu ao configurar o IDE.) Escolha Jogar no controle de áudio na parte superior. Ouça o áudio e assista aos destaques. Explore o controle alterando as velocidades, alterando as vozes, pausando, avançando e retrocedendo. A captura de tela a seguir mostra a página; o texto “Ignora parágrafo oculto” é destacado porque está sendo lido no momento.

Leia páginas da Web e destaque o conteúdo usando o Amazon Polly PlatoBlockchain Data Intelligence. Pesquisa Vertical. Ai.

Tente o mesmo para PRTPStaticConfig.html e PRTPStaticCustom.html. Os resultados são semelhantes. Por exemplo, todos os três lêem o texto alternativo da foto do gato (“Imagem aleatória de um gato”). Todos os três leem NE, NW, SE e SW como palavras completas (“nordeste”, “noroeste”, “sudeste”, “sudoeste”), aproveitando os léxicos do Amazon Polly.

Observe as principais diferenças no áudio:

  • PRTPStaticDefault.html lê todo o texto no corpo da página, incluindo a parte de encerramento na parte inferior com "Suas ideias em uma palavra", "Enviar consulta", "Última atualização em 1º de abril de 2020" e "Perguntas para a equipe de desenvolvimento". PRTPStaticConfig.html e PRTPStaticCustom.html não os leia porque excluem explicitamente o wrapup da síntese de fala.
  • PRTPStaticCustom.html lê o Os mais vendidos de QB mesa diferente das demais. Ele lê apenas as três primeiras linhas e lê o número da linha para cada linha. Ele repete as colunas para cada linha. PRTPStaticCustom.html usa uma transformação personalizada para personalizar a leitura da tabela. As outras páginas usam renderização de tabela padrão.
  • PRTPStaticCustom.html lê “Tom Brady” em um volume mais alto do que o resto do texto. Ele usa a linguagem de marcação de síntese de fala (SSML) prosody tag para adequar a leitura de Tom Brady. As outras páginas não se adaptam dessa maneira.
  • PRTPStaticCustom.html, graças a uma transformação personalizada, lê as telhas principais na ordem NW, SW, NE, SE; ou seja, lê-se “Artigos de hoje”, “Frase do dia”, “Foto do dia”, “Piadas do dia”. As outras páginas são lidas na ordem em que os ladrilhos aparecem na ordem natural NW, NE, SW, SE em que aparecem no HTML: “Artigos de hoje”, “Foto do dia”, “Frase do dia”, “Piadas do Dia."

Vamos nos aprofundar em como o áudio é gerado e como a página destaca o texto.

Pré-gerador estático

Nosso repositório GitHub inclui arquivos de áudio pré-gerados para o PRPTStatic páginas, mas se quiser gerá-las você mesmo, a partir do shell bash no AWS Cloud9 IDE, execute os seguintes comandos:

# 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

Agora vamos ver como esses scripts funcionam.

Caso padrão

Começamos com 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

O script começa executando o programa Python FixHTML.py para fazer o arquivo HTML de origem PRTPStaticDefault.html bem formado. Ele grava a versão bem formada do arquivo para example/tmp_wff.html. Esta etapa é crucial por dois motivos:

  • A maior parte do HTML de origem não é bem formado. Esta etapa repara o HTML de origem para ser bem formado. Por exemplo, muitas páginas HTML não fecham P elementos. Esta etapa os fecha.
  • Mantemos o controle de onde na página HTML encontramos o texto. Precisamos rastrear locais usando a mesma estrutura do modelo de objeto de documento (DOM) que o navegador usa. Por exemplo, o navegador adiciona automaticamente um TBODY para uma TABLE. O programa Python segue os mesmos reparos bem formados do navegador.

gen_ssml.sh recebe o HTML bem formado como entrada, aplica uma transformação de folha de estilo XML (XSLT) a ele e gera um arquivo SSML. (SSML é o idioma no Amazon Polly para controlar como o áudio é renderizado a partir do texto.) No exemplo atual, a entrada é example/tmp_wff.html. A saída é example/tmp.ssml. O trabalho da transformação é decidir qual texto extrair do HTML e alimentar o Amazon Polly. generic.xslt é uma transformação XSLT padrão sensata para a maioria das páginas da web. No snippet de código de exemplo a seguir, ele exclui o controle de áudio, o cabeçalho HTML, bem como elementos HTML como script e form. Também exclui elementos com o atributo oculto. Inclui elementos que normalmente contêm texto, como P, H1 e SPAN. Para estes, ele renderiza uma marca, incluindo a expressão XPath completa do elemento, e o valor do elemento.

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

Veja a seguir um trecho do SSML que é renderizado. Isso é alimentado como entrada para o Amazon Polly. Observe, por exemplo, que o texto “Pula parágrafo oculto” deve ser lido no áudio, e o associamos a uma marca, que nos informa que esse texto ocorre no local da página fornecido pela expressão 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>

Para gerar áudio no Amazon Polly, chamamos o script run_polly.sh. Ele executa o Interface de linha de comando da AWS Comando (AWS CLI) aws polly start-speech-synthesis-task duas vezes: uma para gerar o áudio MP3 e novamente para gerar o arquivo de marcas. Como a geração é assíncrona, o script pesquisa até encontrar a saída no bucket do S3 especificado. Quando encontra a saída, ele baixa para o servidor de compilação e copia os arquivos para o web/polly pasta. A seguir está uma lista das pastas da web:

  • 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

Cada página tem seu próprio conjunto de arquivos MP3 específicos de voz e marcas. Esses arquivos são os arquivos pré-gerados. A página não precisa invocar o Amazon Polly em tempo de execução; os arquivos fazem parte da compilação da web.

Caso orientado a configuração

Em seguida, considere 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

O script é semelhante ao script no caso padrão, mas as linhas em negrito indicam a principal diferença. Nossa abordagem é orientada por configuração. Personalizamos o conteúdo a ser extraído da página especificando o que extrair por meio da configuração, não do código. Em particular, usamos o arquivo JSON transform_config.json, que especifica que o conteúdo a ser incluído são os elementos com IDs title, main, maintable e qbtable. O elemento com ID wrapup deve ser excluído. Veja o seguinte código:

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

Executamos o programa Python ModGenericXSLT.py para modificar generic.xslt, usado no caso padrão, para usar as inclusões e exclusões que especificamos em transform_config.json. O programa grava os resultados em um arquivo temporário (example/tmp.xslt), para o qual passa gen_ssml.sh como sua transformação XSLT.

Esta é uma opção de baixo código. O editor da web não precisa saber escrever XSLT. Mas eles precisam entender a estrutura da página HTML e os IDs usados ​​em seus principais elementos de organização.

Caso de personalização

Finalmente, considere 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

Este script é quase idêntico ao script padrão, exceto que usa seu próprio XSLT—example/custom.xslt— em vez do XSLT genérico. O seguinte é um trecho do 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>

Se você quiser estudar o código em detalhes, consulte os scripts e programas no repositório do GitHub.

Configuração e destaques do navegador

As páginas estáticas incluem um controle de áudio HTML5, que toma como fonte de áudio o arquivo MP3 gerado pelo Amazon Polly e que reside no servidor web:

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

No momento do carregamento, a página também carrega o arquivo de marcas gerado pelo Amazon Polly. Isso ocorre no PRTP.js arquivo, que a página HTML inclui. A seguir está um trecho do arquivo de marcas para 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”}

Durante a reprodução de áudio, há um manipulador de eventos de timer de áudio em PRTP.js que verifica a hora atual do áudio, localiza o texto a ser destacado, localiza sua localização na página e o destaca. O texto a ser destacado é uma entrada do tipo sentence no arquivo de marcas. A localização é a expressão XPath no atributo name da entrada do tipo SSML que precede a sentença. Por exemplo, se a hora for 18400, de acordo com o arquivo de marcas, a frase a ser destacada será “Skips hidden parameter”, que começa em 18334. A localização é a entrada SSML na hora 17667: /html/body[1]/div[2]/ul[1]/li[1].

Testar páginas dinâmicas

A página PRTPDynamic.html demonstra a leitura dinâmica de áudio usando abordagens de extração de áudio padrão, orientadas por configuração e personalizadas.

Caso padrão

No seu navegador, navegue até PRTPDynamic.html. A página tem um parâmetro de consulta, dynOption, que aceita valores default, config e custom. O padrão é default, então você pode omiti-lo neste caso. A página tem duas seções com conteúdo dinâmico:

  • Artigos Mais Recentes - Muda com frequência ao longo do dia
  • Filósofos gregos pesquisam por data – Permite ao visitante pesquisar filósofos gregos por data e mostra os resultados em uma tabela

Leia páginas da Web e destaque o conteúdo usando o Amazon Polly PlatoBlockchain Data Intelligence. Pesquisa Vertical. Ai.

Crie algum conteúdo no Filósofo grego seção inserindo um intervalo de datas de -800 a 0, conforme mostrado no exemplo. Então escolha Encontre.

Agora reproduza o áudio escolhendo Jogar no controle de áudio.

Nos bastidores, a página executa o seguinte código para renderizar e reproduzir o áudio:

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

Primeiro ele chama a função buildSSMLFromDefault in PRTP.js para extrair a maior parte do texto do corpo da página HTML. Essa função percorre a árvore DOM, procurando texto em elementos comuns, como p, h1, pre, span e td. Ele ignora o texto em elementos que geralmente não contêm texto para ser lido em voz alta, como audio, option e script. Ele cria a marcação SSML para ser inserida no Amazon Polly. Veja a seguir um trecho mostrando a extração da primeira linha do philosopher tabela:

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

A chooseRenderAudio funcionam em PRTP.js começa inicializando o AWS SDK para Amazon Cognito, Amazon S3 e Amazon Polly. Essa inicialização ocorre apenas uma vez. Se chooseRenderAudio é invocado novamente porque o conteúdo da página foi alterado, a inicialização é ignorada. Veja o seguinte código:

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

Ele gera áudio MP3 do Amazon Polly. A geração é síncrona para entradas SSML pequenas e assíncrona (com saída enviada para o bucket do S3) para entradas SSML grandes (mais de 6,000 caracteres). No caso síncrono, solicitamos ao Amazon Polly que forneça o arquivo MP3 usando um URL pré-assinado. Quando a saída sintetizada estiver pronta, definimos o src atributo do controle de áudio para esse URL e carregue o controle. Em seguida, solicitamos o arquivo de marcas e o carregamos da mesma maneira que no caso estático. Veja o seguinte código:

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

Caso orientado a configuração

No seu navegador, navegue até PRTPDynamic.html?dynOption=config. Reproduza o áudio. A reprodução de áudio é semelhante ao caso padrão, mas há pequenas diferenças. Em particular, alguns conteúdos são ignorados.

Nos bastidores, ao usar o config opção, a página extrai o conteúdo de forma diferente do caso padrão. No caso padrão, a página usa buildSSMLFromDefault. No caso orientado por configuração, a página especifica as seções que deseja incluir e excluir:

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

A buildSSMLFromConfig função, definida em PRTP.js, percorre a árvore DOM em cada uma das seções cujo ID é fornecido em inclusions. Ele extrai o conteúdo de cada um e os combina, na ordem especificada, para formar um documento SSML. Exclui as seções especificadas em exclusions. Extrai o conteúdo de cada seção da mesma maneira buildSSMLFromDefault extrai o conteúdo do corpo da página.

Caso de personalização

No seu navegador, navegue até PRTPDynamic.html?dynOption=custom. Reproduza o áudio. Existem três diferenças notáveis. Vamos observar isso e considerar o código personalizado que é executado nos bastidores:

  • Ele lê as telhas principais na ordem NW, SW, NE, SE. O código personalizado obtém cada um desses blocos de células de maintable e os adiciona ao SSML na ordem 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” é falado em voz alta. O código personalizado coloca o texto “Tom Brady” dentro de um SSML prosody etiqueta, rótulo, palavra-chave:
if (cellText == "Tom Brady") {
   addSSMLMark(getXpathOfNode( node.childNodes[tdi]));
   startSSMLParagraph();
   startSSMLTag("prosody", {"volume": "x-loud"});
   addSSMLText(cellText);
   endSSMLTag();
   endSSMLParagraph();
}

  • Ele lê apenas as três primeiras linhas da tabela de quarterbacks. Ele lê os cabeçalhos de coluna para cada linha. Verifique o código no repositório do GitHub para descobrir como isso é implementado.

limpar

Para evitar cobranças futuras, exclua a pilha do CloudFormation.

Conclusão

Neste post, demonstramos uma solução técnica para um problema de negócios de alto valor: como usar o Amazon Polly para ler o conteúdo de uma página da Web e destacar o conteúdo à medida que está sendo lido. Mostramos isso usando páginas estáticas e dinâmicas. Para extrair o conteúdo da página, usamos DOM traversal e XSLT. Para facilitar o destaque, usamos o recurso de marcas de fala no Amazon Polly.

Saiba mais sobre o Amazon Polly visitando seu página de serviço.

Fique a vontade para fazer perguntas nos comentários.


Sobre os autores

Leia páginas da Web e destaque o conteúdo usando o Amazon Polly PlatoBlockchain Data Intelligence. Pesquisa Vertical. Ai.Mike Havey é um arquiteto de soluções da AWS com mais de 25 anos de experiência na criação de aplicativos corporativos. Mike é autor de dois livros e vários artigos. Visite sua Amazônia página do autor para ler mais.

Leia páginas da Web e destaque o conteúdo usando o Amazon Polly PlatoBlockchain Data Intelligence. Pesquisa Vertical. Ai.Vinet Kachhawaha é Arquiteto de Soluções na AWS com experiência em aprendizado de máquina. Ele é responsável por ajudar os clientes a arquitetar cargas de trabalho escaláveis, seguras e econômicas na AWS.

Carimbo de hora:

Mais de Aprendizado de máquina da AWS