テクノロジー

VueでVIDEOのミュート操作について

Tags: /
Written by Kishimoto

丸半日分ついやしてしまったので、忘れないためにも備忘録を残しておきます。

自社のサイトを今Vue.jsにちょっとずつ置き換えていってるのですが、VIDEOの制御やらがどうやるのか分からずに調べてると、カスタムディレクティブを使う方法が載っていたので、それをミュートに置き換えた感じだったんですが、これだとSafariの音声付きのポリシーに引っかかってしまう。

Unhandled Promise Rejection: NotAllowedError (DOM Exception 35): The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.

このPromise Rejectionに悩まされました。

自動再生は自動再生なんだけど、mute状態のautoplayでmuteだけ操作させるのはダメみたいです。

それで、音声付きの動画データの場合は、どうもアクションで必ず1度はplay()を発火させないとダメっぽいので、音声ボタンのクリック時にDOMからplay()を発火するやり方になりました。

HTML

<div class="video">
    <video v-mute="is_mute" loop muted autoplay playsinline prelod="auto" class="el-video">
        <source src="動画ファイル" type="video/mp4">
    </video>
    <div class="vol-switch" :class="[active]" @click="muteSwitch">
        <div v-show="is_mute == true"><i class="fas fa-volume-off"></i></div>
        <div v-show="is_mute == false"><i class="fas fa-volume-up"></i></div>
        <span class="on">ON</span>
        <span class="off">OFF</span>
    </div>
</div>

JavaScript

export default {
    data() {
        return {
            is_mute: true,
            video: false
        }
    },
    directives: {
        mute(el, binding) {
            /*
            ここでel.play()としても動かないので注意
            */
            if (binding.value) {
                el.muted = true;
            } else {
                el.muted = false;
            }
        }
    },
    computed: {
        active() {
            return this.is_mute ? false : 'active';
        }
    },
    mounted() {
        // マウントされてからDOMを取得してDataに格納しておく
        this.video = document.querySelector('.el-video');
    },
    methods: {
        muteSwitch: function() {
            // ボタンを押すとplayを発火
            this.video.play();

            // playが動いた状態でis_muteの値を変更
            if (this.is_mute) {
                this.is_mute = false;
            } else {
                this.is_mute = true;
            }
        }
    }
}

カスタムディレクティブからplayを発火するとPromise Rejectionになって動かないので注意。

株式会社MIRAIでは、Webマーケティング・コンサルティングから
ホームページ制作・動画制作など、様々なご相談を承っております。

お仕事のご依頼・ご相談はこちら