I am trying to use IBM Watson’s speech-to-text service using PHP. I don’t know much about the curl language. In the documentation of IBM cloud, there’s this curl code:
curl -X POST -u "apikey:{apikey}" --header "Content-Type: audio/flac" --data-binary @{path_to_file}audio-file.flac "{url}/v1/recognize"
I used a curl to PHP converter service and got this:
// Generated by curl-to-PHP: http://incarnate.github.io/curl-to-php/ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, '{url}/v1/recognize'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); $post = array( 'file' => '@' .realpath('{path_to_file}audio-file.flac') ); curl_setopt($ch, CURLOPT_POSTFIELDS, $post); curl_setopt($ch, CURLOPT_USERPWD, 'apikey' . ':' . '{apikey}'); $headers = array(); $headers[] = 'Content-Type: audio/flac'; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $result = curl_exec($ch); if (curl_errno($ch)) { echo 'Error:' . curl_error($ch); } curl_close($ch);
I am working on a server, my overall PHP code successfully connects to the server and the user can upload a file on the server. But when I want to send the file on the server to the IBM cloud, I get an error. I modified the curl code so that I send the binary content of the file:
<?php // Generated by curl-to-PHP: http://incarnate.github.io/curl-to-php/ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://api.us-south.speech-to-text.watson.cloud.ibm.com/instances/fd2c1d8f-3fba-48aa-846c-f0b4d603b724/v1/recognize'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); $file = file_get_contents('uploads/hello.flac'); $post = array( 'file' => $file ); curl_setopt($ch, CURLOPT_POSTFIELDS, $post); curl_setopt($ch, CURLOPT_USERPWD, 'apikey' . ':' . 'dummyKey'); $headers = array(); $headers[] = 'Content-Type: audio/flac'; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $result = curl_exec($ch); if (curl_errno($ch)) { echo 'Error :' . curl_error($ch); } echo $result; curl_close($ch); ?>
So I changed the associative array when making $post
since I want to pass the binary content of the file to IBM. uploads/hello.flac
is the link to the target file. The uploads directory and my PHP file are in the same directory so addressing is true.
I checked several other links such as this and after a couple hours of tweaking failed to solve the error.
When I echo $result
, this is what I get { "error": "unable to transcode data stream audio/flac -> audio/l16 ", "code": 400, "code_description": "Bad Request" }
, instead of getting something like this:
{ "result_index": 0, "results": [ { "alternatives": [ { "confidence": 0.96 "transcript": "several tornadoes touch down as a line of severe thunderstorms swept through Colorado on Sunday " } ], "final": true } ] }
Thanks.
Advertisement
Answer
Sorry, very late to the party on this one, but…this cURL sequence works for us:
$ibm_instance_url = ""; /// YOUR IBM INSTANCE URL /// EXAMPLE: https://api.eu-gb.speech-to-text.watson.cloud.ibm.com/instances/123456789... $username = "apikey"; $password = ""; /// YOUR IBM API KEY GOES HERE $path_to_file = "/path/to/file/"; $file_name = ""; /// YOUR FILENAME GOES HERE $file_extention = "mp3"; /// YOUR IBM AUDIO FORMAT GOES HERE $open_path_to_filename = $path_to_file . $file_name .".". $file_extention; $file = fopen($open_path_to_filename, 'r'); $filesize = filesize($open_path_to_filename); $bytes = fread($file,$filesize); $headers = array("Content-Type: audio/".$file_extention ,"Transfer-Encoding: chunked"); // ,"Transfer-Encoding: binary" $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $ibm_instance_url."/v1/recognize"); curl_setopt($ch, CURLOPT_USERPWD, "$username:$password"); curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_BINARYTRANSFER, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, $bytes); curl_setopt($ch, CURLOPT_INFILESIZE, $filesize); curl_setopt($ch, CURLOPT_VERBOSE, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $executed = curl_exec($ch); curl_close($ch);
We found that the key to success was making sure that the audio file uploaded to IBM was correctly / formally encoded.