0

Overview

I'm using Plyr as a wrapper for videos on my website and I'm trying to control the video player via it's API when a function is called by a debounce function.

Basically, when I enter a new video ID for YouTube, I want the existing video to be destroyed and then another video to be entered in it's place which is relative to the new ID and then autoplayed.

This will eventually be adapted into another component on my website.

My issue

I can not seem to control the player via the API, meaning I can't destroy or use any Plyr functions to change how it operates once Vue has done it's part.

As you can see from the code below, in the updateVideo function I am trying to play the video using player.play() which then throws me this console error:

Cannot read property 'play' of undefined

I've looked at the documentation to try and see how to solve this but I'm at a dead end.

YouTube.vue

<script>
    import Plyr from 'plyr'
    import axios from 'axios'
    import Swal from 'sweetalert2'
    import _ from 'lodash'

    const Toast = Swal.mixin({
        toast: true,
        position: 'center',
        showConfirmButton: false,
        timer: 3000
    })

    export default {
        data() {
            return {
                // bTqVqk7FSmY
                movieName: 'JL3b_fewO08',
            }
        },
        mounted() {
            const player = new Plyr('.yt-player');
        },
        methods: {
            updateVideo: function() {
                const player = new Plyr('.yt-player');
                player.play(); // This throws an error
                player.volume = 0.5;
            },
            debounceVideo: _.debounce(function() {
                this.updateVideo();
            }, 700)
        },
    }
</script>
<template>
    <div class="my-10 mx-auto pl-10">
        <form class="mb-3">
            <input type="text" v-model="movieName" @input="debounceVideo" class="border-2 p-2 w-full" placeholder="Please specify a movie name" data-city-name>
        </form>
        <div class="w-full">
            <div class="yt-player" data-plyr-provider="youtube" v-bind:data-plyr-embed-id="movieName"></div>
        </div>
    </div>
</template>

My main issue is trying to control the video like the API specifies but won't work.

Also I've looked into vue-plyr and that doesn't seem to fit in with what I'm trying to achieve and still has the same issues.

As always, any help would be really appreciated.

Matt
  • 484
  • 6
  • 19

1 Answers1

1

That's because you have lost the original reference to the Plyr instance: instead, I would suggest when instantiating a new Plyr instance, you store it in a class member as such: this.player = new Plyr('.yt-player');.

Here is your updated code: you simply need to:

  1. add a new key to your data,
  2. assign the newly created instance via this.player = new Plyr(...) and
  3. reference the player instance using this.player:

export default {
    data() {
        return {
            movieName: 'JL3b_fewO08',

            // Create a key in which we will store the new Plyr instance
            player: null,
        }
    },
    mounted() {
        // Store in data
        this.player = new Plyr('.yt-player');
    },
    methods: {
        updateVideo: function() {
            // this.player will have the reference to your Plyr instance
            this.player.play();
            this.player.volume = 0.5;
        },
        debounceVideo: _.debounce(function() {
            this.updateVideo();
        }, 700)
    },
}
Terry
  • 63,248
  • 15
  • 96
  • 118