Skip to content
Advertisement

php IBM Watson Speech to text “unable to transcode data stream audio/flac ” error

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.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement