Transfer sound data blob to server and store it as a file

Currently, I have 3 buttons on my webpage - one to start recording audio, one to stop the recording, and one to play the recorded audio. Using MediaRecorder makes it easy to capture audio as a blob data. However, I am facing issues when trying to upload this blob as an audio file to the server. The setup includes an audio element with a file type, a flag indicating if recording is ongoing (0 or 1), and the requirement to upload the blob once the recording stops.

Below is the code snippet:


var thisAudioBlob = document.getElementById("audioElement");
var playFlag = 0;

function initFunction() {
  async function getUserMedia(constraints) {
    if (window.navigator.mediaDevices) {
      return window.navigator.mediaDevices.getUserMedia(constraints);
    }
    let legacyApi =
      navigator.getUserMedia ||
      navigator.webkitGetUserMedia ||
      navigator.mozGetUserMedia ||
      navigator.msGetUserMedia;
    if (legacyApi) {
      return new Promise(function (resolve, reject) {
        legacyApi.bind(window.navigator)(constraints, resolve, reject);
        return reject('rejected');
      });
    } else {
      // === show an alert
    }
  }
  
  let audioChunks = [];
  let rec;
  let blob; 

  function handlerFunction(stream) {
    rec = new MediaRecorder(stream);
      rec.start();
      rec.ondataavailable = (e) => {
          audioChunks.push(e.data);
          if (rec.state == "inactive") {
            blob = new Blob(audioChunks, { type: "audio/mp3" });
            blobUrl = URL.createObjectURL(blob);
            document.getElementById("audioElement").src = URL.createObjectURL(blob);
            var recordedAudioPath = document.getElementById("audioElement").src;
            tempAudioFilePathField.value = recordedAudioPath;
            recordedAudioFlag = 1;
          }
      };
    }
  
  function startusingBrowserMicrophone(boolean) {
      getUserMedia({ audio: boolean }).then((stream) => {
          handlerFunction(stream);
      });
    }

    startusingBrowserMicrophone(true);
  
    myStopButton.addEventListener("click", (e) => {
      if (playFlag != 1) {
        try {
              new File([thisAudioBlob], "audio_temp.mp3", {
                type: thisAudioBlob.type,
                lastModified:new Date().getTime()
              });
        } catch(error) {
          // === handle error
        }

        rec.stop();
        audioNoteFlagField.value = "1";
      } else {
        playFlag = 0;
        thisAudioBlob.pause();
        bulletIconDiv.style.color = "white";
        myPlayButton.style.color = "white";
        document.getElementById("audioElement").currentTime = 0.01;
        audioText.textContent = "Click play to listen...";
        try {
          new File([thisAudioBlob], "audio_temp.mp3", {
              type: thisAudioBlob.type,
              lastModified:new Date().getTime()
           });
           audioSaveAjax();
        } catch(error) {
           // === handle error
        }
      }
    });
}

function audioSaveAjax() {
  var fd = new FormData();
  fd.append('fname', 'test_audio_file.mp3');
  fd.append('data', thisAudioBlob);
  $.ajax({
    type: 'POST',
    url: ‘get_audio.php',
    data: fd,
    processData: false,
    contentType: false
   }).done(function(data) {
    // === print message in console
  });
}

Unfortunately, I am not able to generate the audio file on the server correctly. Instead of the expected audio file, I only receive a small 25-byte file filled with random characters. What could be causing this issue? Any assistance would be greatly appreciated.

Answer №1

Ensure you are appending the blob created from the audio chunks, not the HTMLAudioElement, to the FormData object. To retrieve the blob in the ajax function, consider using the jQuery data method as shown below.

...
blob = new Blob(audioChunks, { type: "audio/mp3" });
$(thisAudioBlob).data('blob', blob);
...

function audioSaveAjax() {
  var fd = new FormData();
  fd.append('fname', 'test_audio_file.mp3');
  fd.append('data', $(thisAudioBlob).data('blob'), 'free the.mp3');
  $.ajax({
    type: 'POST',
    url: 'get_audio.php',
    data: fd,
    processData: false,
    contentType: false
   }).done(function(data) {
    // === say something through console
  });
}

Answer №2

Check out my demonstration here:

The demo effectively handles video registration, playback, uploading, and deletion without the use of any libraries, just pure javascript.

This should serve as a helpful example for resolving similar issues. Pay attention to the 'recordedBlobs' variable

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Incorporate an object property value into an established Angular/Node app by using the syntax " :12 " instead of just " 12 "

My current project is an Angular/Node MEAN stack application, but my primary concern revolves around JavaScript. When I receive a response object, it includes an SQL identity id console.log(response.recordset[0]); The output is "":12 I want to assign t ...

I am having trouble with the window.location.href function in my browser

Recently, I encountered an issue with my website that uses ajax to post data to a MySQL database using PHP. The problem arose three days ago after accidentally deleting the xampp folder. Despite having backups of all root files, the "window.location.href" ...

