redxtech / vue-plyr

A Vue component for the plyr (https://github.com/sampotts/plyr) video & audio player.
Other
764 stars 136 forks source link

Updating options #455

Open pmcp opened 2 years ago

pmcp commented 2 years ago

What is the correct way of updating the options object?

I've got this options object, but when I change 'this.songName', the player doesn't react:

<template>
  <div>
    <vue-plyr
      v-if="songUrl"
      ref="plyr"
      :options="options">
      <audio>
        <source
          src=""
          type="audio/mp3">
      </audio>
    </vue-plyr>
  </div>
</template>

<script>
export default {
  computed: {
    options() {
      return {
        controls: `<div class="plyr__controls flex">
          <button type="button" class="plyr__control mr-2" aria-label="Play, {title}" data-plyr="play">
              <svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-pause"></use></svg>
              <svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-play"></use></svg>
              <span class="label--pressed plyr__tooltip" role="tooltip">Pause</span>
              <span class="label--not-pressed plyr__tooltip" role="tooltip">Play</span>
          </button>
          <div class="flex-grow flex flex-col italic">
            <div class="text-right">${this.songName}</div>
            <div class="plyr__progress">
                <input data-plyr="seek" type="range" min="0" max="100" step="0.01" value="0" aria-label="Seek">
                  <progress class="plyr__progress__buffer" min="0" max="100" value="0">% buffered</progress>
                <span role="tooltip" class="plyr__tooltip">00:00</span>
            </div>
            <div class="flex justify-end">
              <div class="plyr__time plyr__time--current mr-2" aria-label="Current time">00:00</div>
              <div class="plyr__time plyr__time--duration" aria-label="Duration">00:00</div>
            </div>
         </div>
      </div>`
      }
    },
    songUrl() {
      return this.$store.state.songUrl
    },
    songName() {
      return this.$store.state.songName
    }
  },
  watch: {
    songUrl(newUrl) {
      this.$nextTick().then(() => {
        this.$refs.plyr.player.source = {
          type: 'audio',
          sources: [
            {
              src: newUrl,
              type: 'audio/mp3'
            }
          ]
        }
        this.$refs.plyr.player.play()
      })
    }
  }
}
</script>

Any help or advice?

mrgodhani commented 2 years ago

I have bumped into similar issue too. If you using vue 3 adding key attribute with unique value might help to force rerender the component.

simbiant commented 1 year ago

In case, someone need it. Just wrap player with component and pass options as props, so every time you change options, component will update. I tried to update player directly, but there was error null pointer