Hello i want to make a script that allows the user to record audio from his device mic and then store it as a .mp3 or .wav file on my database. Does anyone knows any tutorials or scripts? I found this one http://stackoverflow.com/questions/16413063/html5-record-audio-to-file but i dont know to make it a file and then store it. Any help?

Recommended Answers

All 31 Replies

I guess so rproffitt. I think this article will have many posts. I'll will upload any answer i got

I am getting an error on }, "URL"); on both occasions TypeError: $(...)[0].play is not a function

this is the button <a class="button disabled one" id="play">Play</a>

$(document).on("click", "#play:not(.disabled)", function(){
    if($(this).parent().data("type") === "mp3"){
      Fr.voice.exportMP3(function(url){
        $("#audio").attr("src", url);
        $("#audio")[0].play();
      }, "URL");
    }else{
      Fr.voice.export(function(url){
        $("#audio").attr("src", url);
        $("#audio")[0].play();
      }, "URL");
    }
    restore();
  });

In regards to errors, you would see if the browser supports that. Hit caniuse.com to see.
But the error sounds more like a coding error to me.

I dont think its a browser thing. i am getting the same error on every browser's console

Uncaught TypeError: $(...)[0].play is not a function
    at app.js:99
    at Object.callExportCallback (Fr.voice.js:166)
    at Fr.voice.js:144
    at Worker.encoderWorker.onmessage (recorder.js:370)

The "is not a function" is a fairly common web code error. I think you'll have to go over your code till you find why it throws that.

Member Avatar for diafol
$("#audio")[0].play();

Try it without the [0] index? Get the audio object and log it to the console, see what's available.

console.log(JSON.stringify($("#audio"), null, 4));
Member Avatar for diafol

Out of interest, was there ever any further work on this?

I'll will upload any answer i got

What was the solution?

Sorry for the delay i found a better script. https://github.com/muaz-khan/RecordRTC/tree/master/RecordRTC-to-PHP It works fine. Save up to server and stores the video/audio file to uplodas/ If anyone has any problem please post in this thread. But its better than the last one.

I want to make it store to database as soon as the user hits 'Stop Recording' and not to have to hit <button id="upload-to-server">Upload To Server</button>

js

 function saveToDiskOrOpenNewTab(recordRTC) {
                recordingDIV.querySelector('#save-to-disk').parentNode.style.display = 'block';
                recordingDIV.querySelector('#save-to-disk').onclick = function() {
                    if(!recordRTC) return alert('No recording found.');
                    recordRTC.save();
                };
                recordingDIV.querySelector('#open-new-tab').onclick = function() {
                    if(!recordRTC) return alert('No recording found.');
                    window.open(recordRTC.toURL());
                };
                recordingDIV.querySelector('#upload-to-server').disabled = false;
                recordingDIV.querySelector('#upload-to-server').onclick = function() {
                    if(!recordRTC) return alert('No recording found.');
                    this.disabled = true;
                    var button = this;
                    uploadToServer(recordRTC, function(progress, fileURL) {
                        if(progress === 'ended') {
                            button.disabled = false;
                            button.innerHTML = 'Click to download from server';
                            button.onclick = function() {
                                window.open(fileURL);
                            };
                            return;
                        }
                        button.innerHTML = progress;
                    });
                };
            }
            var listOfFilesUploaded = [];
            function uploadToServer(recordRTC, callback) {
                var blob = recordRTC instanceof Blob ? recordRTC : recordRTC.blob;
                var fileType = blob.type.split('/')[0] || 'audio';
                var fileName = (Math.random() * 1000).toString().replace('.', '');
                if (fileType === 'audio') {
                    fileName += '.' + (!!navigator.mozGetUserMedia ? 'ogg' : 'wav');
                } else {
                    fileName += '.webm';
                }
                // create FormData
                var formData = new FormData();
                formData.append(fileType + '-filename', fileName);
                formData.append(fileType + '-blob', blob);
                callback('Uploading ' + fileType + ' recording to server.');
                makeXMLHttpRequest('http://localhost/WallScript/save_audio.php', formData, function(progress) {
                    if (progress !== 'upload-ended') {
                        callback(progress);
                        return;
                    }
                    var initialURL = location.href.replace(location.href.split('/').pop(), '') + 'uploads/';
                    callback('ended', initialURL + fileName);
                    // to make sure we can delete as soon as visitor leaves
                    listOfFilesUploaded.push(initialURL + fileName);
                });
            }

