vue项目video视频播放多种实现方式

一、vue-video-player

安装
npm i vue-video-player
引入

import { videoPlayer } from "vue-video-player";
import "video.js/dist/video-js.css";
import "vue-video-player/src/custom-theme.css";

index.vue

<template>
<div>
<video-player
                class="video-player vjs-custom-skin"
                ref="videoPlayer"
                name="videoPlayer"
                id="video"
                :playsinline="true"
                :globalOptions="globalSetting"
                :options="playerOptions"
                @play="onPlayerPlay($event)"
                @pause="onPlayerPause($event)"
                @ended="onPlayerEnded($event)"
                @waiting="onPlayerWaiting($event)"
                @timeupdate="onPlayerTimeupdate($event)"
                @statechanged="playerStateChanged($event)"
                @canplaythrough="onPlayerCanplaythrough($event)"
                @ready = "playerReadied"
        ></video-player>
</div>
</template>
<script>
import { videoPlayer } from "vue-video-player";
    import "video.js/dist/video-js.css";
    import "vue-video-player/src/custom-theme.css";
    import commentsList from "@/components/commentsList";
    export default {
        name: "showVideo",
        components: {
            videoPlayer
        },
        data() {
            return {
                playTime:'',
                current:'',
                playerOptions: {
                    playbackRates: [0.5, 1.0, 1.5, 2.0], // 可选的播放速度
                    autoplay: false, // 如果为true,浏览器准备好时开始回放。
                    muted: false, // 默认情况下将会消除任何音频。
                    loop: false, // 是否视频一结束就重新开始。
                    preload: "auto", // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
                    language: "zh-CN",
                    aspectRatio: "16:9", // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
                    fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
                    sources: [
                        {
                            type: "video/mp4", // 类型
                            src:
                                "xxxxxx.mp4" // url地址
                        }
                    ],
                    poster: "", // 封面地址
                    notSupportedMessage: "此视频暂无法播放,请稍后再试", // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
                    controlBar: {
                        timeDivider: true, // 当前时间和持续时间的分隔符
                        durationDisplay: true, // 显示持续时间
                        remainingTimeDisplay: false, // 是否显示剩余时间功能
                        fullscreenToggle: true // 是否显示全屏按钮
                    },
                },
            };
        },
        beforeRouteLeave(){
            this.$refs.videoPlayer.player.pause()
        },
        methods: {
            // 播放回调
            onPlayerPlay(player) {
                console.log("player play!", player);
            },

            // 暂停回调
            onPlayerPause(player) {
                console.log("player pause!", player);
            },

            // 视频播完回调
            onPlayerEnded($event) {
                console.log(player);
            },
            // DOM元素上的readyState更改导致播放停止
            onPlayerWaiting(player) {
                let time = localStorage.getItem("cacheTime")
                if(player.cache_.currentTime - Number(time) > 0.1){
                    this.current = Number(time)
                    this.playerReadied(player)
                }else{
                    this.current = player.cache_.currentTime
                }
            },

            // 已开始播放回调
            onPlayerPlaying($event) {
                // console.log(player)
            },

            // 当播放器在当前播放位置下载数据时触发
            onPlayerLoadeddata($event) {
                // console.log(player)
            },

            // // 当前播放位置发生变化时触发。
            onPlayerTimeupdate(player) {
                this.playTime = player.cache_.currentTime
                let playTime = player.cache_.currentTime
                setTimeout(function () {
                    localStorage.setItem("cacheTime",playTime)
                },500)


                let time = localStorage.getItem("cacheTime")
                if(player.cache_.currentTime - Number(time) > 2){
                    this.current = Number(time)
                    this.playerReadied(player)
                }else{
                    this.current = player.cache_.currentTime
                }
            },

            //媒体的readyState为HAVE_FUTURE_DATA或更高
            onPlayerCanplay(player) {
                // console.log('player Canplay!', player)
            },

            //媒体的readyState为HAVE_ENOUGH_DATA或更高。这意味着可以在不缓冲的情况下播放整个媒体文件。
            onPlayerCanplaythrough(player) {
                // console.log('player Canplaythrough!', player)
            },

            //播放状态改变回调
            playerStateChanged(playerCurrentState) {
                // console.log('player current update state', playerCurrentState)
            },

            //将侦听器绑定到组件的就绪状态。与事件监听器的不同之处在于,如果ready事件已经发生,它将立即触发该函数。。
            playerReadied(player) {
                // console.log('example player 1 readied', player);
                player.currentTime(this.current)
            }
        }
    };
</script>

<style lang="less">
    .vjs-custom-skin > .video-js .vjs-big-play-button {
        background-color: rgba(0,0,0,0.45);
        font-size: 3.0em;
        /* border-radius: 50%; */
        height: 1.5em !important;
        line-height:1.5em !important;
        margin-top: -1em !important;
    }
    /*这里用了第三方vue-video-player插件,但这个插件有bug,设置globalSetting:{controls:true}隐藏进度条不生效,故可设置插件样式进行隐藏vjs-progress-contro*/
    .vjs-progress-control {
        /*visibility:hidden;       // 隐藏进度条*/
    }

</style>

二、原生video标签播放文件,除了样式丑点没啥毛病

index.vue

