tb-shop-video
Version:
single video component for tbshop
301 lines (249 loc) • 7.62 kB
JavaScript
const throttle = function (func, delay) {
var prev = Date.now();
return function () {
var context = this;
var args = arguments;
var now = Date.now();
if (now - prev >= delay) {
func.apply(context, args);
prev = Date.now();
}
}
}
Component({
data: {
// uniqueId,必须调用getUniqueId生成
// uniqueId: modUtils.helper.getUniqueId('video'),
uniqueId: '',
enableNative: my.renderTarget === 'h5' ? false : undefined,
// 网络状态
// networkType: my.isIDE ? '4G' : 'WIFI',
networkType: '4G',
// 是否静音播放
isVideoMuted: true,
videoTime: 0, // 单位s
remainTime: '00:00', // 单位s
logs: [],
},
onInit() {
const { gdc = {}, mds = {}, modUtils } = this.props;
this.setData({
uniqueId: 'video-' + new Date().getTime() + Math.round(Math.random() * 1000)
});
this.isVideoPlaying = false;
this.isVideoVisible = false;
// mock数据需要修改client文件夹中的page文件
// 正常运行过程中模块总是默认传入data参数
},
deriveDataFromProps(nextProps) {
if (nextProps.muted !== undefined &&
nextProps.muted !== this.props.muted &&
!!nextProps.muted !== this.data.isVideoMuted) {
this.muteVideo(!this.data.isVideoMuted);
}
},
didMount() {
// 加载成功后可以异步获取数据更新数据展示,例如请求接口等操作
const { gdc = {}, mds = {}, modUtils } = this.props;
// 绑定事件
this.bindEvents();
// 初始化视频
this.videoContext = this.videoContext || my.createVideoContext(this.data.uniqueId);
this.setData({
videoTime: this.props.time,
remainTime: this.timeFormatter(this.props.time),
});
this.muteVideo(this.props.muted);
// 获取网络状态
let getNetworkType = (modUtils.my && modUtils.my.getNetworkType) || my.getNetworkType;
if (typeof getNetworkType === 'function') {
getNetworkType({
success: (res) => {
this.setData({
networkType: res.networkType
});
if (this.data.networkType === 'WIFI') {
this.playVideo();
}
},
fail: (err) => {
console.error(`[tb-shop-video getNetworkType failed] ${JSON.stringify(err)}`);
}
});
}
this.doTimeUpdate = throttle(function doTimeUpdate(e) {
const { onTimeUpdate } = this.props;
if (typeof onTimeUpdate === 'function') {
onTimeUpdate(e);
}
if (!this.props.showTime) {
return;
}
let { currentTime } = e.detail || {}
currentTime = Math.floor(currentTime);
this.setData({
remainTime: this.timeFormatter(this.data.videoTime - currentTime),
});
}.bind(this), 1000);
},
didUnmount() {
this.offEvents();
},
methods: {
timeFormatter(time) {
let seconds = (time % 60) || '00';
let minutes = (Math.floor(time / 60) % 60) || '00';
let timeStr = '';
if (String(minutes).length === 1) {
minutes = `0${minutes}`;
}
if (String(seconds).length === 1) {
seconds = `0${seconds}`;
}
timeStr += `${minutes}:`;
timeStr += `${seconds}`;
return timeStr;
},
// 播放或暂停视频
playVideo(shouldPlay = true) {
const { gdc = {}, mds = {}, modUtils } = this.props;
if (shouldPlay && this.data.networkType !== 'WIFI') {
return;
}
// 如果视频没有实例化
if (!this.videoContext) {
return false;
}
// 如果视频不可见,不响应播放
if (shouldPlay === true) {
if (!this.isVideoVisible || this.isVideoPlaying) {
return false;
}
}
if (shouldPlay === false && !this.isVideoPlaying) {
return false;
}
this.isVideoPlaying = shouldPlay;
if (shouldPlay) {
this.videoContext.play();
// 当前视频播放,抛出一个事件,阻止其他所有视频播放
modUtils.emitter.emit('share:play_video', {
uniqueId: this.data.uniqueId
});
} else {
this.videoContext.pause();
}
modUtils.isvLogger.sendLog && modUtils.isvLogger.sendLog('Page_Shop_isv_singe_video-player', 'OTHER', {
shop_id: gdc.shopId,
seller_id: gdc.userId,
widgetId: mds.widgetId,
moduleName: mds.moduleName,
isVideoPlay: shouldPlay,
videoId: this.props.videoId
});
},
handleMuteVideo (e) {
this.muteVideo();
},
muteVideo(muted) {
const { gdc = {}, mds = {}, modUtils } = this.props;
let { isVideoMuted } = this.data || {};
if (muted === undefined) {
isVideoMuted = !isVideoMuted;
} else {
isVideoMuted = !!muted;
}
this.setData({
isVideoMuted
});
if (!this.videoContext) {
return;
}
this.videoContext.mute(isVideoMuted);
modUtils.isvLogger.sendLog && modUtils.isvLogger.sendLog('Page_Shop_isv_singe_video-sound', 'OTHER', {
shop_id: gdc.shopId,
seller_id: gdc.userId,
widgetId: mds.widgetId,
moduleName: mds.moduleName,
isVideoMuted,
videoId: this.props.videoId
});
},
bindEvents() {
const { modUtils } = this.props;
let { EVENT_NAME_MAP = {} } = (modUtils && modUtils.CONSTANTS) || {};
modUtils.emitter.on('share:play_video', (params) => {
let { uniqueId } = params || {}
if (this.data.uniqueId !== uniqueId) {
this.playVideo(false);
}
});
modUtils.emitter.on(EVENT_NAME_MAP.PAGE_DISAPPEAR || 'page.disappear', () => {
this.playVideo(false);
});
modUtils.emitter.on(EVENT_NAME_MAP.PAGE_APPEAR || 'page.appear', () => {
this.setData({
logs: this.data.logs.concat('page:' + new Date().toLocaleTimeString()),
});
this.playVideo();
});
},
offEvents() {
const { modUtils } = this.props;
let { EVENT_NAME_MAP = {} } = modUtils.CONSTANTS || {};
modUtils.emitter.off(EVENT_NAME_MAP.PAGE_DISAPPEAR || 'page.disappear');
modUtils.emitter.off(EVENT_NAME_MAP.PAGE_APPEAR || 'page.appear');
},
handleVideoAppear() {
this.setData({
logs: this.data.logs.concat('video:' + new Date().toLocaleTimeString()),
});
this.isVideoVisible = true;
this.playVideo();
},
handleVideoDisappear() {
this.isVideoVisible = false;
this.playVideo(false);
},
handleClickVideoMask() {
// 默认视频不允许暂停
if (this.props.canPause) {
if (this.isVideoPlaying) {
this.playVideo(false);
} else {
this.playVideo();
}
}
},
handleVideoError(e) {
const { modUtils } = this.props;
let showToast = (modUtils && modUtils.my && modUtils.my.showToast) || my.showToast;
if (typeof showToast === 'function') {
showToast({
content: '视频播放失败,请稍后再试~'
});
}
},
handleUpdateTime(e) {
this.doTimeUpdate(e);
},
handlePlay(e) {
const { onPlay } = this.props;
if (typeof onPlay === 'function') {
onPlay(e);
}
},
handlePause(e) {
const { onPause } = this.props;
if (typeof onPause === 'function') {
onPause(e);
}
},
handleEnded(e) {
const { onEnded } = this.props;
if (typeof onEnded === 'function') {
onEnded(e);
}
}
}
});