I'm using ElevenLabs Api to convert text to speech , this api mainly returns byte[] as an audio , i tried to play it using MediaPlayer and AudioTrack but failed to do so, does anyone how to do that , Thank you in advance
[-61, -65, -61, -69, 80, -61, -124, 0, 0, 7, 40, 1, 103, -62, -76, 17, -62, -128, 1, -61, -113, -62, -99, -61, -83, 115, 24, -62, -80, 0, 0, 57, 38, 104, 0, -61, -108, 47, -61,
private void elevenLab() throws JSONException {
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.POST, LAB_URL, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
// getting response as byte
playFile(response.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
Log.d("VALUE","Response " + Arrays.toString(response.getBytes()));
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d("TAG","Error is " + error.getMessage());
}
}) {
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<String, String>();
headers.put("accept", "audio/mpeg");
headers.put("xi-api-key", LAB_KEY);
headers.put("Content-Type", "application/json");
return headers;
}
@Override
public byte[] getBody() {
JSONObject jsonBody = new JSONObject();
try {
jsonBody.put("text", "Hello How are you man?");
JSONObject voiceSettings = new JSONObject();
voiceSettings.put("stability", 0);
voiceSettings.put("similarity_boost", 0);
jsonBody.put("voice_settings", voiceSettings);
} catch (JSONException e) {
e.printStackTrace();
}
return jsonBody.toString().getBytes();
}
};
requestQueue.add(stringRequest);
}
private void playFile(byte[] response) throws IOException {
int sampleRate = 44100;
int channelConfig = AudioFormat.CHANNEL_OUT_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int bufferSize = AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat);
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, channelConfig, audioFormat, bufferSize, AudioTrack.MODE_STREAM);
audioTrack.play();
audioTrack.write(response, 0, response.length);
}
The main problem with this code is that you are requesting and operating on strings, while the returned object is byte[].
Here's a suggested change to your code:
Request<byte[]> request = new Request<byte[]>(Request.Method.POST, LAB_URL, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// Handle error
}})
{
@Override
public byte[] getBody() throws AuthFailureError {
JSONObject jsonBody = new JSONObject();
try {
jsonBody.put("text", responseMsg);
JSONObject voiceSettings = new JSONObject();
voiceSettings.put("stability", 0);
voiceSettings.put("similarity_boost", 0);
jsonBody.put("voice_settings", voiceSettings);
} catch (JSONException e) {
e.printStackTrace();
}
return jsonBody.toString().getBytes();
}
@Override
public String getBodyContentType() {
return "application/json";
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
headers.put("accept", "audio/mpeg");
headers.put("xi-api-key", "apikey");
return headers;
}
@Override
protected Response<byte[]> parseNetworkResponse(NetworkResponse response) {
return Response.success(response.data, HttpHeaderParser.parseCacheHeaders(response));
}
@Override
protected void deliverResponse(byte[] response) {
try {
playFile(response);
} catch (IOException e) {
e.printStackTrace();
}
}
};
requestQueue.add(request);
Note that this does not check if the response is 200. According to their specs it will return application/json content if something is wrong with the request.