Separar locutores diferentes em uma gravação de áudio

Esta página descreve como conseguir rótulos para diferentes locutores em dados de áudio transcritos pelo Speech-to-Text.

Às vezes, dados de áudio contêm amostras de mais de uma pessoa falando. Por exemplo, o áudio de uma chamada telefônica geralmente tem vozes de duas ou mais pessoas. O ideal é que a transcrição dessa chamada identifique quem fala em quais ocasiões.

Diarização de locutor

O Speech-to-Text pode reconhecer vários locutores no mesmo clipe de áudio. Ao enviar uma solicitação de transcrição de áudio para a Speech-to-Text, é possível incluir um parâmetro para que ela identifique os diferentes locutores na amostra de áudio. Esse recurso, chamado de diarização de locutor, detecta a alternância entre os locutores e rotula por número as vozes individuais identificadas no áudio.

Quando você ativa a diarização de locutor em sua solicitação de transcrição, o Speech-to-Text tenta distinguir as diferentes vozes incluídas na amostra de áudio. O resultado da transcrição rotula cada palavra com um número atribuído a locutores individuais. Palavras ditas pelo mesmo locutor têm o mesmo número. Um resultado da transcrição pode incluir o máximo de locutores que o Speech-to-Text for capaz identificar de forma exclusiva na amostra de áudio.

Quando você usa a diarização de locutor, o Speech-to-Text produz um conjunto de todos os resultados fornecidos na transcrição. Cada resultado inclui as palavras do resultado anterior. Assim, você verá os resultados completos e diarizados da transcrição na matriz words do resultado final.

Revise a página de suporte ao idioma para ver se esse recurso está disponível para seu idioma.

Ativar a diarização de locutor em uma solicitação

Para ativar a diarização de alto-falante, defina o campo diarization_config em RecognitionFeatures. Defina os valores min_speaker_count e max_speaker_count de acordo com quantos falantes você espera na transcrição.

A Speech-to-Text é compatível com a diarização de locutor de todos os métodos de reconhecimento de fala: speech:recognize e Streaming.

Usar um arquivo local

Veja no snippet de código a seguir como ativar a diarização de locutor em uma solicitação de transcrição para a Speech-to-Text usando um arquivo local.

Protocolo

Consulte o endpoint da API speech:recognize para ver todos os detalhes.

Para executar o reconhecimento de fala síncrono, faça uma solicitação POST e forneça o corpo apropriado a ela. Veja a seguir um exemplo de uma solicitação POST usando curl. O exemplo usa a CLI do Google Cloud para gerar um token de acesso. Para instruções sobre como instalar a gcloud CLI, consulte o guia de início rápido.

curl -s -H "Content-Type: application/json" \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    https://speech.googleapis.com/v2/projects/{project}/locations/{location}/recognizers/{recognizer}:recognize \
    --data '{
    "config": {
        "features": {
            "diarizationConfig": {
              "minSpeakerCount": 2,
              "maxSpeakerCount": 2
            },
        }
    },
    "uri": "gs://cloud-samples-tests/speech/commercial_mono.wav"
}' > speaker-diarization.txt

Quando a solicitação é bem-sucedida, o servidor retorna um código de status HTTP 200 OK e a resposta no formato JSON, salvos em um arquivo chamado speaker-diarization.txt.

{
  "results": [
    {
      "alternatives": [
        {
          "transcript": "hi I'd like to buy a Chromecast and I was wondering whether you could help me with that certainly which color would you like we have blue black and red uh let's go with the black one would you like the new Chromecast Ultra model or the regular Chrome Cast regular Chromecast is fine thank you okay sure we like to ship it regular or Express Express please terrific it's on the way thank you thank you very much bye",
          "confidence": 0.92142606,
          "words": [
            {
              "startOffset": "0s",
              "endOffset": "1.100s",
              "word": "hi",
              "speakerLabel": "2"
            },
            {
              "startOffset": "1.100s",
              "endOffset": "2s",
              "word": "I'd",
              "speakerLabel": "2"
            },
            {
              "startOffset": "2s",
              "endOffset": "2s",
              "word": "like",
              "speakerLabel": "2"
            },
            {
              "startOffset": "2s",
              "endOffset": "2.100s",
              "word": "to",
              "speakerLabel": "2"
            },
            ...
            {
              "startOffset": "6.500s",
              "endOffset": "6.900s",
              "word": "certainly",
              "speakerLabel": "1"
            },
            {
              "startOffset": "6.900s",
              "endOffset": "7.300s",
              "word": "which",
              "speakerLabel": "1"
            },
            {
              "startOffset": "7.300s",
              "endOffset": "7.500s",
              "word": "color",
              "speakerLabel": "1"
            },
            ...
          ]
        }
      ],
      "languageCode": "en-us"
    }
  ]
}

