一、安装

npm install vue-video-player --save

二、 组件内引入

import { videoPlayer } from 'vue-video-player'
import 'video.js/dist/video-js.css'
import 'vue-video-player/src/custom-theme.css'
export default {
  components: {
    videoPlayer
  }
}

问题1:拖动进度条和播放结束会触发暂停

uniapp H5项目内,视频点击暂停需显示蒙层,但是vue-video-player 拖动进度条和播放结束时也会触发暂停,这种情况下不需要展示蒙层,查看源码后,发现DEFAULT_EVENTS不包含拖动事件,可以传入:events=“[‘seeking’,‘seeked’]”,通过正在拖动和拖动结束事件给个标识。

IOS video禁止拖拽进度条 video拖动进度条_ide

主要代码

<template>
	<view class="video_box">
		<video-player @play="videoPlay" @pause="videoPause"
							@ended="videoEnded" @timeupdate="videoTimeUp" @loadeddata="videoLoaded"
							@seeking="videoSeeking" @seeked="videoSeeked" :events="['seeking','seeked']"
							class="video-player vjs-custom-skin" id="videoPlayer" ref="videoPlayer" :playsinline="true"
							:options="playerOptions">
		</video-player>
		<view class="subscribe-box flex justify-center align-center dir-col" v-if="isShowSubs && !isSeeking">
				<view class="mb-44 f-30 text-c">订阅后可观看完整课程</view>
				<view class="mb-44 subs-btn" @click="toSubscribe">立即订阅</view>
			</view>
	</view>

