diff --git a/pom.xml b/pom.xml index bba68f1af18..0a59c6fe3c2 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ monitoring/v3 pubsub/cloud-client spanner/cloud-client - speech/grpc + speech/cloud-client storage/cloud-client storage/json-api storage/storage-transfer diff --git a/speech/README.md b/speech/README.md index 0744f0f4498..9d54a590b10 100644 --- a/speech/README.md +++ b/speech/README.md @@ -3,10 +3,6 @@ This directory contains several samples for the [Cloud Speech API](https://cloud.google.com/speech/) with Java. -- [grpc](grpc) - - A sample for accessing Cloud Speech streaming and non streaming apis with [gRPC](http://www.grpc.io/). - - [Cloud Client](cloud-client) A sample for accessing Cloud Speech streaming and non streaming apis using the [Cloud Client Library for Java](https://github.com/GoogleCloudPlatform/google-cloud-java). diff --git a/speech/grpc/README.md b/speech/grpc/README.md deleted file mode 100644 index b4407df50ef..00000000000 --- a/speech/grpc/README.md +++ /dev/null @@ -1,101 +0,0 @@ -# Cloud Speech API gRPC samples for Java - -This is a sample repo for accessing the [Google Cloud Speech API](http://cloud.google.com/speech) with -[gRPC](http://www.grpc.io/) client library. Note that these samples are for `advanced users` and is in -BETA. Please see [Google Cloud Platform Launch Stages](https://cloud.google.com/terms/launch-stages). - -## Prerequisites - -### Enable the Speech API - -If you have not already done so, [enable the Google Cloud Speech API for your project](https://console.developers.google.com/apis/api/speech.googleapis.com/overview). -You must be whitelisted to do this. - - -### Download and install Java and Maven - -Install [Java7 or -higher](http://www.oracle.com/technetwork/java/javase/downloads/jre7-downloads-1880261.html). - -This sample uses the [Apache Maven][maven] build system. Before getting started, be -sure to [download][maven-download] and [install][maven-install] it. When you use -Maven as described here, it will automatically download the needed client -libraries. - -[maven]: https://maven.apache.org -[maven-download]: https://maven.apache.org/download.cgi -[maven-install]: https://maven.apache.org/install.html - - -### Set Up to Authenticate With Your Project's Credentials - -The example uses a service account for OAuth2 authentication. -So next, set up to authenticate with the Speech API using your project's -service account credentials. - -Visit the [Cloud Console](https://console.developers.google.com), and navigate to: -`API Manager > Credentials > Create credentials > -Service account key > New service account`. -Create a new service account, and download the json credentials file. - -Then, set -the `GOOGLE_APPLICATION_CREDENTIALS` environment variable to point to your -downloaded service account credentials before running this example: - - export GOOGLE_APPLICATION_CREDENTIALS=/path/to/your/credentials-key.json - -If you do not do this, you will see an error that looks something like this when -you run the example scripts: -`WARNING: RPC failed: Status{code=PERMISSION_DENIED, description=Request had insufficient authentication scopes., cause=null}`. -See the -[Cloud Platform Auth Guide](https://cloud.google.com/docs/authentication#developer_workflow) -for more information. - -## Build the application - -Then, build the program: - -```sh -$ mvn package -``` - -or - -```sh -$ mvn compile -$ mvn assembly:single -``` - -## Run the clients - -These programs return the transcription of the audio file you provided. Please -note that the audio file must be in RAW format. You can use `sox` -(available, e.g. via [http://sox.sourceforge.net/](http://sox.sourceforge.net/) -or [homebrew](http://brew.sh/)) to convert audio files to raw format. - -### Run the sync client - -To use the sync method to transcribe a 16,000Hz sample audio file, run the following: - -```sh -$ bin/speech-sample-sync.sh --host=speech.googleapis.com --port=443 \ ---uri=resources/audio.raw --sampling=16000 -``` - -### Run the async client - -To use the async method to transcribe a 16,000Hz sample audio file, run the following: - -```sh -$ bin/speech-sample-async.sh --host=speech.googleapis.com --port=443 \ ---uri=resources/audio.raw --sampling=16000 -``` - -### Run the streaming client - -To use the streaming method to transcribe a 16,000Hz sample audio file, run the following: - -```sh -$ bin/speech-sample-streaming.sh --host=speech.googleapis.com --port=443 \ ---sampling=16000 -``` diff --git a/speech/grpc/bin/speech-sample-async.sh b/speech/grpc/bin/speech-sample-async.sh deleted file mode 100755 index be843b1b4e0..00000000000 --- a/speech/grpc/bin/speech-sample-async.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# Copyright 2016 Google Inc. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -SRC_DIR="$( cd "$( dirname "$0" )/.." && pwd )" -java -cp "${SRC_DIR}/target/grpc-sample-1.0-jar-with-dependencies.jar" \ - com.examples.cloud.speech.AsyncRecognizeClient "$@" diff --git a/speech/grpc/bin/speech-sample-streaming.sh b/speech/grpc/bin/speech-sample-streaming.sh deleted file mode 100755 index 8fc77e6afaf..00000000000 --- a/speech/grpc/bin/speech-sample-streaming.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# Copyright 2016 Google Inc. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -SRC_DIR="$( cd "$( dirname "$0" )/.." && pwd )" -java -cp "${SRC_DIR}/target/grpc-sample-1.0-jar-with-dependencies.jar" \ - com.examples.cloud.speech.StreamingRecognizeClient "$@" diff --git a/speech/grpc/bin/speech-sample-sync.sh b/speech/grpc/bin/speech-sample-sync.sh deleted file mode 100755 index 322d11af2cb..00000000000 --- a/speech/grpc/bin/speech-sample-sync.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# Copyright 2016 Google Inc. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -SRC_DIR="$( cd "$( dirname "$0" )/.." && pwd )" -java -cp "${SRC_DIR}/target/grpc-sample-1.0-jar-with-dependencies.jar" \ - com.examples.cloud.speech.SyncRecognizeClient "$@" diff --git a/speech/grpc/pom.xml b/speech/grpc/pom.xml deleted file mode 100644 index f42b2f22b28..00000000000 --- a/speech/grpc/pom.xml +++ /dev/null @@ -1,166 +0,0 @@ - - - 4.0.0 - - com.google.cloud.speech - grpc-sample - 1.0 - jar - - speech-grpc-sample - https://cloud.google.com/speech/ - 2016 - - - - com.google.cloud - doc-samples - 1.0.0 - ../.. - - - - - Apache 2 - http://www.apache.org/licenses/LICENSE-2.0.txt - repo - - - - - Google - http://www.google.com - - - - UTF-8 - 2.3 - 1.0.3 - 3.6.0 - 0.5.0 - - 1.8 - 1.8 - - - - - - com.google.cloud - google-cloud-speech - 0.12.0-alpha - - - junit - junit - 4.12 - test - - - commons-cli - commons-cli - 1.3.1 - - - com.google.auth - google-auth-library-credentials - 0.6.1 - - - com.google.auth - google-auth-library-oauth2-http - 0.6.1 - - - - com.google.guava - guava-jdk5 - - - - - com.google.guava - guava - 20.0 - - - com.google.truth - truth - 0.32 - test - - - org.mockito - mockito-all - 1.10.19 - test - - - io.grpc - grpc-auth - ${grpc-version} - - - io.grpc - grpc-netty - ${grpc-version} - - - io.grpc - grpc-protobuf - ${grpc-version} - - - io.grpc - grpc-stub - ${grpc-version} - - - log4j - log4j - 1.2.17 - - - - - - - - - - maven-assembly-plugin - - - jar-with-dependencies - - - - - simple-command - package - - attached - - - - - - - - - diff --git a/speech/grpc/resources/audio.raw b/speech/grpc/resources/audio.raw deleted file mode 100644 index 5ebf79d3c9c..00000000000 Binary files a/speech/grpc/resources/audio.raw and /dev/null differ diff --git a/speech/grpc/resources/audio32KHz.raw b/speech/grpc/resources/audio32KHz.raw deleted file mode 100644 index 6b52fc326f8..00000000000 Binary files a/speech/grpc/resources/audio32KHz.raw and /dev/null differ diff --git a/speech/grpc/src/main/java/com/examples/cloud/speech/AsyncRecognizeClient.java b/speech/grpc/src/main/java/com/examples/cloud/speech/AsyncRecognizeClient.java deleted file mode 100644 index 9d9d5899a4b..00000000000 --- a/speech/grpc/src/main/java/com/examples/cloud/speech/AsyncRecognizeClient.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright 2016 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.examples.cloud.speech; - -import com.google.auth.oauth2.GoogleCredentials; -import com.google.cloud.speech.v1beta1.AsyncRecognizeRequest; -import com.google.cloud.speech.v1beta1.AsyncRecognizeResponse; -import com.google.cloud.speech.v1beta1.RecognitionAudio; -import com.google.cloud.speech.v1beta1.RecognitionConfig; -import com.google.cloud.speech.v1beta1.RecognitionConfig.AudioEncoding; -import com.google.cloud.speech.v1beta1.SpeechGrpc; -import com.google.longrunning.GetOperationRequest; -import com.google.longrunning.Operation; -import com.google.longrunning.OperationsGrpc; - -import io.grpc.ManagedChannel; -import io.grpc.ManagedChannelBuilder; -import io.grpc.StatusRuntimeException; -import io.grpc.auth.ClientAuthInterceptor; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.Option; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; - -import java.io.IOException; -import java.net.URI; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Client that sends audio to Speech.AsyncRecognize and returns transcript. - */ -public class AsyncRecognizeClient { - - private static final Logger logger = Logger.getLogger(AsyncRecognizeClient.class.getName()); - - private static final List OAUTH2_SCOPES = - Arrays.asList("https://www.googleapis.com/auth/cloud-platform"); - - private final URI input; - private final int samplingRate; - - private final ManagedChannel channel; - private final SpeechGrpc.SpeechBlockingStub speechClient; - private final OperationsGrpc.OperationsBlockingStub statusClient; - - /** - * Construct client connecting to Cloud Speech server at {@code host:port}. - */ - public AsyncRecognizeClient(ManagedChannel channel, URI input, int samplingRate) - throws IOException { - this.input = input; - this.samplingRate = samplingRate; - this.channel = channel; - - speechClient = SpeechGrpc.newBlockingStub(channel); - statusClient = OperationsGrpc.newBlockingStub(channel); - } - - public void shutdown() throws InterruptedException { - channel.shutdown().awaitTermination(5, TimeUnit.SECONDS); - } - - public static ManagedChannel createChannel(String host, int port) throws IOException { - GoogleCredentials creds = GoogleCredentials.getApplicationDefault(); - creds = creds.createScoped(OAUTH2_SCOPES); - ManagedChannel channel = - ManagedChannelBuilder.forAddress(host, port) - .intercept(new ClientAuthInterceptor(creds, Executors.newSingleThreadExecutor())) - .build(); - - return channel; - } - - /** - * Sends a request to the speech API and returns an Operation handle. - */ - public void recognize() { - RecognitionAudio audio; - try { - audio = RecognitionAudioFactory.createRecognitionAudio(this.input); - } catch (IOException e) { - logger.log(Level.WARNING, "Failed to read audio uri input: " + input); - return; - } - logger.info("Sending " + audio.getContent().size() + " bytes from audio uri input: " + input); - RecognitionConfig config = - RecognitionConfig.newBuilder() - .setEncoding(AudioEncoding.LINEAR16) - .setSampleRate(samplingRate) - .build(); - AsyncRecognizeRequest request = - AsyncRecognizeRequest.newBuilder().setConfig(config).setAudio(audio).build(); - - Operation operation; - Operation status; - try { - operation = speechClient.asyncRecognize(request); - - // Print the long running operation handle - logger.log( - Level.INFO, - String.format("Operation handle: %s, URI: %s", operation.getName(), input.toString())); - } catch (StatusRuntimeException e) { - logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus()); - return; - } - - while (true) { - try { - logger.log(Level.INFO, "Waiting 2s for operation, {0} processing...", operation.getName()); - Thread.sleep(2000); - GetOperationRequest operationReq = - GetOperationRequest.newBuilder().setName(operation.getName()).build(); - status = - statusClient.getOperation( - GetOperationRequest.newBuilder().setName(operation.getName()).build()); - - if (status.getDone()) { - break; - } - } catch (Exception ex) { - logger.log(Level.WARNING, ex.getMessage()); - } - } - - try { - AsyncRecognizeResponse asyncRes = status.getResponse().unpack(AsyncRecognizeResponse.class); - - logger.info("Received response: " + asyncRes); - } catch (com.google.protobuf.InvalidProtocolBufferException ex) { - logger.log(Level.WARNING, "Unpack error, {0}", ex.getMessage()); - } - } - - public static void main(String[] args) throws Exception { - - String audioFile = ""; - String host = "speech.googleapis.com"; - Integer port = 443; - Integer sampling = 16000; - - CommandLineParser parser = new DefaultParser(); - - Options options = new Options(); - options.addOption( - Option.builder() - .longOpt("uri") - .desc("path to audio uri") - .hasArg() - .argName("FILE_PATH") - .build()); - options.addOption( - Option.builder() - .longOpt("host") - .desc("endpoint for api, e.g. speech.googleapis.com") - .hasArg() - .argName("ENDPOINT") - .build()); - options.addOption( - Option.builder() - .longOpt("port") - .desc("SSL port, usually 443") - .hasArg() - .argName("PORT") - .build()); - options.addOption( - Option.builder() - .longOpt("sampling") - .desc("Sampling Rate, i.e. 16000") - .hasArg() - .argName("RATE") - .build()); - - try { - CommandLine line = parser.parse(options, args); - if (line.hasOption("uri")) { - audioFile = line.getOptionValue("uri"); - } else { - System.err.println("An Audio uri must be specified (e.g. file:///foo/baz.raw)."); - System.exit(1); - } - - if (line.hasOption("host")) { - host = line.getOptionValue("host"); - } else { - System.err.println("An API enpoint must be specified (typically speech.googleapis.com)."); - System.exit(1); - } - - if (line.hasOption("port")) { - port = Integer.parseInt(line.getOptionValue("port")); - } else { - System.err.println("An SSL port must be specified (typically 443)."); - System.exit(1); - } - - if (line.hasOption("sampling")) { - sampling = Integer.parseInt(line.getOptionValue("sampling")); - } else { - System.err.println("An Audio sampling rate must be specified."); - System.exit(1); - } - } catch (ParseException exp) { - System.err.println("Unexpected exception:" + exp.getMessage()); - System.exit(1); - } - - ManagedChannel channel = AsyncRecognizeClient.createChannel(host, port); - - AsyncRecognizeClient client = - new AsyncRecognizeClient(channel, URI.create(audioFile), sampling); - try { - client.recognize(); - } finally { - client.shutdown(); - } - } -} diff --git a/speech/grpc/src/main/java/com/examples/cloud/speech/RecognitionAudioFactory.java b/speech/grpc/src/main/java/com/examples/cloud/speech/RecognitionAudioFactory.java deleted file mode 100644 index 2f340b94fb4..00000000000 --- a/speech/grpc/src/main/java/com/examples/cloud/speech/RecognitionAudioFactory.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2016 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.examples.cloud.speech; - -import com.google.cloud.speech.v1beta1.RecognitionAudio; -import com.google.protobuf.ByteString; - -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; - -/* - * RecognitionAudioFactory takes a URI as an input and creates a RecognitionAudio. - * The URI can point to a local file or a file on Google Cloud Storage. - */ -public class RecognitionAudioFactory { - - private static final String FILE_SCHEME = "file"; - private static final String GS_SCHEME = "gs"; - - /** - * Takes an input URI of form $scheme:// and converts to audio request. - * - * @param uri input uri - * @return RecognitionAudio recognition audio - */ - public static RecognitionAudio createRecognitionAudio(URI uri) throws IOException { - if (uri.getScheme() == null) { - uri = new File(uri.toString()).toURI(); - Path path = Paths.get(uri); - return audioFromBytes(Files.readAllBytes(path)); - } else if (uri.getScheme().equals(FILE_SCHEME)) { - Path path = Paths.get(uri); - return audioFromBytes(Files.readAllBytes(path)); - } else if (uri.getScheme().equals(GS_SCHEME)) { - return RecognitionAudio.newBuilder().setUri(uri.toString()).build(); - } - throw new RuntimeException("scheme not supported " + uri.getScheme()); - } - - /** - * Convert bytes to RecognitionAudio. - * - * @param bytes input bytes - * @return RecognitionAudio recognition audio - */ - private static RecognitionAudio audioFromBytes(byte[] bytes) { - return RecognitionAudio.newBuilder().setContent(ByteString.copyFrom(bytes)).build(); - } -} diff --git a/speech/grpc/src/main/java/com/examples/cloud/speech/StreamingRecognizeClient.java b/speech/grpc/src/main/java/com/examples/cloud/speech/StreamingRecognizeClient.java deleted file mode 100644 index 7a70b0359fb..00000000000 --- a/speech/grpc/src/main/java/com/examples/cloud/speech/StreamingRecognizeClient.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright 2016 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.examples.cloud.speech; - -import static org.apache.log4j.ConsoleAppender.SYSTEM_OUT; - -import com.google.auth.oauth2.GoogleCredentials; -import com.google.cloud.speech.v1beta1.RecognitionConfig; -import com.google.cloud.speech.v1beta1.RecognitionConfig.AudioEncoding; -import com.google.cloud.speech.v1beta1.SpeechGrpc; -import com.google.cloud.speech.v1beta1.StreamingRecognitionConfig; -import com.google.cloud.speech.v1beta1.StreamingRecognitionResult; -import com.google.cloud.speech.v1beta1.StreamingRecognizeRequest; -import com.google.cloud.speech.v1beta1.StreamingRecognizeResponse; -import com.google.protobuf.ByteString; - -import io.grpc.ManagedChannel; -import io.grpc.ManagedChannelBuilder; -import io.grpc.auth.ClientAuthInterceptor; -import io.grpc.stub.StreamObserver; - -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.Option; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; -import org.apache.log4j.ConsoleAppender; -import org.apache.log4j.Level; -import org.apache.log4j.Logger; -import org.apache.log4j.SimpleLayout; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import javax.sound.sampled.AudioFormat; -import javax.sound.sampled.AudioSystem; -import javax.sound.sampled.DataLine; -import javax.sound.sampled.LineUnavailableException; -import javax.sound.sampled.TargetDataLine; - - -/** - * Client that sends streaming audio to Speech.Recognize and returns streaming transcript. - */ -public class StreamingRecognizeClient { - - private static final Logger logger = Logger.getLogger(StreamingRecognizeClient.class.getName()); - - private final ManagedChannel channel; - private final SpeechGrpc.SpeechStub speechClient; - private static final List OAUTH2_SCOPES = - Arrays.asList("https://www.googleapis.com/auth/cloud-platform"); - - static final int BYTES_PER_SAMPLE = 2; // bytes per sample for LINEAR16 - - private final int samplingRate; - final int bytesPerBuffer; // buffer size in bytes - - // Used for testing - protected TargetDataLine mockDataLine = null; - - /** - * Construct client connecting to Cloud Speech server at {@code host:port}. - */ - public StreamingRecognizeClient(ManagedChannel channel, int samplingRate) - throws IOException { - this.samplingRate = samplingRate; - this.channel = channel; - this.bytesPerBuffer = samplingRate * BYTES_PER_SAMPLE / 10; // 100 ms - - speechClient = SpeechGrpc.newStub(channel); - - // Send log4j logs to Console - // If you are going to run this on GCE, you might wish to integrate with - // google-cloud-java logging. See: - // https://github.com/GoogleCloudPlatform/google-cloud-java/blob/master/README.md#stackdriver-logging-alpha - ConsoleAppender appender = new ConsoleAppender(new SimpleLayout(), SYSTEM_OUT); - logger.addAppender(appender); - } - - public void shutdown() throws InterruptedException { - channel.shutdown().awaitTermination(5, TimeUnit.SECONDS); - } - - static ManagedChannel createChannel(String host, int port) throws IOException { - GoogleCredentials creds = GoogleCredentials.getApplicationDefault(); - creds = creds.createScoped(OAUTH2_SCOPES); - ManagedChannel channel = - ManagedChannelBuilder.forAddress(host, port) - .intercept(new ClientAuthInterceptor(creds, Executors.newSingleThreadExecutor())) - .build(); - - return channel; - } - - /** - * Return a Line to the audio input device. - */ - private TargetDataLine getAudioInputLine() { - // For testing - if (null != mockDataLine) { - return mockDataLine; - } - - AudioFormat format = new AudioFormat(samplingRate, BYTES_PER_SAMPLE * 8, 1, true, false); - DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); - if (!AudioSystem.isLineSupported(info)) { - throw new RuntimeException(String.format( - "Device doesn't support LINEAR16 mono raw audio format at {%d}Hz", samplingRate)); - } - try { - TargetDataLine line = (TargetDataLine) AudioSystem.getLine(info); - // Make sure the line buffer doesn't overflow while we're filling this thread's buffer. - line.open(format, bytesPerBuffer * 5); - return line; - } catch (LineUnavailableException e) { - throw new RuntimeException(e); - } - } - - /** Send streaming recognize requests to server. */ - public void recognize() throws InterruptedException, IOException { - final CountDownLatch finishLatch = new CountDownLatch(1); - StreamObserver responseObserver = - new StreamObserver() { - private int sentenceLength = 1; - /** - * Prints the transcription results. Interim results are overwritten by subsequent - * results, until a final one is returned, at which point we start a new line. - * - * Flags the program to exit when it hears "exit". - */ - @Override - public void onNext(StreamingRecognizeResponse response) { - List results = response.getResultsList(); - if (results.size() < 1) { - return; - } - - StreamingRecognitionResult result = results.get(0); - String transcript = result.getAlternatives(0).getTranscript(); - - // Print interim results with a line feed, so subsequent transcriptions will overwrite - // it. Final result will print a newline. - String format = "%-" + this.sentenceLength + 's'; - if (result.getIsFinal()) { - format += '\n'; - this.sentenceLength = 1; - - if (transcript.toLowerCase().indexOf("exit") >= 0) { - finishLatch.countDown(); - } - } else { - format += '\r'; - this.sentenceLength = transcript.length(); - } - System.out.print(String.format(format, transcript)); - } - - @Override - public void onError(Throwable error) { - logger.log(Level.ERROR, "recognize failed: {0}", error); - finishLatch.countDown(); - } - - @Override - public void onCompleted() { - logger.info("recognize completed."); - finishLatch.countDown(); - } - }; - - StreamObserver requestObserver = - speechClient.streamingRecognize(responseObserver); - try { - // Build and send a StreamingRecognizeRequest containing the parameters for - // processing the audio. - RecognitionConfig config = - RecognitionConfig.newBuilder() - .setEncoding(AudioEncoding.LINEAR16) - .setSampleRate(samplingRate) - .build(); - StreamingRecognitionConfig streamingConfig = - StreamingRecognitionConfig.newBuilder() - .setConfig(config) - .setInterimResults(true) - .setSingleUtterance(false) - .build(); - - StreamingRecognizeRequest initial = - StreamingRecognizeRequest.newBuilder().setStreamingConfig(streamingConfig).build(); - requestObserver.onNext(initial); - - // Get a Line to the audio input device. - TargetDataLine in = getAudioInputLine(); - byte[] buffer = new byte[bytesPerBuffer]; - int bytesRead; - - in.start(); - // Read and send sequential buffers of audio as additional RecognizeRequests. - while (finishLatch.getCount() > 0 - && (bytesRead = in.read(buffer, 0, buffer.length)) != -1) { - StreamingRecognizeRequest request = - StreamingRecognizeRequest.newBuilder() - .setAudioContent(ByteString.copyFrom(buffer, 0, bytesRead)) - .build(); - requestObserver.onNext(request); - } - } catch (RuntimeException e) { - // Cancel RPC. - requestObserver.onError(e); - throw e; - } - // Mark the end of requests. - requestObserver.onCompleted(); - - // Receiving happens asynchronously. - finishLatch.await(1, TimeUnit.MINUTES); - } - - public static void main(String[] args) throws Exception { - - String host = null; - Integer port = null; - Integer sampling = null; - - CommandLineParser parser = new DefaultParser(); - - Options options = new Options(); - options.addOption( - Option.builder() - .longOpt("host") - .desc("endpoint for api, e.g. speech.googleapis.com") - .hasArg() - .argName("ENDPOINT") - .build()); - options.addOption( - Option.builder() - .longOpt("port") - .desc("SSL port, usually 443") - .hasArg() - .argName("PORT") - .build()); - options.addOption( - Option.builder() - .longOpt("sampling") - .desc("Sampling Rate, i.e. 16000") - .hasArg() - .argName("RATE") - .build()); - - try { - CommandLine line = parser.parse(options, args); - - host = line.getOptionValue("host", "speech.googleapis.com"); - port = Integer.parseInt(line.getOptionValue("port", "443")); - - if (line.hasOption("sampling")) { - sampling = Integer.parseInt(line.getOptionValue("sampling")); - } else { - System.err.println("An Audio sampling rate (--sampling) must be specified. (e.g. 16000)"); - System.exit(1); - } - } catch (ParseException exp) { - System.err.println("Unexpected exception:" + exp.getMessage()); - System.exit(1); - } - - ManagedChannel channel = createChannel(host, port); - StreamingRecognizeClient client = new StreamingRecognizeClient(channel, sampling); - try { - client.recognize(); - } finally { - client.shutdown(); - } - } -} diff --git a/speech/grpc/src/main/java/com/examples/cloud/speech/SyncRecognizeClient.java b/speech/grpc/src/main/java/com/examples/cloud/speech/SyncRecognizeClient.java deleted file mode 100644 index 9b8e68efb17..00000000000 --- a/speech/grpc/src/main/java/com/examples/cloud/speech/SyncRecognizeClient.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright 2016 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.examples.cloud.speech; - -import com.google.auth.oauth2.GoogleCredentials; -import com.google.cloud.speech.v1beta1.RecognitionAudio; -import com.google.cloud.speech.v1beta1.RecognitionConfig; -import com.google.cloud.speech.v1beta1.RecognitionConfig.AudioEncoding; -import com.google.cloud.speech.v1beta1.SpeechGrpc; -import com.google.cloud.speech.v1beta1.SyncRecognizeRequest; -import com.google.cloud.speech.v1beta1.SyncRecognizeResponse; -import com.google.protobuf.TextFormat; - -import io.grpc.ManagedChannel; -import io.grpc.ManagedChannelBuilder; -import io.grpc.StatusRuntimeException; -import io.grpc.auth.ClientAuthInterceptor; - -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.Option; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; - -import java.io.IOException; -import java.net.URI; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Client that sends audio to Speech.SyncRecognize and returns transcript. - */ -public class SyncRecognizeClient { - - private static final Logger logger = Logger.getLogger(SyncRecognizeClient.class.getName()); - - private final URI input; - private final int samplingRate; - - private final ManagedChannel channel; - private final SpeechGrpc.SpeechBlockingStub speechClient; - - private static final List OAUTH2_SCOPES = - Arrays.asList("https://www.googleapis.com/auth/cloud-platform"); - - /** - * Construct client connecting to Cloud Speech server at {@code host:port}. - */ - public SyncRecognizeClient(ManagedChannel channel, URI input, int samplingRate) - throws IOException { - this.input = input; - this.samplingRate = samplingRate; - this.channel = channel; - - speechClient = SpeechGrpc.newBlockingStub(channel); - } - - private RecognitionAudio createRecognitionAudio() throws IOException { - return RecognitionAudioFactory.createRecognitionAudio(this.input); - } - - public void shutdown() throws InterruptedException { - channel.shutdown().awaitTermination(5, TimeUnit.SECONDS); - } - - static ManagedChannel createChannel(String host, int port) throws IOException { - GoogleCredentials creds = GoogleCredentials.getApplicationDefault(); - creds = creds.createScoped(OAUTH2_SCOPES); - ManagedChannel channel = - ManagedChannelBuilder.forAddress(host, port) - .intercept(new ClientAuthInterceptor(creds, Executors.newSingleThreadExecutor())) - .build(); - - return channel; - } - - /** Send a non-streaming-recognize request to server. */ - public void recognize() { - RecognitionAudio audio; - try { - audio = createRecognitionAudio(); - } catch (IOException e) { - logger.log(Level.WARNING, "Failed to read audio uri input: " + input); - return; - } - logger.info("Sending " + audio.getContent().size() + " bytes from audio uri input: " + input); - RecognitionConfig config = - RecognitionConfig.newBuilder() - .setEncoding(AudioEncoding.LINEAR16) - .setSampleRate(samplingRate) - .build(); - SyncRecognizeRequest request = - SyncRecognizeRequest.newBuilder().setConfig(config).setAudio(audio).build(); - - SyncRecognizeResponse response; - try { - response = speechClient.syncRecognize(request); - } catch (StatusRuntimeException e) { - logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus()); - return; - } - logger.info("Received response: " + TextFormat.printToString(response)); - } - - public static void main(String[] args) throws Exception { - - String audioFile = ""; - String host = "speech.googleapis.com"; - Integer port = 443; - Integer sampling = 16000; - - CommandLineParser parser = new DefaultParser(); - - Options options = new Options(); - options.addOption( - Option.builder() - .longOpt("uri") - .desc("path to audio uri") - .hasArg() - .argName("FILE_PATH") - .build()); - options.addOption( - Option.builder() - .longOpt("host") - .desc("endpoint for api, e.g. speech.googleapis.com") - .hasArg() - .argName("ENDPOINT") - .build()); - options.addOption( - Option.builder() - .longOpt("port") - .desc("SSL port, usually 443") - .hasArg() - .argName("PORT") - .build()); - options.addOption( - Option.builder() - .longOpt("sampling") - .desc("Sampling Rate, i.e. 16000") - .hasArg() - .argName("RATE") - .build()); - - try { - CommandLine line = parser.parse(options, args); - if (line.hasOption("uri")) { - audioFile = line.getOptionValue("uri"); - } else { - System.err.println("An Audio uri must be specified (e.g. file:///foo/baz.raw)."); - System.exit(1); - } - - if (line.hasOption("host")) { - host = line.getOptionValue("host"); - } else { - System.err.println("An API enpoint must be specified (typically speech.googleapis.com)."); - System.exit(1); - } - - if (line.hasOption("port")) { - port = Integer.parseInt(line.getOptionValue("port")); - } else { - System.err.println("An SSL port must be specified (typically 443)."); - System.exit(1); - } - - if (line.hasOption("sampling")) { - sampling = Integer.parseInt(line.getOptionValue("sampling")); - } else { - System.err.println("An Audio sampling rate must be specified."); - System.exit(1); - } - } catch (ParseException exp) { - System.err.println("Unexpected exception:" + exp.getMessage()); - System.exit(1); - } - - ManagedChannel channel = createChannel(host, port); - SyncRecognizeClient client = new SyncRecognizeClient(channel, URI.create(audioFile), sampling); - try { - client.recognize(); - } finally { - client.shutdown(); - } - } -} diff --git a/speech/grpc/src/test/java/com/examples/cloud/speech/RecognitionAudioFactoryTest.java b/speech/grpc/src/test/java/com/examples/cloud/speech/RecognitionAudioFactoryTest.java deleted file mode 100644 index 0f1e01b24c4..00000000000 --- a/speech/grpc/src/test/java/com/examples/cloud/speech/RecognitionAudioFactoryTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2016 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.examples.cloud.speech; - -import static org.junit.Assert.assertEquals; - -import com.google.cloud.speech.v1beta1.RecognitionAudio; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.io.File; -import java.io.IOException; -import java.net.URI; - -/** - * Unit tests for {@link RecognitionAudioFactory}. - */ -@RunWith(JUnit4.class) -public class RecognitionAudioFactoryTest { - private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); - private static final String BUCKET = PROJECT_ID; - - @Test - public void verifyBytesInSizeFromLocalFile() throws IOException { - URI uri = new File("resources/audio.raw").toURI(); - RecognitionAudio audio = RecognitionAudioFactory.createRecognitionAudio(uri); - - int numBytes = audio.getContent().toByteArray().length; - - //assert the number of bytes in the audio as 57958 - assertEquals(57958, numBytes); - } - - @Test - public void verifyBytesInSizeFromGoogleStorageFile() throws IOException { - String audioUri = "gs://" + BUCKET + "/speech/audio.raw"; - - URI uri = URI.create(audioUri); - RecognitionAudio audio = RecognitionAudioFactory.createRecognitionAudio(uri); - - int numBytes = audio.getContent().toByteArray().length; - - //assert the number of bytes in the audio as 0 - assertEquals(0, numBytes); - - //assert the uri - assertEquals(audioUri, audio.getUri()); - } -} diff --git a/speech/grpc/src/test/java/com/examples/cloud/speech/StreamingRecognizeClientTest.java b/speech/grpc/src/test/java/com/examples/cloud/speech/StreamingRecognizeClientTest.java deleted file mode 100644 index 7ed15a0fe9e..00000000000 --- a/speech/grpc/src/test/java/com/examples/cloud/speech/StreamingRecognizeClientTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2016 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.examples.cloud.speech; - -import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.when; - -import io.grpc.ManagedChannel; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.PrintStream; -import javax.sound.sampled.TargetDataLine; - - -/** - * Unit tests for {@link StreamingRecognizeClient }. - */ -@RunWith(JUnit4.class) -public class StreamingRecognizeClientTest { - private final ByteArrayOutputStream stdout = new ByteArrayOutputStream(); - private static final PrintStream REAL_OUT = System.out; - - @Mock private TargetDataLine mockDataLine; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - System.setOut(new PrintStream(stdout)); - } - - @After - public void tearDown() { - System.setOut(REAL_OUT); - } - - @Test - public void test16KHzAudio() throws InterruptedException, IOException { - String host = "speech.googleapis.com"; - int port = 443; - ManagedChannel channel = StreamingRecognizeClient.createChannel(host, port); - - final FileInputStream in = new FileInputStream("resources/audio.raw"); - - final int samplingRate = 16000; - final StreamingRecognizeClient client = new StreamingRecognizeClient(channel, samplingRate); - - // When audio data is requested from the mock, get it from the file - when(mockDataLine.read(any(byte[].class), anyInt(), anyInt())).thenAnswer(new Answer() { - public Object answer(InvocationOnMock invocation) { - Object[] args = invocation.getArguments(); - byte[] buffer = (byte[])args[0]; - int offset = (int)args[1]; - int len = (int)args[2]; - assertThat(buffer.length).isEqualTo(len); - - try { - // Sleep, to simulate realtime - int samplesPerBuffer = client.bytesPerBuffer / StreamingRecognizeClient.BYTES_PER_SAMPLE; - int samplesPerMillis = samplingRate / 1000; - Thread.sleep(samplesPerBuffer / samplesPerMillis); - - // Provide the audio bytes from the file - return in.read(buffer, offset, len); - - } catch (Exception e) { - throw new RuntimeException(e); - } - } - }); - client.mockDataLine = mockDataLine; - - client.recognize(); - - assertThat(stdout.toString()).contains("how old is the Brooklyn Bridge"); - } - - @Test - public void test32KHzAudio() throws InterruptedException, IOException { - String host = "speech.googleapis.com"; - int port = 443; - ManagedChannel channel = StreamingRecognizeClient.createChannel(host, port); - - final FileInputStream in = new FileInputStream("resources/audio32KHz.raw"); - - final int samplingRate = 32000; - final StreamingRecognizeClient client = new StreamingRecognizeClient(channel, samplingRate); - - // When audio data is requested from the mock, get it from the file - when(mockDataLine.read(any(byte[].class), anyInt(), anyInt())).thenAnswer(new Answer() { - public Object answer(InvocationOnMock invocation) { - Object[] args = invocation.getArguments(); - byte[] buffer = (byte[])args[0]; - int offset = (int)args[1]; - int len = (int)args[2]; - assertThat(buffer.length).isEqualTo(len); - - try { - // Sleep, to simulate realtime - int samplesPerBuffer = client.bytesPerBuffer / StreamingRecognizeClient.BYTES_PER_SAMPLE; - int samplesPerMillis = samplingRate / 1000; - Thread.sleep(samplesPerBuffer / samplesPerMillis); - - // Provide the audio bytes from the file - return in.read(buffer, offset, len); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - }); - client.mockDataLine = mockDataLine; - - client.recognize(); - - assertThat(stdout.toString()).contains("how old is the Brooklyn Bridge"); - } -}