我是google-cloud-java的新手。
尝试使用google-cloud-speech做一些Speech Recognition
。
我已经写了下面的代码,但是有一个问题,我不知道如何指定凭据,所以我得到了下面的错误,不知道怎么做,现在搜索网络2小时了:
java.io.IOException: The Application Default Credentials are not available. They
are available if running in Google Compute Engine. Otherwise, the environment v
ariable GOOGLE_APPLICATION_CREDENTIALS must be defined pointing to a file defini
ng the credentials. See https://developers.google.com/accounts/docs/application-
default-credentials for more information.
将音频从麦克风发送到Google服务器并返回文本
package googleSpeech;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.TargetDataLine;
import com.google.api.gax.rpc.ClientStream;
import com.google.api.gax.rpc.ResponseObserver;
import com.google.api.gax.rpc.StreamController;
import com.google.cloud.speech.v1.RecognitionConfig;
import com.google.cloud.speech.v1.SpeechClient;
import com.google.cloud.speech.v1.StreamingRecognitionConfig;
import com.google.cloud.speech.v1.StreamingRecognizeRequest;
import com.google.cloud.speech.v1.StreamingRecognizeResponse;
import com.google.protobuf.ByteString;
public class GoogleSpeechTest {
public GoogleSpeechTest() {
//Set credentials?
//Target data line
TargetDataLine microphone;
AudioInputStream audio = null;
//Check if Microphone is Supported
checkMicrophoneAvailability();
//Capture Microphone Audio Data
try {
// Signed PCM AudioFormat with 16kHz, 16 bit sample size, mono
AudioFormat format = new AudioFormat(16000, 16, 1, true, false);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
//Check if Microphone is Supported
if (!AudioSystem.isLineSupported(info)) {
System.out.println("Microphone is not available");
System.exit(0);
}
//Get the target data line
microphone = (TargetDataLine) AudioSystem.getLine(info);
microphone.open(format);
microphone.start();
//Audio Input Stream
audio = new AudioInputStream(microphone);
} catch (Exception ex) {
ex.printStackTrace();
}
//Send audio from Microphone to Google Servers and return Text
try (SpeechClient client = SpeechClient.create()) {
ResponseObserver<StreamingRecognizeResponse> responseObserver = new ResponseObserver<StreamingRecognizeResponse>() {
public void onStart(StreamController controller) {
// do nothing
}
public void onResponse(StreamingRecognizeResponse response) {
System.out.println(response);
}
public void onComplete() {
}
public void onError(Throwable t) {
System.out.println(t);
}
};
ClientStream<StreamingRecognizeRequest> clientStream = client.streamingRecognizeCallable().splitCall(responseObserver);
RecognitionConfig recConfig = RecognitionConfig.newBuilder().setEncoding(RecognitionConfig.AudioEncoding.LINEAR16).setLanguageCode("en-US").setSampleRateHertz(16000)
.build();
StreamingRecognitionConfig config = StreamingRecognitionConfig.newBuilder().setConfig(recConfig).build();
StreamingRecognizeRequest request = StreamingRecognizeRequest.newBuilder().setStreamingConfig(config).build(); // The first request in a streaming call has to be a config
clientStream.send(request);
while (true) {
byte[] data = new byte[10];
try {
audio.read(data);
} catch (IOException e) {
System.out.println(e);
}
request = StreamingRecognizeRequest.newBuilder().setAudioContent(ByteString.copyFrom(data)).build();
clientStream.send(request);
}
} catch (Exception e) {
System.out.println(e);
}
}
/**
* Checks if the Microphone is available
*/
public static void checkMicrophoneAvailability() {
enumerateMicrophones().forEach((string , info) -> {
System.out.println("Name :" + string);
});
}
/**
* Generates a hashmap to simplify the microphone selection process. The keyset is the name of the audio device's Mixer The value is the first
* lineInfo from that Mixer.
*
* @author Aaron Gokaslan (Skylion)
* @return The generated hashmap
*/
public static HashMap<String,Line.Info> enumerateMicrophones() {
HashMap<String,Line.Info> out = new HashMap<String,Line.Info>();
Mixer.Info[] mixerInfos = AudioSystem.getMixerInfo();
for (Mixer.Info info : mixerInfos) {
Mixer m = AudioSystem.getMixer(info);
Line.Info[] lineInfos = m.getTargetLineInfo();
if (lineInfos.length >= 1 && lineInfos[0].getLineClass().equals(TargetDataLine.class))//Only adds to hashmap if it is audio input device
out.put(info.getName(), lineInfos[0]);//Please enjoy my pun
}
return out;
}
public static void main(String[] args) {
new GoogleSpeechTest();
}
}
按照给出的答案进行操作
我的凭据.json看起来像我出现错误:
{
"installed": {
"client_id": "",
"project_id": "",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://accounts.google.com/o/oauth2/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_secret": "",
"redirect_uris": [
"urn:ietf:wg:oauth:2.0:oob",
"http://localhost"
]
}
}
错误:
java.io.IOException: Error reading credential file from environment variable GOO
GLE_APPLICATION_CREDENTIALS, value 'D:/GOXR3PLUS STUDIO/XR3IA/creds.json': Error
reading credentials from stream, 'type' field not specified.
更新3
解决了此链接后的错误-> https://github.com/Triple-T/gradle-play-publisher/issues/141
答案 0 :(得分:2)
我假设您是从Google Cloud Console下载凭据的。它们应该作为文件保存在计算机上的某个地方。
您需要设置GOOGLE_APPLICATION_CREDENTIALS
环境变量,使其直接指向该文件。指定该文件的路径。例如,如果在当前工作目录上方的文件夹中将凭据称为creds.json
,则可以将环境变量设置为../creds.json
。您还可以指定绝对路径。
要实际设置环境变量,每个操作系统会有所不同。 Here's a good post可以帮助您。如果您使用的是Intellij,则可以set it directly in the run configuration。
答案 1 :(得分:0)
您的凭据文件如下所示:
Java
中的另一种方法,但使用后果自负public class SetEnv {
public static void setEnv(Map<String, String> newenv)
throws ClassNotFoundException, IllegalAccessException, NoSuchFieldException {
try {
Class<?> processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment");
Field theEnvironmentField = processEnvironmentClass.getDeclaredField("theEnvironment");
theEnvironmentField.setAccessible(true);
Map<String, String> env = (Map<String, String>) theEnvironmentField.get(null);
env.putAll(newenv);
Field theCaseInsensitiveEnvironmentField = processEnvironmentClass
.getDeclaredField("theCaseInsensitiveEnvironment");
theCaseInsensitiveEnvironmentField.setAccessible(true);
Map<String, String> cienv = (Map<String, String>) theCaseInsensitiveEnvironmentField.get(null);
cienv.putAll(newenv);
} catch (NoSuchFieldException e) {
Class[] classes = Collections.class.getDeclaredClasses();
Map<String, String> env = System.getenv();
for (Class cl : classes) {
if ("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {
Field field = cl.getDeclaredField("m");
field.setAccessible(true);
Object obj = field.get(env);
Map<String, String> map = (Map<String, String>) obj;
map.clear();
map.putAll(newenv);
}
}
}
}
}
并这样称呼它:
Map<String, String> google = new HashMap<>();
google.put("GOOGLE_APPLICATION_CREDENTIALS",
new ClassPathResource("google_credentials.json").getURI().getPath());
SetEnv.setEnv(google);
最后一个错误。问题是因为您生成的文件无效。 您需要创建一个新的有效密码。
从API管理器中,只需创建选择“创建凭据”> “服务帐户密钥”并为该服务生成一个新密钥,即 关联到您的Google Play帐户。