This is the HTML

     <section class="experiment recordrtc">
            <h2 class="header">
                <select style="visibility:hidden" class="recording-media">
                    <option value="record-video">Video</option>
                </select>
                <select style="visibility:hidden" class="media-container-format">
                    <option disabled>WebM</option>
                    <option disabled>Mp4</option>
                    <option>WAV</option>
                    <option disabled>Ogg</option>
                    <option disabled>Gif</option>
                </select>

                <button>Start Recording</button>
            </h2>

            <div style="text-align: center; display: none;">
                <button id="save-to-disk">Save To Disk</button>
                <button id="open-new-tab">Open New Tab</button>
                <button id="upload-to-server">Upload To Server</button>
            </div>

            <br>

I put visibility:hidden because i dont want the user to have to choose if he wants audio or video or what type of file should he/she should upload I want by default to be webm for Video and ogg for audio but it stores webm

Member Avatar for diafol

THanks for the update simonloa - this was certainly interesting and I'm sure many will benefit from your research / work :)

Ineed some help with the this script. I dont want to press a button to upload the file to my server iwant it to be done as soon as the user presses Stop Recording. Can anyone help me?

Stop Recording script

 recordingDIV.querySelector('button').onclick = function() {
                var button = this;
                if(button.innerHTML === 'Stop Recording') {
                    button.disabled = true;
                    button.disableStateWaiting = true;
                    setTimeout(function() {
                        button.disabled = false;
                        button.disableStateWaiting = false;
                    }, 2 * 1000);
                    button.innerHTML = 'Start Recording';
                    function stopStream() {
                        if(button.stream && button.stream.stop) {
                            button.stream.stop();
                            button.stream = null;
                        }
                    }
                    if(button.recordRTC) {
                        if(button.recordRTC.length) {
                            button.recordRTC[0].stopRecording(function(url) {
                                if(!button.recordRTC[1]) {
                                    button.recordingEndedCallback(url);
                                    stopStream();
                                    saveToDiskOrOpenNewTab(button.recordRTC[0]);
                                    return;
                                }
                                button.recordRTC[1].stopRecording(function(url) {
                                    button.recordingEndedCallback(url);
                                    stopStream();
                                });
                            });
                        }
                        else {
                            button.recordRTC.stopRecording(function(url) {
                                button.recordingEndedCallback(url);
                                stopStream();
                                saveToDiskOrOpenNewTab(button.recordRTC);
                            });
                        }
                    }
                    return;
                }

Upload to Server script

recordingDIV.querySelector('#upload-to-server').disabled = false;
                    recordingDIV.querySelector('#upload-to-server').onclick = function() {
                        if(!recordRTC) return alert('No recording found.');
                        this.disabled = true;
                        var button = this;
                        uploadToServer(recordRTC, function(progress, fileURL) {
                            if(progress === 'ended') {
                                button.disabled = false;
                                button.innerHTML = 'Click to download from server';
                                button.onclick = function() {
                                    window.open(fileURL);
                                };
                                return;
                            }
                            button.innerHTML = progress;
                        });
                    };
                }
                var listOfFilesUploaded = [];
                function uploadToServer(recordRTC, callback) {
                    var blob = recordRTC instanceof Blob ? recordRTC : recordRTC.blob;
                    var fileType = blob.type.split('/')[0] || 'audio';
                    var fileName = (Math.random() * 1000).toString().replace('.', '');
                    if (fileType === 'audio') {
                        fileName += '.' + (!!navigator.mozGetUserMedia ? 'ogg' : 'wav');
                    } else {
                        fileName += '.webm';
                    }
                    // create FormData
                    var formData = new FormData();
                    formData.append(fileType + '-filename', fileName);
                    formData.append(fileType + '-blob', blob);
                    callback('Uploading ' + fileType + ' recording to server.');
                    makeXMLHttpRequest('http://localhost/WallScript/save_audio.php', formData, function(progress) {
                        if (progress !== 'upload-ended') {
                            callback(progress);
                            return;
                        }
                        var initialURL = location.href.replace(location.href.split('/').pop(), '') + 'uploads/';
                        callback('ended', initialURL + fileName);
                        // to make sure we can delete as soon as visitor leaves
                        listOfFilesUploaded.push(initialURL + fileName);
                    });
                }
                function makeXMLHttpRequest(url, data, callback) {
                    var request = new XMLHttpRequest();
                    request.onreadystatechange = function() {
                        if (request.readyState == 4 && request.status == 200) {
                            callback('upload-ended');
                        }
                    };
                    request.upload.onloadstart = function() {
                        callback('Upload started...');
                    };
                    request.upload.onprogress = function(event) {
                        callback('Upload Progress ' + Math.round(event.loaded / event.total * 100) + "%");
                    };
                    request.upload.onload = function() {
                        callback('progress-about-to-end');
                    };
                    request.upload.onload = function() {
                        callback('progress-ended');
                    };
                    request.upload.onerror = function(error) {
                        callback('Failed to upload to server');
                        console.error('XMLHttpRequest failed', error);
                    };
                    request.upload.onabort = function(error) {
                        callback('Upload aborted.');
                        console.error('XMLHttpRequest aborted', error);
                    };
                    request.open('POST', url);
                    request.send(data);
                }
