CodeNewbie
CodeNewbie

Reputation: 203

Display currentTime of a song in vue

I'd like to know how can I make time constantly update itself. So when I press the play button the seconds start to update automatically from 0:00 to the end , because now it just updates onclick. I am trying to use HTML5 audio and I have successfully managed to get the time updating as a label from this line of code:

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

But thats not what I need, I would like to get the time attribute in data() to get updated and displayed in the label as shown in my HTML code.

I tried adding an event listener but it did not work... It gets called and every call was logged with console.log but time attribute was not 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>

Upvotes: 0

Views: 3237

Answers (3)

Ali Seivani
Ali Seivani

Reputation: 551

For 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>

Upvotes: 0

Daniel
Daniel

Reputation: 35714

you could just add a generic timer dynamically. You can use a watch to add/remove it like so:

(untested code)

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;
        }
    }
};

Upvotes: 0

Radu Diță
Radu Diță

Reputation: 14191

Inside your addEventListener you get a different this than you might expect.

Either use fat arrow

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

or, the old way, save this

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

Upvotes: 2

Related Questions