API de síntese em lote para conversão de texto em fala

A API de síntese em lote pode sintetizar um grande volume de entrada de texto (longo e curto) de forma assíncrona. Editores e plataformas de conteúdo de áudio podem criar conteúdo de áudio longo em um lote. Por exemplo: audiolivros, artigos de notícias e documentos. A API de síntese em lote pode criar áudio sintetizado por mais de 10 minutos.

Importante

A API de síntese em lote está geralmente disponível. A API Long Audio será desativada em 1º de abril de 2027. Para obter mais informações, consulte Migrar para API de síntese em lote.

A API de síntese em lote é assíncrona e não retorna áudio sintetizado em tempo real. Você envia arquivos de texto para serem sintetizados, pesquisa o status e baixa a saída de áudio quando o status indica sucesso. As entradas de texto devem ser texto simples ou texto SSML (Speech Synthesis Markup Language).

Este diagrama fornece uma visão geral de alto nível do fluxo de trabalho.

Diagrama do fluxo de trabalho da API de síntese em lote.

Gorjeta

Você também pode usar o SDK de fala para criar áudio sintetizado por mais de 10 minutos, iterando sobre o texto e sintetizando-o em partes. Para obter um exemplo em C#, consulte GitHub.

Você pode usar as seguintes operações de API REST para síntese em lote:

Operação Método Chamada à API REST
Criar síntese em lote PUT texttospeech/batchsyntheses/YourSynthesisId
Obter síntese em lote GET texttospeech/batchsyntheses/YourSynthesisId
Listar síntese de lotes GET texttospeech/batchsyntheses
Excluir síntese em lote DELETE texttospeech/batchsyntheses/YourSynthesisId

Para obter exemplos de código, consulte GitHub.

Criar síntese em lote

Para enviar uma solicitação de síntese em lote, construa o caminho e o corpo da solicitação HTTP PUT de acordo com as seguintes instruções:

  • Defina a propriedade necessária inputKind .
  • Se a inputKind propriedade estiver definida como "PlainText", você também deverá definir a voice propriedade no synthesisConfig. No exemplo abaixo, o inputKind é definido como "SSML", portanto, o synthesisConfig não está definido.
  • Opcionalmente, você pode definir o description, timeToLiveInHourse outras propriedades. Para obter mais informações, consulte Propriedades de síntese em lote.

Nota

O tamanho máximo da carga útil JSON que será aceito é de 2 megabytes.

Defina o necessário YourSynthesisId no caminho. O YourSynthesisId tem que ser único. Deve ter de 3 a 64 anos, conter apenas números, letras, hífenes, sublinhados e pontos, começa e termina com uma letra ou número.

Faça uma solicitação HTTP PUT usando o URI, conforme mostrado no exemplo a seguir. Substitua YourSpeechKey pela chave de recurso Fala, substitua YourSpeechRegion pela região de recurso Fala e defina as propriedades do corpo da solicitação conforme descrito anteriormente.

curl -v -X PUT -H "Ocp-Apim-Subscription-Key: YourSpeechKey" -H "Content-Type: application/json" -d '{
    "description": "my ssml test",
    "inputKind": "SSML",
    "inputs": [
        {
            "content": "<speak version=\"1.0\" xml:lang=\"en-US\"><voice name=\"en-US-JennyNeural\">The rainbow has seven colors.</voice></speak>"
        }
    ],
    "properties": {
        "outputFormat": "riff-24khz-16bit-mono-pcm",
        "wordBoundaryEnabled": false,
        "sentenceBoundaryEnabled": false,
        "concatenateResult": false,
        "decompressOutputFiles": false
    }
}'  "https://YourSpeechRegion.api.cognitive.microsoft.com/texttospeech/batchsyntheses/YourSynthesisId?api-version=2024-04-01"

Deverá receber um corpo de resposta no seguinte formato:

{
  "id": "YourSynthesisId",
  "internalId": "7ab84171-9070-4d3b-88d4-1b8cc1cb928a",
  "status": "NotStarted",
  "createdDateTime": "2024-03-12T07:23:18.0097387Z",
  "lastActionDateTime": "2024-03-12T07:23:18.0097388Z",
  "inputKind": "SSML",
  "customVoices": {},
  "properties": {
    "timeToLiveInHours": 744,
    "outputFormat": "riff-24khz-16bit-mono-pcm",
    "concatenateResult": false,
    "decompressOutputFiles": false,
    "wordBoundaryEnabled": false,
    "sentenceBoundaryEnabled": false
  }
}

