Google-cloud-php: Base64-encoded files from PHP not accepted

Created on 26 Jul 2020  Â·  6Comments  Â·  Source: googleapis/google-cloud-php

As your standard PHP script is not working at all @https://github.com/googleapis/google-cloud-php/issues/3254, I tried a cURL request instead:

This file works from the command prompt:

D:\Temp>gcloud ml speech recognize subs.wav --language-code=ja-JP
{
  "results": [
    {
      "alternatives": [
        {
          "confidence": 0.9474271,
          "transcript": "çˆ¶ă«ăŻæ„›äșșăŒă„ăŸă‚“ă§ă™ă“ăźă‚«ăƒŒăƒ‰ăźă“ăšăŒé ­ă‹ă‚‰é›ąă‚ŒăȘă„ă‚“ă§ă™ćƒ•ăŻăŸă çœŸćźŸăŒçŸ„ă‚ŠăŸă„ă ă‘ă§ă™ç§ă˜ă‚ƒăȘいわ"
        }
      ]
    },
    {
      "alternatives": [
        {
          "confidence": 0.90079355,
          "transcript": "男たäșșちょっべæ€ȘしくăȘいだっど5000äž‡è¶…ăˆăŸé€”ç«Żèż‘ă„ă„ăŠăăŸă‚“ă§ă—ă‚‡ă†ç§èš€ăŁăŸă‚ˆă­ć­äŸ›ăŻăŸă éŁŻèĄŒăŁăŠă“ă‚Œă ăŁăŸ"
        }
      ]
    },
    {
      "alternatives": [
        {
          "confidence": 0.8782166,
          "transcript": "ć­äŸ›æŹČしいんだよあăȘたはèȘ°ă‹ă‚’ć„œăăȘべこべある"
        }
      ]
    }
  ]
}

However, in PHP this happens:

$file = file_get_contents('D:\Temp\subs.wav');
$audio = base64_encode($file);
$apikey = 'DELETEDONPURPOSE';

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://speech.googleapis.com/v1/speech:recognize?key=' . $apikey);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\n  'config': {\n    'encoding': 'LINEAR16',\n    'sampleRateHertz': 16000,\n    'languageCode': 'ja-JP',\n    'enableWordTimeOffsets': false\n  },\n  'audio': {\n    'content': ' . $audio . '\n  }\n}");

$headers = array();
$headers[] = 'Content-Type: application/json; charset=utf-8';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);

var_dump($result);

This gives:
string(4420931) "{ "error": { "code": 400, "message": "Invalid value at 'audio.content' (TYPE_BYTES), Base64 decoding failed for \" . UklGRjhLGQBX...

So all options are blocked. I have to add that compared to Azure, this is about the most user-unfirendly documentation I have ever seen. Nothing works out of the box. I got Azure Speech Regocnition up and running in 5 minutes; I've spent 2 days on Google, and nothing works. The only reason why I'm persisting, is that your voice recognition seems to be superior. But please, help me out here.

speech question

All 6 comments

Your request body contains invalid JSON. JSON fields and string values must use double quotes.

Use json_encode to properly encode your request body:

$body = [
    'config' => [
        'encoding' => 'LINEAR16',
        'sampleRateHertz' => 16000,
        'languageCode' => 'ja-JP',
        'enableWordTimeOffsets' => false,
    ],
    'audio' => [
        'content' => base64_encode($audio)
    ]
];
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));

Thank you for your help! This was generated by an automated cuRL generator on the net and I never looked back. Stupid of me.

This helps already, but we're not there yet...

Transcribing D:\Temp\subs_1min.wav...

Result:
string(3) "{} "

I double-checked: the file has a bit-depth of 16 bits, is mono and has a 16000 sampling rate. It's size is about 180 K.

Of course, this is purely for testing purposes. If it works, I'm genuinely interested in taking a Google Cloud subscription.

We currently have:

$audio = "D:\Temp\subs_8s.wav";
echo 'Transcribing ' . $audio . '...<br><br>';

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://speech.googleapis.com/v1/speech:recognize?key=' . $apikey);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
$body = [
    'config' => [
        'encoding' => 'LINEAR16',
        'sampleRateHertz' => 16000,
        'languageCode' => 'ja-JP',
        'enableWordTimeOffsets' => false,
    ],
    'audio' => [
        'content' => base64_encode($audio)
    ]
];
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));

$headers = array();
$headers[] = 'Content-Type: application/json; charset=utf-8';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);

var_dump($result);

Are you able to share the source audio file? It's much easier to debug speech when both of us are working off the same inputs.

Your sample doesn't fetch the audio file contents -- is that the issue? You're sending the file name as the audio content. When I send the base64-encoded contents to the API, I receive a response:

string(271) "{
  "results": [
    {
      "alternatives": [
        {
          "transcript": "æ‰‹ă«ăŻæ„›äșșăŒă„ăŸă‚“ă§ă™ă“ăźă‚«ăƒŒăƒ‰ăźă“ăšăŒé ­ă‹ă‚‰é›ąă‚ŒăȘいんです",
          "confidence": 0.94493204
        }
      ],
      "languageCode": "ja-jp"
    }
  ]
}"

But of course! During all the edits, that bit got lost. Thank you very much for your help! I now have a working concept. I'll continue with some larger files and then subscribe. It's strange that @#3254 doesn't work, but this does the same in the end and is good enough for me. Besides, I like this approach more, as I can now exacty see what is happening, whereas using the Google Libraries is pretty convoluted and not very transparant.

Final result:

`$audiofilename = "D:\Temp\subs_8s.wav";
$audiofilecontents = file_get_contents($audiofilename);
echo 'Transcribing ' . $audiofilename . '...

';

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://speech.googleapis.com/v1/speech:recognize?key=' . $apikey);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
$body = [
'config' => [
'encoding' => 'LINEAR16',
'sampleRateHertz' => 16000,
'languageCode' => 'ja-JP',
'enableWordTimeOffsets' => false,
],
'audio' => [
'content' => base64_encode($audiofilecontents)
]
];
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));

$headers = array();
$headers[] = 'Content-Type: application/json; charset=utf-8';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);

var_dump($result);`

Was this page helpful?
0 / 5 - 0 ratings

Related issues

smalot picture smalot  Â·  6Comments

Najtmare picture Najtmare  Â·  6Comments

codeflorist picture codeflorist  Â·  5Comments

joseph1125 picture joseph1125  Â·  8Comments

ruschoni02 picture ruschoni02  Â·  6Comments