</template>
<script>
export default {
    data() {
        return { 
	        videoSrc: '',
	        durationTime: '', // 视频总时常
			currentTime: '', // 当前播放进度时长 
			isShowSubs:false,
            playerOptions: {
					playbackRates: [0.8, 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: [{
						type: "video/mp4", // 类型
						src: '' // url地址
					}],
					poster: '', // 封面地址
					notSupportedMessage: '此视频暂无法播放,请稍后再试', // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
					controlBar: {
						timeDivider: true, // 当前时间和持续时间的分隔符
						durationDisplay: true, // 显示持续时间
						remainingTimeDisplay: false, // 是否显示剩余时间功能
						fullscreenToggle: true // 是否显示全屏按钮
					}
				},
				isSeeking: false,
				isVideoEnd:false
        }
    },
	watch: {
		videoSrc(newVal) {
			this.$set(this.playerOptions.sources[0], 'src', newVal)
		}
	},
    onLoad() {
        this.initVideo()
    },  
    methods: { 
	    //初始化视频内容
	    initVideo(){
			//调用接口获取视频链接和进度
			this.videoSrc = res.url;
			this.progress = res.progress; 
			this.$nextTick(() => {  
				this.$refs.videoPlayer.player.play();
			})
		},
		// 视频信息加载完成,获取总时长,若接口返回进度,断点播放
		videoLoaded(item) {
			this.durationTime =  item.cache_.duration  
			if (this.progress > 0) { 
				item.currentTime(Number(this.durationTime) * Number(this.progress));	 
			}
		},
		// 当前播放进度
		videoTimeUp(item) {
			this.currentTime = item.cache_.currentTime 
		},
		// 正在拖动
		videoSeeking(item) {
			this.isSeeking = true
		},
		// 拖动结束
		videoSeeked(item) {
			this.isSeeking = false
		},
		// 点击播放
		videoPlay() {
			//清除定时器
			if (this.pauseTimer) {
				clearTimeout(this.pauseTimer);
			}
		},
		// 触发暂停
		videoPause(item) {
			//利用定时器延迟
			this.pauseTimer = setTimeout(() => {
				if(this.isVideoEnd)
					return
				if (this.isSeeking)
					return
				// 展示蒙层
				this.isShowSubs = true
			}, 100);
		}, 
		// 播放结束
		videoEnded() {
			this.isVideoEnd=true
		},
    }
}
</script>

问题2:微信h5无法自动播放

initVideo(){ 
		this.$nextTick(() => {  
			let video = this.$refs.videoPlayer.player;
			// 微信内置浏览器内置方法WeixinJSBridge
			if (window.WeixinJSBridge) {
			    WeixinJSBridge.invoke('getNetworkType', {},  (e) =>{
			        video.play();
			    }, false);
			}  else video.play();
		})
}

问题3:移动端倍速按钮改写

项目中视频播放主要在移动端H5,倍速点击无法显示菜单去选择,只能点击倍速按钮一直切换,vue-video-player底层用的video.js,要去改写PlaybackRateMenuButton

import _videojs from 'video.js'
const videojs = window.videojs || _videojs
data() {
    return { 
		playerOptions:{
			controlBar: {
				playbackRateMenuButton: false //隐藏原始播放速率按钮
			}
		}
	}
}
methods:{
	// 在播放前调用
	initRate() {
		//防止切换视频显示多个倍速按钮
		this.$refs.videoPlayer.player.getChild('controlBar').removeChild('definePlaybackRateMenuButton');
		//插件中的倍速菜单类名
		this.menu = this.$refs.videoPlayer.player.controlBar.el_.querySelector('.vjs-menu')
		//扩展原来的倍速按钮
		let definePlaybackRateMenuButton = videojs.extend(videojs.getComponent('PlaybackRateMenuButton'), { 
			handleClick: function() { 
				//video.js的样式会覆盖display:block, 需要移除
				this.menu.el_.classList.remove('vjs-hidden') 
				 //选择倍速后倍速菜单会隐藏,但是再次点击倍速按钮样式为block,无法显示菜单,所以这里处理为每次点击展示
				this.menu.el_.style.display ='block';
			},
			//这个方法必须,因为新组件需要自己的rates数组。player的option里面定义的只是PlaybackRateMenuButton原始组件的rates数组
			playbackRates: function() {
				return [2.0, 1.5, 1.25, 1.0, 0.8]
			}
		});
		//注册定义的新rate组件
		videojs.registerComponent('definePlaybackRateMenuButton', definePlaybackRateMenuButton);
		//将组件添加到控制栏的按钮组中,5是添加的位置
		this.$refs.videoPlayer.player.getChild('controlBar').addChild('definePlaybackRateMenuButton', {}, 5); 
	}
}
/* js配置将倍速隐藏了,所以这里需要展示 */
.vjs-control-bar .vjs-playback-rate{
	display: block !important;
}

问题4:video按钮样式

默认的底部按钮样式不符合UI,需要重写

.video_box {
		position: sticky;
		top: 0;
		z-index: 99;
		width: 100%;
		height: 484rpx;
		overflow-x: hidden;

		.vjs-custom-skin {
			/deep/ .video-js {
				width: 100%;
				height: 484rpx;
			}

			/*播放按钮设置成宽高一致,圆形,居中*/
			/deep/ .video-js .vjs-big-play-button {
				background-color: rgba(255, 255, 255, 0.7) !important;
				border-radius: 50% !important;
				width: 1.6em !important;
				height: 1.6em !important;
				margin-top: -1em !important;
				margin-left: -1em !important;
				color: #000 !important;
				border: none !important;
			}

			/* controls 播放按钮位置调整 */
			/deep/ .video-js .vjs-big-play-button .vjs-icon-placeholder:before {
				top: -12rpx;
			}

			/* controls 背景透明度调整 */
			/deep/ .video-js .vjs-control-bar {
				background-color: rgba(0, 0, 0, 0.7) !important;
			}

			/* controls 按钮去除默认样式 */
			/deep/ .video-js .vjs-control-bar .vjs-button {
				background-color: rgba(255, 255, 255, 0) !important;
				color: #fff !important;
				border: none !important;
				outline: none;
			}

			/* controls 调整IOS按钮不水平居中的问题 */
			/deep/ .video-js .vjs-control-bar .vjs-icon-placeholder:before {
				width: 76rpx !important;
				height: 84rpx !important;
				line-height: 84rpx !important;
			}

			/*进度条背景轨道*/
			/deep/ .video-js .vjs-slider {
				background-color: rgba(255, 255, 255, 0.45) !important;
				border-radius: 1em;
			}

			/*去除画中画按钮*/
			/deep/ .vjs-picture-in-picture-control {
				display: none;
			}
		} 
		
		/*进度条进度*/
		.vjs-custom-skin /deep/ .video-js .vjs-play-progress,
		.vjs-custom-skin /deep/ .video-js .vjs-volume-level {
			border-radius: 1em;
		}
	}