Google Cloud Speech-to-Text sobre gRPC no Delphi

· Componentes

O Speech-to-Text converte áudio falado em texto escrito. O Google Cloud expõe isso como um serviço gRPC, e o sgcWebSockets Enterprise inclui um cliente Speech tipado construído sobre o genérico TsgcGRPCClient, para que você possa transcrever áudio diretamente do Delphi e do C++Builder. Você monta uma requisição de reconhecimento com algumas propriedades, a envia por gRPC e lê a transcrição de volta, sem necessidade de runtime externo ou protobufs escritos à mão.

Como funciona

O gRPC são mensagens Protocol Buffers encapsuladas sobre HTTP/2, então o cliente Speech viaja pelo mesmo transporte que o restante da biblioteca. Um TsgcHTTP2Client abre uma conexão TLS para speech.googleapis.com:443, um TsgcGRPCClient trata o enquadramento gRPC e os trailers sobre ele, e as mensagens Speech tipadas em sgcGRPC_Google_Speech serializam e analisam a requisição e a resposta para você.

As APIs do Google Cloud são autenticadas. Você se autentica com uma conta de serviço, trocando sua chave JSON por um token bearer de curta duração, e envia esse token como metadado gRPC em cada chamada. A requisição em si é uma RecognitionConfig (idioma, codificação, taxa de amostragem) mais o áudio, seja como bytes inline ou um URI do Cloud Storage. O serviço responde com um ou mais resultados, cada um contendo alternativas de transcrição ordenadas por pontuação de confiança.

Autenticando com uma conta de serviço

O cliente do Google Cloud transforma uma chave JSON de conta de serviço em um token bearer. Carregue a chave, defina as propriedades JWT e vincule a audiência ao endpoint do Speech para que o token autoassinado seja aceito. Assim que o token chegar, adicione-o ao DefaultMetadata do cliente gRPC como um cabeçalho authorization, que então acompanha cada chamada.

uses
  sgcHTTP2_Client, sgcGRPC_Client, sgcGRPC_Types,
  sgcHTTP_Google_Cloud, sgcGRPC_Google_Speech;

// service-account JWT authentication
Cloud.GoogleCloudOptions.Authentication := gcaJWT;
Cloud.GoogleCloudOptions.JWT.ClientEmail := ClientEmail;
Cloud.GoogleCloudOptions.JWT.PrivateKeyId := PrivateKeyId;
Cloud.GoogleCloudOptions.JWT.PrivateKey.Text := PrivateKey;
Cloud.GoogleCloudOptions.JWT.ProjectId := ProjectId;
// self-signed service-account JWT is audience-bound to the Speech endpoint
Cloud.GoogleCloudOptions.JWT.API_Endpoint := 'https://speech.googleapis.com/';

// once the token is acquired, send it on every gRPC call
GRPC.DefaultMetadata.Clear;
GRPC.DefaultMetadata.Add('authorization', 'Bearer ' + Token);

Conectando o cliente gRPC

O canal é uma conexão HTTP/2. Aponte um TsgcHTTP2Client para o host do Speech com TLS habilitado, atribua-o à propriedade Client do componente gRPC e selecione o tipo de conteúdo do protocolo. O serviço Speech fala Protocol Buffers, então use grpcProto sem compressão.

HTTP2 := TsgcHTTP2Client.Create(nil);
HTTP2.Host := 'speech.googleapis.com';
HTTP2.Port := 443;
HTTP2.TLS  := True;

GRPC := TsgcGRPCClient.Create(nil);
GRPC.Client := HTTP2;
GRPC.ChannelOptions.ContentType := grpcProto;
GRPC.ChannelOptions.Compression := grpcNoCompression;

HTTP2.Active := True;

Reconhecendo áudio e lendo a transcrição

Para transcrever, monte um TsgcGRPCSpeechRecognizeRequest. Preencha o Config com o código de idioma, a codificação e a taxa de amostragem, aponte Audio.Uri para um objeto do Cloud Storage (ou defina Audio.Content com bytes inline) e chame Recognize no serviço google.cloud.speech.v1.Speech. A requisição se serializa com ToBytes, e a resposta é analisada de volta em uma resposta tipada que você pode percorrer em busca de resultados e alternativas.

