Como usar a sintetização em lote para um avatar da conversão de texto em fala

A API de sintetização em lote para avatar de conversão de texto em fala permite a sintetização assíncrona de texto em um avatar falante como um arquivo de vídeo. Editores e plataformas de conteúdo de vídeo podem utilizar essa API para criar conteúdo de vídeo com avatar em um lote. Essa abordagem pode ser adequada para vários casos de uso, como materiais de treinamento, apresentações ou anúncios.

O vídeo de avatar sintético será gerado quase em tempo real depois que o sistema receber a entrada de texto. A saída de vídeo gerada pode ser baixada na síntese do modo de lote. Você envia texto a ser sintetizado, sonda o status da síntese e baixa a saída de áudio quando o status indica êxito. Os formatos de entrada de texto precisam ser texto sem formatação ou texto SSML (Linguagem de Marcação de Síntese de Fala).

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

Captura de tela da exibição de uma visão geral de alto nível do fluxo de trabalho de síntese em lote.

Você pode usar as operações de API REST a seguir para síntese em lote.

Operação Método Chamada da API REST
Criar síntese em lote PUT avatar/batchsyntheses/{SynthesisId}?api-version=2024-08-01
Obter síntese em lote GET avatar/batchsyntheses/{SynthesisId}?api-version=2024-08-01
Listar síntese em lote GET avatar/batchsyntheses/?api-version=2024-08-01
Excluir síntese em lote DELETE avatar/batchsyntheses/{SynthesisId}?api-version=2024-08-01

Você pode consultar os exemplo de código no GitHub.

Criar uma solicitação de síntese em lote

Algumas propriedades em formato JSON são necessárias quando você cria um novo trabalho de síntese em lote. Outras propriedades são opcionais. A resposta de síntese em lote inclui outras propriedades para fornecer informações sobre o status e os resultados da síntese. Por exemplo, a propriedade outputs.result contém o local de onde você pode baixar um arquivo de vídeo que contém o vídeo de avatar. A partir de outputs.summary, você pode acessar o resumo e os detalhes de depuração.

Para enviar uma solicitação de síntese em lotes, construa o corpo da solicitação HTTP POST seguindo estas instruções:

  • Defina a propriedade inputKind obrigatória.
  • Se a propriedade inputKind estiver definida como PlainText, você também precisará definir a propriedade voice no synthesisConfig. No exemplo abaixo, o inputKind está definido como SSML, portanto, o speechSynthesis não está definido.
  • Defina a propriedade SynthesisId obrigatória. Escolha uma SynthesisId exclusiva para o mesmo recurso de fala. A SynthesisId pode ser uma cadeia de caracteres de 3 a 64 caracteres, incluindo letras, números, “-” ou “_”, com a condição de que ela precisa começar e terminar com uma letra ou um número.
  • Defina as propriedades obrigatórias talkingAvatarCharacter e talkingAvatarStyle. Os caracteres e estilos de avatar com suporte podem ser encontrados aqui.
  • Opcionalmente, você pode definir as propriedades videoFormat, backgroundColor e outras. Para obter mais informações, confira as propriedades de síntese em lotes.

Observação

O tamanho máximo de conteúdo JSON aceito é de 500 quilobytes.

Cada recurso de Fala pode ter até 200 trabalhos de síntese em lotes executados simultaneamente.

O comprimento máximo do vídeo de saída atualmente é de 20 minutos, com possíveis aumentos no futuro.

Para fazer uma solicitação HTTP PUT, use o formato de URI mostrado no exemplo a seguir. Substitua YourSpeechKey pela chave de recurso de Fala, YourSpeechRegion pela região do recurso de Fala e defina as propriedades do corpo da solicitação, conforme descrito acima.

curl -v -X PUT -H "Ocp-Apim-Subscription-Key: YourSpeechKey" -H "Content-Type: application/json" -d '{
    "inputKind": "SSML",
    "inputs": [
        {
         "content": "<speak version='\''1.0'\'' xml:lang='\''en-US'\''><voice name='\''en-US-AvaMultilingualNeural'\''>The rainbow has seven colors.</voice></speak>"
        }
    ],
    "avatarConfig": {
        "talkingAvatarCharacter": "lisa",
        "talkingAvatarStyle": "graceful-sitting"
    }
}'  "https://YourSpeechRegion.api.cognitive.microsoft.com/avatar/batchsyntheses/my-job-01?api-version=2024-08-01"

