Display a visual progress indicator during audio recording

I am currently using the MediaRecorder functionality to capture audio and I would like to display a progress bar showing the recording process. Here is the code snippet from my recorder template:

 <p id="countdowntimer">Current Status: Beginning in<span id="countdown">10</span> seconds</p>
 <progress ref="seekbar" value="0" max="1" id="progressbar"></progress>

Here is the function I am using:

mounted() {
let timeleft = 10;
const timeToStop = 20000;
const timeToStart = 1000;
const downloadTimer = setInterval(() => {
  timeleft -= 1;
  document.getElementById('countdown').textContent = timeleft;
  if (timeleft <= 0) {
    clearInterval(downloadTimer);
    document.getElementById('countdowntimer').textContent = 'Current Status: Recording';


    const that = this;
    navigator.getUserMedia = navigator.getUserMedia ||
      navigator.webkitGetUserMedia ||
      navigator.mozGetUserMedia;
    navigator.getUserMedia({ audio: true, video: false }, (stream) => {
      that.stream = stream;
      that.audioRecorder = new MediaRecorder(stream, {
        mimeType: 'audio/webm;codecs=opus',
        audioBitsPerSecond: 96000,
      });

      that.audioRecorder.ondataavailable = (event) => {
        that.recordingData.push(event.data);
      };

      that.audioRecorder.onstop = () => {
        const blob = new Blob(that.recordingData, { type: 'audio/ogg' });
        that.dataUrl = window.URL.createObjectURL(blob);
        // document.getElementById('audio').src = window.URL.createObjectURL(blob);
      };

      that.audioRecorder.start();

      console.log('Media recorder started');

      setTimeout(() => {
        that.audioRecorder.stop();
        document.getElementById('countdowntimer').textContent = 'Current Status: Stopped';
        console.log('Stopped');
      }, timeToStop);
    }, (error) => {
      console.log(JSON.stringify(error));
    });
  }
}, timeToStart);

}

I am now trying to update the progress bar accordingly:

  const progressbar = document.getElementById('progressbar');
  progressbar.value = some value;

My main objective is to dynamically increase the progress bar based on the recording progress. How can I achieve this?

Answer №1

Instead of

<progress ref="seekbar" value="0" max="1" id="progressbar"></progress>

try this instead

<progress ref="seekbar" value="0" max="100" id="progressbar"></progress>

for your progress bar update in the loop, you can calculate the value like this:

const progressbar = document.getElementById('progressbar');
progressbar.value = 100*(ELAPSED TIME) / timetostop;

NOTE:

To calculate your "elapsed time", you can do the following:

elapsedTime = 0;

setTimeout(function () {
   //functions that run in the loop:
    elapsedTime+1000;
}, 1000);

Answer №2

This is the solution I used to fix my issue:

    const progressElement = document.getElementById('progressbar');
    let progressWidth = 1;
    const progressIntervalId = setInterval(() => {
      if (progressWidth >= 100) {
        clearInterval(progressIntervalId);
      } else {
        const stopTimeInSeconds = timeToStop / 1000;
        progressWidth += 100 / stopTimeInSeconds;
        progressElement.value = progressWidth;
      }
    }, timeToStart);

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

Creating a loading component using the power of the useEffect hook

One of the components I've been working with is a loading bar that can be easily imported like this: import { CircleToBlockLoading } from "react-loadingg"; I tried using it in the following way, but it doesn't seem to render anything: ...

Generate a library using Vue CLI from a component and then import it into your project

When using vue-cli to build my lib, I run the following command: "build": "vue-cli-service build --target lib --name myLib ./src/component.vue" After the build, how can I import my component from the dist folder? Importing from path-to-myLib/src/compone ...

Creating nested dynamic routes in Vue without specifying a route prefix is achievable by

In order to implement a nested category lookup using routes, I have configured a locale parameter like: /en. The desired route structure includes placeholders such as: /:locale/:category/:subcategory/:process For example, a real-world scenario would be: ...

Tips for enabling the `ignoreUndefinedProperties` feature in Node.js

I'm currently in the process of creating a REST api for my Node.js and Express application. However, I keep encountering an error stating that properties are undefined whenever I attempt to send a request. How can I go about enabling 'ignoreundef ...

The issue with Extjs store.proxy.extraParams being undefined appears to only occur in Internet Explorer