A status propriedade deve progredir de NotStarted status, para Running, e finalmente para Succeeded ou Failed. Você pode chamar a API de síntese em lote GET periodicamente até que o status retornado seja Succeeded ou Failed.

Obter síntese em lote

Para obter o status do trabalho de síntese em lote, faça uma solicitação HTTP GET usando o URI, conforme mostrado no exemplo a seguir. Substitua YourSpeechKey pela chave de recurso Fala e substitua YourSpeechRegion pela região de recurso Fala.

curl -v -X GET "https://YourSpeechRegion.api.cognitive.microsoft.com/texttospeech/batchsyntheses/YourSynthesisId?api-version=2024-04-01" -H "Ocp-Apim-Subscription-Key: YourSpeechKey"

Deverá receber um corpo de resposta no seguinte formato:

{
  "id": "YourSynthesisId",
  "internalId": "7ab84171-9070-4d3b-88d4-1b8cc1cb928a",
  "status": "Succeeded",
  "createdDateTime": "2024-03-12T07:23:18.0097387Z",
  "lastActionDateTime": "2024-03-12T07:23:18.7979669",
  "inputKind": "SSML",
  "customVoices": {},
  "properties": {
    "timeToLiveInHours": 744,
    "outputFormat": "riff-24khz-16bit-mono-pcm",
    "concatenateResult": false,
    "decompressOutputFiles": false,
    "wordBoundaryEnabled": false,
    "sentenceBoundaryEnabled": false,
    "sizeInBytes": 120000,
    "succeededAudioCount": 1,
    "failedAudioCount": 0,
    "durationInMilliseconds": 2500,
    "billingDetails": {
      "neuralCharacters": 29
    }
  },
  "outputs": {
    "result": "https://stttssvcuse.blob.core.windows.net/batchsynthesis-output/29f2105f997c4bfea176d39d05ff201e/YourSynthesisId/results.zip?SAS_Token"
  }
}

A partir do outputs.result, você pode baixar um arquivo ZIP que contém o áudio (como 0001.wav), resumo e detalhes de depuração. Para obter mais informações, consulte os resultados da síntese em lote.

Listar síntese de lotes

Para listar todos os trabalhos de síntese em lote para o recurso Speech, faça uma solicitação HTTP GET usando o URI, conforme mostrado no exemplo a seguir. Substitua YourSpeechKey pela chave de recurso de Fala e substitua YourSpeechRegion pela região de recurso de Fala. Opcionalmente, você pode definir os skip parâmetros de consulta e maxpagesize (até 100) na URL. O valor padrão para skip é 0 e o valor padrão para maxpagesize é 100.

curl -v -X GET "https://YourSpeechRegion.api.cognitive.microsoft.com/texttospeech/batchsyntheses?api-version=2024-04-01&skip=1&maxpagesize=2" -H "Ocp-Apim-Subscription-Key: YourSpeechKey"

Deverá receber um corpo de resposta no seguinte formato:

{
  "value": [
    {
      "id": "my-job-03",
      "internalId": "5f7e9ab6-2c92-4dcb-b5ee-ec0983ee4db0",
      "status": "Succeeded",
      "createdDateTime": "2024-03-12T07:28:32.5690441Z",
      "lastActionDateTime": "2024-03-12T07:28:33.0042293",
      "inputKind": "SSML",
      "customVoices": {},
      "properties": {
        "timeToLiveInHours": 744,
        "outputFormat": "riff-24khz-16bit-mono-pcm",
        "concatenateResult": false,
        "decompressOutputFiles": false,
        "wordBoundaryEnabled": false,
        "sentenceBoundaryEnabled": false,
        "sizeInBytes": 120000,
        "succeededAudioCount": 1,
        "failedAudioCount": 0,
        "durationInMilliseconds": 2500,
        "billingDetails": {
          "neuralCharacters": 29
        }
      },
      "outputs": {
        "result": "https://stttssvcuse.blob.core.windows.net/batchsynthesis-output/29f2105f997c4bfea176d39d05ff201e/my-job-03/results.zip?SAS_Token"
      }
    },
    {
      "id": "my-job-02",
      "internalId": "5577585f-4710-4d4f-aab6-162d14bd7ee0",
      "status": "Succeeded",
      "createdDateTime": "2024-03-12T07:28:29.6418211Z",
      "lastActionDateTime": "2024-03-12T07:28:30.0910306",
      "inputKind": "SSML",
      "customVoices": {},
      "properties": {
        "timeToLiveInHours": 744,
        "outputFormat": "riff-24khz-16bit-mono-pcm",
        "concatenateResult": false,
        "decompressOutputFiles": false,
        "wordBoundaryEnabled": false,
        "sentenceBoundaryEnabled": false,
        "sizeInBytes": 120000,
        "succeededAudioCount": 1,
        "failedAudioCount": 0,
        "durationInMilliseconds": 2500,
        "billingDetails": {
          "neuralCharacters": 29
        }
      },
      "outputs": {
        "result": "https://stttssvcuse.blob.core.windows.net/batchsynthesis-output/29f2105f997c4bfea176d39d05ff201e/my-job-02/results.zip?SAS_Token"
      }
    }
  ],
  "nextLink": "https://YourSpeechRegion.api.cognitive.microsoft.com/texttospeech/batchsyntheses?skip=3&maxpagesize=2&api-version=2024-04-01"
}