commented: How is the RTC Audio Script working for you? We just started using it. Where do you add the scripts in wp? Thank you for you assistance. +0
Member Avatar for diafol

I'm not sure you can do this. Uploading a local file via js requires some nominal "'ok" from the user. This could be as straightforward as loading a file into a file control and wrap a form.submit event to its onchange event.

The 'Ok' is given to the user as an option Later because he or she have to press a share button. This script should -upload the audio video file to database and create an id - and it does but you have to press a button to do that and i want it to be done as soon as the user hits stop recording

Member Avatar for diafol

The point I'm making is that an upload needs some manual input otherwise js programs could steal data.

Exactly. Can you post some code?

Member Avatar for diafol

I'm not au fait with the script you're using. Sorry. I'd have to download the script and play with it. Haven't got the time right now. May look over next few days.

Does anyone knows where i can't find a Javascript expert to solve this? Except from freelancer

Toptal is another source when you need to hire out.

But I agree with diafol on the issue of user interaction on the upload of a file. That sounds like good security for javascript otherwise folk could steal files by you just visiting any web site.

IOW. Don't ask folk to break javascript security features.

The problem i have is that i am trying to implement it on my code. The values were stored just fine but when i try to store it my way it doesn't

html

Start recording an audio
                        <section class="experiment recordrtc">
                            <h2 class="header">
                                <select style="visibility:hidden" class="recording-media">
                                    <option value="record-audio">Audio</option>
                                </select>
                                <select  style="visibility:hidden" class="media-container-format">
                                    <option>WAV</option>
                                </select>
                                <button>Start Recording</button>
                            </h2>
                            <div style="text-align: center; display: none;">
                                <button id="save-to-disk">Save To Disk</button>
                                <button id="open-new-tab">Open New Tab</button>
                                <button id="upload-to-server">Upload To Server</button>
                            </div><br>
                            <video controls muted></video>
                        </section>
                           <form id="audioform1" method="post" enctype="multipart/form-data" >
                        <div id="previewaudio" class="marginbottom10">
                        </div>
                         <input type="hidden" id="audioType">
                        <div id="audioloadstatus" class="displaynone marginbottom10">
                            <img src="<?php echo BASE_URL; ?>wall_icons/ajaxloader.gif" class="icon"> <?php echo $lang['UploadingPleaseWait'] ; ?>....
                        </div>
                        <input type="hidden" id="uploadvalues">
                        <input type="hidden" id="upload_uid"  value="<?php echo $sessionUid;?>" name="update_uid">
                        <input type="hidden" id="upload_token"   value="<?php echo $sessionToken;?>" name="update_token">
                        </form>

php

