steelejay / LowkeySpeech

Google Speech API in Unity (C#)
44 stars 19 forks source link

Produces a 403 error #3

Closed stroomwid closed 5 years ago

stroomwid commented 6 years ago

Сan I ask, I use your code and my API key, but it produces a 403 error, what could be the problem? I used unity 2018.2.4.f1 Link what i use: http://www.google.com/speech-api/v2/recognize?output=json&lang=en-us&key=xxx

steelejay commented 6 years ago

Hey dude, I'm afraid I haven't gotten the chance to run this code on 2018 yet. LukasMeine did a 2018 fork that you can check out here: https://github.com/LukasMeine/LowkeySpeech

You can find more notes on running that code here: https://github.com/steelejay/LowkeySpeech/issues/2

hexicle commented 6 years ago

@stroomwid In your Google Cloud console, make sure that you allow your application to connect to Google Cloud. To do this, navigate to https://console.cloud.google.com, select the Navigation Menu on the top-left (the three horizontal lines on the left of 'Google' image below), hover over the APIs & Services tab and click Credentials. On the right of your API key, click the pencil icon to edit restrictions. Scroll down to Key restrictions and make sure that you have allowed your API key to accept requests from your application.

capture - copy

freiSMS commented 6 years ago

@hexicle : I am getting the same error and allready followed your instructions above. The Google Console now says that the key does not restrict any applications and that they can access the API "Cloud Speech Api".

Edit: I only found documentation about the v1 REST API for Google Cloud Speech API. It says that the base URL is https://speech.googleapis.com (not anymore the http://www.google.com/speech-api in the code?). When chaning the base URL an the Version to v1 I can see the HTTP Posts in the google console but I get 400 "bad request" as a result. Any ideas?

freiSMS commented 6 years ago

More results on the mistake search:

1) When taking a wav file converting it to flac and the to Base64 I am able to send a Post Request via Fiddler Web Debuger. It results in a good translation of the wav file. The json paramters are: "config": { "encoding": "FLAC", "sampleRateHertz": 16000, "languageCode": "en-US" 2) The recording of the wav file in unity also is not the problem. I can process it like the above wav file and get a good translation. .... So I think the mistake is at the creation of the jsonBody or at the json paramters.

hexicle commented 6 years ago

@freiSMS Which repository is causing the issue? This repository, steelejay/LowkeySpeech is known to have issues with Google API. Be sure to use LukasMeine/LowkeySpeech which was made to solve the issues with Google API.

freiSMS commented 6 years ago

@hexicle I am using the lukasMeine Repo.

hexicle commented 6 years ago

@freiSMS I do not know the solution and will try it out later. But just in case it helps, in GoogleVoiceSpeech.cs , the response printed by line 105 will always be empty while the response printed by line 161 contains the actual response, because line 105 executes before the response can be retrieved from the API, whereas line 161 is properly asynchronous and waits for the response before printing it.

I speculate that Google API was updated again causing this issue, I will test the repository in a few hours to see if the case is actually caused by an update to Google API.

freiSMS commented 6 years ago

Sounds great @heixicle thanks =). Like I said: by changing the URL I was able to contact cloud speech.

hexicle commented 6 years ago

I tested the LukasMeine/LowkeySpeech repository as is and it produces the 403 Forbidden even with valid API keys. It produces the following error:

Error uploading file error: System.Net.WebException: The remote server returned an error: (403) Forbidden.
  at System.Net.HttpWebRequest.CheckFinalStatus (System.Net.WebAsyncResult result) [0x00000] in <filename unknown>:0 
  at System.Net.HttpWebRequest.SetResponseData (System.Net.WebConnectionData data) [0x00000] in <filename unknown>:0 
UnityEngine.Debug:Log(Object)
GoogleVoiceSpeech:HttpUploadFile(String, String, String, String) (at Assets/Scripts/GoogleVoiceSpeech.cs:166)
GoogleVoiceSpeech:OnGUI() (at Assets/Scripts/GoogleVoiceSpeech.cs:105)

You are right, the solution is to update the request URL and parameters for contacting the Google Speech API.

freiSMS commented 6 years ago

Nice @hexicle =) Did it work for you? Can you post the parameters?

freiSMS commented 6 years ago

