Saving WAV File Recorded in Chrome to Server
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.
Media Recorder Save in WAV format across browsers
I built a package which should do exactly what you want. It's called extendable-media-recorder. It offers the same interface as the native MediaRecorder
but allows to "extend" it with custom codecs. The example codec is wav.
Here is how you could use it to record a stream coming from getUserMedia()
:
import { MediaRecorder, register } from 'extendable-media-recorder';
import { connect } from 'extendable-media-recorder-wav-encoder';
await register(await connect());
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const mediaRecoder = new MediaRecorder(stream, { mimeType: 'audio/wav' });
It will use the built-in MediaRecorder
to record pcm data in Chrome. In Firefox and Safari the Web Audio API is used to get the pcm data. Once the data has been retrieved it gets send to a worker which decodes it as wav.
How to Reduce wav File-size created by Recorder.js
The problem with wav is that the files are non-compressed, therefore they take up a lot of space on the disk, just 1 minute of recording can take as much as 10 Megabytes.
The solution to this? Well let’s convert the wav file to mp3. Simply saving the wav file and then converting it will not do. We will need to convert the recording, to mp3, in real time, in the browser.
https://nusofthq.com/blog/recording-mp3-using-only-html5-and-javascript-recordmp3-js/
Use JavaScript to record audio as .wav in Chrome
Originally, I was using MediaRecorder to get audio and create a Blob from said audio with type audio/wav
. That was not working in Chrome, but it was in Firefox. I gave up on that and started working with ScriptProcessorNode. Again, it worked on Firefox, but not Chrome. After some debugging, it became clear that on Chrome, recBuffers was getting filled with alternating lists. I'm still not sure why that was happening, but my guess is something like scoping or caching since spread syntax solved it. Changing a line in onaudioprocess from this.recBuffers[i].push(e.inputBuffer.getChannelData(i));
to this.recBuffers[i].push([...e.inputBuffer.getChannelData(i)]);
worked.
Using PHP to save file with unknown file name
First of all, you should add some checks to make sure you won't get post flooded. The minimal way to do this would be by making sure the POST comes from the same server IP (though there are several ways to spoof that):
if ($_SERVER['REMOTE_ADDR'] != $_SERVER['SERVER_ADDR']) {
http_response_code(403);
die('Forbidden');
}
Also, make sure you only execute this script when you actually receive a file>
if (!$_FILES) {
http_response_code(400);
die('File missing');
}
As for your filename problem: You are only uploading one file at a time, so $_FILES
will only have one element that you can retrieve with current()
.
$target_dir = 'audio/';
$file = current($_FILES);
$target_file = $target_dir . basename($file['name']);
move_uploaded_file($file['tmp_name'], $target_file);
// why would you do this?
chmod($target_file,0755);
Related Topics
Access to Laravel 5 App Locally from an External Device
Loop Code for Each File in a Directory
How to Specify Composer Install Path
How to Add a Line Break Within Echo in PHP
PHP APIs for Hotmail, Gmail and Yahoo
Using Usort in PHP with a Class Private Function
How to Pass Arguments to My Function Through Add_Action
Proper Url Forming with a Query String and an Anchor Hashtag
Sqlstate[Hy000] [1698] Access Denied for User 'Root'@'Localhost'
Should I Use Prepared Statements for MySQL in PHP Performance-Wise
Improve Password Hashing with a Random Salt
Finding Common Prefix of Array of Strings
Logging in to Joomla 1.5 Using External Form (Not Within Joomla Folder, But on Same Server)