Show the current time of a track using VueJS

Is there a way to have the time continuously update itself without needing to click on anything? When I press play, I want the seconds to automatically start updating from 0:00 until the end of the audio track. Currently, the time only updates when clicked. I am using HTML5 audio and so far I have been able to display the time as it updates with this line of code:

sound.ontimeupdate = function () { document.getElementById('Time').innerHTML = sound.currentTime.toFixed() }

However, this is not exactly what I need. I want the time attribute in data() to be updated and displayed in the label according to my HTML code.

I attempted to add an event listener but it didn't work. The function was called, and each call was logged with console.log, but the time attribute wasn't getting updated.

let sound = null
export default {
  data () {
    return {
      isPlaying: false,
      time: 0,
      duration: 0
    }
  },
  methods: {
    playMusic () {
      if (!sound) {
        sound = new Audio(require('assets/YES.mp3'))
      }
      this.isPlaying = true
      sound.play()
      
      // sound.addEventListener('timeupdate', function () { this.time = sound.currentTime.toFixed() })   -- did not work

      this.time = sound.currentTime.toFixed()
    }

HTML:

<label id="Time" @timeupdate>
    {{ time }}:{{ duration }}
</label>

Answer №1

When working with the addEventListener method, you may notice that the context of this is not what you expected.

To solve this issue, one option is to use a fat arrow function.

sound.addEventListener('timeupdate', () => this.time = sound.currentTime.toFixed() )

Alternatively, you can stick to the traditional method by saving the value of this in another variable.

let that = this
sound.addEventListener('timeupdate', function () { that.time = sound.currentTime.toFixed() })

Answer №2

One way to dynamically add a generic timer is to utilize a watch function for adding and removing it:

(code example - untested)

export default {
    data() {
        return {
            isPlaying: false,
            time: 0,
            duration: 0,
            intervalId: null,
            sound: null
        };
    },
    watch: {
        isPlaying(isPlaying) {
            if (this.intervalId !== null) {
                clearInterval(this.intervalId);
            }
            if (isPlaying) {
                this.sound.play();
                this.intervalId = setInterval(() => {
                    this.time = this.sound.currentTime.toFixed();
                }, 500);
            } else {
                this.sound.stop();
            }
        }
    },
    methods: {
        playMusic() {
            if (!this.sound) {
                this.sound = new Audio(require("assets/YES.mp3"));
            }
            this.isPlaying = true;
        }
    }
};

Answer №3

Looking to implement vue3 script setup?

<template>
  <audio :src="file.mp3" id="stream" autoplay></audio>
  <span>{{ currentTime }}</span>
</template>

<script setup>
import { onUpdated } from "vue";
const currentTime = ref();
onUpdated(() => {
  let audio = document.getElementById("stream");
  audio.addEventListener("timeupdate", function () {
    currentTime.value = audio.currentTime.toFixed();
  });
});
</script>

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 an Image Link within Nivo Slider

I have been trying to figure out how to make an image a link in NivoSlider. I know that I can use captions to create a link, but I want the actual image to be clickable for better accessibility. I found a similar question on StackOverflow, but it was rela ...

Applying a class change in Vue.js upon mounting

How can I make a button element with a .hover property trigger the hover animation as soon as the page loads? I want to apply a class to the button when the page is mounted and then remove it later. What is the best approach for this? I considered using a ...

Elements are randomly glitching out with CSS transitions in Firefox

Chrome is working perfectly for me, but when I switch to Firefox it behaves differently than expected I am attempting to create a simple animation (utilizing transitions) that continuously runs on mouseover and smoothly returns to the starting position on ...

Can you explain the key distinctions among Highland.js, Kefir.js, and Rx.js?

Given the emphasis on objective answers on SO, my inquiry is focused on understanding the distinct functional and performance characteristics of these three functional/reactive libraries. This knowledge will guide me in selecting the most suitable option ...

Creating a dynamic dropdown menu based on a class value using JavaScript in PHP

There are two dropdown menus on my webpage that display information from my SQL table. The first dropdown contains different "Colors," and the second dropdown contains members associated with each color group. Each member is categorized into different optg ...

Obtain element by selecting a specific class using Javascript

<select class="tmcp-field tillagg-width tm-epo-field tmcp-select" name="tmcp_select_30" data-price="" data-rules="" data-original-rules="" id="tmcp_select_ ...

Karma is unable to locate the module within the specified relative path

I'm facing a challenge with Karma not being able to load a specific file. As a novice in Karma, I dedicated the entire day to researching and checking documentation for similar issues with no luck. Upon initiating the karma process, it encounters an ...

Error in Node.js Socket.io: The disconnect event is being triggered before the connect event

When the client reconnects after a network drop, the disconnect event is triggered on the server. Client code: var url ='192.168.1.101', port = '80', socket = io.connect('http://' + url + ':' + port, { &apo ...

Finding a path match with Regexp using path-to-regexp

When obtaining a user's information by their unique id: /user/{id} I convert this path to a regular expression: pathToRegexp(path.replace(/\{/g, ':').replace(/\}/g, '')) Next, I compare it with: const matchedPaths = ...

Using the HTML video tag to apply different background colors based on the individual machines being

My web application includes a video that is set to play against the same background color as the webpage. However, I am experiencing an issue where the video background appears differently on various machines using the same browser. What I would like to ac ...

Error in Vue.js: Trying to access properties of an undefined object

My understanding of vue.js is limited, but based on what I know, this code should work. However, when attempting to access the variable in the data property, it seems unable to locate it. data: function() { return { id: 0, clients: [] ...

Automatically select a value in MUI AutoComplete and retrieve the corresponding object

I recently set up a list using the MUI (v4) Select component. I've received a feature request to make this list searchable due to its extensive length. Unfortunately, it appears that the only option within MUI library for this functionality is the Au ...

In both Chrome and Edge, the default value for the <select> tag is successfully set, however, this functionality is not working in

I have defined two values in the created method, 2018 and My Name, and assigned them to separate data properties. These data properties are then passed as v-bind to a component. The issue I am facing is that in Chrome and Edge, both values are set as defa ...

Several middlewares using router.params()

Is it possible to include multiple middlewares as parameters in the function router.params() in Node-Express? I currently have the following setup: const checkAuth = (req, res, next) => {console.log("checking auth"); next()} const checkAuth = ...

What is the process for incorporating a full-page blog into a blog preview?

I customized a template, but there is a blog section within the div that I am struggling to replicate. Here is the test website for reference: Below is the HTML code for the blog section: <!-- Blog Start --> <section class="section bg ...

file downloads may fail due to undefined response data

I attempted to send files from Spring Boot to Vue, but when I open the files, they appear empty. Upon checking the res.data, I discovered that it is undefined. Below is the code for Spring Boot: The controller: @GetMapping("/download/{path}") pub ...

Flask causing AJAX Request to encounter a CORS Policy issue

Currently, I am utilizing Flask to construct a basic backoffice system. In an attempt to execute some requests on the client-side using AJAX, I keep encountering a persistent error: Access to XMLHttpRequest at '...' from origin 'http://lo ...

An error occurred - 0x800a1391 - JavaScript runtime error: The function 'SelectAllCheckBoxes' has not been defined

I'm currently in the process of learning web development and I am trying to incorporate jQuery into my ASP .NET page. Within the header section, I have included the necessary references: <head id="Head1" runat="server"> <link href=" ...

JavaScript callbacks are not executed synchronously

My Objective : I am attempting to initiate a payment order in the payment gateway server and then send back the order details to the client using Firebase cloud functions. This process involves utilizing firebase cloud functions. The Order() function ha ...

Is it possible to transfer a variable from my javascript code to a jsp file?

Within a HTML file, I have created a variable in JavaScript consisting of an array with two entries - a latitude and a longitude. I am looking to use AJAX to send this variable and then utilize it in my JSP file to populate a form. Does anyone have any su ...