Você deve receber um corpo de resposta no seguinte formato:

{
    "id": "my-job-01",
    "internalId": "5a25b929-1358-4e81-a036-33000e788c46",
    "status": "NotStarted",
    "createdDateTime": "2024-03-06T07:34:08.9487009Z",
    "lastActionDateTime": "2024-03-06T07:34:08.9487012Z",
    "inputKind": "SSML",
    "customVoices": {},
    "properties": {
        "timeToLiveInHours": 744,
    },
    "avatarConfig": {
        "talkingAvatarCharacter": "lisa",
        "talkingAvatarStyle": "graceful-sitting",
        "videoFormat": "Mp4",
        "videoCodec": "hevc",
        "subtitleType": "soft_embedded",
        "bitrateKbps": 2000,
        "customized": false
    }
}

A propriedade status deve mudar do status NotStarted para Running e, por fim, 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 lotes

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 YourSynthesisId por sua ID de síntese em lotes, YourSpeechKey pela sua chave de recurso de Fala e YourSpeechRegion pela sua região de recurso de Fala.

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

Você deve receber um corpo de resposta no seguinte formato:

{
    "id": "my-job-01",
    "internalId": "5a25b929-1358-4e81-a036-33000e788c46",
    "status": "Succeeded",
    "createdDateTime": "2024-03-06T07:34:08.9487009Z",
    "lastActionDateTime": "2024-03-06T07:34:12.5698769",
    "inputKind": "SSML",
    "customVoices": {},
    "properties": {
        "timeToLiveInHours": 744,
        "sizeInBytes": 344460,
        "durationInMilliseconds": 2520,
        "succeededCount": 1,
        "failedCount": 0,
        "billingDetails": {
            "neuralCharacters": 29,
            "talkingAvatarDurationSeconds": 2
        }
    },
    "avatarConfig": {
        "talkingAvatarCharacter": "lisa",
        "talkingAvatarStyle": "graceful-sitting",
        "videoFormat": "Mp4",
        "videoCodec": "hevc",
        "subtitleType": "soft_embedded",
        "bitrateKbps": 2000,
        "customized": false
    },
    "outputs": {
        "result": "https://stttssvcprodusw2.blob.core.windows.net/batchsynthesis-output/xxxxx/xxxxx/0001.mp4?SAS_Token",
        "summary": "https://stttssvcprodusw2.blob.core.windows.net/batchsynthesis-output/xxxxx/xxxxx/summary.json?SAS_Token"
    }
}

No campo outputs.result, você pode baixar um arquivo de vídeo que contém o vídeo do avatar. O campo outputs.summary permite baixar o resumo e os detalhes de depuração. Para obter mais informações sobre resultados de síntese em lote, confira resultados da síntese em lote.

Listar síntese em lotes

Para listar todos os trabalhos de síntese em lote para o recurso de Fala, faça uma solicitação HTTP GET usando o URI, conforme mostrado no exemplo a seguir.

Substitua YourSpeechKey pela sua chave do recurso de Fala e YourSpeechRegion pela sua região do recurso de Fala. Opcionalmente, você pode definir os parâmetros de consulta skip e top (tamanho da página) na URL. O valor padrão de skip é 0 e o valor padrão de maxpagesize é 100.

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

Você receberá um corpo de resposta no seguinte formato:

