浏览器缓存视频进度,vue-video-player

谭昕
2023-12-01

整个vue组件放进来了,基本上是用id+视频地址,判断id是否存在,如果有则调用缓存拿到上次播放市场playTime,然后从这个时长加载

主要方法关键字play (id,url) , open() ,close (e) ,

//当前播放位置发生变化时触发。
        onPlayerTimeupdate(player)

//将侦听器绑定到组件的就绪状态。与事件监听器的不同之处在于,如果ready事件已经发生,它将立即触发该函数。。
        playerReadied(player) {
            player.currentTime(this.playTime)

vue-video-player依赖自己搜着加载就行了

npm install vue-video-player -save

下面是整个组件:

<template>
     <transition :name="effect">
        <div class="video-main" v-if="status" >
            <div class="video-box" @click.self="close">
                
                <div class="video-body">
					<div class="video-header clearfix">
					    <b role="button" class="video-close" @click.stop="close">×</b>
					</div>
                    <!-- 普通视频 -->
					<video-player  ref="videoPlayer" :playsinline="true"
						:options="playerOptions" @play="onPlayerPlay($event)" @pause="onPlayerPause($event)"
						@ended="onPlayerEnded($event)" @loadeddata="onPlayerLoadeddata($event)"
						@waiting="onPlayerWaiting($event)" @playing="onPlayerPlaying($event)"
						@timeupdate="onPlayerTimeupdate($event)" @canplay="onPlayerCanplay($event)"
						@canplaythrough="onPlayerCanplaythrough($event)" @ready="playerReadied"
						@statechanged="playerStateChanged($event)" v-if="playerOptions.sources[0].src"></video-player>
                    <!-- <video
                        class="video"
                        :src="url"
                        webkit-playsinline
                        playsinline
                        controls=""
                        :muted="false"
                        preload="meta"
                        autoplay="false"
                        loop="false"
                        ref="video"
                        v-if="url"
                    ></video> -->
                    <!-- YouTube视频 -->
                    <iframe
                        id="ytplayer"
                        type="text/html"
                        :width="isMobile ? '100%' : '1280'"
                        :height="isMobile ? setHight : '720'"
                        frameborder="0"
                        :src="youtube"
                        allowfullscreen
                        v-if="youtube"
                    />
                </div>
            </div>
        </div>
    </transition>
</template>

<script>
	
	import {
		videoPlayer
	} from 'vue-video-player'
	import 'video.js/dist/video-js.css'
	import 'vue-video-player/src/custom-theme.css'
export default {
    name: 'videoTwo',
    data () {
        return {
            effect: 'fade-in',
            status: false,
            url: '',
            youtube: '',
            isMobile: false,
            setHight: 0,
			
			id: 1,
			playTime: '0',
			arrplayTime: [],
			
			paused: true,
			playerOptions: {
				playbackRates: [0.7, 1.0, 1.5, 2.0], // 播放速度
				autoplay: true, // 如果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: [{
					// src: '../../static/video/test.mp4', // 路径
					src: 'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4'
					// type: 'video/mp4' // 类型
				}],
				poster: '', // 你的封面地址
				// width: document.documentElement.clientWidth,
				notSupportedMessage: '此视频暂无法播放,请稍后再试', // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
				controlBar: {
					timeDivider: true,
					durationDisplay: true,
					remainingTimeDisplay: false,
					fullscreenToggle: true // 全屏按钮
				}
			}
        }
    },
	components: {
		videoPlayer
	},
    computed: {

    },
    methods: {
        play (id,url) {
			this.id = id
			this.open()
            // url必填
            if(!url) {
                //console.log('video url is required.')
                return
            }

            // 写入url
            let youtube_short = url.match(/https?:\/\/youtu\.be\/(.*)/),
                youtube_long = url.match(/https?:\/\/www.youtube\.com\/watch\/?\?(.*)/),
                youtube_embed = /https?:\/\/www.youtube\.com\/embed\/.+?/.test(url)

            if(youtube_short) {
                // 短链接提取id
                this.youtube = `https://www.youtube.com/embed/${youtube_short[1]}`
            }
            else if(youtube_long) {
                // 长链接提取id
                let search = youtube_long[1]
                search.replace(/([^=]*)=([^&]*)&?/g, function(str, key, val) {
                    if(key === 'v') {
                        this.youtube = `https://www.youtube.com/embed/${decodeURIComponent(val).replace(/</g, "&lt;").replace(/>/g, "&gt;")}`
                    }
                })
            } else if(youtube_embed) {     
                // 内嵌专用链接               
                this.youtube = url
            } else {
                this.playerOptions.sources[0].src = url
            }

            // 弹出
            this.show()
        },
        show () {
            this.status = true 
            this.changeEffect('fade-out')
        },
		open() {
			let arrplayTime = sessionStorage.getItem("arrplayTime")
			arrplayTime = JSON.parse(arrplayTime)
			if (arrplayTime != null && arrplayTime.length != 0) {
				this.arrplayTime = arrplayTime
			}else{
				this.arrplayTime = []
			}
			if (this.arrplayTime != [] && this.arrplayTime.length != 0) {
				this.playTime = this.checkFn(this.id,this.arrplayTime)
			}else{
				this.playTime = 0
			}
		},
        close (e) {
            this.status = false
            this.playerOptions.sources[0].src = this.youtube = ''
            this.changeEffect('fade-in')
			
			let playtimes = {
				id: this.id,
				playtime: this.playTime
			}
			this.arrplayTime = this.formateArrObjData(this.arrplayTime,playtimes,'id')
			
			sessionStorage.setItem("arrplayTime", JSON.stringify(this.arrplayTime))
			
           
        },
        changeEffect (name) {
            setTimeout(() => {
                this.effect = name
            }, 3e2)
        },
		
		
		playerStateChanged(player) {
			// console.log(player);
		},
		//监听媒体是否已到达结尾,播放完
		
		//DOM元素上的readyState更改导致播放停止。
		onPlayerWaiting(player) {
			// console.log(player);
		},
		//媒体不再被禁止播放,并且已开始播放。
		onPlayerPlaying(player) {
			// console.log(player);
		},
		//当播放器在当前播放位置下载数据时触发
		onPlayerLoadeddata(player) {
			// console.log(player);
		},
		//当前播放位置发生变化时触发。
		onPlayerTimeupdate(player) {
			this.playTime = player.cache_.currentTime
			// console.log(player);
		},
		//媒体的readyState为HAVE_FUTURE_DATA或更高
		onPlayerCanplay(player) {
			// console.log('player Canplay!', player)
		},
		//媒体的readyState为HAVE_ENOUGH_DATA或更高。这意味着可以在不缓冲的情况下播放整个媒体文件。
		onPlayerCanplaythrough(player) {
			// console.log('player Canplaythrough!', player)
		},
		//将侦听器绑定到组件的就绪状态。与事件监听器的不同之处在于,如果ready事件已经发生,它将立即触发该函数。。
		playerReadied(player) {
			// seek to 10s
			//console.log('example player 1 readied', player);
			player.currentTime(this.playTime)

			// console.log('example 01: the player is readied', player)
		},
		onPlayerPlay(player) {
			this.paused = false
			// console.log('onPlayerPlay!', player)
		},
		onPlayerPause(player) {
			this.paused = true
			// console.log('onPlayerPause!', player)
		},
		onPlayerEnded(player) {
			this.paused = false
			//console.log('player ended!', player)
		},
		
		//判断num在objarr里,拿到obj的另一个参数
		checkFn(num, objArr) {
			let times = 0
			if (!(objArr instanceof Array)) {
			  times = 0						//'请传入正确格式的数组'
			}
			
		  objArr.forEach(function (item) {
		    if (item.id == num) {
		        times = item.playtime
			   return false;
		    }
		  })
		  return times
		},
		//判断对象数组中是否有某个对象,有则替换无则添加
		formateArrObjData(initialArr, obj, pro) {
		  // 判定数据是否为数组
		  if (!(initialArr instanceof Array)) {
		    return 	[]						//'请传入正确格式的数组'
		  }
		  // 判定数据是否为对象
		  if (!(obj instanceof Object)) {
		    return 	[]						//'请传入正确格式的对象'
		  }
		  if (!pro) {
		    return 	[]						//'请传入正确格式的属性名'
		  }
		 
		  let index = initialArr.findIndex((val) => val[pro] === obj[pro])
		  let tempArr = initialArr
		  // 如果有就替换  没有就添加
		  if (initialArr.findIndex((val) => val[pro] === obj[pro]) !== -1) {
		    tempArr.splice(index, 1, obj);
		  } else {
		    tempArr.push(obj);
		  }
		  return tempArr
		},
		
    },
    mounted() {     
        let resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize'
        let setSize = () => {
            this.setHight = document.documentElement.clientHeight
        }
        window.addEventListener(resizeEvt, setSize, false)
        setSize()
		
    },
	
}
</script>

