Saving WAV File Recorded in Chrome to Server - php

I've seen many partial answers to this here and elsewhere, but I am very much a novice coder and am hoping for a thorough solution. I have been able to set up recording audio from a laptop mic in Chrome Canary (v. 29.x) and can, using recorder.js, relatively easily set up recording a .wav file and saving that locally, a la:
http://webaudiodemos.appspot.com/AudioRecorder/index.html
But I need to be able to save the file onto a Linux server I have running. It's the actual sending of the blob recorded data to the server and saving it out as a .wav file that's catching me up. I don't have the requisite PHP and/or AJAX knowledge about how to save the blob to a URL and to deal, as I have been given to understand, with binaries on Linux that make saving that .wav file challenging indeed. I'd greatly welcome any pointers in the right direction.

Client side JavaScript function to upload the WAV blob:
function upload(blob) {
var xhr=new XMLHttpRequest();
xhr.onload=function(e) {
if(this.readyState === 4) {
console.log("Server returned: ",e.target.responseText);
}
};
var fd=new FormData();
fd.append("that_random_filename.wav",blob);
xhr.open("POST","<url>",true);
xhr.send(fd);
}
PHP file upload_wav.php:
<?php
// get the temporary name that PHP gave to the uploaded file
$tmp_filename=$_FILES["that_random_filename.wav"]["tmp_name"];
// rename the temporary file (because PHP deletes the file as soon as it's done with it)
rename($tmp_filename,"/tmp/uploaded_audio.wav");
?>
after which you can play the file /tmp/uploaded_audio.wav.
But remember! /tmp/uploaded_audio.wav was created by the user www-data, and (by PHP default) is not readable by the user. To automate adding the appropriate permissions, append the line
chmod("/tmp/uploaded_audio.wav",0755);
to the end of the PHP (before the PHP end tag ?>).
Hope this helps.

Easiest way, if you just want to hack that code, is go in to recorderWorker.js, and hack the exportWAV() function to something like this:
function exportWAV(type){
var bufferL = mergeBuffers(recBuffersL, recLength);
var bufferR = mergeBuffers(recBuffersR, recLength);
var interleaved = interleave(bufferL, bufferR);
var dataview = encodeWAV(interleaved);
var audioBlob = new Blob([dataview], { type: type });
var xhr=new XMLHttpRequest();
xhr.onload=function(e) {
if(this.readyState === 4) {
console.log("Server returned: ",e.target.responseText);
}
};
var fd=new FormData();
fd.append("that_random_filename.wav",audioBlob);
xhr.open("POST","<url>",true);
xhr.send(fd);
}
Then that method will save to server from inside the worker thread, rather than pushing it back to the main thread. (The complex Worker-based mechanism in RecorderJS is because a large encode should be done off-thread.)
Really, ideally, you'd just use a MediaRecorder today, and let it do the encoding, but that's a whole 'nother ball of wax.

Related

How to read a log file live that is constantly updating in server to web textbox

the log file will be in notepad format the values will be like this 11.23445646,56.3456578954
10.23445646,26.3456578954
16.23445646,-46.3456578954
I'm planning to get the data from server to website textbox, of first value which I marked as italic the values will change after few seconds the updated value will come first. I tried some PHP example but not getting it in the below text box the values I need to get.. for example: x=11.23445646, y=56.3456578954, pls guide me
Longtitude <input id="x" type="number" value = "" onkeyup="updateMarker('x')">
Latitude <input id="y" type="number"value = "" onkeyup="updateMarker('y')">
Updated Answer
You can do this now using Web Socketing. Here is a guide and hello-wrold example of a php websocket server:
http://socketo.me/docs/hello-world
And to see how to implement client side javascript of websocket, you can see the bottom of the link put above, which shows you this snippet:
var conn = new WebSocket('ws://localhost:8080');
conn.onopen = function(e) {
console.log("Connection established!");
};
conn.onmessage = function(e) {
console.log(e.data);
};
Old
PHP does not support live connections generally in the way you expect, you have to simulate it via repeated AJAX request. How? For instance on each second, or each two seconds.
You first have to write an ajax in your HTML with jQuery library:
Sending a request each second:
var url = "url_to_you_file";
var textarea_id = "#textarea";
setInterval(function(){
$.ajax({
url : "site.com/get-file-logs.php",
type : "POST",
success : function(data){
$(".textarea").html(data);
}
});
}, 1000);
Then in PHP file you would write this:
$file_path = "path_to_your_file";
$file_content = file_get_contents($file_path);
echo $file_content;
The above example gets the file content and sends it back to your browser. You may want to process it in a certain way; that then changes your approach a little bit. Because you must always stick to JSON format when you try to get data back from server to be manipulated by Javascript.
PHP doesn't really do "live" page updates since normally when a web browser (or other user agent) loads a web page once it's done downloading the page then PHP is already finished and can't touch what's already on the client.
Best way to do this would probably be to use a JavaScript AJAX call to periodically load the updated values from a PHP script and then update the values on the page.
Or if it's a really small page (in byte size) you could just make it automatically reload the whole page (with updated values) if that is not a problem for you.
In any case every time the PHP script is called it would just open the file in read mode and only read the latest values from the beginning of the file and return those. See fread(). Or maybe file_get_contents() or file() would be easier and just read the first line.
AJAX is a bit larger topic and I don't currently have the time to explain the whole process of updating the page using JavaScript. Google is your friend.

