Convert base 64 to audio Mp3 Format on PHP - php

I have an "audio" tag with the script (actually a plugin) that receives and saves it as base64. And this works okay.
I am trying to alter the script to send the base64 into the server and convert it to mp3 and display the recorded audio in the page.
This is what I have done so far.
Script to save file through ajax:
$(document).on("click", "#download:not(.disabled)", function(){
Fr.voice.export(function(url){
//$("<a href='"+url+"' download='MyRecording.wav'></a>")[0].click();
var src = url;
$.ajax({
url: $("#base_url").val() + "ajax/saveRecordedVoice",
type: "POST",
data: {"record_src": src},
success: function(result){
alert(result);
}
});
}, "base64");
restore();
});
PHP Script to Convert and Save File:
public function saveRecordedVoice()
{
$audio = $_POST['record_src'];
$decoded = base64_decode($audio);
$file_location = "assets/records/recorded_audio.mp3";
$success = file_put_contents($file_location, $decoded);
if($success){
echo "File Saved";
}else{
echo "Uh-uh!";
}
}
The file was successfully saved as .mp3 in my server but when I try to play it manually, Media player says:

Without knowing which plugin you're using to capture the audio, it's hard to really be sure. However i assume that the:
//$("<a href='"+url+"' download='MyRecording.wav'></a>")[0].click();
actually worked before, meaning that whatever audio you're receiving is direct sound.
Mp3 however is an encoded format, and as such, your media player is probably failing, trying to decode unencoded audio.
Try changing the output ending:
$file_location = "assets/records/recorded_audio.wav";
and see if those files will play for you.
If that does not solve it, you should output the "url" you send as data, to see if it sends unwanted markers/headers along.

Related

PHP - Read content of BLOB file

I uploaded a *.mp4 video and converted it to a Blob type using JavaScript's new Blob() function.
I send this Blob to PHP, using AJAX.
Now I want to read the content of this Blob inside PHP. In other words, I need the binary data of this Blob and want to store it into a PHP variabele.
However, it seems impossible to read a Blob file with PHP, since fread, fopen and file_get_contents are failing all! When I'm opening the Blob URL in my browser the video is playing fine.
My question is, how do I get the binary data of this Blob with PHP, without installing extensions/libraries?
var_dump($_FILES['video']);
Array
(
[name] => blob
[type] => video/mp4
[tmp_name] => C:\xampp\tmp\php43B8.tmp
[size] => 58
[error] => 0
)
// Try 1
if ($stream = fopen($_FILES['video']['tmp_name'], 'r')) {
echo stream_get_contents($stream, filesize($_FILES['video']['tmp_name']));
fclose($stream);
}
// Try 2
if ($fp = fopen($_FILES['video']['tmp_name'], 'r')) {
echo fread($fp, filesize($_FILES['video']['tmp_name']));
fclose($fp);
}
// Try 3
file_get_contents($_FILES['video']['tmp_name'])
Result is always: blob:http://localhost/d53e40bd-686b-46c8-9e81-94789351466f
I know this is a late reply and you may have fixed this issue already but heres what I did for my BLOB processing. Since the blob is already uploaded to the TEMP file location, we first move the uploaded file somewhere using PHP's move_uploaded_file function. From there, you can read contents and such and then delete the file from your server when processing is completed.
Heres a very basic exampleusing an image file:
// Ajax data for posting the blob, remember to set process data to false
formData.append('code', 'uploadedImage');
formData.append('image', blob);
var url = "script.upload.php";
$.ajax({
type: 'POST',
url: url,
data: formData,
processData: false,
contentType: false,
success: function (data) {}
});
// PHP Code for uploading the file to the server
if ($_POST['code'] == "uploadedImage") {
$data = $_FILES['image']['tmp_name'];
move_uploaded_file($data, $_SERVER['DOCUMENT_ROOT'] . "/img/" . time() . ".png");
}
We now have a file like 1542839470.png at our base directory / images location. From here, the image can now be read, moved, streamed, stored, whatever. I am using a handy plugin called Croppie to resize, rotate and crop my images as well for anyone looking for a neat tool. By processing them first, I can avoid having to do anything with them after. As you are doing video, this won't apply in your specific case, but it's a handy plugin for people doing similar stuff (like me).
Once you are done with the file, either by curl to YouTube API or whatever processing you do with the finished file, you can simply delete the file using the following. Cache the video or file name and location from above (simple to do by setting a location $var) and feed that into this command.
unlink("path_to_file_location"); //delete it