Replicate the preceding input data by simply clicking a button

Here is some HTML and jQuery code that I am working with: $(".btn-copy").click(function() { var previousContent = $(this).prev()[0]; previousContent.select(); document.execCommand('copy'); }); <script src="https://cdnjs.cloudflare.com ...

Serve as a proxy for several hosts with identical URL structures

I've been utilizing the http-proxy-middleware to handle my API calls. Is there a way to proxy multiple target hosts? I've searched for solutions in the issues but still haven't found a clear answer. https://github.com/chimurai/http-proxy-m ...

"Utilizing React.js to implement white-space styling on numeric values for

I am a beginner in Reactjs and eager to learn and improve. Here is some code I have been working on: there's an <h1> element with the text "test", and beneath it, I want to display numbers vertically like this: 1:1, 1:2, 1:3. However, the CSS do ...

JavaScript : Retrieve attributes from a JSON object

Situation : I have a JSON object with multiple properties and need to send only selected properties as a JSON string to the server. Approach : To exclude certain properties from the JSON string, I utilized the Object.defineProperty() method to set enumera ...

The markers from KML exported from My Maps are not showing up on the Google Maps JavaScript API

I have a map on Google My Maps that I want to showcase through the Google Maps JavaScript API. This way, I can easily merge multiple maps into one and add paths/markers without needing to code it all manually. Test out the map I'm using by clicking t ...

What is the best way to add the current date to a database?

code: <?php session_start(); if(isset($_POST['enq'])) { extract($_POST); $query = mysqli_query($link, "SELECT * FROM enquires2 WHERE email = '".$email. "'"); if(mysqli_num_rows($query) > 0) { echo '<script&g ...

Permanent Solution for HTML Textbox Value Modification

https://i.sstatic.net/nB58K.pngI'm currently working on a GPS project where I am attempting to capture the altitude (above sea level) value in textbox1 and convert it into a ground level value displayed in textbox2. In this scenario, the GPS Altitude ...

Ways to stop two JavaScript files from running at the same time

After combining two JavaScript files, I am facing some issues. The first file handles validation while the second one has an ajax plugin for form submission after validation. When I include these files in the header section, they both run simultaneously. H ...

Should the updater method be placed in the state or passed directly to the context?

Is it better to have this context setup like so: <MatchContext.Provider value={this.state.match}> Or should I structure it as follows in my state? match: { match: null, updateMatch: this.updateMatch }, Which approach is more eff ...

Utilizing ThemeProvider in a Different Component in React

In my App.js file, I have a function that toggles between light and dark mode themes: import { createTheme, ThemeProvider } from '@mui/material/styles' import Button from '@mui/material/Button' import Header from './components/Head ...

Handling events for components that receive props from various components in a list

In my code, I have a component called PrivateReview which includes event handlers for updating its content. export default function PrivateReview(props) { const classes = useStyles(); const removeReviewAndReload = async () => { await ...

What is the best way to ensure that a child div can expand to fit within the scrollable area of its parent div

I am facing an issue with a parent div that changes size based on the content inside it. When the content exceeds the initial size, causing the parent to scroll instead of expanding, I have a child div set to 100% width and height of the parent. However, t ...

Answer found: How to effectively filter data arrays in a React client application

I've been working on mapping the GraphQL data onto a React app and I'm facing an issue with making the filtration dynamic for user input. Currently, I am using .filter() to apply client-side filtration but struggling to figure out how to make it ...

Retrieve the information located within the error section of an Ajax request

When sending an ajax request to a Django view, I am including data in the response based on certain logic. return JsonResponse(content={ "Message": "user is not present.", },status=400) This response falls under the error section ...

Using jQuery and AJAX to send a post request in a Razor page and automatically redirect to the view returned by a MVC Action (similar to submitting

I send a json array to the MVC Action using either JQuery or Ajax, and the Action processes the request correctly. However, when the MVC Action returns a View, I am unsure of how to redirect to this View or replace the body with it. Overall, everything se ...

JSON file not found by the system

I am currently working on a basic program that consists of 3 files: 1. An HTML file named index.html 2. A JavaScript file named app.js 3. A JSON dataset called dataset.json I am struggling to make the browser recognize the data in my program. This is ...

Having trouble executing an npm script - getting an error message that reads "Error: spawn node_modules/webpack/bin/webpack.js EACCES"

After installing and configuring Linux Mint, I encountered an error when trying to run my project with the npm run dev command. The error message "spawn node_modules / webpack / bin / webpack.js EACCES" keeps appearing. I have attempted various methods fo ...

JavaScript - Utilizing appendChild as soon as an element becomes available

I'm encountering an issue with my Chrome Extension where I am unable to detect some of the elements that I need to select within a page. var innerChat = document.querySelector('.chat-list'); My goal is to appendChild to this element, but t ...