Post web image to a server

I've read many posts that due to security risks you cannot upload to your server with an image from your folder as javascript isnt allowed such access. However, I have a situation where i have an svg image on a web site that I convert to a png whilst on the website. But, I wish to send the converted image to my server.
Will I encounter the same problems as if I were uploading from my documents?
I tried to make an example of jsfiddle but it seems it doesnt accept document.write very well, so here's sort of a work-around:
DEMO: jsfiddle
Ideally we would have a button defined as so:
<button id="image" onClick="image()">Convert & Send</button>
Then have the code that does the conversion within a function along with the ajax
function image() {
//conversion code & ajax
}
So in conclusion I would just like to know if this is possible if not, i would be grateful if you could show an alternative way, whether it may include a combination of php.
thanks in advance
It seems as though the fiddle isnt loading heres the snippet: of the conversion
function image () {
var svg = document.getElementById("svg-container").innerHTML.trim();
var canvas = document.getElementById('svg-canvas');
canvg(canvas, svg, { renderCallback: function () {
var img = canvas.toDataURL("image/png");
document.write('<img src="'+img+'"/>');
}
});
I'm not sure about what your question is, but indeed, you can use a combination of Ajax + PHP to upload your image.
The client would POST an encoded image (e.g. encoded in Base64) using ajax (using jQuery.post, for example), while the PHP would receive the image and store it (after decoding it) in your server.
For an example of the process, check this question, where a specific case of a canvas is discussed. I think your SVG conversion could work in a similar way.
PS: For some reason, I couldn't load your Fiddle.
EDIT:
So both Ajax & PHP are written on the front end to send the image to
my server/database (ruby on rails). Is that correct?
No. Only Javascript (with Ajax) is used in the client. PHP would be the server part of the process, so in your case it would not be used as you are already using Ruby on Rails. In other words:
The client (browser) uses Javascript (maybe JQuery) to POST the image data (in your snippet, img) to the server (more info here).
The server (a PHP, ASPX or Ruby script [among others]) gets the POSTed data and saves the picture on disk (some info here).
If you can use PHP (in the server) for the specific process of saving the image, you can use the question I linked before as a guide.
Yes Of Course Their are ways:
I know 2:
1-(This One I know it works on chrome and Firefox but don't know IE):
First Get The Base 64 Data Of An Image In Canvas:
<canvas id="Canv" ....(Other Attributes)>
Your Browser does not support the canvas element :(
</canvas>
<button type="button" OnClick="Image()">Transform and Save</button>
<script type="text/javascript>
var can =document.getElementById('Can');
var ctx = can.getContext("2d");
//do something with ctx
function image(){
//You Should check the real format using img.src
var data = can.toDataURL("image/png");
var array = data.split(".");
var Base64Data = array[1];
//Now step 2 :Sent it to PHP
//Check for Browser compatibly
var ajx = new XmlHttpRequest()
ajx.onreadystatechange=function()
{
if (ajx.readyState==4 && ajx.status==200)
{
if(ajx.ResponseText == "Err"){//if the paged returned error
alert("An error Has Occurred");
return;
}//if not
alert("Saved Succesufuly");
}
}
ajx.open("GET","Save.php?q=" + Base64Data , true);
}
</script>
Step3: Interprete it With PHP
<?PHP
if(isset($_GET['q] And !Empty($_GET['q'])){
try {
$Data = $_GET['q'];
$hndl = fopen("Saved/Pic1.jpg" , "w");
fwrite($hndl , $Data);
fclose($hndl);
}catch(Exception $err){
echo "Err";
}
}else {
echo "Err";
}
?>
Yeap And That it.:D
You Could also loop throught each file in that directory and create a load button that get the Base64 Value And the first stuffs and out it into canvas using pucontent method of canvas element object

How to make documents upload using AJAX with progress Bar

I want to make an upload page for my site so that documents get uploaded asynchronously, I tried using AJAX, but AJAX has a limited access to the users filesystem, and when the information is sent to the server only the file name appears without the directory, I would like suggestion on how to do this easily without using JQuery, and also I would like to know if there is a way to monitor the progress of a file upload, so that I could add a progress bar to my site.
function createXMLHttpRequestObject(){
var xmlHttp = 3;
if(window.ActiveXObject){
try{
//test for new version of internet Explorer
xmlHttp = new ActiveXObject("Msxml.XMLHTTP");
}
catch(e){
try{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e){
xmlHttp = 2;
}
}
}
else{
try{
xmlHttp = new XMLHttpRequest();
}
catch(e){
xmlHttp = 1;
}
}
if(!xmlHttp){
alert("Error creating Objece");
}
else{
var xHttpArr = new Array();
xHttpArr.push(xmlHttp);
var i = xHttpArr.length - 1;
return xHttpArr[i];
}
}
function process(xmlHttp, i){
if(xmlHttp.readyState == 4 || xmlHttp.readyState == 0){
//value = encodeURIComponent( objRef.value );
xmlHttp.open("GET", "php/AjaxBody.php?value="+i, true);
xmlHttp.onreadystatechange = handleServerResponse;
xmlHttp.send(null);
}
else{
alert("Hold on");
}
}
function handleServerResponse(){
if(test.readyState == 1 || test.readyState == 2 || test.readyState == 3){
}
if (test.readyState == 4){
if(test.status == 200){
txtResponse = test.responseText;
bodyDiv = document.getElementById("body");
bodyDiv.innerHTML = txtResponse;
}
else{
alert("Error with the xmlHttp status");
}
}
/*
else{
alert("Error with the xmlHttp readystate: " + x.status);
} */
}
Above is the code that creates the Object
button.onclick = function() {
send = createXMLHttpRequestObject();
frmUpload = document.getElementById("frmUpload");
file = document.getElementById("fileUpload");
processSending(send, frmUpload);
}
Above when the process method is called to send the file,
on the server I try to echo the file path, only the the name appears, like this
<?php
echo $_GET['value'];
?>
First of all you are doing your file upload wrong. File uploads require you to do a proper POST request using forms as it requires the enctype form attribute to be multipart/form-data. Why? The browser sends the binary file data through the POST request and does the hard work of encoding the data correctly through the POST request to be read on the server. Any other way and you will just be getting the file name at the server (you can verify this with a tool like Fiddler).
Alright, then how do you do a file upload using AJAX? AFAIK it's not possible to read the user's file system directly (I think FileReader only allows reading through the sandboxed file system through the browser but I may be wrong here), so IMO there are 2 ways to go here:
Using a hidden iframe approach for the file upload. Google it you will find lots of info it.
Use a Flash based uploader. More on this at the end.
As far as getting the location of the file on the users file system using Javascript goes, forget about it. It's considered a security concern and many browsers only return the file name on reading the element value when using the HTML input file tag. (Unless you are thinking of using a flash component. More on that in the last point.)
Now coming to the progress bar issue. When your PHP script is actually run the entire file has already been uploaded to the server. So how to show a progress bar? A few (hackish) ways:
An old school approach is to create a CGI script on the server to handle the upload. The advantage? CGI scripts can be run during the upload allowing you to retrieve the actual byte level progress of the upload. But this also requires you to update the progress at some place on the server which you can poll (with a separate AJAX request) and show in the browser to the user.
Another most commonly used approach is using a flash based uploader (please don't kill me StackOverflow community). Yes it's still used by big names (I am looking at you Facebook). The advantage you will have is that you don't need any special scripts on the server. The Flash based client is fully aware of the number of bytes uploaded. Also you may have access to the actual file path string (note the use of may and string) which is not so openly possible with plain JS and HTML.
You could use a FileReader and read the file into an ArrayBuffer or a BinaryString and then use multiple requests to send for example 1 mb sized packages. The receiving php script would then have to 'rebuild' the file by appending each received part to it. This would also solve the problem of echoing the file path on the server as you can (and have to) decide where to save it before writing to it.

Images generated by JavaScript Canvas API aren't viewable when saved?

Full code can also be found here: https://gist.github.com/1973726 (partially version on jsfiddle http://jsfiddle.net/VaEAJ/ obviously couldn't have php running with jsfiddle)
I initially wrote some code which took a canvas element and saved it as an image (see working code here: https://gist.github.com/1973283) and afterwards I updated it so it could process multiple canvas elements but the main difference now is that the image data is passed through to my PHP script via jQuery ajax method rather than via a hidden form field.
Problem is the images appear to be blank. They are about 200kb each when generated so they obviously have some content but when you preview the image nothing shows and when I try and open the image in Adobe Fireworks or another photo application I can't open the file.
The image data appears to be coming through to the server fine, but I'm really not sure why now when I write the image using base64_decode it would mean the images that are generated would no longer be viewable? The only thing I can think of is that maybe the posting of data via ajax isn't sending all the data through and so it's generating an image but it's not the full content and so the image is incomplete (hence why a photo application can't open it).
When checking the post data in Firebug it suggests that the limit has been reached? Not sure if that's what the problem is?
The problem was actually with sending data via XHR. I was using jQuery ajax method initially and then I swapped it out for my own ajax abstraction but the problem was still occuring until someone on twitter suggested I use FormData to pass the data to the server-side PHP. Sample is as follows... (full code can be seen here: https://gist.github.com/1973726)
// Can't use standard library AJAX methods (such as…)
// data: "imgdata=" + newCanvas.toDataURL()
// Not sure why it doesn't work as we're only abstracting an API over the top of the native XHR object?
// To make this work we need to use a proper FormData object (no data on browser support)
var formData = new FormData();
formData.append("imgdata", newCanvas.toDataURL());
var xhr = new XMLHttpRequest();
xhr.open("POST", "saveimage.php");
xhr.send(formData);
// Watch for when the state of the document gets updated
xhr.onreadystatechange = function(){
// Wait until the data is fully loaded, and make sure that the request hasn't already timed out
if (xhr.readyState == 4) {
// Check to see if the request was successful
if (checkHTTPSuccess(xhr)) {
// Execute the success callback
onSuccessfulImageProcessing(card, newCanvas, ctx, getHTTPData(xhr));
}
else {
throw new Error("checkHTTPSuccess failed = " + e);
}
xhr.onreadystatechange = null;
xhr = null;
}
};
```
If you are not having Cross Origin SECURITY_ERR's (which your Fiddle suffers from, but as long as your images are on the same server they will be fine), and you are getting some data so you are probably having problems with your PHP. From the PHP user notes, you have to replace the spaces with +'s to decode base64 that has been encoded with Javascript.
$data = str_replace(" ", "+", $_POST['imgdata']);
file_put_contents("generated.png", base64_decode($data));

HTML 5 Drag & Drop upload with jQuery and PHP

I'm currently following this example for HTML 5 drag and drop. I am hoping to use this to upload the dropped files to a remote FTP server with a php script. However, how do my php script access these dropped files ?
With a regular web form, I can use $_FILES.. But I don't suppose I can use $_FILES for the dropped files..
On the example, the script calls handleFiles function after a drop event
function handleFiles(files) {
var file = files[0];
document.getElementById("droplabel").innerHTML = "Processing " + file.name;
var reader = new FileReader();
// init the reader event handlers
reader.onprogress = handleReaderProgress;
reader.onloadend = handleReaderLoadEnd;
// begin the read operation
reader.readAsDataURL(file);
}
I guessing that I can iterate each element of the array list, and send each element to my php script. As I've mentioned above, how can I send this element from the array list to the php script? JSON ? jQuery POST ?
I am aware that there are various jquery plugins available to achieve this, and I have downloaded a few of them... However I'm just curious to know if I can implement the same thing with this example.
I presume by upload you mean upload it in a ajax operation.
file refer to a File object, which is available for you after the user had drop the file. After that you have two options:
Read the file using FileReader, send the text in xhr as post data (not recommend as it only work with text)
Pass the object to FormData then pass the FormData object to xhr to send the file (Doesn't work with Firefox <= 3.6 though)
Check Mozilla Developer Center document for the usage of these interfaces. I have working projects that use these objects, however there are too much bridging code to be a good walk-through demo. https://github.com/timdream/html5-file-upload
Why not use an open source solution for your problem rather than re-inventing the wheel.
http://plupload.com/
Is pretty much all you will ever need. I use it and it works wonders. Also, it falls back onto html 4 form uploading when a browser cannot handle html5.

Categories