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();
}
Related
I have an HTML5 audio recorder which produces an audio blob (recorder.js by Matt Diamond) and executes a jquery ajax call to my PHP file.
function audioUpload() {
recorder && recorder.exportWAV(function(blob) {
//first look at the blob
console.log(blob);
var fd = new FormData();
fd.append('audioBlob', blob);
var audioBlob = fd.get('audioBlob');
//second look at the blob
console.log(audioBlob);
$.ajax({
method: "POST",
data: fd,
contentType: false,
processData: false,
url: "audioSend.php",
}).done(function(data) {
console.log(data);
})
});
There are two console.log functions here that report the blob:
In the first, the console reads as a blob. 1 In another part of the code I create an object URL with this and can play the audio using an HTML5 audio tag, so it's working.
In the second, the console reads it as a file. 2 I can understand this, as blobs are file-like objects by definition. Still, I'm not sure why it isn't reported as a blob like the first instance.
The formData object is posted to audioSend.php where I get the value and insert it into my DB.
$audioBlob = $_FILES['audioBlob'];
$results = mysqli_query($connection, "INSERT INTO audioLog (audio) VALUES ('$audioBlob')");
echo ($audioBlob);
Attempting to insert the blob value into my DB throws an "Array to String Conversion" error, and echoing $audioBlob confirms that it is read as an array. The value shown in my MYSQL DB Blob column is only a few bytes as a result, and not the much larger audio blob object that I want.
Why is the blob read as an array, and how can I get the REAL blob value be inserted into my DB?
You are POSTing the data, so access it via $_POST:
$audioBlob = $_POST['audioBlob'];
Also, use prepared statements as you are vulnerable to SQL injection.
Taking a second look at your code and, while I'm no JS programmer, it looks like you've disabled any sort of graceful POST and have just crammed the raw data into a POST request.
If you want to get this data you'll have to open the php://input stream which contains the un-processed POST body. Eg:
$f_in = fopen('php://input', 'rb');
$f_out = fopen($APPROOT.'/files/foo.bin', 'wb');
while( ! feof($f_in) ) {
$buf = fread($f_in, 4096);
fwrite($f_out, $buf);
}
fclose($f_in);
fclose($f_out);
Which will write the POST data to the file $APPROOT.'/files/foo.bin' 4KB at a time without cramming the entire thing into memory first.
If you want to upload it as a file and have it available in $_FILES you'll have to look into how to properly upload a file via whatever JS library that is.
What I'm trying to accomplish
[x] 1) User fills out form
[x] 2) User adds images to form through "drag & drop (html5)" or by "click to choose images"
and a preview is displayed on the page. (done)
Here it's easy to add code to trigger an upload of theese images to the server but I don't want that just yet.
[x] 3) Users clicks "add me & my desk" --> Create user account if doesn't already exist
[x] 4) Desk is added, and a connection to the right user is added as well.
[x] 5) Create a folder with the same name (id) as the desk_id.
::::THE QUESTION::::
6) -->> now I want to upload those dragged and dropped, or selected images to that folder.
:::::::::::::::::::
I've gotten this far with the information I found here: http://www.html5rocks.com/en/tutorials/file/dndfiles/ (the actual page really rocks!9
I know about this awesome solution: http://blueimp.github.com/jQuery-File-Upload/
But it's overkill for what I'm trying to do, and I happen to be so proud that I've got everything else working, and I really do think I'm so close.
words and expressions that keep coming up: read blob, check array blob, read from sandbox, canvas.toDataURL()
I feel that the answer is here: http://www.html5rocks.com/en/tutorials/file/xhr2/
AND / OR HERE http://www.html5rocks.com/en/tutorials/file/dndfiles/ Or HERE /
http://www.html5rocks.com/en/tutorials/file/filesystem/ (under "Duplicating user-selected files"), OR HERE http://robertnyman.com/2010/12/16/utilizing-the-html5-file-api-to-choose-upload-preview-and-see-progress-for-multiple-files/
You could say I'm at the next step after this: Preview an image before it is uploaded
but perhaps I could get a push in the right direction? :)
Of course I've had a look at these:
HTML5 Pre-resize images before uploading
facebook js api - HTML5 canvas upload as a photo
Currently displaying preview from DND files like this:
for (var i = 0, f; f = uppladdadeFiler[i]; i++) {
// Only process image files.
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
// Render thumbnail.
var span = document.createElement('span');
span.innerHTML = ['<img class="thumb preview" src="', e.target.result,
'" title="', escape(theFile.name), '"/>'].join('');
document.getElementById('listImages').insertBefore(span, null);
var span2 = document.createElement('span');
span2.innerHTML = ['<img class="thumb inside" src="', e.target.result,
'" title="', escape(theFile.name), '"/>'].join('');
document.getElementById('huvudbilden').insertBefore(span2, null);
};
})(f);
$('#valdaBilder').show();
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
I will give you some inputs which I hope will lead you in the right direction. Please note that I am not providing an off-the-shelf working answer because of two reasons - 1. I am just too lazy:) and 2. from what I can see you are smart enough to figure it out once you get the gist of it... so here goes:
First thing to do is have a button named, say, 'Upload Files' and attach a fn to it like uploadFiles(). Now this function will look something like below:
function uploadFiles()
{
var file = files[0];
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function()
{
if (xhr.readyState==4 && xhr.status==200)
alert(xhr.responseText);
};
xhr.open('POST', '/upload.php', true);
xhr.setRequestHeader('X-FILE-NAME', file.name);
xhr.send(file);
}
Ok, so the explanation:
var file = files[0];
The files object array should be something that you create in your drag and drop eventlistener functions, which will be file objects representing the files you dropped into the dropzone. Usually you create them so: files = event.dataTransfer.files; which creates a FileList object named files In the example I am only considering the first file in the dropzone - hence files[0]
I guess the rest of the code is pretty self-explanatory. One thing to note is:
xhr.setRequestHeader('X-FILE-NAME', file.name);
xhr.send(file);
As you can see we are sending out raw binary data content to the server. So the post operation is writing into the server stream with raw binary data of what the file contains. This is an important point because this affects how the server is able to read this posted data.
Server side upload.php:
I am just going to read the first 1000 bytes of the uploaded file and print it back into the client (which, based on the javascript code above, will alert it into the browser)
<?php
$streamHandle = fopen("php://input","rb");
$streamContent = fread($streamHandle,1000);
echo $streamContent;
?>
Many people get confused on how to read content at the server side and think about using $_POST, or $_FILES, but if you are sending data using X-FILE-NAME, then you have to read it by opening a handle to php://input which is the standard input stream of the running php process.
Once you have read the stream, it is only a matter of fwrite-ing it into a new file in whatever directory you want to.
Like I said, this is not a turn-key solution that you can just copy-paste into your particular code, but I hope this helps you in looking in the right direction for file uploads using HTML5's drag and drop and the file API provided by Javascript to support it.
There's an image gallery site, and the user can manipulate the images via javascript and HTML5 canvas. Is it possible to send back the manipulated image to the server for storing with PHP?
HERE you can find a complete article on the subject. But here's the short version and source codes:
First you need to convert the canvas binary data as a base 64 encoded string to send it to server:
var image = canvas.toDataURL("image/png");
Send this with an ajax call:
var ajax = new XMLHttpRequest();
ajax.open("POST",'save.php', false);
ajax.setRequestHeader('Content-Type', 'application/upload');
ajax.send(image);
Finally the PHP script save.php looks like this:
<?php
if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
// Get the data
$imageData=$GLOBALS['HTTP_RAW_POST_DATA'];
// Remove the headers (data:,) part.
// A real application should use them according to needs such as to check image type
$filteredData=substr($imageData, strpos($imageData, ",")+1);
// Need to decode before saving since the data we received is already base64 encoded
$unencodedData=base64_decode($filteredData);
//echo "unencodedData".$unencodedData;
// Save file. This example uses a hard coded filename for testing,
// but a real application can specify filename in POST variable
$fp = fopen( 'test.png', 'wb' );
fwrite( $fp, $unencodedData);
fclose( $fp );
}
?>
The PHP script parses the raw post data, converts from base 64 to binary, and saves to a file. For more information on Base 64 check out THIS Wikipedia article.
Yes, canvas supports returning the image data as either Base64 encoded data url or Blob. See http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-canvas-todataurl . You can then grab the data url and post it using AJAX to your server, and Base64-decode it there.
I've recently written a Python module that writes meta tags and values to PNG images using PIL, with the intent to have a webpage read the tags and sort the images accordingly (I'm not interested in the default stuff like Camera Type, I attach tags like "CarModel" if I've just been to a rally for example.
Does anyone recommend a way of reading the PNG meta? I'm using PHP at the moment (http://stackoverflow.com/questions/2190236/how-can-i-read-png-metadata-from-php at the bottom) which is great for the reason that it only pics up the tags I've added, but annoying as I can't figure away of building a neat array with the data for many pictures. Can javascript do this?
Sorry If I've been rubbish at explaining, but I'll re-explain if needs be.
you should have a look at the following php function - exif_read_data
PS: javascript can't do that as far as I know
i had a similar task. I had to write physical dimensions and additional metadata to PNG files. I have found some solutions and combined it into one small library.
png-metadata
it could read and write PNG metadata. it could be used on client and server side.
May be it will help somebody.
Here how you can read PNG metadata in the Browser:
function loadFileAsBlob(url){
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status === 200) {
resolve(this.response);
// myBlob is now the blob that the object URL pointed to.
}else{
reject(this.response);
}
};
xhr.send();
})
};
const blob = await loadFileAsBlob('1000ppcm.png');
metadata = readMetadataB(blob);
Here is a link to a Javascript library that claims to be able to read image metadata:
http://blog.nihilogic.dk/2008/08/imageinfo-reading-image-metadata-with.html
The nihilogic Javascript libraries are indeed very useful for client-side EXIF reading and parsing; but that only applies to JPEG images, as the metadata is supported only in the JPEG and TIFF format (and the TIFF format only supported natively by Safari browser).
PNG can include metadata but not in the form of IPTC or EXIF fields as JPEG or TIFF formats allow.
I am trying to get documents(ie. pdf, excel, word doc, etc) to open in a download box. for some reason the excel files work correctly but none of the others do. I think I need to setHeader using javascript(i believe that jquery does not have core functions that do this, but correct me if i'm wrong). here is a sample of my code.
$(function() {
$('a.media-link').click(function(event){
var fileName = $(this).html();
var property_id = $("input[name=capturePropId]").val();
//alert(fileName);
event.preventDefault(); //stop the browser from following
window.location.href = '../uploads/properties/'+
property_id+'/media/'+fileName+'';
response.setHeader("Content-Disposition", "attachment;
filename=\"" + fileName + "\"");
});
});
When i do this i get an error "response.setHeader response is undefinded. does anyone have any ideas?
You need to set the headers differently for each filetype. Take a look here.
You can't change server's response with JavaScript and you can't control how browser decides to open a new link outside of chosing this/new window. It is up to server to decide what to return for your request - i.e. it can response with the same JPG image for all requests or any other type of response.
You need to put the code that sets headers on the server that serves the request. You have correct code if your server is ASP.Net one ( http://support.microsoft.com/kb/260519).