jQuery using AJAX to display PDF data obtained from a PHP file

I am trying to use AJAX to query a PHP file and display a PDF file to the user. The response from the PHP file is the raw data of a PDF file stored on my server. Below is the code I am using to try and accomplish this but it isn't working. I keep getting a bad request error from my browser. Does anyone know the right way of doing this?
My end goal is I do not want the user to be able to see the server path where I store my PDF files. I only want the PDF files to be accessible using the AJAX / PHP script. I understand it's not the most secure method but I just want to keep the layman away from my PDF files.
jQuery:
$.ajax({
type: "POST",
url: 'process.php',
data: {"name" : "value"},
success: function (data) {
var json = $.parseJSON(data);
if(json.hasOwnProperty('success')){
window.location(json.success);
// json.success should contain the pdf binary data
// i just cant figure out how display the pdf in the browser
}
}
});
PHP:
<?php
$fileName = $_POST['name'];
if(isset($fileName)){
$file = './path-to-forms/'.$fileName.'.pdf';
$pdfData = file_get_contents($file);
$data = array("success" => $pdfData, "name" => $fileName);
echo json_encode($data);
}
?>
Does anyone know the right way of doing this?
A couple changes should get the file downloading correctly:
Update the PHP code to send the file contents using base-64 encoding (i.e. with base64_encode()):
$data = array("success" => base64_encode($pdfData));
When the AJAX response completes, create an anchor (link) and simulate clicking on it using .click() to initiate the PDF download. I can't find any jQuery method window.location() on api.jquery.com... if you find it, let me know. Maybe you were thinking of updating the (read-only) property window.location?
var json = $.parseJSON(data);
if(json.hasOwnProperty('success')){
var a = document.createElement("a");
a.href = 'data:application/pdf;base64,'+json.success;
a.download = "filePDF"; //update for filename
document.body.appendChild(a);
a.click();
// remove `a` following `Save As` dialog,
// `window` regains `focus`
window.onfocus = function () {
document.body.removeChild(a)
}
}
Credit to guest271314 for the adapted code from this answer along with some of the code from Alexandre's code in the answer below that.
See it demonstrated in this phpfiddle.

Send a file (type audio) without input type="file" in ajax

I create a file at the client (record) and then I'd send it on my remote server. However I can not find how to do it without using an input file, I have the file path but when I need to send it by ajax is not detected in $ _FILES side PHP. If I create a blob it works but the file does not match the recording.
Is it possible?
[UPDATE 1]
The file is a audio/mpeg, this file is created after an audio recording, where I get the location and I can play it again. I need to recover without the user clicks on a file input
HTML
<form enctype="multipart/form-data" id="form_message" method="POST">
<textarea name="message" id="message" value="" placeholder="Ecris quelque chose"></textarea>
<input type="submit" style="display:none;" value="Valider"/>
</form>
JS
fd = new FormData();
fd.append('audiofile', 'filepath.mp3');
// other data
function submit_form_message(fd){
$.ajax({
type: 'POST',
url: "url",
data: fd,
processData: false,
contentType: false,
success: function(data){}
});
}
PHP
if($_FILES['audiofile']['size'] !=0){
if ($_FILES['audiofile']['error'] == 0){
$extensions_valides = array('mp3' , 'wav');
if(in_array($_POST['extension'],$extensions_valides)){
$tmp_name = $_FILES["audiofile"]["tmp_name"];
$name_file = $notId.".".$_POST['extension'];
move_uploaded_file($tmp_name, $_SERVER['DOCUMENT_ROOT']."/Bell/sound/".$name_file);
}
}
}
Found this here, which I think may be your best bet: Using local file for Web Audio API in Javascript
Step 1: create Base 64 sound font
First I need to convert my mp3 to a Base64 encoded string and store it
as JSON. I found a website that does this conversion for me here -
http://www.mobilefish.com/services/base64/base64.php You may need
to remove return characters using a text editor but for anyone that
needs an example I found some piano tones here -
https://raw.github.com/mudcube/MIDI.js/master/soundfont/acoustic_grand_piano-mp3.js
Note that in order to work with my example you're need to remove the
header part data:audio/mpeg;base64,
Step 2: decode sound font to ArrayBuffer
You could implement this yourself but I found an API that does this
perfectly (why re-invent the wheel, right?) -
https://github.com/danguer/blog-examples/blob/master/js/base64-binary.js
Resource taken from - here
Step 3: Adding the rest of the code
Fairly straightforward
var cNote = acoustic_grand_piano.C2;
var byteArray = Base64Binary.decodeArrayBuffer(cNote);
var context = new webkitAudioContext();
context.decodeAudioData(byteArray, function(buffer) {
var source = context.createBufferSource(); // creates a sound source
source.buffer = buffer;
source.connect(context.destination); // connect the source to the context's destination (the speakers)
source.noteOn(0);
}, function(err) { console.log("err(decodeAudioData): "+err); });
Since you're passing a String of Base64 content, you are not sending a raw file, and thus do not need to select a file. You can then decode the Base64 in PHP and write it to a new Audio file on the server.