foreach(array('video', 'audio') as $type) 
    {
        if (isset($_FILES["${type}-blob"])) 
        {
            $uploadUid=$_POST['update_uid'];
            $token=$_POST['update_token'];
            $key=md5(SITE_KEY.$uploadUid);
            echo $token.$uploadUid;exit;

it doesn't return the variables uploadUid and token. I am getting nothing in Response on the NETWORK XKR while if i try echo 'something'; it returns

JAVASCRIPT

var formData = new FormData();
                formData.append(fileType + '-filename', fileName);
                formData.append(fileType + '-blob', blob);
                callback('Uploading ' + fileType + ' recording to server.');
                makeXMLHttpRequest('http://localhost/WallScript/api/audioRecording', formData, function(progress) {
                    if (progress !== 'upload-ended') {
                        callback(progress);
                        return;
                    }
                    var initialURL = location.href.replace(location.href.split('/').pop(), '') + 'uploads/';
                    callback('ended', initialURL + fileName);
                    // to make sure we can delete as soon as visitor leaves
                    listOfFilesUploaded.push(initialURL + fileName);
                });
Member Avatar for diafol
if (isset($_FILES["${type}-blob"])) 

try

if (isset($_FILES["{$type}-blob"])) 

No, thats not the issue. I think if that was wrong it wouldn't echo 'whatever'; The probem is that is doesn't passes the values token and uploadUid from HTML

I think that the problem is that the values are not being passed thourgh Javascript

here

 var formData = new FormData();
                formData.append(fileType + '-filename', fileName);
                formData.append(fileType + '-blob', blob);

                callback('Uploading ' + fileType + ' recording to server.');
                makeXMLHttpRequest('http://localhost/WallScript/api/audioRecording', formData, function(progress) {

how do i pass these values from HTML to formData so that they can go to api/audioRecording?

 <input type="hidden" id="uploadvalues">
                            <input type="hidden" id="upload_uid"  value="<?php echo $sessionUid;?>" name="update_uid">
                            <input type="hidden" id="upload_token"   value="<?php echo $sessionToken;?>" name="update_token">
Member Avatar for diafol

WHy not just get the form itself, as in:

var myForm = document.getElementById('theFormIdWhateverItIs');
formData = new FormData(myForm);

Now everything in the form, including any files in a file upload control, should be ready to send. You can add more info with .append

OK should i append every parameter i need? How do i do that?

i do it like this but some reason it refreshs the page

<form id="audioForm2" method="post" enctype="multipart/form-data" >
                                <select style="visibility:hidden" class="recording-media">
                                    <option value="record-audio">Audio</option>
                                </select>
                                <select  style="visibility:hidden" class="media-container-format">
                                    <option>WAV</option>
                                </select>
                                <button>Start Recording</button>
                            </h2>
                            <div style="text-align: center; display: none;">
                                <button id="save-to-disk">Save To Disk</button>
                                <button id="open-new-tab">Open New Tab</button>
                                <button id="upload-to-server">Upload To Server</button>
                            </div><br>
                            <video controls muted></video>
                        </section>

                        <div id="previewaudio" class="marginbottom10">
                        </div>
                         <input type="hidden" id="audioType">
                        <div id="audioloadstatus" class="displaynone marginbottom10">
                            <img src="<?php echo BASE_URL; ?>wall_icons/ajaxloader.gif" class="icon"> <?php echo $lang['UploadingPleaseWait'] ; ?>....
                        </div>
                        <input type="hidden" id="uploadvalues">
                        <input type="hidden" id="upload_uid"  value="<?php echo $sessionUid;?>" name="update_uid">
                        <input type="hidden" id="upload_token"   value="<?php echo $sessionToken;?>" name="update_token">
                        <input type="hidden" id="group_id" value="<?php echo $groupID; ?>" name="group_id">
                        </form>

js

var myFormAudio = document.getElementById('audioForm2');
                formData = new FormData(myFormAudio);
                var formData = new FormData();
                formData.append(fileType + '-filename', fileName);
                formData.append(fileType + '-blob', blob);

                callback('Uploading ' + fileType + ' recording to server.');
                makeXMLHttpRequest('http://localhost/WallScript/api/audioRecording', formData, function(progress) {

How do pass these values

<input type="hidden" id="uploadvalues">
                        <input type="hidden" id="upload_uid"  value="<?php echo $sessionUid;?>" name="update_uid">
                        <input type="hidden" id="upload_token"   value="<?php echo $sessionToken;?>" name="update_token">

in here

formData.append('username', 'Chris');
formData.append('userpic', myFileInput.files[0], 'chris.jpg');

i am doing this formData.append(fileType + '-uploadUid', uploadUid);
and i am getting this on Response [object HTMLInputElement]

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.