var
  oRequest: TsgcGRPCSpeechRecognizeRequest;
  oResponse: TsgcGRPCResponse;
  oSpeech: TsgcGRPCSpeechRecognizeResponse;
  oResult: TsgcGRPCSpeechRecognitionResult;
  oAlt: TsgcGRPCSpeechRecognitionAlternative;
  i, j: Integer;
begin
  oRequest := TsgcGRPCSpeechRecognizeRequest.Create;
  try
    oRequest.Config.Encoding := 0;             // 0 = ENCODING_UNSPECIFIED, let the API detect
    oRequest.Config.SampleRateHertz := 16000;
    oRequest.Config.LanguageCode := 'en-US';
    oRequest.Config.EnableAutomaticPunctuation := True;
    oRequest.Audio.Uri := 'gs://my-bucket/audio.flac';

    oResponse := GRPC.Call('google.cloud.speech.v1.Speech', 'Recognize',
      oRequest.ToBytes);
  finally
    oRequest.Free;
  end;

  if oResponse.StatusCode <> grpcOK then
  begin
    ShowMessage('gRPC error: ' + oResponse.StatusMessage);
    Exit;
  end;

  oSpeech := TsgcGRPCSpeechRecognizeResponse.Create;
  try
    oSpeech.LoadFromBytes(oResponse.Data);
    for i := 0 to oSpeech.ResultCount - 1 do
    begin
      oResult := oSpeech.ResultItem(i);
      for j := 0 to oResult.AlternativeCount - 1 do
      begin
        oAlt := oResult.Alternative(j);
        Memo1.Lines.Add('Transcript: ' + oAlt.Transcript);
        Memo1.Lines.Add('Confidence: ' + FloatToStr(oAlt.Confidence));
      end;
    end;
  finally
    oSpeech.Free;
  end;
end;

Configuração de reconhecimento

O objeto Config na requisição mapeia diretamente para a mensagem RecognitionConfig do Google. Além de idioma e taxa de amostragem, você pode definir MaxAlternatives para solicitar variantes ordenadas, ProfanityFilter para mascarar palavras ofensivas, AudioChannelCount para áudio multicanal, EnableAutomaticPunctuation para uma saída legível e Model para escolher um modelo de reconhecimento ajustado. Cada propriedade é opcional e só é emitida no protocolo quando definida, então você envia apenas o que precisa.

Áudio inline ou um URI do Cloud Storage

Clipes curtos podem viajar dentro da requisição: atribua os bytes brutos de áudio a Audio.Content e o cliente os embute no protobuf. Para arquivos maiores, envie o áudio para um bucket e defina Audio.Uri com um caminho gs://, o que mantém a requisição pequena e permite que o Google leia o objeto diretamente. As duas opções são mutuamente exclusivas, você define uma ou a outra em uma dada requisição.

Resultados e alternativas

Uma resposta é uma lista de resultados, um por segmento de áudio reconhecido. Cada resultado carrega uma ou mais alternativas ordenadas por probabilidade, com a transcrição mais provável primeiro e uma pontuação de Confidence entre 0 e 1. Itere ResultCount e AlternativeCount para ler todas, ou simplesmente pegue a primeira alternativa do primeiro resultado para a melhor estimativa. Os auxiliares tipados fazem a análise do protobuf, então você trabalha com strings e floats Delphi comuns.

Disponibilidade

O cliente Speech-to-Text gRPC tipado faz parte da edição Enterprise do sgcWebSockets e roda em Windows, macOS, Linux, iOS e Android. Um exemplo pronto para executar, no qual este artigo se baseia, está em Demos\21.GRPC\11.Speech_to_Text, e a referência completa está na página do produto gRPC Client.

Dúvidas ou comentários? Entre em contato. Você receberá uma resposta das pessoas que escreveram o código.