{
    "value": [
        {
            "id": "my-job-02",
            "internalId": "14c25fcf-3cb6-4f46-8810-ecad06d956df",
            "status": "Succeeded",
            "createdDateTime": "2024-03-06T07:52:23.9054709Z",
            "lastActionDateTime": "2024-03-06T07:52:29.3416944",
            "inputKind": "SSML",
            "customVoices": {},
            "properties": {
                "timeToLiveInHours": 744,
                "sizeInBytes": 502676,
                "durationInMilliseconds": 2950,
                "succeededCount": 1,
                "failedCount": 0,
                "billingDetails": {
                    "neuralCharacters": 32,
                    "talkingAvatarDurationSeconds": 2
                }
            },
            "avatarConfig": {
                "talkingAvatarCharacter": "lisa",
                "talkingAvatarStyle": "casual-sitting",
                "videoFormat": "Mp4",
                "videoCodec": "h264",
                "subtitleType": "soft_embedded",
                "bitrateKbps": 2000,
                "customized": false
            },
            "outputs": {
                "result": "https://stttssvcprodusw2.blob.core.windows.net/batchsynthesis-output/xxxxx/xxxxx/0001.mp4?SAS_Token",
                "summary": "https://stttssvcprodusw2.blob.core.windows.net/batchsynthesis-output/xxxxx/xxxxx/summary.json?SAS_Token"
            }
        },
        {
            "id": "my-job-01",
            "internalId": "5a25b929-1358-4e81-a036-33000e788c46",
            "status": "Succeeded",
            "createdDateTime": "2024-03-06T07:34:08.9487009Z",
            "lastActionDateTime": "2024-03-06T07:34:12.5698769",
            "inputKind": "SSML",
            "customVoices": {},
            "properties": {
                "timeToLiveInHours": 744,
                "sizeInBytes": 344460,
                "durationInMilliseconds": 2520,
                "succeededCount": 1,
                "failedCount": 0,
                "billingDetails": {
                    "neuralCharacters": 29,
                    "talkingAvatarDurationSeconds": 2
                }
            },
            "avatarConfig": {
                "talkingAvatarCharacter": "lisa",
                "talkingAvatarStyle": "graceful-sitting",
                "videoFormat": "Mp4",
                "videoCodec": "hevc",
                "subtitleType": "soft_embedded",
                "bitrateKbps": 2000,
                "customized": false
            },
            "outputs": {
                "result": "https://stttssvcprodusw2.blob.core.windows.net/batchsynthesis-output/xxxxx/xxxxx/0001.mp4?SAS_Token",
                "summary": "https://stttssvcprodusw2.blob.core.windows.net/batchsynthesis-output/xxxxx/xxxxx/summary.json?SAS_Token"
            }
        }
    ],
    "nextLink": "https://YourSpeechRegion.api.cognitive.microsoft.com/avatar/batchsyntheses/?api-version=2024-08-01&skip=2&maxpagesize=2"
}

Em outputs.result, você pode baixar um arquivo de vídeo que contém o vídeo do avatar. A partir de outputs.summary, você pode acessar o resumo e os detalhes de depuração. Para obter mais informações, confira os resultados da síntese em lotes.

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

Obter o arquivo de resultados da síntese em lote

Depois de obter um trabalho de síntese em lote com status igual a "Êxito", você poderá baixar os resultados de saída de vídeo. Use a URL da propriedade outputs.result da resposta obter síntese em lotes.

Para obter o status do trabalho de síntese em lotes, faça uma solicitação HTTP GET usando o URI, conforme mostrado no exemplo a seguir. Substitua YourOutputsResultUrl pela URL da propriedade outputs.result da resposta obter síntese em lotes. Substitua YourSpeechKey pela chave do recurso de Fala.

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

Para obter o arquivo de resumo 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 propriedade outputs.summary da resposta obter síntese em lotes. Substitua YourSpeechKey pela chave do recurso de Fala.

curl -v -X GET "YourOutputsSummaryUrl" -H "Ocp-Apim-Subscription-Key: YourSpeechKey" > summary.json

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

{
  "jobID": "5a25b929-1358-4e81-a036-33000e788c46",
  "status": "Succeeded",
  "results": [
    {
      "texts": [
        "<speak version='1.0' xml:lang='en-US'><voice name='en-US-AvaMultilingualNeural'>The rainbow has seven colors.</voice></speak>"
      ],
      "status": "Succeeded",
      "videoFileName": "244a87c294b94ddeb3dbaccee8ffa7eb/5a25b929-1358-4e81-a036-33000e788c46/0001.mp4",
      "TalkingAvatarCharacter": "lisa",
      "TalkingAvatarStyle": "graceful-sitting"
    }
  ]
}

Excluir síntese em lotes

Depois que você recuperar os resultados da saída de áudio e não precisar mais do histórico de trabalhos de síntese em lote, você poderá excluí-lo. O serviço de Fala mantém cada histórico de síntese por até 31 dias ou a duração especificada pela propriedade de solicitação timeToLiveInHours, o que ocorrer mais cedo. A data e a hora da exclusão automática para trabalhos de síntese com um status de "Êxito" ou "Falha" é calculada como a soma das propriedades lastActionDateTime e timeToLive.

Para excluir um trabalho de síntese em lotes, faça uma solicitação HTTP DELETE usando o formato de URI a seguir. Substitua YourSynthesisId por sua ID de síntese em lotes, YourSpeechKey pela sua chave de recurso de Fala e YourSpeechRegion pela sua região de recurso de Fala.

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

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

Próximas etapas