我正在使用一个非常基本的 java 声音类从 Bing Translate 流式传输音频以用于汉字的发音。它对我测试过的所有 20 个单词都非常有效,除了一个。
当我尝试获得单词“你”的发音时(意思是你),我得到了错误的声音。奇怪的是,当我获取在代码中形成的 URL 并手动将其放入浏览器(我正在使用 Bing Translate HTTP API)时,我得到了正确的声音。所以在我看来,错误必须在我的代码中的某个地方。我唯一能想到的地方就是缓冲区。
真正奇怪的是,我没有得到沉默或胡言乱语。相反,返回的声音是用中文说“一半”(字面意思是“二分之一”)的方式。正如我之前所说,当我将 URL 放入浏览器时,我会听到“你”的正确声音。
编辑:另外,如果我输入你们(对你来说是复数并且包括原始字符),我会得到正确的声音。
我的代码如下。在我的 pvsm 中,我所拥有的只是创建此类的一个实例,然后调用 speakWord(你)
public class WordSpeaker {
private static final String TEST_CONN = "http://api.microsofttranslator.com/v2/Http.svc/" +
"Detect?appId=5768596A4F34453BDAED3138E800D4F7EB5097B9&text=hello";
private static final String TEST_VAL = "en";
private static final String URL_FRONT = "http://api.microsofttranslator.com/v2/Http.svc/Speak?appId=" +
"5768596A4F34453BDAED3138E800D4F7EB5097B9" + "&text=";
private static final String URL_END = "&language=zh-cn";
private AudioInputStream audioStream = null;
private static final int EXTERNAL_BUFFER_SIZE = 128000;
public WordSpeaker() {
}
public void speakWord(String sWord) {
try {
URL bingTranslate = new URL(URL_FRONT + sWord + URL_END);
System.out.println(bingTranslate.toString());
audioStream = AudioSystem.getAudioInputStream(bingTranslate);
} catch (Exception e) {
e.printStackTrace();
}
AudioFormat format = audioStream.getFormat();
SourceDataLine line = null;
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
try {
line = (SourceDataLine) AudioSystem.getLine(info);
line.open(format);
} catch (LineUnavailableException le) {
System.out.println(le);
} catch (Exception e) {
e.printStackTrace();
}
line.start();
int bytesRead = 0;
byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];
while (bytesRead != -1){
try{
bytesRead = audioStream.read(abData,0,abData.length);
} catch (Exception e){
e.printStackTrace();
}
if (bytesRead >=0){
int bytesWritten = line.write(abData,0,bytesRead);
}
}
line.drain();
line.close();
}
private boolean testBing() {
try {
URL test = new URL(TEST_CONN);
BufferedReader testRead = new BufferedReader(new InputStreamReader(test.openStream()));
String inLine = testRead.readLine();
return inLine.substring(inLine.lastIndexOf("\">") + 2, inLine.lastIndexOf("<")).equals(TEST_VAL);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}