A partir do outputs.result, você pode baixar um arquivo ZIP que contém o áudio (como 0001.wav), resumo e detalhes de depuração. Para obter mais informações, consulte os resultados da síntese em lote.

A value propriedade na resposta json lista suas solicitações de síntese. A lista é paginada, com um tamanho máximo de página de 100. A "nextLink" propriedade é fornecida conforme necessário para obter a próxima página da lista paginada.

Excluir síntese em lote

Exclua o histórico de trabalhos de síntese em lote depois de recuperar os resultados da saída de áudio. O serviço de Fala mantém o histórico de síntese em lote por até 31 dias, ou a duração da propriedade de solicitação timeToLiveInHours , o que ocorrer primeiro. A data e a hora da exclusão automática (para trabalhos de síntese com um status de "Aprovado" ou "Reprovado") são iguais às lastActionDateTime + timeToLiveInHours propriedades.

Para excluir um trabalho de síntese em lote, faça uma solicitação HTTP DELETE usando o URI, conforme mostrado no exemplo a seguir. Substitua YourSynthesisId pelo ID de síntese em lote, substitua YourSpeechKey pela chave de recurso de fala e substitua YourSpeechRegion pela região de recurso de fala.

curl -v -X DELETE "https://YourSpeechRegion.api.cognitive.microsoft.com/texttospeech/batchsyntheses/YourSynthesisId?api-version=2024-04-01" -H "Ocp-Apim-Subscription-Key: YourSpeechKey"

Os cabeçalhos de resposta incluem HTTP/1.1 204 No Content se a solicitação de exclusão foi bem-sucedida.

Resultados da síntese em lote

Depois de obter um trabalho de síntese em lote com status "Succeeded", você pode baixar os resultados da saída de áudio. Use a URL da outputs.result propriedade da resposta get batch synthesis .

Para obter o arquivo de resultados de síntese em lote, faça uma solicitação HTTP GET usando o URI, conforme mostrado no exemplo a seguir. Substitua YourOutputsResultUrl pela URL da outputs.result propriedade da resposta get batch synthesis . Substitua YourSpeechKey pela chave de recurso de fala.

curl -v -X GET "YourOutputsResultUrl" -H "Ocp-Apim-Subscription-Key: YourSpeechKey" > results.zip

Os resultados estão em um arquivo ZIP que contém o áudio (como 0001.wav), resumo e detalhes de depuração. O prefixo numerado de cada nome de arquivo (mostrado abaixo como [nnnn]) está na mesma ordem que as entradas de texto usadas quando você criou a síntese em lote.

Nota

O [nnnn].debug.json arquivo contém o ID do resultado da síntese e outras informações que podem ajudar na solução de problemas. As propriedades que ele contém podem mudar, portanto, você não deve tomar nenhuma dependência no formato JSON.

O ficheiro de resumo contém os resultados da síntese para cada entrada de texto. Aqui está um arquivo de exemplo summary.json :

{
  "jobID": "7ab84171-9070-4d3b-88d4-1b8cc1cb928a",
  "status": "Succeeded",
  "results": [
    {
      "contents": [
        "<speak version=\"1.0\" xml:lang=\"en-US\"><voice name=\"en-US-JennyNeural\">The rainbow has seven colors.</voice></speak>"
      ],
      "status": "Succeeded",
      "audioFileName": "0001.wav",
      "properties": {
        "sizeInBytes": "120000",
        "durationInMilliseconds": "2500"
      }
    }
  ]
}

Se os dados do limite da frase foram solicitados ("sentenceBoundaryEnabled": true), então um arquivo correspondente [nnnn].sentence.json é incluído nos resultados. Da mesma forma, se os dados de limite do Word foram solicitados ("wordBoundaryEnabled": true), então um arquivo correspondente [nnnn].word.json é incluído nos resultados.

