由于uni不能操作dom,所以我们需要使用renderjs来创建video视频的dom
1. 案例
<template>
<view class="video-plays">
<!-- video 视频 -->
<view class="video-js" :video="videoInfo" :change:video="video.updateData" ref="video"></view>
</view>
</template>
<script>
export default {
data(){
return {
videoInfo:{},
videoDom:"",
videoData:''
}
},
created(){
// 初始化页面,请求数据视频
uni.getStorage({
key: 'videoInfoMation',
success: (obj)=> {
this.getVideo(obj.data)
}
})
},
methods:{
//请求视频数据
getVideo(obj){
this.server.getVideo({
videoId: obj.videoId
})
.then(res => {
if (res.code == 200) {
let duration = {
start:obj.start,
end: obj.end
}
// 构造所需的数据,传递到renderjs里面,用于渲染videojs
this.videoInfo={
url:res.data.url, // 地址
duration:duration, // 渲染开始时间/结束时间对象
}
}
})
}
}
}
</script>
<script module="video" lang="renderjs">
// videojs 引入
import './video-offset.js';
import Videojs from 'video.js';
import 'video.js/dist/video-js.css';
export default {
data(){
return {
}
},
methods: {
// 初始化视频
initVideo(url,duration){
// 清空已存在是vidoejs
if(this.videoDom){
this.videoDom.dispose();
this.videoDom = null;
}
// 创建video并且添加属性
var video = document.createElement('video')
video.id = 'video'
video.style = 'width: 100%;' // 不设置高度,让视频自动撑开
video.setAttribute("class", "video-js vjs-default-skin vjs-big-play-centered");
video.controls = true
this.$refs.video.$el.appendChild(video)
// 设置option
let option ={
controls: true,
muted: false, // 静音切换
autoplay: false,
fluid: true, //宽高自适应
preload: "auto",
loop: true,//循坏播放
sources: [
{
type: "video/mp4", // mp4格式
src: url
},
{
type: "video/webm",// webm格式
src: url
}
],
controlBar: {
//控制条组件
children: [
{
name: 'playToggle',
}, // 播放按钮
{
name: 'volumePanel', // 音量控制
inline: false, // 不使用水平方式
},
{
name: 'currentTimeDisplay',
}, // 当前已播放时间
{
name: 'timeDivider',
}, // 时间分割线
{
name: 'durationDisplay',
}, // 总时间
{
name: 'progressControl',
}, // 播放进度条
]
},
};
let _this = this
// 创建videojs实例
this.videoDom =Videojs(video,option ,function onPlayerReady() {
this.on("loadstart",function(){
console.log("开始请求数据 ");
})
this.on("progress",function(){
console.log("正在请求数据 ");
})
this.on("loadedmetadata",function(){
console.log("获取资源长度完成 ")
})
this.on("canplaythrough",function(){
console.log("视频源数据加载完成")
})
this.on("waiting", function(){
console.log("等待数据")
});
this.on("play", function(){
console.log("视频开始播放")
});
this.on("playing", function(){
console.log("视频播放中")
});
this.on("pause", function(){
console.log("视频暂停播放")
});
this.on("ended", function(){
console.log("视频播放结束");
});
this.on("error", function(){
console.log("加载错误")
});
this.on("seeking",function(){
console.log("视频跳转中");
})
this.on("seeked",function(){
console.log("视频跳转结束");
})
this.on("ratechange", function(){
console.log("播放速率改变")
});
this.on("timeupdate",function(){
console.log("播放时长改变");
})
this.on("volumechange",function(){
console.log("音量改变");
})
this.on("stalled",function(){
console.log("网速异常");
})
});
// 截取时间播放
this.videoDom.offset({
start: duration.start,
end: duration.end,
})
},
// 监听从从外部传递进来的数据
updateData(newValue, oldValue, ownerInstance, instance) {
if(newValue !==oldValue){
// 监听 service 层数据变更
this.initVideo(newValue.url,newValue.duration)
}
},
}
}
</script>
<style lang="less" scoped>
</style>
// offset.js
/* eslint-disable no-unused-vars */
/*! @name videojs-offset @version 2.1.0 @license MIT */
import videojs from 'video.js';
var version = "2.1.0";
var defaults = {}; // Cross-compatibility for Video.js 5 and 6.
var registerPlugin = videojs.registerPlugin || videojs.plugin; // const dom = videojs.dom || videojs;
/**
* Checks whether the clip should be ended.
*
* @function onPlayerTimeUpdate
*
*/
var onPlayerTimeUpdate = function onPlayerTimeUpdate() {
var curr = this.currentTime();
if (curr < 0) {
this.currentTime(0);
this.play();
}
// console.log('this._offsetEnd', this._offsetEnd);
// console.log('curr', curr);
// console.log('this._offsetStart', this._offsetStart);
if (this._offsetEnd > 0 && curr > this._offsetEnd - this._offsetStart) {
// this.off('timeupdate', onPlayerTimeUpdate);
this.pause();
// this.trigger('ended');
if (!this._restartBeginning) {
this.currentTime(this._offsetEnd - this._offsetStart);
} else {
this.trigger('loadstart');
// this.currentTime(0);
}
}
};
/**
* Function to invoke when the player is ready.
*
* This is a great place for your plugin to initialize itself. When this
* function is called, the player will have its DOM and child components
* in place.
*
* @function onPlayerReady
* @param {Player} player
* A Video.js player.
* @param {Object} [options={}]
* An object of options left to the plugin author to define.
*/
var onPlayerReady = function onPlayerReady(player, options) {
player.one('play', function () {
player.on('timeupdate', onPlayerTimeUpdate);
});
};
/**
* A video.js plugin.
*
* In the plugin function, the value of `this` is a video.js `Player`
* instance. You cannot rely on the player being in a "ready" state here,
* depending on how the plugin is invoked. This may or may not be important
* to you; if not, remove the wait for "ready"!
*
* @function offset
* @param {Object} [options={}]
* An object of options left to the plugin author to define.
*/
var offset = function offset(options) {
var _this = this;
options = options || {};
var Player = this.constructor;
this._offsetStart = parseFloat(options.start || '0');
this._offsetEnd = parseFloat(options.end || '0');
this._restartBeginning = true;
if (!Player.__super__ || !Player.__super__.__offsetInit) {
Player.__super__ = {
__offsetInit: true,
duration: Player.prototype.duration,
currentTime: Player.prototype.currentTime,
bufferedPercent: Player.prototype.bufferedPercent,
remainingTime: Player.prototype.remainingTime
};
Player.prototype.duration = function () {
if (this._offsetEnd > 0) {
return this._offsetEnd - this._offsetStart;
}
return Player.__super__.duration.apply(this, arguments) - this._offsetStart;
};
Player.prototype.currentTime = function (seconds) {
var num = seconds + this._offsetStart
if (isNaN(num)) {
num = 0
}
if (seconds !== undefined) {
return Player.__super__.currentTime.call(this, num);
}
return Player.__super__.currentTime.apply(this) - this._offsetStart;
};
Player.prototype.remainingTime = function () {
return this.duration() - this.currentTime();
};
Player.prototype.startOffset = function () {
return this._offsetStart;
};
Player.prototype.endOffset = function () {
if (this._offsetEnd > 0) {
return this._offsetEnd;
}
return this.duration();
};
}
this.ready(function () {
onPlayerReady(_this, videojs.mergeOptions(defaults, options));
});
}; // Register the plugin with video.js.
registerPlugin('offset', offset); // Include the version number.
offset.VERSION = version;
export default offset;
网友评论