I currently have an ExtJs store set up with specific configurations. var fieldsStore = new Ext.create('Ext.data.Store', { model : 'FieldsModel', proxy : { type : 'ajax', url : 'queryBuilder_getQueryDetails', ...

Next.js is throwing an unhandled runtime error of type TypeError, which is causing issues with reading properties of null, specifically the 'default' property

"use client" import { useKindeBrowserClient } from '@kinde-oss/kinde-auth-nextjs' import Image from 'next/image'; import React from 'react' function DashboardHeader() { const {user} = useKindeBrowserClient(); r ...

Converting Epoch time to date in NextJS

In my NextJS app, I have a date displayed in a div. <div>{post.createdat}</div> The date is shown in epoch time (1609553315666), indicating the number of seconds that have elapsed since 1970. I'm wondering if there's a way to conver ...

Using Javascript/HTML to enable file uploads in Rails

I'm currently facing an issue with uploading and parsing a file in Rails, as well as displaying the file content in a sortable table. I followed a tutorial on to get started. This is what my index.html.erb View file looks like: <%= form_tag impo ...

Creating distinctive identifiers for individual function parameters in JavaScript using addEventListener

I am working on a for loop that dynamically generates elements within a div. Each element should trigger the same function, but with a unique ID. for(var i = 0; i < 10; i++) { var p = document.createElement("p"); var t = document. ...

What is the best way to split an array into smaller chunks?

My JavaScript program fetches this array via ajax every second, but the response time for each request is around 3 to 4 seconds. To address this delay, I attempted to split the array into chunks, however, encountered difficulties in completing the task: { ...

Creating dynamic web content using PHP and JavaScript

I stumbled upon a tutorial on the PHP.net website within the "PHP and HTML" manual which includes an example titled Generating JavaScript with PHP. Currently, I am experimenting with a basic demo of this concept on my own to grasp the process before attem ...

Customize Magento pop-up close function on click event

I developed a unique module with a Magento pop-up feature. I am looking to customize the close event for the pop-up. <div onclick="Windows.close(&quot;browser_window_updatecc&quot;, event)" id="browser_window_updatecc_close" class="magento_clos ...

Using String interpolation in Vue.js to bind a computed attribute

I am working with a set of computed data that each returns a specific URL - computed:{ facebookUrl(){return "facebook.com"}, twitterUrl(){return "twitter.com"} } Within the template, I have a v-for loop and each item has a 'name' attribute (nam ...

Experiencing difficulties with a callback function while making a jQuery getJSON request via AJAX

Within my utility .js file, there is a method that fetches data using Ajax. The challenge I am facing is that this method does not have prior knowledge of the caller. After the Ajax call completes asynchronously, it needs to send an object back to the cal ...

The equation:() is malfunctioning

Here is a code snippet I'm working with: $("#button").click(function () { for (var i = 0; i < 4; i++) { setTimeout(function () { $(".rows:eq("+i+")").css("background-color", "blue"); ...

Watch the video and follow along with your mouse using jQuery

Wouldn't it be cool to have a video play and follow your mouse pointer when you hover over the red box? And then once you move away, the video stops and disappears. Check out my progress so far: jsfiddle Here's the jQuery code I've used: $ ...

Importing d3.JS JSON data without polluting the global scope

Here is a JSON object: { "temp_data": [10,15,20] } I'm trying to import it: var temp_data; //Importing from JSON if(true){ d3.json("graph.json", function(error, graph) { if (error){ throw error; } temp_da ...

Having difficulty categorizing an array with a multi-dimensional structure using a computed function in VueJS

I am currently using Vue to update an array called "draggables" based on the logic that if an object exists in another array of arrays named "dropzones," it should be removed from draggables. Each draggable item will only be present in the index of the mu ...

Is there a way to apply an event function after adding elements through append?

When I click the button, a div is appended inside the body. However, I am trying to make it so that when I click on this newly appended div, an alert message pops up. I have tried implementing this with a highlighted area, but have been unsuccessful. How c ...

Creating an anonymous component in Vue.js involves enclosing the received slots (vnodes) within a wrapper component

Is there a way to wrap two specified named slots, slotOne and slotTwo, which are located in the child component at this.$scopedSlots.slotOne and this.$scopedSlots.slotTwo respectively? I would like to then conditionally render these slots (vnodes) as shown ...