1

I need to dynamically embed returned audio data so I can play requested mpegs.

<embed src= is looking for a file path, but I don't have files locally.

I make a successful request which returns audio/mpeg binary data:

enter image description here

    $.get('testPHP.php?translate_tts?ie=utf-8&tl=zh-CN&q=你好',
        function (returned_data) {
            document.getElementById("audio").innerHTML=
                "<embed src=\""+returned_data+"\" hidden=\"true\" autostart=\"true\" loop=\"false\" />";
        }
    );

How can I create the audio element with that data?

PHP:

<?php
header('Content-type: text/plain; charset=utf-8');
$params = http_build_query(array("ie" => $_GET['ie'],"tl" => $_GET["tl"], "q" => $_GET["q"]));
$ctx = stream_context_create(array("http"=>array("method"=>"GET","header"=>"Referer: \r\n"))); //create and return stream context
$soundfile = file_get_contents("https://translate.google.com/translate_tts?".$params, false, $ctx); //reads file into string (string with params[utf-8, tl, q], use include path bool, custom context resource headers)

header("Content-type: audio/mpeg");
header("Content-Transfer-Encoding: binary");
header('Pragma: no-cache');
header('Expires: 0');

echo base64_encode($binary_data);

Edit: I'm able to play audio if I pull directly from my server:

    var returned_data = '/recordings/subjects/Wo_I.mp3';
    document.getElementById("audio").innerHTML=
        "<embed src=\""+returned_data+"\" hidden=\"true\" autostart=\"true\" loop=\"false\" />";

Resource interpreted as Document but transferred with MIME type audio/mpeg: "http://melon.localhost/recordings/subjects/Wo_I.mp3".

If I try encoding in base64 in PHP above...

'<embed src="data:audio/mpeg;base64,'+returned_data+'" hidden="true" autostart="true" loop="false"/>'

It's transferred with MIME to audio/mpeg, but no music plays.

Resource interpreted as Document but transferred with MIME type audio/mpeg: "data:audio/mpeg;base64,".

user3871
  • 12,432
  • 33
  • 128
  • 268
  • This is just a guess, but could you get the script to return a base64 string and then do `''` – Mike Jun 20 '15 at 03:10
  • On second thought, if this works, encode it in JS, not PHP, because base64 encoding makes the filesize about 4/3 of the original. – Mike Jun 20 '15 at 03:19
  • @Mike how do I encode it in JS? That didn't work. See above for error – user3871 Jun 20 '15 at 03:21
  • That's not base64 encoding. It looks like URL encoding to me. In your PHP do `echo base64_encode($binary_data);` – Mike Jun 20 '15 at 03:26
  • response is: `Resource interpreted as Document but transferred with MIME type audio/mpeg: "data:audio/mpeg;base64,".` this looks better, but no sound plays – user3871 Jun 20 '15 at 03:28
  • That just means you need to get rid of the content-type header that PHP sends and instead send `text/plain` because base64_encode produces an alphanumeric string. – Mike Jun 20 '15 at 03:31
  • @Mike okay, I've removed `header("Content-type: audio/mpeg");` and replaced with `header("content-type: text/plain");` in the php script above. I'm getting the same message. – user3871 Jun 20 '15 at 03:34
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/81047/discussion-between-mike-and-growler). – Mike Jun 20 '15 at 03:35

1 Answers1

1

You could base64 encode the audio file using PHP and put the data directly into the <embed> tag.

In your PHP, send header("Content-type: text/plain"); (since you will now be sending plain text) and base64 encode the audio file using base64_encode():

echo base64_encode($binary_data);

Then in your JavaScript, you would put it directly into the <embed> tag:

elem.innerHTML = '<embed src="data:audio/mpeg;base64,'+returned_data+'" hidden="true" autostart="true" loop="false"/>';

Note that when you base64 encode the size is about 4/3 of its binary equivalent, so if you are transferring large audio files, it would be preferred to do the encoding using Javascript. Since unfortunately there's no native javascript function to base64 encode binary data, here's an example of how you could do it.

Community
  • 1
  • 1
Mike
  • 23,542
  • 14
  • 76
  • 87