I am trying to use google's text to speech in my php website to be hosted on a live Cpanel Server
I have enabled the text to speech API, Created API KEY in Credentials section, also downloaded the json file of credentials from Create service account key page.
Then I downloaded the sample files from Github and also used composer to build the library
Now I dont understand where to put my keys. At every place, it demangs to EXPORT the key in Shell, but that would work for 1 open command prompt session and will have to be exported every time.
As I want to run this code on a live cpanel based hosting, so I think it wont be possible to export.
Is there any place within the codes where I can pass the key?
On this url article at stackoverflow: the first answer exports the response of CURL to synthesize-text.txt but we require mp3 output
Another answer states that we should use jq but since its a shared hsoting server, I am not sure if we can arrange jq.
Is ther any way out to this problem?
Update
Tried the following code after referring to the answer by #V.Tur
$params = [
"audioConfig"=>[
"audioEncoding"=>"MP3",
"pitch"=> "1",
"speakingRate"=> "1",
"effectsProfileId"=> [
"medium-bluetooth-speaker-class-device"
]
],
"input"=>[
"ssml"=>'<speak>The <say-as interpret-as=\"characters\">SSML</say-as>
standard <break time=\"1s\"/>is defined by the
<sub alias=\"World Wide Web Consortium\">W3C</sub>.</speak>'
],
"voice"=>[
"languageCode"=> "hi-IN",
"name" =>"hi-IN-Wavenet-B",
'ssmlGender'=>'MALE'
]
];
$data_string = json_encode($params);
$speech_api_key = "My_Key_Here";
$url = 'https://texttospeech.googleapis.com/v1/text:synthesize?fields=audioContent&key=' . $speech_api_key;
$handle = curl_init($url);
curl_setopt($handle, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($handle, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string)
]
);
$response = curl_exec($handle);
$responseDecoded = json_decode($response, true);
curl_close($handle);
if($responseDecoded['audioContent']){
return $responseDecoded['audioContent'];
}
I get the audio downloaded but the pauses/breaks I have mentioned in ssml did not work. I tried passing data to $params as below
$params = "{
'input':{
'ssml':'<speak>The <say-as interpret-as=\"characters\">SSML</say-as>
standard <break time=\"1s\"/>is defined by the
<sub alias=\"World Wide Web Consortium\">W3C</sub>.</speak>'
},
'voice':{
'languageCode':'en-us',
'name':'en-US-Standard-B',
'ssmlGender':'MALE'
},
'audioConfig':{
'audioEncoding':'MP3'
}
}";
But I get the following error:
Array ( [error] => Array ( [code] => 400 [message] => Invalid JSON
payload received. Unknown name "": Root element must be a message.
[status] => INVALID_ARGUMENT [details] => Array ( [0] => Array (
[#type] => type.googleapis.com/google.rpc.BadRequest [fieldViolations]
=> Array ( [0] => Array ( [description] => Invalid JSON payload received. Unknown name "": Root element must be a message. ) ) ) ) ) )
How to solve this?
Below my working example text-to-speech, you could redo for your needs:
public static function getSound($text)
{
$text = trim($text);
if($text == '') return false;
$params = [
"audioConfig"=>[
"audioEncoding"=>"LINEAR16",
"pitch"=> "1",
"speakingRate"=> "1",
"effectsProfileId"=> [
"medium-bluetooth-speaker-class-device"
]
],
"input"=>[
"text"=>$text
],
"voice"=>[
"languageCode"=> "en-US",
"name" =>"en-US-Wavenet-F"
]
];
$data_string = json_encode($params);
$url = 'https://texttospeech.googleapis.com/v1/text:synthesize?fields=audioContent&key=' . $speech_api_key;
$handle = curl_init($url);
curl_setopt($handle, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($handle, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string)
]
);
$response = curl_exec($handle);
$responseDecoded = json_decode($response, true);
curl_close($handle);
if($responseDecoded['audioContent']){
return $responseDecoded['audioContent'];
}
return false;
}
using:
public static function saveSound($text)
{
$speech_data = SpeechAPI::getSound($text);//see method upper
if($speech_data) {
$file_name = strtolower(md5(uniqid($text)) . '.mp3');
$path = FileUpload::getFolder();//just return directory path
if(file_put_contents($path.$file_name, base64_decode($speech_data))){
return $file_name;
}
}
return null;
}
For SSML standart need to change input params:
$text = "<speak>The <say-as interpret-as=\"characters\">SSML</say-as>
standard <break time=\"1s\"/>is defined by the
<sub alias=\"World Wide Web Consortium\">W3C</sub>.</speak>";
$params = [
"audioConfig"=>[
"audioEncoding"=>"LINEAR16",
"pitch"=> "1",
"speakingRate"=> "1",
"effectsProfileId"=> [
"medium-bluetooth-speaker-class-device"
]
],
"input"=>[
//"text"=>$text
"ssml" => $text
],
"voice"=>[
"languageCode"=> "en-US",
"name" =>"en-US-Wavenet-F"
]
];
about choose audioEncoding - https://cloud.google.com/speech-to-text/docs/encoding
Related
I am having trouble finding out why my script is returning "result":null,"error" rather than a successful transaction.
This curl command works when run manually;
curl --user username:password --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "sendtoaddress", "params": ["someaddress", 0.001] }' -H 'content-type: text/plain;' http://".199.42.160.41:8332
Here is the code I'm using attempting to replicate the above curl command which works;
$url = "http://199.42.160.41:8332";
$address = "address";
$address = '"'.$address.'"'; //Adding double quotation marks around the address.
$amount = 0.001;
$bounty = $address.', '.$amount;
$payload = ["jsonrpc" => "1.0", "id" => "curltest", "method" => "sendtoaddress", "params" => [$bounty] ];
$payload=json_encode($payload);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERPWD, $user . ":" . $pass);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_POSTREDIR, 3);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$res=curl_exec($ch);
echo "<br/><br/>";
echo "Result from attempting to send transaction is below this line</br>";
print_r($res);
curl_close($ch);
With the above I can see that $payload is set as follows;
$payload is set to the following;
Array ( [jsonrpc] => 1.0 [id] => curltest [method] => sendtoaddress [params] => Array ( [0] => "sendtoaddress", 0.001 ) )
What am I missing or doing wrong?
Edit: My $payload looks like this once it's been converted to jsonrpc
{"jsonrpc":"1.0","id":"curltest","method":"sendtoaddress","params":["someaddress, 0.001"]}
From what I can tell, I need to have it look like this;
{"jsonrpc":"1.0","id":"curltest","method":"sendtoaddress","params":["someaddress", 0.001]}
Found and fixed the issue. $payload wasn't what I needed, I needed to use two variables for it to be formatted correctly for jsonrpc.
//$payload = ["jsonrpc" => "1.0", "id" => "curltest", "method" => "sendtoaddress", "params" => [$bounty] ];
$payload = ["jsonrpc" => "1.0", "id" => "curltest", "method" => "sendtoaddress", "params" => [$address, $amount] ];
Now that $payload is set correctly the script works!
I am trying to get more than 20 images with the searches endpoint:
$data = '{
"query": {
"ands": [
{
"output": {
"input": {
"data": {
"image": {
"url": "' . $url . '"
}
}
}
}
}
]
}
}';
$ch = curl_init('https://api.clarifai.com/v2/searches?
page=1&per_page=30');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Authorization: Key " . self::$clarify_user_apikey,
"Content-Type: application/json")
);
$output = curl_exec($ch);
curl_close($ch);
The images are initialized above in the $data variable.
Does the image search not have pagination and per_page attributes, or what am I doing wrong?
However I change the two attributes, I always get a max of 20 images back. The App / Project in question has more than 70k images, and the explorer app shows more images as well.
Thanks!
I found the answer.
For easier understanding I formatted the JSON part into an array.
$data = array(
"query" => array(
"ands" => array(
array(
"output" => array(
"input" => array(
"data" => array(
"image" => array(
"url" => $url
)
)
)
)
)
)
),
"pagination" => array(
"page" => 1,
"per_page" => 100
),
);
This code gives 100 images back. I haven't seen an upper limit yet, but it seems to work fine with 500 images as well. The request call gets slow then, though.
I am creating a new PHP application in which I want to interact with Keybase.
First option is to use the API, but unfortunately I am running into some issues.
First step is to call the signup call.
I managed to create a curl request, but I am not sure what the pwh should look like.
I tried:
$fp = #fopen('/dev/urandom','rb');
if ($fp !== FALSE) {
$prBits .= #fread($fp,16);
#fclose($fp);
}
$salt = bin2hex($prBits);
$pwh = implode(unpack("H*",password_hash('MyP#ssword'.$prBits, PASSWORD_BCRYPT)));
But making the call results in:
{
"status": {
"code": 100,
"desc": "need a PDPKA5 key",
"name": "INPUT_ERROR"
},
"csrf_token": "lgHZIDA4ZjYyNzgy.....86aMrL09"
}
The complete call:
$data = [
"name" => "My Name",
"email" => "mymail#example.com",
"username" => "SomeUnusedUsername1234",
"pwh" => $pwh,
"pwh_version" => 3,
"salt" => $salt,
"invitation_id" => "000000001"
);
$dataString = json_encode($data);
$ch = curl_init('https://keybase.io/_/api/1.0/signup.json');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $dataString);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
$result = curl_exec($ch);
Anyone got a working example or solution?
I am trying to call Google Cloud Speech API by using PHP and got a problem.
$stturl = "https://speech.googleapis.com/v1beta1/speech:syncrecognize?key=xxxxxxxxxxxx";
$upload = file_get_contents("1.wav");
$upload = base64_encode($upload);
$data = array(
"config" => array(
"encoding" => "LINEAR16",
"sampleRate" => 16000,
"languageCode" => "en-US"
),
"audio" => array(
"Content" => $upload,
)
);
$jsonData = json_encode($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $stturl);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
$result = curl_exec($ch);
The result says that it is INVALID JSON PAYLOAD.
{ "error": { "code": 400, "message": "Invalid JSON payload received.
Unknown name \"content\" at 'audio': Cannot find field.", "status":
"INVALID_ARGUMENT", "details": [ { "#type":
"type.googleapis.com/google.rpc.BadRequest", "fieldViolations": [ {
"field": "audio", "description": "Invalid JSON payload received.
Unknown name \"content\" at 'audio': Cannot find field." } ] } ] } } "
I think this is because $upload isn't configured correctly.
According Google Cloud Speech API, it should be "A base64-encoded string".
https://cloud.google.com/speech/reference/rest/v1beta1/RecognitionAudio
That's why I used base64_encode function, but it seems JSON doesn't process this value correctly.
Any thoughts?
You need to construct the properly formatted input as an array and then json encode it. For example, to send a file, base64encode it as "content" and submit to the API as shown:
$data = array(
"config" => array(
"encoding" => "LINEAR16",
"sample_rate" => $bitRate,
"language_code" => "en-IN"
),
"audio" => array(
"content" => base64_encode($filedata)
)
);
$data_string = json_encode($data);
$ch = curl_init($googlespeechURL);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
$result = curl_exec($ch);
$result_array = json_decode($result, true);
please make 'content' instead of 'Content'
small letter 'c'
its work for me.
Hi im trying to translate this python script to php. I don't have much knowledge of Python and limited for PHP.
The python script is:
import urllib2
import json
data = {
"Inputs": {
"input1": {
"ColumnNames": ["Client_ID"],
"Values": [ [ "0" ], [ "0" ], ]
},
},
"GlobalParameters": {}
}
body = str.encode(json.dumps(data))
url = 'https://ussouthcentral.services.azureml.net/workspaces/3e1515433b9d477f8bd02b659428cddc/services/cb1b14b17422435984943d51b5957ec7/execute?api-version=2.0&details=true'
api_key = 'abc123'
headers = {'Content-Type':'application/json', 'Authorization':('Bearer '+ api_key)}
req = urllib2.Request(url, body, headers)
try:
response = urllib2.urlopen(req)
result = response.read()
print(result)
except urllib2.HTTPError, error:
print("The request failed with status code: " + str(error.code))
print(error.info())
print(json.loads(error.read()))
In a bid to try and convert it myself, here is what I have done so far:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
$data = array(
'Inputs'=> array(
'input1'=> array(
'ColumnNames' => ["Client_ID"],
'Values' => [ [ "0" ], [ "0" ], ]
),
),
'GlobalParameters'=> array()
);
$body = json_encode($data);
$url = 'https://ussouthcentral.services.azureml.net/workspaces/3e1515433b9d477f8bd02b659428cddc/services/cb1b14d17425435984943d41a5957ec7/execute?api-version=2.0&details=true';
$api_key = 'abc123';
$headers = array('Content-Type'=>'application/json', 'Authorization'=>('Bearer '+ $api_key));
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL,$url);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($curl);
var_dump($result);
im sure I have got lots wrong but would appreciate the help.
thanks
I just had to do this myself and though I'd provide an answer for you. If you're going to talk to Azure's ML platform using php, you need to build your CURL call like this:
$data = array(
'Inputs'=> array(
'input1'=> array(
'ColumnNames' => array("header1", "header2", "header3"),
'Values' => array( array("value1" , "value2" , "value3"))
),
),
'GlobalParameters'=> null
);
$body = json_encode($data);
$url = 'your-endpoint-url';
$api_key = 'your-api-key';
$headers = array('Content-Type: application/json', 'Authorization:Bearer ' . $api_key, 'Content-Length: ' . strlen($body));
$this->responseArray['body'] = $body;
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($curl);
Of all the places to get hung up, it was on the GlobalParameters for me, and is for you, too. You need this instead:
GlobalParameters => null
This generates the following JSON
GlobalParameters: {}
whereas
GlobalParameters => array()
gives
GlobalParameters: []
it's a subtle distinction, but enough to make Azure throw a hissy fit.
I didn't test using your curl_setopt functions and instead used what I've included in my example. I'm assuming it will work using the curl_setopts you have, but I don't know for sure.
I had some trouble adapting this perfectly, and I wanted to be able to easily work with JSON & Guzzle. Below is the solution that I built.
First is the function for making the actual call to Azure. Note that Guzzle wants your URL to be split into the domain and URI pieces.
This should all be in your .env file (if you're using Laravel at least).
AZURE_BASE=https://ussouthcentral.services.azureml.net
AZURE_URL=/workspaces/[[YOUR_STUFF_HERE]]/services/[[YOUR_STUFF_HERE]]/execute?api-version=2.0&format=swagger
AZURE_PRIMARY_KEY=[[YOUR_KEY]]
use GuzzleHttp\Client;
public function learn () {
$client = new Client([
'base_uri' => env('AZURE_BASE'),
'timeout' => 2.0,
]);
$headers = [
'Authorization' => 'Bearer ' .env('AZURE_PRIMARY_KEY'),
'Accept' => 'application/json',
'Content-Type' => 'application/json'
];
$data = $this->test_data();
$body = json_encode($data);
$response = $client->request('POST', env('AZURE_URL'), [
'headers' => $headers,
'body' => $body
]);
return $response;
}
As other answers have noted, the data setup is very touchy. new \stdClass is the key here, as we need to end up with a JSON Object ({}) not an array ([]). stdClass creates that empty object for us.
function test_data () {
return array(
'Inputs'=> array(
'input1'=> array(
[
'DESC' => "",
'2-week-total'=> "1",
'last-week'=> "1",
'this-week'=> "1",
'delta'=> "1",
'normalized delta'=> "1",
'delta-percent'=> "1",
'high-total-delta'=> "1",
'high-total-amt'=> "1",
'role'=> ""
]
),
),
'GlobalParameters'=> new \stdClass,
);
}
Now when you call ->learn(), you'll get back some nice JSON to do what you need.