Aqui está um exemplo de arquivo de dados do Word com deslocamento de áudio e duração em milissegundos:

[
  {
    "Text": "The",
    "AudioOffset": 50,
    "Duration": 137
  },
  {
    "Text": "rainbow",
    "AudioOffset": 200,
    "Duration": 350
  },
  {
    "Text": "has",
    "AudioOffset": 562,
    "Duration": 175
  },
  {
    "Text": "seven",
    "AudioOffset": 750,
    "Duration": 300
  },
  {
    "Text": "colors",
    "AudioOffset": 1062,
    "Duration": 625
  },
  {
    "Text": ".",
    "AudioOffset": 1700,
    "Duration": 100
  }
]

Latência de síntese em lote e práticas recomendadas

Ao usar a síntese em lote para gerar fala sintetizada, é importante considerar a latência envolvida e seguir as melhores práticas para alcançar os melhores resultados.

Latência na síntese em lote

A latência na síntese em lote depende de vários fatores, incluindo a complexidade do texto de entrada, o número de entradas no lote e as capacidades de processamento do hardware subjacente.

A latência para a síntese em lote é a seguinte (aproximadamente):

  • A latência de 50% das saídas de fala sintetizadas está dentro de 10-20 segundos.

  • A latência de 95% das saídas de fala sintetizadas está dentro de 120 segundos.

Melhores práticas

Ao considerar a síntese em lote para seu aplicativo, é recomendável avaliar se a latência atende aos seus requisitos. Se a latência estiver alinhada com o desempenho desejado, a síntese em lote pode ser uma escolha adequada. No entanto, se a latência não atender às suas necessidades, você pode considerar o uso de API em tempo real.

Códigos de estado HTTP

A seção detalha os códigos de resposta HTTP e as mensagens da API de síntese em lote.

HTTP 200 OK

HTTP 200 OK indica que a solicitação foi bem-sucedida.

HTTP 201 criado

HTTP 201 Criado indica que a solicitação de síntese de lote de criação (via HTTP PUT) foi bem-sucedida.

Erro HTTP 204

Um erro HTTP 204 indica que a solicitação foi bem-sucedida, mas o recurso não existe. Por exemplo:

  • Você tentou obter ou excluir um trabalho de síntese que não existe.
  • Você excluiu com êxito um trabalho de síntese.

Erro HTTP 400

Aqui estão exemplos que podem resultar no erro 400:

  • O outputFormat não é suportado ou é inválido. Forneça um valor de formato válido ou deixe outputFormat em branco para usar a configuração padrão.
  • O número de entradas de texto solicitadas excedeu o limite de 10.000.
  • Você tentou usar uma ID de implantação inválida ou uma voz personalizada que não foi implantada com êxito. Verifique se o recurso de fala tem acesso à voz personalizada e se a voz personalizada foi implantada com êxito. Você também deve garantir que o mapeamento de está correto em sua solicitação de síntese de {"your-custom-voice-name": "your-deployment-ID"} lote.
  • Você tentou usar um recurso de Fala F0 , mas a região oferece suporte apenas à camada de preço de recurso de Fala Padrão .
  • Você tentou criar um novo trabalho de síntese em lote que excedesse o limite de 300 trabalhos ativos. Cada recurso de fala pode ter até 300 trabalhos de síntese em lote que não têm um status de "Bem-sucedido" ou "Reprovado".

Erro HTTP 404

A entidade especificada não pode ser encontrada. Confirme se o ID da sintetização está correto.

Erro HTTP 429

Há demasiados pedidos recentes. Cada aplicativo cliente pode enviar até 100 solicitações por 10 segundos para cada recurso de fala. Reduza o número de solicitações por segundo.

Erro HTTP 500

HTTP 500 Internal Server Error indica que a solicitação falhou. O corpo da resposta contém a mensagem de erro.

Exemplo de erro HTTP

Aqui está um exemplo de solicitação que resulta em um erro HTTP 400, porque a inputs propriedade é necessária para criar um trabalho.

curl -v -X PUT -H "Ocp-Apim-Subscription-Key: YourSpeechKey" -H "Content-Type: application/json" -d '{
    "inputKind": "SSML"
}'  "https://YourSpeechRegion.api.cognitive.microsoft.com/texttospeech/batchsyntheses/YourSynthesisId?api-version=2024-04-01"

Nesse caso, os cabeçalhos de resposta incluem HTTP/1.1 400 Bad Request.

O corpo da resposta é semelhante ao seguinte exemplo JSON:

{
  "error": {
    "code": "BadRequest",
    "message": "The inputs is required."
  }
}

Próximos passos