How to play MP3 format data in browser?

I am using php for server side scripting. In default I am using "audio" tag for playing audio files, Because my api call returns file path so it is easily handle.
for example my example look like this:
{
'id':123,
'question':'tell about your self?',
'audio':'/wdk/path/00fl.mp3'
}
so i can easily use this in audio tag.<audio src="www.abc.in/wdk/path/00fl.mp3" preload="auto">
But now i getting different format of API response. It returns data content instead of url. For example
{
'id':123,
'question':'tell about your self?',
'audio':'/wdk/path/MP3'
}
so now i need to make curl call again with content-type:audio/mpeg for getting data-content.It returns raw mp3 format data. So how can we play the audio file in browser? is any player there for convert mp3 format data to player data straightly? and i tried another way, but i could not able to store a mp3 format file in php.
can we create mp3 file using php? for ex:
$myfile = fopen("D:\xampp\htdocs\abc\testfile.mp3", "w");
$fwrite($myfile, $result);
my curl response like this:
ID3#TSSELavf56.15.102��8�Infora
!#%*,.0357<>#BEGIMPRTVY[adfhjmqsuxz|~��������������������������������������������������Lavc56.13$a5Cwc��8�"#�p7I<��Z���<ѣF�
��HP���.uN{P�! �{�����������]�D�DDwww��������"'����_���";�������=��B""�������
If you are getting the contents of the mp3 file, you can use data URI, the source is just encoded file contents:
echo '<audio src="data:audio/mpeg;base64,'.base64_encode($sound_text).'" autoplay="autoplay" controls ></audio>';
Data-URI
You could use data-URIs as #n-dru suggests in his answer, but you should be aware of a couple of things:
Base-64 increases the data size by 33%, and strings in JavaScript uses two bytes per char.
Some browsers limits the maximum data-URIs length (as there is a significant overhead decoding them)
Blob + ObjectURL
A better approach IMO, is to use Blobs and ObjectURLs. It's not without its own drawbacks though:
Require CORS fulfillment to load the data for the Blob (ie. your sample data must come from the same server as the page -or- the server must allow CORS usage)
The URL object must be prefixed in some browsers (incl. webkit)
The advantage is that the data can be loaded and used as a raw byte-buffer with no overhead in decoding nor bandwidth.
Example
This example loads the MP3 data (which would be the raw data you receive), then creates a Blob and an ObjectURL for the Blob. This can then be set as source for the audio element.
The example also shows how to handle the asynchronous nature of the various stages.
var audio = document.getElementById("audio");
audio.onload = function() {
// audio has loaded..
audio.play();
// continue from here (or the onerror event, not shown)
};
// load the url as raw data and create an ObjectURL:
loadRaw("/wdk/path/MP3", function(url) {
audio.src = url;
});
function loadRaw(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.responseType = "arraybuffer";
xhr.onerror = function() {console.log("Network error.")};
xhr.onload = function() {
if (xhr.status === 200) {
var blob = new Blob([xhr.response], {type: "audio/mpeg"}),
oURL = (URL || webkitURL).createObjectURL(blob);
callback(oURL);
}
else {console.log("Loading error:" + xhr.statusText)}
};
xhr.send();
}

Upload XML file, put in temporary folder or localStorage and access contents

I have an HTML form as such which consists of a input type=file.
<form method="post" id="xml-upload" enctype="multipart/form-data">
<input type="file" accept=".xml" required name="xml-selection-hidden" id="upload-btn">
</form>
(There is no submit button, submit is triggered via jQuery:)
$("input[type=file]#upload-btn").change(function(){
$("form#xml-upload").submit();
});
That's the easy part. Now, I am not quite knowledgeable in PHP file handling so the next part is harder for me. My idea of how these things work is that I make a PHP file and link to it in the action attribute of the form. For instance action="upload.php".
First of I need to check the file type, XML only (might allow TXT in the feature, but not of yet). A maximum size of the file of around 200kB ought to suffice. Simply using an embedded if-clause seems fine? (not tested)
if(($_FILES["file"]["type"]=="text/xml")) {
if ($_FILES["file"]["size"] < 200000) {
// run function
} else {
// error: max file size is 200kB
}
} else {
// error: only xml files are allowed
}
But now I'm stuck.
The goal is to manipulate the XML client-side. This is useful because I allow users to either choose the file upload option, or to give a direct XML input in a textarea. The server-side function (jQuery) for parsing the XML in the textarea is already finished, so it would be useful if I could use the same function to parse the XML that I get from the uploaded file.
I thought of two options:
1. The uploaded file is put in a temporary directory with a random name, I then run an ajax call with jQuery to the file. But how? How do I get jQuery to know where the file is stored?
2. Store the content of the uploaded file in localStorage and manipulate it accordingly. When a new file is uploaded, the older localStorage ought to be cleared of course.
The script that is run on the XML is something along these lines. Just so you know what happens with the XML input:
var xml = $("textarea#xml-input").val(),
xmlParsed = $.parseXML(xml),
xmlObject = $(xmlParsed);
$("#tree").html(output(xmlObject.find('node').first()));
function output(nodes) {
var newList = $("<ol>");
nodes.each(function (x, e) {
var newLI = $('<li> </li>');
for (var i = 0, l = e.attributes.length, a = null; i < l; i++) {
a = e.attributes[i];
newLI.attr("data-" + a.nodeName, a.value);
if (a.nodeName == "cat") {
newLI.html('' + a.value + '');
}
else if (a.nodeName == "word") {
newLI.html('' + a.value + '');
}
}
if ($(this).children('node').length) {
newLI.append(output($(this).children('node')));
}
newList.append(newLI);
});
return newList;
}
As I have said, I have tried my best in this post and gave it all I got, but I lack the knowledge. Looking for some help here. All help welcome!
For doing same as you wants you can create your own "xml_tmp" folder in your server root and then by using PHP move_uploaded_file() function to store your file in directory you selected for this and after storing current uploaded xml file you can ask via AJAX to get file name and path then send the requested info back to the client by using jQuery.parseXML() method you can read and manipulate your xml there.
I hope it help you!
Storing uploaded file by PHP:
move_uploaded_file($_FILES["file"]["tmp_name"], "xml_tmp/tmp.xml")
Imagine that 'xmlSrc' variable is the result of response from you AJAX call for requesting xml path and name
$.ajax({
type: "GET",
url: xmlSrc,
dataType: "xml",
success: function(xml) {
var xmlDoc = xml,
$xml = $( xmlDoc ),
$author = $xml.find( "author" );
// append the text from your parsed xml element to some HTML element
$( "#element" ).append( $author.text() );
}
});
1. The uploaded file is put in a temporary directory with a random name, I then run an ajax call with jQuery to the file. But how? How do I get jQuery to know where the file is stored?
jQuery has no interest in the temporary filename. The moment your PHP script has processed the upload request, the temporary file is deleted. That's on the server-side. jQuery is on client side.
So jQuery would get a filename of an inexistent file then.
You're perhaps looking for the browser file API which is able to access contents of a file without uploading it. Which seems fair as you're anyway dealing with a textbox if I understood your question right.

Categories