<style lang="scss">
	.video-player {
		display: table;
		width: 900px;
		height: 450px;
		position: fixed;
		top: 200px;
		left: 486px;
	    font-size: 36px;
	    background-color: rgba(0, 0, 0, 0.25);
	    z-index: 100;
		.video-js .vjs-big-play-button {
		    position: absolute;
		    top: 45%;
		    left: 45%;
		}
	}
    .video-main {
        display: table;
        width: 100%;
        height: 100%;
        position: fixed;
        top: 0;
        left: 0;
        font-size: 36px;
        background-color: rgba(0,0,0,0.25);
        z-index: 100;
        .video-box {
            display: table-cell;
            height: auto;
            vertical-align: middle;
            // padding-top: 20px;
            position: relative;
            max-height: 80%;
            .video-body {
                width: 1300px;
                margin: auto;
            }
            .video-header {
					display: table;
					width: 1px;
					height: 1px;
					position: fixed;
					margin: 8px 8px;
					top: 142px;
					left: 1330px;
                    font-size: 36px;
                    background-color: rgba(0, 0, 0, 0.25);
                    z-index: 100;
            }
            .video-close {
                float: right;
                width: 48px;
                line-height: 48px;
                text-align: center;
                font-size: 100%;
                font-weight: 100;
                color: #fff;
                background-color: #000;
                transition: background-color 0.25s, color 0.25s;
                cursor: pointer;
                &:hover {
                    color: #f56c6c;
                    background-color: #fff;
                }
            }
            .video-body{
                max-height: 88%;
            }
            .video {
                width: 100%;
                max-height: 100%;
            }
        }
    }
</style>

 类似资料: