Google Cloud Speech-to-Text su gRPC in Delphi

· Componenti

Speech-to-Text trasforma l'audio parlato in testo scritto. Google Cloud lo espone come servizio gRPC e sgcWebSockets Enterprise include un client Speech tipizzato costruito sul generico TsgcGRPCClient, così puoi trascrivere audio direttamente da Delphi e C++Builder. Assembli una richiesta di riconoscimento con poche proprietà, la invii su gRPC e leggi la trascrizione di ritorno, senza alcun runtime esterno o protobuf scritto a mano.

Come funziona

gRPC è costituito da messaggi Protocol Buffers incapsulati su HTTP/2, quindi il client Speech viaggia sullo stesso trasporto del resto della libreria. Un TsgcHTTP2Client apre una connessione TLS verso speech.googleapis.com:443, un TsgcGRPCClient gestisce sopra di esso l'incapsulamento gRPC e i trailer, e i messaggi Speech tipizzati in sgcGRPC_Google_Speech serializzano e analizzano per te la richiesta e la risposta.

Le API di Google Cloud sono autenticate. Ti autentichi con un account di servizio, scambiando la sua chiave JSON con un token bearer di breve durata, e invii quel token come metadata gRPC su ogni chiamata. La richiesta in sé è un RecognitionConfig (lingua, codifica, frequenza di campionamento) più l'audio, byte inline oppure un URI di Cloud Storage. Il servizio risponde con uno o più risultati, ognuno contenente alternative di trascrizione ordinate con un punteggio di confidenza.

Autenticarsi con un account di servizio

Il client Google Cloud trasforma una chiave JSON dell'account di servizio in un token bearer. Carica la chiave, imposta le proprietà JWT e vincola l'audience all'endpoint Speech in modo che il token autofirmato sia accettato. Una volta arrivato il token, aggiungilo al DefaultMetadata del client gRPC come header authorization, che poi viaggia su ogni chiamata.

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

Connettere il client gRPC

Il canale è una connessione HTTP/2. Punta un TsgcHTTP2Client all'host Speech con TLS abilitato, assegnalo alla proprietà Client del componente gRPC e seleziona il content type del protocollo. Il servizio Speech parla Protocol Buffers, quindi usa grpcProto senza compressione.

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;

Riconoscere l'audio e leggere la trascrizione

Per trascrivere, costruisci un TsgcGRPCSpeechRecognizeRequest. Compila il Config con il codice lingua, la codifica e la frequenza di campionamento, punta Audio.Uri a un oggetto di Cloud Storage (oppure imposta Audio.Content con byte inline) e chiama Recognize sul servizio google.cloud.speech.v1.Speech. La richiesta si serializza da sola con ToBytes e la risposta si analizza in un oggetto tipizzato che puoi scorrere per risultati e alternative.

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;

Configurazione del riconoscimento

L'oggetto Config sulla richiesta corrisponde direttamente al messaggio RecognitionConfig di Google. Oltre a lingua e frequenza di campionamento, puoi impostare MaxAlternatives per richiedere varianti ordinate, ProfanityFilter per mascherare le parole offensive, AudioChannelCount per audio multicanale, EnableAutomaticPunctuation per un output leggibile e Model per scegliere un modello di riconoscimento ottimizzato. Ogni proprietà è opzionale e viene emessa sul filo solo quando impostata, così invii solo ciò di cui hai bisogno.

Audio inline o un URI di Cloud Storage

Le clip brevi possono viaggiare dentro la richiesta: assegna i byte audio grezzi ad Audio.Content e il client li incorpora nel protobuf. Per file più lunghi, carica l'audio in un bucket e imposta invece Audio.Uri a un percorso gs://, il che mantiene la richiesta piccola e lascia che Google legga l'oggetto direttamente. I due sono mutuamente esclusivi, imposti l'uno o l'altro su una data richiesta.

Risultati e alternative

Una risposta è una lista di risultati, uno per ogni segmento di audio riconosciuto. Ogni risultato porta una o più alternative ordinate per probabilità, con la trascrizione più probabile per prima e un punteggio di Confidence tra 0 e 1. Itera su ResultCount e AlternativeCount per leggerli tutti, oppure prendi semplicemente la prima alternativa del primo risultato per l'ipotesi migliore. Gli helper tipizzati fanno l'analisi del protobuf, così lavori con normali stringhe e float Delphi.

Disponibilità

Il client gRPC Speech-to-Text tipizzato fa parte dell'edizione Enterprise di sgcWebSockets e gira su Windows, macOS, Linux, iOS e Android. Un esempio pronto all'uso, quello su cui si basa questo articolo, è in Demos\21.GRPC\11.Speech_to_Text e il riferimento completo è sulla pagina prodotto gRPC Client.

Domande o feedback? Contattaci. Riceverai una risposta dalle persone che hanno scritto il codice.