@hexicle: When tracing the http Request with fiddler I get this result from server: bd { "error": { "code": 400, "message": "Invalid JSON payload received. Unexpected token.\nRIFF$A\n\u0000WAVEfmt \u0010\u0000\u0000\u0000\n^", "status": "INVALID_ARGUMENT" } } ....It s strange: the google speech api says that wav and flac files tell their format in data. I think that is what the "Riff...Wav... " part does. But the server can't understand it.

freiSMS commented 6 years ago

I tried to add the json objects to the request stream like the google speech api structure wants it:

{   
"config": {     object(RecognitionConfig)   },
   "audio": {     object(RecognitionAudio)   }
 }

So the code now looks like this:

        StringBuilder headerString = new StringBuilder();
        headerString.Append("{\"audio\": {\"content\": \" ");
        byte[] headerBytes = Encoding.ASCII.GetBytes(headerString.ToString());

        StringBuilder byteResultString = new StringBuilder();

    Stream rs = wr.GetRequestStream();
        rs.Write(headerBytes, 0, headerBytes.Length);
    FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
    byte[] buffer = new byte[4096];
    int bytesRead = 0;
    while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) {
        rs.Write(buffer, 0, bytesRead);
               byteResultString.Append(buffer);
    }
        string bodyEndString = " \"  },  \"config\": {\"languageCode\": \"en-US\"  }}";
        byte[] bodyEndBytes = Encoding.ASCII.GetBytes(bodyEndString);

But the Http Request won't contain the bodyEndString.... If i don't write the media file the http request the body EndString is there. Do I have problems with encoding?

freiSMS commented 6 years ago

I do.... I thought the files in example projects and the one in the code folder are the same.... They are not. In the example folder is the new version, where @LukasMeine does what I only tryed to do ;-). To make it work I had to do two changes: 1) Edit Line 139 and 141:

string resultString = jsonresponse ["result"] [0].ToString ();
string transcripts = jsonResults ["alternative"] [0] ["transcript"].ToString ();

The json "result" object is now called "results" and instead of "alternative" you have to parse "alternatives"

2) In line 204 return the result object

202               var result = streamReader.ReadToEnd();
203               Debug.Log("Response:" + result);
204               return result;

If you don't line 215 will result the string "empty" and json will therefore faile parsing afterwards.

LukasMeine commented 6 years ago

Hey guys, looks like Google's API has changed once again. I may have the time to update my fork and finally submit a pull request to this project tonight. Does that interest you?

hexicle commented 6 years ago

@LukasMeine Yes

freiSMS commented 6 years ago

@lukasMeine I integrated your work in my speech assistant, so momently I am happy. But for other projects I could need the repo. Thanks =)

yodashtein commented 6 years ago

Hi @LukasMeine , I am too working on a VR project using google's speech to text. I'm currently also having the same error problem using steelejay's version. Very interested in your updates to get this fixed!

yodashtein commented 6 years ago

Guys I seem to be getting this error:

{ "error": { "code": 403, "message": "The request is missing a valid API key.", "status": "PERMISSION_DENIED" } }


Any ideas how to get a valid API key? I entered one in that I got from the google console: Credentials -> API Keys.

hexicle commented 6 years ago

@yodashtein None of the repositories work right now even with valid API keys, which I am guessing is because of an update to Google Speech API on July 28 2018.

Usually, in order for an API key to work it needs to allow requests from an application, as described above. However, I am getting the same error 403 Invalid key despite following following those steps and allowing requests. Therefore, I am guessing that the real problem is not because we are using invalid API keys, but actually because the API link http://www.google.com/speech-api/v2/recognize?output=json&lang=en-us&key= is deprecated and therefore cannot be used at all.

hexicle commented 6 years ago

@LukasMeine I really really want your update

LukasMeine commented 6 years ago

Just got some spare time to work at it, I should be making a pull request in the next few hours.

LukasMeine commented 6 years ago

@yodashtein @hexicle Making a pull request right now ;)

image

And @steelejay, i guess i could maintain this repo if you are interested.

cg1312 commented 5 years ago

@LukasMeine I am still getting a 400 Error. Could you please look into the issue?

LukasMeine commented 5 years ago

@cg1312 I just tested my fork and it works just fine.

proof:

image

Troubleshooting

steelejay commented 5 years ago

Is this good now? Can we close it?