Google Cloud Speech-to-Text via gRPC in Delphi

· Componenten

Speech-to-Text zet gesproken audio om in geschreven tekst. Google Cloud biedt dit aan als een gRPC-service, en sgcWebSockets Enterprise levert een getypeerde Speech-client gebouwd op de generieke TsgcGRPCClient, zodat je audio rechtstreeks vanuit Delphi en C++Builder kunt transcriberen. Je stelt een herkenningsrequest samen met een paar eigenschappen, verstuurt het over gRPC, en leest het transcript terug, zonder externe runtime of handgeschreven protobufs.

Hoe het werkt

gRPC bestaat uit Protocol Buffers-berichten ingekapseld over HTTP/2, dus de Speech-client rijdt op dezelfde transport als de rest van de bibliotheek. Een TsgcHTTP2Client opent een TLS-verbinding naar speech.googleapis.com:443, een TsgcGRPCClient verzorgt de gRPC-framing en trailers daarbovenop, en de getypeerde Speech-berichten in sgcGRPC_Google_Speech serialiseren en parsen de request en response voor je.

Google Cloud-API's zijn geauthenticeerd. Je authenticeert met een service-account door zijn JSON-sleutel in te wisselen voor een kortlevend bearer-token, en je verstuurt dat token als gRPC-metadata bij elke call. De request zelf is een RecognitionConfig (taal, codering, sample rate) plus de audio, ofwel inline bytes ofwel een Cloud Storage-URI. De service antwoordt met een of meer resultaten, elk met gerangschikte transcript-alternatieven en een betrouwbaarheidsscore.

Authenticeren met een service-account

De Google Cloud-client zet een service-account-JSON-sleutel om in een bearer-token. Laad de sleutel, stel de JWT-eigenschappen in, en bind de audience aan het Speech-endpoint zodat het zelfondertekende token wordt geaccepteerd. Zodra het token binnenkomt, voeg je het toe aan de DefaultMetadata van de gRPC-client als een authorization-header, die vervolgens bij elke call meereist.

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

De gRPC-client verbinden

Het kanaal is een HTTP/2-verbinding. Richt een TsgcHTTP2Client op de Speech-host met TLS ingeschakeld, wijs het toe aan de Client-eigenschap van het gRPC-component, en selecteer het wire-contenttype. De Speech-service spreekt Protocol Buffers, dus gebruik grpcProto zonder compressie.

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;

Audio herkennen en het transcript uitlezen

Om te transcriberen bouw je een TsgcGRPCSpeechRecognizeRequest. Vul de Config in met de taalcode, codering en sample rate, richt Audio.Uri op een Cloud Storage-object (of stel Audio.Content in met inline bytes), en roep Recognize aan op de google.cloud.speech.v1.Speech-service. De request serialiseert zichzelf met ToBytes, en het antwoord parset terug naar een getypeerde response die je kunt doorlopen voor resultaten en alternatieven.

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;

Herkenningsconfiguratie

Het Config-object op de request komt rechtstreeks overeen met Google's RecognitionConfig-bericht. Naast taal en sample rate kun je MaxAlternatives instellen om gerangschikte varianten te vragen, ProfanityFilter om aanstootgevende woorden te maskeren, AudioChannelCount voor meerkanaals audio, EnableAutomaticPunctuation voor leesbare uitvoer, en Model om een afgestemd herkenningsmodel te kiezen. Elke eigenschap is optioneel en wordt alleen op de wire verzonden wanneer ingesteld, zodat je precies stuurt wat je nodig hebt.

Inline audio of een Cloud Storage-URI

Korte fragmenten kunnen binnen de request reizen: wijs de ruwe audiobytes toe aan Audio.Content en de client sluit ze in in de protobuf. Voor langere bestanden upload je de audio naar een bucket en stel je in plaats daarvan Audio.Uri in op een gs://-pad, wat de request klein houdt en Google het object rechtstreeks laat lezen. De twee sluiten elkaar uit, je stelt het een of het ander in op een gegeven request.

Resultaten en alternatieven

Een response is een lijst met resultaten, één per herkend audiosegment. Elk resultaat draagt een of meer alternatieven geordend op waarschijnlijkheid, met het meest waarschijnlijke transcript eerst en een Confidence-score tussen 0 en 1. Doorloop ResultCount en AlternativeCount om ze allemaal te lezen, of neem simpelweg het eerste alternatief van het eerste resultaat voor de beste gok. De getypeerde helpers doen het protobuf-parsen, zodat je werkt met gewone Delphi-strings en floats.

Beschikbaarheid

De getypeerde Speech-to-Text gRPC-client maakt deel uit van de sgcWebSockets Enterprise-editie en draait op Windows, macOS, Linux, iOS en Android. Een kant-en-klaar voorbeeld, het voorbeeld waarop dit artikel is gebaseerd, staat in Demos\21.GRPC\11.Speech_to_Text, en de volledige referentie staat op de productpagina van de gRPC Client.

Vragen of feedback? Neem contact op. Je krijgt antwoord van de mensen die de code hebben geschreven.