Go

Para aprender a instalar e usar a biblioteca de cliente da Speech-to-Text, consulte Bibliotecas de cliente da Speech-to-Text. Para mais informações, consulte a documentação de referência da API Speech-to-Text Go.

Para autenticar no Speech-to-Text, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.


import (
	"context"
	"fmt"
	"io"
	"os"
	"strings"

	speech "cloud.google.com/go/speech/apiv1"
	"cloud.google.com/go/speech/apiv1/speechpb"
)

// transcribe_diarization_gcs_beta Transcribes a remote audio file using speaker diarization.
func transcribe_diarization(w io.Writer, filename string) error {
	// filename := "path-to-an-audio-file"

	ctx := context.Background()
	client, err := speech.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("NewClient: %w", err)
	}
	defer client.Close()

	diarizationConfig := &speechpb.SpeakerDiarizationConfig{
		EnableSpeakerDiarization: true,
		MinSpeakerCount:          2,
		MaxSpeakerCount:          2,
	}

	recognitionConfig := &speechpb.RecognitionConfig{
		Encoding:          speechpb.RecognitionConfig_LINEAR16,
		SampleRateHertz:   8000,
		LanguageCode:      "en-US",
		DiarizationConfig: diarizationConfig,
	}

	// Get the contents of the local audio file
	content, err := os.ReadFile(filename)
	if err != nil {
		return fmt.Errorf("error reading file %v", err)
	}
	audio := &speechpb.RecognitionAudio{
		AudioSource: &speechpb.RecognitionAudio_Content{Content: content},
	}

	longRunningRecognizeRequest := &speechpb.LongRunningRecognizeRequest{
		Config: recognitionConfig,
		Audio:  audio,
	}

	operation, err := client.LongRunningRecognize(ctx, longRunningRecognizeRequest)
	if err != nil {
		return fmt.Errorf("error running recognize %v", err)
	}

	response, err := operation.Wait(ctx)
	if err != nil {
		return err
	}

	// Speaker Tags are only included in the last result object, which has only one
	// alternative.
	alternative := response.Results[len(response.Results)-1].Alternatives[0]

	wordInfo := alternative.GetWords()[0]
	currentSpeakerTag := wordInfo.GetSpeakerTag()

	var speakerWords strings.Builder

	speakerWords.WriteString(fmt.Sprintf("Speaker %d: %s", wordInfo.GetSpeakerTag(), wordInfo.GetWord()))

	// For each word, get all the words associated with one speaker, once the speaker changes,
	// add a new line with the new speaker and their spoken words.
	for i := 1; i < len(alternative.Words); i++ {
		wordInfo := alternative.Words[i]
		if currentSpeakerTag == wordInfo.GetSpeakerTag() {
			speakerWords.WriteString(" ")
			speakerWords.WriteString(wordInfo.GetWord())
		} else {
			speakerWords.WriteString(fmt.Sprintf("\nSpeaker %d: %s",
				wordInfo.GetSpeakerTag(), wordInfo.GetWord()))
			currentSpeakerTag = wordInfo.GetSpeakerTag()
		}
	}
	fmt.Fprintf(w, speakerWords.String())
	return nil
}

Python

Para aprender a instalar e usar a biblioteca de cliente da Speech-to-Text, consulte Bibliotecas de cliente da Speech-to-Text. Para mais informações, consulte a documentação de referência da API Speech-to-Text Python.

Para autenticar no Speech-to-Text, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

from google.cloud import speech_v1p1beta1 as speech

client = speech.SpeechClient()

speech_file = "resources/commercial_mono.wav"

with open(speech_file, "rb") as audio_file:
    content = audio_file.read()

audio = speech.RecognitionAudio(content=content)

diarization_config = speech.SpeakerDiarizationConfig(
    enable_speaker_diarization=True,
    min_speaker_count=2,
    max_speaker_count=10,
)

config = speech.RecognitionConfig(
    encoding=speech.RecognitionConfig.AudioEncoding.LINEAR16,
    sample_rate_hertz=8000,
    language_code="en-US",
    diarization_config=diarization_config,
)

print("Waiting for operation to complete...")
response = client.recognize(config=config, audio=audio)

# The transcript within each result is separate and sequential per result.
# However, the words list within an alternative includes all the words
# from all the results thus far. Thus, to get all the words with speaker
# tags, you only have to take the words list from the last result:
result = response.results[-1]

words_info = result.alternatives[0].words

# Printing out the output:
for word_info in words_info:
    print(f"word: '{word_info.word}', speaker_tag: {word_info.speaker_tag}")

return result