<template>
<div>
<video
                  src="xxxxx.mp4"
                  :controls="videoOptions.controls"
                  class="video-js vjs-big-play-centered vjs-fluid"
                  webkit-playsinline="true"
                  playsinline="true"
                  x-webkit-airplay="allow"
                  x5-playsinline
                  style="width: 100%;"
                  @play="onPlayerPlay"
                  @pause="onPlayerPause"
                  @seeking="seeking"
                  autoplay="autoplay"
                  ref="video">
            </video>
</div>
</template>

<script>
export default {
        name: "showVideo",
        data() {
            return {
                videoOptions: {
                    controls:true,
                    src:
                        "xxxxxxx.mp4", // url地址
                },
                player: null,
                playTime:'',
                seekTime:'',
                current:'',
        },
        beforeRouteLeave(){
            //
        },
        mounted() {
            this.initVideo();
        },
        methods: {
                initVideo() {
                //原生初始化视频方法
                let myVideo = this.$refs.video;
                //ontimeupdate
                  myVideo.ontimeupdate = function() {myFunction()};
                  let _this = this;

                  function myFunction(){
                      let playTime = myVideo.currentTime
                      setTimeout(function () {
                          localStorage.setItem("cacheTime",playTime)
                      },500)
                      let time = localStorage.getItem("cacheTime")
                      // 当前播放位置发生变化时触发。
                      if(playTime - Number(time) > 2){
                          myVideo.currentTime = Number(time)
                      }else{
                      }
                  };
              
            // 播放回调
            onPlayerPlay(player) {
                // this.globalSetting = true
                console.log("player play!", player);
                // document.getElementsByClassName("vjs-control-bar").style.display = "block";
                // document.getElementsByClassName("vjs-control-bar").style.display = "block";
            },

            // 暂停回调
            onPlayerPause(player) {
                // this.globalSetting.controls = false;
                // console.log("player pause!", player);
                // var video = document.getElementById("video");
                // video.controls=false;
                // document.getElementsByClassName("vjs-control-bar").style.display = "none";
            },
            },

        beforeDestroy() {
            if (this.player) {
                this.player.dispose()
            }
        }
        }
</script>

三、video.js插件

1、先安装video.js...

index.vue

<template>
<div>
<video
                id="myVideo"
                ref="myvideo"
                class="video-js vjs-big-play-centered vjs-fluid"
                controls
                preload="auto"
                width="100%"
                height="100%"
                @on="onPlayerPlay"
                @pause="onPlayerPause"
                :poster="videoOptions.src"
        >
            <source
                    type="video/mp4"
                    :src="videoOptions.src"
            >
        </video>
</div>
</template>
<script>
//直接引入videojs会报错 
import _videojs from 'video.js'
const videojs = window.videojs || _videojs
import 'video.js/dist/video-js.css'
export default {
name: "showVideo",
data(){
  return {
                videoOptions: {
                    controls:true,
                    src: "xxxxxxxxx.mp4", // url地址
                },
                player: null
  }
},
mounted() {
            this.initVideo();
          
        },
methods: {
            initVideo() {
                //页面dom元素渲染完毕,执行回调里面的方法
                let options = {
                    controls: true,
                    //自动播放属性,muted:静音播放
                    autoplay: false,
                    //建议浏览器是否应在<video>加载元素后立即开始下载视频数据。
                    preload: "auto",
                    //设置视频播放器的显示宽度(以像素为单位)
                    // width: "800px",
                    //设置视频播放器的显示高度(以像素为单位)
                    // height: "400px",
                    controlBar:{
                        playToggle:true
                    }
                };
                this.player = videojs(this.$refs.myvideo,options,function() {
                    let _this = this;
                    this.on('timeupdate', function() {
                        this.playTime = this.currentTime()
                        let playTime = this.currentTime()
                        setTimeout(function () {
                            localStorage.setItem("cacheTime",playTime)
                        },500)


                        let time = localStorage.getItem("cacheTime")
                        if(this.currentTime() - Number(time) > 2){
                            this.current = Number(time)
                            this.currentTime(this.current)
                        }else{
                            this.current = this.currentTime()
                        }
                    })

                    this.on('ended', function() {
                        console.log('ended',"播放结束")
                    })

                    this.on('progress', function() {
                        console.log('progress',"开始播放")
                    })

                    this.on('error', function() {
                        _this.$message.warning("异常,无法播放")
                    })
                })
            }
}
}

</script>
<style lang="less">
    /*修改播放器样式*/
    .video-js{
        width: 120%!important;
        height: 100%!important;
    }
    .video-js .vjs-big-play-button {
        background-color: rgba(0,0,0,0.45);
        font-size: 3.0em;
        border-radius: 50%;
        height: 1.5em !important;
        line-height:1.5em !important;
        margin-top: -1em !important;
    }
    .vjs-paused .vjs-big-play-button,
    .vjs-paused .vjs-big-play-button {
        display: block!important;
    }
    .myVideo-dimensions {
        width: 100%!important;
        height: 100%!important;
        display: block!important;
    }
    .vjs-poster{
        background-size: 100% 100%!important;
    }
</style>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,165评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,503评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,295评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,589评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,439评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,342评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,749评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,397评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,700评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,740评论 2 313
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,523评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,364评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,755评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,024评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,297评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,721评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,918评论 2 336

推荐阅读更多精彩内容